Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

PIC18F46K22 collegamento EUSART

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] PIC18F46K22 collegamento EUSART

Messaggioda Foto Utentespivo » 16 apr 2015, 20:20

Ciao a tutti,
E' da qualche settimana che tento di far funzionare l'EUSART di un PIC18F46K22 http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf cosa che con PIERIN mi è sempre riuscita.
Ho scritto tutto il codice in un unica funzione per farlo leggere più facilmente.

Codice: Seleziona tutto
void main(void)
{
// CONFIGURAZIONE OSCILLATORE
OSCCON = 0b01110000;    // bit7: device enters SLEEP on sleep instruction[0]
                        // bit6-4: HFINTOSC 16MHz [111]
                        // bit3: status bit [0]
                        // bit2: status bit [0]
                        // bit1-0: clock defined by CONFIG bits [00]
OSCTUNE = 0b11000000;   // bit7:  device clock derived from the MFINTOSC or HFINTOSC source
                        // bit6: PLL enabled [1]
                        // bit5-0: oscillator tuning [000000]
Delay1KTCYx(10);

    char ch;

    UART1MD = 0;

    LATA = 0x00;
    TRISA = 0xFF;

    LATB = 0x00;
    TRISB = 0xFF;
   
    //RC6 = TX1  RC7 = RX1
    ANSELC = 0x00; //datasheet pag 296
    //the analog I/O function must be disabled by clearing the corrisponding ANSEL bit
    LATC = 0x00;
    TRISC = 0xFF;  //datasheet pag 268 RX1 e TX1 set 1
   
    LATD = 0x00;
    TRISD = 0x00; //USCITE
    LATE = 0x00;
    TRISE = 0xFF;


    RC1IE = 1;
    RC1IP = 1;

    GIE = 1;
    PEIE = 1;

// trasmissione a 19200 8 bit 1 di stop
    SPBRG1 = 0b01000000;     //parte bassa freq
    SPBRGH1 = 0b00000011;    //parte alta ferq

    BAUDCON1bits.BRG16 = 1;
    TXSTA1bits.BRGH = 1;

    TXSTA1bits.SYNC = 0;
    RCSTA1bits.SPEN = 1;
    TXSTA1bits.TXEN = 1;
    RCSTA1bits.CREN = 1;

    RC1IE=1;
    RC1IP=1;

    GIE=1;
    PEIE=1;

//MESSAGGIO 123
    while(!PIR1bits.TX1IF);
    TXREG1 = 49;
    while(!PIR1bits.TX1IF);
    TXREG1 = 50;
    while(!PIR1bits.TX1IF);
    TXREG1 = 51;

//CICLO INFINITO
    while(1)
    {

    while(!PIR1bits.RC1IF);
    ch = RCREG1;

    while(!PIR1bits.TX1IF);
    TXREG1 = ch;

    if (ch == 50) LATD = 0xFF;
     
    }
}

Ho collegato il PIC ad un convertitore seriale/USB e uso un "Hiperterminal" per comunicare, ma purtroppo c'è qualcosa che non va.
In pratica quando attivo il PIC dovrei ricevere il messaggio 123, ma ricevo solo 13, ed il ciclo infinito non finziona.
Credo sia un problema di interrupt visto che con l'ausilio di qualche led mi sono accorto che il ciclo infinito si blocca all'istruzione while(!PIR1bits.RC1IF);.
Avete consigli? Grazie ciao Ivo.
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

0
voti

[2] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto UtenteWALTERmwp » 17 apr 2015, 1:45

Ciao Foto Utentespivo, premetto di non avere controllato i bit(s)/registri di configurazione e il datasheet ma non vedo la presenza della routine di interrupt.
Gli interrup(s) (alcuni) sono abilitati ma nulla che gestisca il vettore (low o high).
Quando si verificano il PC viene portato a quegli indirizzi, ma poi, che istruzioni trova ?
I risultati potrebbero essere anche imprevedibili.
Non credo basti affidarsi all'assegnazione di un valore sul TXREG1 o alla lettura dello RCREG1 per azzerare le rispettive flag(s).

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[3] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto Utentespivo » 17 apr 2015, 13:15

