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 CCS Technical Support

Quick RS232 question.

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



Joined: 19 Jan 2005
Posts: 8

View user's profile Send private message

Quick RS232 question.
PostPosted: Wed Dec 21, 2005 12:30 am     Reply with quote

Hi to all.
I have a RS232 routine that I have been using for a while and it is working fine , but when I compare it to others routines the one I'm using is very different. I got some of the code from someone on this forum and some is my own.
Mine seems more complicated. As I said it works fine , but I think it's
probably doing unnecessary stuff.
Any pointers would be great.
Cheers
Ned

Code:

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7 , bits=8, parity=N )
#priority RDA,timer2
#include <serial.h>


#locate RCREG= 0x1A  // from datasheet RCREG

struct {
unsigned char RX9D:1;
unsigned char OERR:1;
unsigned char FERR:1;
unsigned char ADDEN:1;
unsigned char CREN:1;
unsigned char SREN:1;
unsigned char RX9:1;
unsigned char SPEN:1;
} RCSTAbits ;                            //struct RCSTAbits @ location 0x18 from datasheet
#locate RCSTAbits=0x18

unsigned int i;                           // gen variable used in for loops etc..
//------------------------------------------------------PROTOTYPES----------------------------------------------------------------


void process_data(void);
void calculate_checksum(unsigned int numbytes);
void clear_buffer(void);
//----------------------------------------------------------------------------------------------------------------------------------


//------------------------------------------------serial interrupt-----------------------------
#INT_RDA
void recieve_Sdata(void)
{
int tmp;
if(RCSTAbits.OERR ==0) // no recieve errors
   {
      serial_buffer[buff_counter] = RCREG;
      tmp = RCREG;   // reading buffer 2 times clears it
      tmp = RCREG;
      buff_counter++;
   }
   else         // clear recieve errors
      {
          RCSTAbits.CREN = 0;
                    RCSTAbits.CREN = 1;
                                                 // must go 0 then 1 to clear                                               // acc to data sheet
                    tmp = RCREG;   // reading buffer 2 times clears it
                    tmp = RCREG;
                      buff_counter =0;


       }
}

Ttelmah
Guest







PostPosted: Wed Dec 21, 2005 3:40 am     Reply with quote

You don't do much extra, but you do it in a way that makes it seem more. :-)
Historically, CCS, had no ability to clear overrun errors. Some time ago (quite a while, perhaps a year or more), the ability was added to CCS, to automatically handle these errors, if the keyword 'ERRORS', was added to the serial setup. I'd suspect that your code 'predates' this.
So you can now get basically the same effect, by just using 'getc', and adding the ERRORS keyword.
Second, going back a little further, the #bit, and #byte declaration ability was added. Before this, the only way to access a bit in a register, was to declare a variable, and locate it at the required place, and then access bits in this, either using a structure, or bit controls/masking. With these declarations, register accesses, can be made a lot tidier looking. Your code uses the 'older' format.
So your code could be redeclared a lot 'smaller looking', by declaring using #bit/#byte, and doing the I/O with these. It could be made even smaller looking, by using ERRORS, and getc. In each case, the actual operations involved would remain basically the same, but the code to generate them, would be a lot more compact. So you are not 'doing unnecessary stuff', but the 'guts' are visible, rather than taking advantage of latter compiler shortcuts.

So, the 'overrun handler', could just be:
Code:

#bit CREN=0x18.4
#bit OERR=0x18.1

if (OERR) {
   CREN=0;
   CREN=1;
}


Will clear the overrun error (you should have already read the register, and if the second register is full - it will be - the interrupt will still be set, and will be called again, to get the second byte - hence the double read, though 'tidy', is not really needed).

Equally:
Code:

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7 , bits=8, parity=N , ERRORS)

#INT_RDA
void recieve_Sdata(void)
{
      serial_buffer[buff_counter] = getc();
      buff_counter++;
}


Will retrieve the data, and clear the OERR, if it has happened!.
The same toggling of CREN, will be done automatically, inside the code generated by the getc function, it is just no longer 'visible'...

Best Wishes
seegoon



Joined: 19 Jan 2005
Posts: 8

View user's profile Send private message

PostPosted: Wed Dec 21, 2005 3:52 am     Reply with quote

Thanks Ttelmah.
All makes sense now. I'll try and convert my code to the newer format.
Thanks again.
Ned
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