CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PIC16F1779 UART PROBLEM - Garbage when sending data

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jaikumar



Joined: 15 Dec 2006
Posts: 109

View user's profile Send private message

PIC16F1779 UART PROBLEM - Garbage when sending data
PostPosted: Sat Jul 29, 2023 7:58 am     Reply with quote

Hi,

I am working on a simple UART code with RX interrupt. I am getting garbage when sending read data back. Here is my code. any help would be great.
ccs version 5.115

main.h file
Code:

#include <16F1779.h>
#device ADC=10
#use delay(xtal=8000000)

#fuses XT NOMCLR NOBROWNOUT NOWDT NOLVP
#use pwm(CCP1,OUTPUT=PIN_B5,TIMER=2,FREQUENCY=20000,DUTY=0)

#define RX_PIN PIN_C7
#define TX_PIN PIN_C6

#pin_select U1RX = RX_PIN
#pin_select U1TX = TX_PIN
#use rs232(UART1,baud=9600,parity=N,xmit=TX_PIN,rcv=RX_PIN,bits=8,DISABLE_INTS)



main.c file
Code:

#include <main.h>
 

#define RELOAD (int16)33600  //50ms pulse
#define BUFFER_SIZE 16
/*
PIN_B5 PWM
PIN_B4 DRIVER DIR
TIMER1 PIN_C0
*/

typedef enum{
idle,
RxReceived
}stateControl;


volatile int8 delay50ms = 0;
stateControl currentState;
byte RxBuffer[BUFFER_SIZE];
byte RxDataCount = 0;
byte i = 0;


#INT_TIMER1
void timer1_isr(void)
{
   clear_interrupt(INT_TIMER1);
   set_timer1(RELOAD);
   delay50ms = 1;
}

#INT_RDA
void rda_int(void)
{
    RxBuffer[RxDataCount++]=getc();
}

void main()
{
   setup_wdt(WDT_OFF);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);      //104 ms overflow
   clear_interrupt(INT_TIMER1);
   set_timer1(RELOAD);                          // Preload value
   enable_interrupts(INT_TIMER1);               // Enable Timer1 interrupt
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);   
   output_low(PIN_B2);
   output_low(PIN_B4);
   RxDataCount = 0;
   currentState = idle;
   while(TRUE)
   {
     
      switch (currentState)
      {
        case idle:    if (RXDataCount > 14)
                      {
                        currentState = RxReceived;
                      }
                      break;
   
       case RxReceived:
                      disable_interrupts(GLOBAL);
                      for (i=0; i<16; i++)
                      {
                      putc(RxBuffer[i]);
                      }
                      RXDataCount = 0;
                      currentState = idle;
                      enable_interrupts(GLOBAL);
                      break;
       }
   }
   
}



Last edited by jaikumar on Sat Jul 29, 2023 8:01 am; edited 1 time in total
jaikumar



Joined: 15 Dec 2006
Posts: 109

View user's profile Send private message

PostPosted: Sat Jul 29, 2023 7:59 am     Reply with quote

This is the data sent:
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35

data received back in terminal
71 7E 74 8F 77 79 71 7E 74 0F
Ttelmah



Joined: 11 Mar 2010
Posts: 19249

View user's profile Send private message

PostPosted: Sat Jul 29, 2023 9:16 am     Reply with quote

On this:

#use rs232(UART1,baud=9600,parity=N,xmit=TX_PIN,rcv=RX_PIN,bits=8,DISABLE_INTS)

Change to:
use rs232(UART1,baud=9600,parity=N,bits=8)

Also you don't need to clear interrupt in the timer interrupt, the compiler
does this for you.

XT is wrong for an 8MHz crystal. Wants to be HS. However why not use the
PLL?. Run at 32Mhz from the 8MHz crystal.

Describe (or post a link to a picture of the circuit), how the actual
serial connections are made.
PrinceNai



Joined: 31 Oct 2016
Posts: 462
Location: Montenegro

View user's profile Send private message

PostPosted: Sat Jul 29, 2023 9:24 am     Reply with quote

Can you confirm that your RX buffer contains correct characters before sending them out?
jaikumar



Joined: 15 Dec 2006
Posts: 109

View user's profile Send private message

PostPosted: Sat Jul 29, 2023 11:24 pm     Reply with quote

The actual problem was the crystal in the board. It is marked 8Mhz but it
produces about 10.21 or something like that Mhz. Used the internal oscillator and everything is fine.
I would like to thank everybody for helping me.
Ttelmah



Joined: 11 Mar 2010
Posts: 19249

View user's profile Send private message

PostPosted: Sun Jul 30, 2023 8:47 am     Reply with quote

Did you correct the fact that you were driving it incorrectly?...
jaikumar



Joined: 15 Dec 2006
Posts: 109

View user's profile Send private message

PostPosted: Sun Jul 30, 2023 10:33 am     Reply with quote

Yes Ttelmah, I did change the fuse to HS and made the alteration that you said regarding the UART. But the software was asking for PIN setting(PPS). and once that was chosen it is working now. Once again thanks for your help. Regards.
Ttelmah



Joined: 11 Mar 2010
Posts: 19249

View user's profile Send private message

PostPosted: Mon Jul 31, 2023 5:28 am     Reply with quote

That's an unusual failure for a crystal. Normally they will only lock onto
undertones or harmonics. I remember one poster here a while ago, had a
crystal that he thought was a particular frequency, but when he checked
the ID code on the case, was actually completely different.
The only time I've seen odd frequencies like that was when I had a batch
where the hermetic sealing had failed, and after washing the boards all
gave really odd values.
Sounds like it may just be a faulty unit. Sad
jeremiah



Joined: 20 Jul 2010
Posts: 1319

View user's profile Send private message

PostPosted: Mon Jul 31, 2023 7:45 am     Reply with quote

Ttelmah wrote:


#use rs232(UART1,baud=9600,parity=N,xmit=TX_PIN,rcv=RX_PIN,bits=8,DISABLE_INTS)

Change to:
use rs232(UART1,baud=9600,parity=N,bits=8)



I would further recommend:
Code:

use rs232(UART1,baud=9600,parity=N,bits=8,ERRORS)


For the OP's benefit, the reason you remove the xmit= and rcv= parts is that the combination of the #pin_select's and the UART1 in the #use rs232() tell it the pins. You generally only use xmit= and rcv= for software UARTs.

The DISABLE_INTS option is for software UARTS as well. Since you are using a hardware UART, you don't need those options.
Ttelmah



Joined: 11 Mar 2010
Posts: 19249

View user's profile Send private message

PostPosted: Mon Jul 31, 2023 9:51 am     Reply with quote

Well said.
Just to further explain. The PIC UART has the behaviour that on the
RX side, if data is not reliably read when it becomes available if the
internal FIFO becomes full (normally on the second or third character
depending on the chip), OERR gets set, and receive hangs. Adding
'ERRORS' adds a tiny extra test to getc, so if the UART is in this state,
the compiler will flag this, and clear the error.
Basically you should always have ERRORS unless you add your own
error handling.
jaikumar



Joined: 15 Dec 2006
Posts: 109

View user's profile Send private message

PostPosted: Mon Jul 31, 2023 11:45 am     Reply with quote

Understood.

Regards.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group