Grazie Foto UtenteWALTERmwp, Siccome ho appena iniziato ad usare questo micro non ho ancora sviluppato bene gli interrupt, per ora mi accontentavo di una semplice funzione di echo spudoratamente copiata da http://www.electroyou.it/tardofreak/wiki/pierin-pic18-nozioni-di-base-sulla-seriale di Foto UtenteTardoFreak, che su pierin funziona.
Sto ancora provando ma per ora non capisco cosa sbaglio.
Grazie Ciao Ivo
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

0
voti

[4] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto UtenteWALTERmwp » 17 apr 2015, 14:15

spivo ha scritto:Grazie
prego, figurati.
Proporrei, al momento, di limitare confronti o comparazioni con altri riferimenti mantenendo l'osservazione su quanto hai scritto.
spivo ha scritto:Sto ancora provando ma per ora non capisco cosa sbaglio.

Come ti ho riportato non vedo il richiamo alla routine di interrupt; inseriscila nel tuo codice, in base a quanto prevede la sintassi del linguaggio che preferisci usare, in modo tale che poi, una volta eseguita, ritorni in maniera ortodossa al tuo main; per ciò non è necessario altro se non ripristinare l'abilitazione generale degli interrupt(s).
Infatti, una volta che il codice è passato ad eseguire quanto previsto nella routine di interrupt (e a prescindere da quanto essa contiene), gli interrupt(s) credo vengano disabilitati.
Allora, se si vuole che al termine e all'uscita della routine gli interrupt(s) continuino ad essere gestiti è indispensabile abilitarli nuovamente ( ... questo a meno di eccezioni relative a questo PIC18).
Fai questa prova e facci sapere.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[5] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto Utentespivo » 17 apr 2015, 20:32

Ciao,
WALTERmwp ha scritto:Come ti ho riportato non vedo il richiamo alla routine di interrupt; inseriscila nel tuo codice, in base a quanto prevede la sintassi del linguaggio che preferisci usare,

Io uso Mplabx e xc8 le routine di interrupt sono queste:
Codice: Seleziona tutto
/******************************************************************************/
/*Files to Include                                                            */
/******************************************************************************/

#if defined(__XC)
    #include <xc.h>         /* XC8 General Include File */
#elif defined(HI_TECH_C)
    #include <htc.h>        /* HiTech General Include File */
#elif defined(__18CXX)
    #include <p18cxxx.h>    /* C18 General Include File */
#endif

#if defined(__XC) || defined(HI_TECH_C)

#include <stdint.h>         /* For uint8_t definition */
#include <stdbool.h>        /* For true/false definition */
#include "user.h"
#endif

/******************************************************************************/
/* Interrupt Routines                                                         */
/******************************************************************************/

/* High-priority service */

#if defined(__XC) || defined(HI_TECH_C)
void interrupt high_isr(void)
#elif defined (__18CXX)
#pragma code high_isr=0x08
#pragma interrupt high_isr
void high_isr(void)
#else
#error "Invalid compiler selection for implemented ISR routines"
#endif

{
// if (RC1IF)
//    {
//
//        while(!PIR1bits.RC1IF);
//        ch = RCREG1;
//
//        while(!PIR1bits.TX1IF);
//        TXREG1 = ch;
//
//
//
//
//
//    }


      /* This code stub shows general interrupt handling.  Note that these
      conditional statements are not handled within 3 seperate if blocks.
      Do not use a seperate if block for each interrupt flag to avoid run
      time errors. */

#if 0
   
      /* TODO Add High Priority interrupt routine code here. */

      /* Determine which flag generated the interrupt */
      if(<Interrupt Flag 1>)
      {
          <Interrupt Flag 1=0>; /* Clear Interrupt Flag 1 */
      }
      else if (<Interrupt Flag 2>)
      {
          <Interrupt Flag 2=0>; /* Clear Interrupt Flag 2 */
      }
      else
      {
          /* Unhandled interrupts */
      }

#endif

}

