RS232 receiver problem PIC16

Thread Starter

Egberts

Joined Jun 7, 2014
13
Hey guys!
I am stuck with a little project of mine and I hope you can help me.
I'm quite new to PIC programming and i am trying to build a PIC to PIC serial communication. I already programmed the sender, but now i have problems with the receiver part. I want to make a LED flash on RC0 every time a receiving interrupt occurs to check if it works. I use the PICkit 2 UART tool to send to my PIC, but when I do, nothing happens. Is there somthing wrong in the code or am i missing something?

Thanks in advance!

Rich (BB code):
#include <htc.h>
#include <pic16f690.h>


    unsigned char counter=0;//Overflow counter
    unsigned char counter2=0;//Overflow counter

    void initTMR0 (void);
    void initUART (void);

    void main()
    {
       initTMR0();  //TMR0 init
       initUART();  // UART init
       ANSEL = 0;
       TRISB5 = 1; //RX input
       TRISB7 = 0;// TX output
       TRISC=0;     // PORTC = output
       PORTC=0;     // PORTC reset

      while(1)
      {

      };
    }


    void initTMR0(void)
    {
       OPTION_REGbits.PS0=1; //Prescaler is divide by 256
       OPTION_REGbits.PS1=1;
       OPTION_REGbits.PS2=1;
       OPTION_REGbits.PSA=0; //Timer Clock Source is from Prescaler
       OPTION_REGbits.T0CS=0;//Prescaler gets clock from FCPU (1MHz)

       INTCONbits.T0IE=1;   //Enable TIMER0 Interrupt
       INTCONbits.T0IF=0;
       INTCONbits.PEIE=1;     //Enable Peripheral Interrupt
       INTCONbits.GIE=1;      //Enable interrupts globally

       PIR1bits.RCIF = 0;  // make interrupt flag = 0

    }

    void initUART(void)
    {
        SPBRG = 25; //Fosch 4Mhz -> baudrate 2400
        TXSTAbits.BRGH = 0;  //Sets Low Baud Rate
        TXSTAbits.SYNC = 0;  //Sets Asynchronous mode
        RCSTAbits.SPEN = 1;  //Enables EUSART
       // TXSTAbits.TXEN = 1;  //Enables the EUSART transmiter
        RCSTAbits.CREN = 1; //enable receive
        PIE1bits.RCIE = 1;  //enables receive interrupt flag
        
    }


    //Main Interrupt Service Routine (ISR)
    void interrupt ISR ()
    {
        //unsigned char c;

   if (PIR1bits.RCIF == 1)                  //check for recieve interrupt
     {
                  counter ++;
           if (counter == 15)
           {
                counter = 0;
                PORTC=0b00000001;
           }
           else PORTC=0;
         PIR1bits.RCIF=0;                     //  interrupt flag off
      }

}
 

Thread Starter

Egberts

Joined Jun 7, 2014
13
Thanks for your reply!
I tried to disable the TMR0 interrupt, but still nothing happens.
Is there something wrong with my code or am i missing something?
 

Thread Starter

Egberts

Joined Jun 7, 2014
13
Allright thanks for the answers guys!
So i implemented an unsigned to read the RCREG and commented the TMR0 interrupt and this gave me some promising results. But still the LED isn't blinking so I dont know for sure if the communication works. What would be the next step?
Tanks!

The modified code:
Rich (BB code):
#include <htc.h>
#include <pic16f690.h>


    unsigned char counter=0;//Overflow counter
    unsigned char counter2=0;//Overflow counter

    void initTMR0 (void);
    void initUART (void);

    void main()
    {
       initTMR0();  //TMR0 init
       initUART();  // UART init
       ANSEL = 0;
       TRISB5 = 1; //RX input
       TRISB7 = 0;// TX output
       TRISC=0;     // PORTC = output
       PORTC=0;     // PORTC reset

      while(1)
      {

      };
    }


    void initTMR0(void)
    {
       OPTION_REGbits.PS0=1; //Prescaler is divide by 256
       OPTION_REGbits.PS1=1;
       OPTION_REGbits.PS2=1;
       OPTION_REGbits.PSA=0; //Timer Clock Source is from Prescaler
       OPTION_REGbits.T0CS=0;//Prescaler gets clock from FCPU (1MHz)

       //INTCONbits.T0IE=1;   //Enable TIMER0 Interrupt
       //INTCONbits.T0IF=0;
       INTCONbits.PEIE=1;     //Enable Peripheral Interrupt
       INTCONbits.GIE=1;      //Enable interrupts globally

       PIR1bits.RCIF = 0;  // make interrupt flag = 0

    }

    void initUART(void)
    {
        SPBRG = 25; //Fosch 4Mhz -> baudrate 2400
        TXSTAbits.BRGH = 0;  //Sets Low Baud Rate
        TXSTAbits.SYNC = 0;  //Sets Asynchronous mode
        RCSTAbits.SPEN = 1;  //Enables EUSART
       // TXSTAbits.TXEN = 1;  //Enables the EUSART transmiter
        RCSTAbits.CREN = 1; //enable receive
        PIE1bits.RCIE = 1;  //enables receive interrupt flag

    }


    //Main Interrupt Service Routine (ISR)
    void interrupt ISR ()
    {
        unsigned c;

   if (PIR1bits.RCIF == 1)                  //check for receive interrupt
     {
                  counter ++;
           if (counter == 15)
           {
		c = RCREG;
                counter = 0;
                PORTC=0b00000001;
           }
           else PORTC=0;
         //PIR1bits.RCIF=0;                     //  interrupt flag off
      }

}
 

