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

Uart Framing Problems

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



Joined: 02 Aug 2010
Posts: 1

View user's profile Send private message

Uart Framing Problems
PostPosted: Mon Aug 02, 2010 6:35 pm     Reply with quote

EDIT SOLVED: The problem was in silicon. Don't use PIC24hj12gp202 for high speed UART! It corrupts the transmission!



Hi. I am having trouble with the uart misreading transmissions from a sensor. I can't even get it to read its own transmissions properly. The Rx and Tx are connected together for the following test program. I transmit 2 0x01's and receive a 0x02 and 0x00. The staus register indicates a framing problem (FERR bit in the U1STA). Has anyone had or heard of similar problems?

I've edited the test program to respond to posters. The simplified program still has the same problem. Also sending an 'A' doesn't work either.

Code:


#use rs232(UART1, baud=9600,bits=8, parity=N, stop=1)




void main()
{
char buffer_tbe[24];   
char buffer_rda[24];
   set_uart_speed(9600);
    reset_serial_buffers();
    clear_interrupt(INT_RDA);
    enable_interrupts(INT_RDA);
    enable_interrupts(INT_TBE);
   putc(0x01);   
   putc(0x01);
   delay_us(1000);
}



Last edited by aspalmer on Tue Aug 10, 2010 11:59 am; edited 6 times in total
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

View user's profile Send private message Visit poster's website

PostPosted: Tue Aug 03, 2010 7:43 am     Reply with quote

Ok first things first: how do you know it is a framing error and not anything else? A framing error occurs when the UART can't 'lock' onto the start bit; it starts reading from in-between the byte and produces gibberish at the output. I think you should first try to debug it for other problems before assuming it is a frameshift error.

Are you sure the baud rates are the same (9600 baud) at both ends? Double check this.

I see a whole lot of code above and I don't particularly want to read it. Try making a simple program that replicates the problem you are facing.
Code:
while(1)
{
      putc(0x01);
      putc(0x01);
      delay_ms(100);
}
You need to fill in the appropriate statements to include the header files/declare fuses/initialize the UART/etc.

If you get the same problem then post back.

Rohit
mkuang



Joined: 14 Dec 2007
Posts: 257

View user's profile Send private message Send e-mail

PostPosted: Tue Aug 03, 2010 8:14 am     Reply with quote

This:

putc(0x01);

Does not output a readable ASCII character. Why don't you try something like putc('A') instead.

Where are you enabling the transmit and receive interrupts?
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Wed Aug 04, 2010 4:11 am     Reply with quote

I would be looking seriously at how TBE is handled. Once you enable INT_TBE, this interrupt will immediately be called. This is why it should _not_ be enabled till data is actually waiting to be sent in the software buffer. The originally posted TBE handling, looked messy, since you had interrupt driven serial transmit handling, and were also sending characters without this. You need to use 'one or the other', and not both. I'd guess you are actually sending garbage characters from the buffer, and these are resulting in the errors you are seeing.

Though this won't support buffers over 256 bytes, the attached is generic buffer handling code, and the corresponding interrupt/bputc. See if this solves the problem - send everything with bputc:
Code:

#ifdef (__PCH__)
#byte TXREG=0xFAD
#byte TXSTA=0xFAC
#byte PIR1=0xF9E
#else
#byte TXREG=0x19
#byte TXSTA=0x98
#byte PIR1=0xC
#endif
#bit TRMT=TXSTA.1
#bit TXIF=PIR1.4

#define BUFFSIZE (32)

struct buffer {
   char buff[BUFFSIZE];
   int8 in;
   int8 out;
};

struct buffer rs232_txbuff, rs232_rxbuff; //setup buffers

#define bkbhit(b) (b##.in!=b##.out)
#define isempty(b) (b##.in==b##.out)
#define incin(b) if(++b##.in>=BUFFSIZE) b##.in=0
#define incout(b) if(++b##.out>=BUFFSIZE) b##.out=0
#define clrbuff(b) b##.out=b##.in=0

//Serial RX interrupt
#int_rda
void receive_rs232(void) {
   rs232_rxbuff.buff[rs232_rxbuff.in]=getc();
   incin(rs232_rxbuff);
   if (rs232_rxbuff.in==rs232_rxbuff.out) {
      //Buffer overflow
      incout(rs232_rxbuff);
   }
}

#INT_TBE /* Transmit buffer empty interrupt */
void TXINT(void) {
   if (isempty(rs232_txbuff)) {
      DISABLE_INTERRUPTS(INT_TBE);
   }
   else {
      TXREG=rs232_txbuff.buff[rs232_txbuff.out];
      incout(rs232_txbuff);
   }
}

//Routine to send a RS232 char

void rs232_bputc(char val) {
   int8 next;
   /* routine to send one character on the RS232.
      This puts the specified character into the software transmit buffer (if data is allready
      being transmitted), or else sends the single character to the RS232 UART. */
   /* Hold transmission if the buffer is full */
   //Buffer is full if _next_ addition address matches current retrieval
   //address
   next=rs232_txbuff.in+1;
   if (next>=BUFFSIZE) next=0;
   disable_interrupts(INT_TBE);
   while (next==rs232_txbuff.out) {
      if (TXIF==1) {
         /* Here the transmit hardware buffer is empty */
         TXREG=rs232_txbuff.buff[rs232_txbuff.out];
         //So send one char
         TXIF=0;
         incout(rs232_txbuff);
      }
   }
   /* put character into the output buffer */
   rs232_txbuff.buff[rs232_txbuff.in]=val;
   rs232_txbuff.in=next;

   /* Enable interrupts */
   enable_interrupts(INT_TBE);
}

//Routine to get a character from the RS232. Waits if no data available
char rs232_bgetc() {
   int8 temp;
   while (!bkbhit(rs232_rxbuff)) ;
   temp=rs232_rxbuff.buff[rs232_rxbuff.out];
   incout(rs232_rxbuff);
   return temp;
}

As shown this also enables a RX buffer, and this shows how to use the 'bkbhit' function, to 'know' if a character is available.
Enable the RS232 receive interrupt, and the global interrupt, to use these. The transmit interrupt is automatically handled.

Best Wishes
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