/* Low-priority interrupt routine */
#if defined(__XC) || defined(HI_TECH_C)
void low_priority interrupt low_isr(void)
#elif defined (__18CXX)
#pragma code low_isr=0x18
#pragma interruptlow low_isr
void low_isr(void)
#else
#error "Invalid compiler selection for implemented ISR routines"
#endif
{

      /* This code stub shows general interrupt handling.  Note that these
      conditional statements are not handled within 3 seperate if blocks.
      Do not use a seperate if block for each interrupt flag to avoid run
      time errors. */

#if 0

      /* TODO Add Low Priority interrupt routine code here. */

      /* Determine which flag generated the interrupt */
      if(<Interrupt Flag 1>)
      {
          <Interrupt Flag 1=0>; /* Clear Interrupt Flag 1 */
      }
      else if (<Interrupt Flag 2>)
      {
          <Interrupt Flag 2=0>; /* Clear Interrupt Flag 2 */
      }
      else
      {
          /* Unhandled interrupts */
      }

#endif

}

Sono quelle che mi si creano nel file interrupts.c quando uso PIC 18 C template da Nuovo progetto.
Ho fatto svariati tentativi, utilizzando anche le routine interrupt ma nulla.
Quando eseguo while(!PIR1bits.TX1IF); non aspetta, quando eseguo while(!PIR1bits.RC1IF); si blocca e se riceve qualcosa non va alla routine di interrupt :?
Grazie ancora ciao
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

0
voti

[6] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto UtenteWALTERmwp » 18 apr 2015, 8:12

Ma adesso, il file che contiene la routine di interrupt è compreso nella compilazione ?
Se si, cosa prevede come codice ?
spivo ha scritto:Ho fatto svariati tentativi, utilizzando anche le routine interrupt ma nulla.
ma "nulla" cosa significa ?
Il medesimo risultato o riscontri differenti tra loro in base a tentativi differenti ?

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[7] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto Utentespivo » 18 apr 2015, 20:11

Ciao,
penso di si che sia che il file interrupt.c sia compreso nella compilazione, ci pensa il template, per ora le routine sono vuote, volevo delegare la ricezione del carattere a:
Codice: Seleziona tutto
   while(!PIR1bits.RC1IF);
    ch = RCREG1;
direttamente del main.
spivo ha scritto: spivo ha scritto:Ho fatto svariati tentativi, utilizzando anche le routine interrupt ma nulla.

ma "nulla" cosa significa ?
Il medesimo risultato o riscontri differenti tra loro in base a tentativi differenti ?

Sempre il medesimo risultato sembra che il pin 26 alias rc7 alias rx1 non sia in ricezione.

Ho provato un'altra cosa cercando in internet ho scoperto che xc8 ha una libreria usart.h con la quale ho provato a scrivere questo:
Codice: Seleziona tutto
/******************************************************************************/
/* Files to Include                                                           */
/******************************************************************************/

#if defined(__XC)
    #include <xc.h>        /* XC8 General Include File */
#elif defined(HI_TECH_C)
    #include <htc.h>       /* HiTech General Include File */
#elif defined(__18CXX)
    #include <p18cxxx.h>   /* C18 General Include File */
#endif

#if defined(__XC) || defined(HI_TECH_C)

#include <pic18f46k22.h>
#include <stdint.h>        /* For uint8_t definition */
#include <stdbool.h>       /* For true/false definition */
#include <usart.h>
#endif

#include "system.h"        /* System funct/params, like osc/peripheral config */
#include "user.h"          /* User funct/params, such as InitApp */