John P

Joined Oct 14, 2008
2,026
This may be a dumb response, but please assure us that you've wired between pins 18 and 12, and pins 19 and 10, assuming the PICkit is still connected to the programming pins (i.e. pins 19 and 18). The UART in the PICkit communicates over the two data lines, but obviously those lines have to be connected to the PIC's UART! Also, you aren't explicitly setting the TRIS bits for A0 and A1 to high-Z; even if the default state on reset does that, I always set them.

And please, humor our nerdiness and don't say "RS232" when you mean UART or serial port. It's not RS232 unless you use the specified voltages, which everyone tries to avoid.

A handy way to test a UART is
Rich (BB code):
   if (PIR1bits.RCIF == 1)                  //check for recieve interrupt SP-1
     txreg = rcreg;
No interrupts needed. Just put it in a loop and see if what goes in comes out.
 

Thread Starter

Egberts

Joined Jun 7, 2014
13
I am sorry John, but i don't really understand what you mean. I placed the PIC on my breadboard and made two 'headers':
- The program header: attached all the necessary lines to program device.
- The UART header: Pin 2 VDD, pin 3 VSS, pin 4 (PIC)TX and pin 5 (PIC)RX, like in the PICkit 2 user guide.

Haha i am sorry I confused those, I get the difference now!

I followed your advice and i placed your line of code in my while(1) loop, but i still don't get any response from my UART. Same result all over again..
 

paulfjujo

Joined Mar 6, 2014
23
hello,

try to reverse the order in the hardware init part

Rich (BB code):
void main()
    {
       initTMR0();  //TMR0 init
       ANSEL = 0;
       ANSELH=0;
        TRISB5 = 1; //RX input
       TRISB7 = 0;// TX output
       TRISC=0;     // PORTC = output
       PORTC=0;     // PORTC reset
        initUART();  // UART init
don't forget to reenable
Rich (BB code):
TXSTAbits.TXEN = 1;  //Enables the EUSART transmiter
and

Rich (BB code):
volatile  unsigned char counter=0;//Overflow counter
 

Thread Starter

Egberts

Joined Jun 7, 2014
13
Wow thanks guys I finally got it working! Made my day!
But Paul, could you tell me what the difference is between a normal unsigned char and a volatile unsigned char?
 

paulfjujo

Joined Mar 6, 2014
23
hello,

volatile must be specified if you want to use a variable wich is used in your main
application or other function AND inside an interrupt.
Some compiler can adjust this type themself (like MikroC PRO)
but other, as C18 MPLAB need to specify the type volatile xxxxx !
other compiler , i don't know.
so a volatile variable can be modfied everywhere in the program.
at every time.
 

ErnieM

Joined Apr 24, 2011
8,377
could you tell me what the difference is between a normal unsigned char and a volatile unsigned char?
The "volatile" qualifier is used to instruct the compiler not to make any assumption about a variable in that it's value may be used in non-obvious ways. This includes variables that change inside an ISR and also many system register values.

Wikipedia has a decent article on it's use.

There is some confusion about it's usage. Marking all variables as volatile is going overboard, but there are some key areas where this should be done, especially when using a compiler with optimization capabilities.

With a basic (non optimizing) compiler you probably do not need it, but if you ever improve or change your compiler then formerly good code can break and fail.

Aside: there is nothing special about the Mikro C compiler's ability to predict when to automatically apply volatile. In fact, if you can find where it places it's device specific headers (which are actually dot C types in Mikro C 'silently" included into your project) you can see where the register variables are commonly marked as volatile right in the manufacturer's own code.
 
Top