void main(void)
{
    /* Configure the oscillator for the device */
    ConfigureOscillator();

    /* Initialize I/O and Peripherals for application */
    InitApp();

    int i;

    LATA = 0x00;
    TRISA = 0xFF;
    LATB = 0x00;
    TRISB = 0xFF;
    LATC = 0x00;
    TRISC = 0x00;
    LATD = 0x00;
    TRISD = 0x00; //USCITE
    LATE = 0x00;
    TRISE = 0xFF;

    Open1USART( USART_TX_INT_ON &
            USART_RX_INT_ON &
            USART_ASYNCH_MODE &
            USART_EIGHT_BIT &
            USART_SINGLE_RX &
            USART_BRGH_HIGH,
            207);

    char ch = 0;

    Write1USART(50);
    while (Busy1USART());
    Write1USART(51);
    while (Busy1USART());
    Write1USART(52);
    while (Busy1USART());
    Write1USART(53);
    while (Busy1USART());
    Write1USART(54);
    while (Busy1USART());
    Write1USART(55);
    while (Busy1USART());

    while (!DataRdy1USART());
    ch = Read1USART();

    Write1USART(ch);
    while (Busy1USART());

    while(1)
    {
        LATD = 0xFF;
        for (i=0;i<4000; i++){
        __delay_ms(1);
        }
        LATD = 0x00;
        for (i=0;i<400; i++){
        __delay_ms(1);
        }
   }

}


:evil: Ma sempre lo stesso problema, invia i dati e non li riceve, per la precisione il programma scrive 234567 e poi non arriva al ciclo infinito che è un semplice lampeggio.
PS il convertitore seriale-usb sembra funzionare bene ho provato a fare un loop e riceve ed invia correttamente.
Grazie ancora Ciao.
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

0
voti

[8] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto UtenteWALTERmwp » 19 apr 2015, 10:50

Non riesco a capire in quale condizione ti trovi.
Si potrebbe provare ad eliminare una variabile evitando, al momento, di richiamare i vettori di interrupt(s).
Commenta nel codice l'abilitazione (GIE ...), che tra l'altro è doppia, ma conserva, come test dell'avvenuta trasmissione o ricezione, l'interrogazione delle flag(s) TX1IF e RC1IF, ammesso che questo sia sufficiente ad evitare la generazione e l'inclusione del modulo "interrupt.c".
In alternativa (lasciando quindi l'abilitazione per GIE), come altra verifica, proverei a commentare le tre scritture dei tre caratteri che precedono l'ingresso al while infinito.
Cosa ne pensi ?

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[9] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto Utentespivo » 19 apr 2015, 13:03

grazie Foto UtenteWALTERmwp per il supporto.
Ho provato con o senza attivare gli interrupt, il risultato è sempre quello, il PIC non riceve i dati, ho provato anche ad eliminare la trasmissione prima del ciclo infinito ma nulla.
Per sicurezza (magari sbaglio i collegamenti ho una porta bruciata ?) ho provato anche l'USART2 ed un altro pic18f46k22, ma nulla.
Cercando in giro ho trovato questa discussione http://www.microchip.com/forums/m708959.aspx dove parlano (se non ho capito male) di un OERR flag, che non ho idea di cosa sia ora prova a fare qualche ricerca.
Grazie ancora ciao Ivo
Avatar utente
Foto Utentespivo
375 1 12
Frequentatore
Frequentatore
 
Messaggi: 179
Iscritto il: 19 dic 2012, 21:29

0
voti

[10] Re: PIC18F46K22 collegamento EUSART

Messaggioda Foto UtenteWALTERmwp » 19 apr 2015, 19:50

spivo ha scritto:Cercando in giro ho trovato questa discussione
si fa riferimento al bit di "overrun" (OERR) cioè si sovra-scrittura.
In quella discussione, però, la ricezione è relativa ad un flusso di dati (videocamera) ben diverso dal tuo caso, a meno che in output, tramite hyperterminal, tu generi l'invio (di un file) senza controllo.
Potresti intanto riportare, in FidoCadJ, la parte dello schema del collegamento "micro-convertitore-PC" ?

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
23,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6833
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti