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

Avoiding Framing Errors.

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



Joined: 08 Sep 2003
Posts: 492
Location: India

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

Avoiding Framing Errors.
PostPosted: Sun Jan 09, 2005 10:11 pm     Reply with quote

Hi,

Whenever I send a stream of data I get framing error in the receiver application ( I am using a VB application , which has the MSCOMM control).


This problem occurs occasionaly, most of the times it works well.

My question is how can I avoid these errors ???

Thanks
Arun


The Source code is here

void usart_tx_16byte(int16 nData)
{

switch (nBit)
{

case 0:

putc(make8(nData,1));
nBit=1;
break;
case 1:

putc(make8(nData,0));
nBit=0;
break;
}

}



void main()

{

initialise(); ( Not required )

do
{


if (bProximityFlg==1)
{
disable_interrupts(INT_EXT);
disable_interrupts(INT_TIMER2);
disable_interrupts(INT_RDA);
nPrevLPlaten=nLPlaten;
nPrevUPlaten=nUPlaten;
nPrevLoadCell=nLoadCell;
nPrevTime=nTimeCntr;

delay_ms(nProxDelay);

nLoadCell=read_analog(LOADCELL_CHN);
nUPlaten=read_analog(UPLATEN_CHN);
nLPlaten=read_analog(LPLATEN_CHN);

bProximityFlg=0;
bSampleFlg=0;
usart_tx_16byte(nLoadCell);
/// putc('A');
delay_ms(5);
usart_tx_16byte(nLoadCell);
// putc('a');
delay_ms(5);
usart_tx_16byte(nUPlaten);
// putc('B');
delay_ms(5);
usart_tx_16byte(nUPlaten);
// putc('b');
delay_ms(5);

usart_tx_16byte(nLPlaten);
// putc('C');
delay_ms(5);
usart_tx_16byte(nLPlaten);
// putc('c');
delay_ms(5);
usart_tx_16byte(nTimeCntr);
// putc('D');
delay_ms(5);
usart_tx_16byte(nTimeCntr);
// putc('d');
delay_ms(5);

nTimeCntr=0;
bTimerFlg=1;

enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_RDA);

// putc('R');

}

if (bRcvFlg==1)
usart_rcvr();

if (bMotorCFlg==1)
{
motorc_delay(nMotorCDelay);
bMotorCFlg=0;

}

if (bLogFlg==1)
{

//The Interrupts are enabled here for the first time.

if (bIntFlg==0)
{

ext_int_edge(L_TO_H);
setup_timer_2(T2_DIV_BY_1,0xF9,4);

bIntFlg=1;
bSampleFlg=0;
bProximityFlg=0;
ext_int_edge(L_TO_H);
enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER2);

}
}
else
{

if (bIntFlg==1)
{
bIntFlg=0;
bTimerFlg=0;
bSampleFlg=0;
bProximityFlg=0;
disable_interrupts(INT_EXT);
disable_interrupts(INT_TIMER2);

}

}



} while(TRUE);


}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Sun Jan 09, 2005 10:41 pm     Reply with quote

1. Make sure the signal is clean
2. Use a "magic" crystal that gives you 0% error.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Jan 10, 2005 2:13 am     Reply with quote

Quote:
Whenever I send a stream of data I get framing error in the receiver application
Is this receiver application running on the PIC or on the PC?

You didn't give all your source code, especially the #use RS232 line is missing. Are you using a hardware or software UART?


The most common problem with framing errors is the use of a software UART in combination with interrupts.

A few general remarks:
- When posting code in this forum use the 'code' button, this will ensure formatting of your code is retained,
- Always mention the processor model and compiler version you are using.
- Post a complete working program.
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

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

RE: Receive Buffer Overflow
PostPosted: Mon Jan 10, 2005 12:21 pm     Reply with quote

Hi ,

Version : 3.179
MCU : PIC 16F628
ADC : MCP 3208

Thanks for the tip, I will use them in my next posting. You are right I did not post the entire code. I am posting the entire code below...

Also there is a bit of a problem here....the error I am getting is Receive Buffer Overflow and not Framing Error. I made a mistake by
writing Framing Error....Sorry about that.......

This problem (Receive Buffer Overflow ) occurs only sometimes, When I restart the PIC it works well.

thanks
arun

The Code...........


Code:

#include <16F628.h>

#FUSES XT,NOWDT,PUT,NOPROTECT,NOMCLR,NOCPD,BROWNOUT,NOLVP

#use delay(clock=4000000)
#use rs232(baud=9600,xmit=pin_b2, rcv=pin_b1)


#define VERSIONID 0x03

////////////////////////////////////////////////////////// EEPROM ADDRESS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


#define LOADCELL_CHN 0x07
#define UPLATEN_CHN 0x00
#define LPLATEN_CHN 0x01

#define MOTORC_ADDRS 0x20
#define PDELAY_ADDRS 0x10

#define GAIN_SETTING 0x11
#define LPLATEN_SETTING 0x12
#define UPLATEN_SETTING 0x14

#define EEPROM_DATA_CHK1 0x7F
#define EEPROM_DATA_CHK2 0x7E


#define MCP3208_CLK  pin_a2
#define MCP3208_DOUT pin_a4
#define MCP3208_DIN  pin_b3
#define MCP3208_CS   pin_a3


#define PROXIMITY   pin_b0
#define MOTORC   pin_a5

#define ONLINE   pin_a1
#define COLLET   pin_b7
#define SHIELD   pin_b6
#define RAM   pin_b5
#define MOTOR   pin_b4



char cRcvData;
int bRcvFlg,nUSARTCmd,bTxdFlg;



int16 nTimeCntr,nPrevTime;
int16 nLoadCell, nUPlaten,nLPlaten,nPrevUPlaten,nPrevLPlaten,nPrevLoadCell;

int bTimerFlg,bLogFlg,bIntFlg,bProximityFlg,bMotorCFlg,bSampleFlg;
int nLoadcellChn,nUplatenChn,nLPlatenChn;
int nLocation,nData,nBit,nProxDelay,nMotorCDelay;


void motorc_delay(int nDelay)
{

   int n;
   
   n=0;

   do
   {
      delay_ms(1000);
      n++;

   } while((n<nDelay)&&(input(MOTORC)==0));

   if (input(MOTORC)==1)
      putc('H');
   else
      putc('L');

}


void init_eeprom()

{

   int nEEData1,nEEData2,nCntr;

   nEEData1=read_eeprom(EEPROM_DATA_CHK1);
   nEEData2=read_eeprom(EEPROM_DATA_CHK2);

   if ((nEEData1!=0x0A)||(nEEData2!=0xA0))

   {
      //Erase all data.
      for (nCntr=0;nCntr<253;++nCntr)
      {

         write_eeprom(nCntr,0);
      }

   write_eeprom(EEPROM_DATA_CHK1,0x0A);
   write_eeprom(EEPROM_DATA_CHK2,0xA0);   
   
   }

}

void write_eeprom_16byte(int nAddress,int16 nData)
{

   write_eeprom(nAddress,make8(nData,1));
   write_eeprom(nAddress+1,make8(nData,0));

}


void adc_init()
{
   output_high(MCP3208_CS);
}




void write_adc_byte(BYTE data_byte, BYTE number_of_bits) {
   BYTE i;

   delay_us(2);
   for(i=0; i<number_of_bits; ++i) {
      output_low(MCP3208_CLK);
      if((data_byte & 1)==0)
         output_low(MCP3208_DIN);
      else
         output_high(MCP3208_DIN);
      data_byte=data_byte>>1;
      delay_us(50);
      output_high(MCP3208_CLK);
      delay_us(50);
   }
}


BYTE read_adc_byte(BYTE number_of_bits) {
   BYTE i,data;

   data=0;
   for(i=0;i<number_of_bits;++i) {
      output_low(MCP3208_CLK);
      delay_us(50);
      shift_left(&data,1,input(MCP3208_DOUT));
      output_high(MCP3208_CLK);
      delay_us(50);
   }
   return(data);
}


long int read_analog_mcp(BYTE channel, BYTE mode) {
   int l;
   long int h;
   BYTE ctrl_bits;

   delay_us(200);

   if(mode!=0)
      mode=1;

   output_low(MCP3208_CLK);
   output_high(MCP3208_DIN);
   output_low(MCP3208_CS);

   if(channel==1)               // Change so MSB of channel #
      ctrl_bits=4;            //      is in LSB place
   else if(channel==3)
      ctrl_bits=6;
   else if(channel==4)
      ctrl_bits=1;
   else if(channel==6)
      ctrl_bits=3;
   else
      ctrl_bits=channel;

   ctrl_bits=ctrl_bits<<1;

   if(mode==1)                  // In single mode
      ctrl_bits |= 1;
   else                        // In differential mode
      ctrl_bits &= 0xfe;

   ctrl_bits=ctrl_bits<<1;      // Shift so LSB is start bit
   ctrl_bits |= 1;

   write_adc_byte( ctrl_bits, 7);   // Send the control bits

   h=read_adc_byte(8);
   l=read_adc_byte(4)<<4;

   output_high(MCP3208_CS);

   return((h<<8)|l);
}


long int read_analog( BYTE channel )   // Auto specifies single mode
{
   return read_analog_mcp( channel, 1);
}




#ZERO_RAM

void initialise()
{

//   int16 g;

   setup_comparator(NC_NC_NC_NC);
    set_tris_a(0b00110000);
   set_tris_b(0b00000011);

   output_low(COLLET);
   output_low(SHIELD);
   output_low(RAM);
   output_low(MOTOR);

   output_low(ONLINE);

   init_eeprom();
   nProxDelay=read_eeprom(PDELAY_ADDRS);

   if (nProxDelay==0)
   {
      nProxDelay=0x1E;
      write_eeprom(PDELAY_ADDRS,0x1E);
   }

   nMotorCDelay=read_eeprom(MOTORC_ADDRS);

   if (nMotorCDelay==0)
   {
      nMotorCDelay=0x07;
      write_eeprom(MOTORC_ADDRS,0x07);
   }

   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

}

void usart_tx_16byte(int16 nData)
{

   switch (nBit)
   {

      case 0:
   
            putc(make8(nData,1));
            nBit=1;
            break;
      case 1:

            putc(make8(nData,0));
            nBit=0;
            break;
   }

}

void get_command(char cCmd)
{

   switch (cCmd)
   {
      case 'V':      //Version Data
         
         putc(VERSIONID);
         nUSARTCmd=0;

         break;

   
      case 'A':   //Acknowledge

         putc('A');
         output_high(ONLINE);
         nUSARTCmd=0;

         break;

      case 'S':      //Shield
         
         putc('A');
         nUSARTCmd=1;

         break;

   
      case 'C':      //Collet


         putc('A');
         nUSARTCmd=2;
         break;

      case 'R':      //Ram
         
         putc('A');
         nUSARTCmd=3;

         break;

   
      case 'M':      //Motor

         putc('A');
         nUSARTCmd=4;
         break;

      case 'X':      //Reset CPU

         putc('A');
         reset_cpu();

         break;

      case 'l':      //Start the Logging process. The MCU will send data to PC.
               //and PC goes to receive mode.

         putc('A');
         bLogFlg=1;
         bIntFlg=0;
         nUSARTCmd=0;

         break;

      case 'Z':      //End the Logging process.
      
         putc('A');
         bLogFlg=0;
         nUSARTCmd=0;

         break;

      case 'L':   //Location of EEPROM

      
         nLocation=0;
         nUSARTCmd=5;
         putc('A');

         break;


      case 'D':   //EEPROM data

         nData=0;
         nUSARTCmd=6;
         putc('A');
      
         break;


      case 'O':   //Operation


         nUSARTCmd=7;
         putc('A');

         break;


      case 'G':            //Get ADC Data

         nPrevLPlaten=read_analog(LPLATEN_CHN);
         nPrevUPlaten=read_analog(UPLATEN_CHN);
         nPrevLoadCell=read_analog(LOADCELL_CHN);
         nUSARTCmd=0;

         putc('A');   

         break;

      case 'u':       //read Processed data

      
         usart_tx_16byte(nPrevUPlaten);
         

         break;


      case 'd':      //read LPlaten

         usart_tx_16byte(nPrevLPlaten);
         
         break;


      case 't':      //torque

         usart_tx_16byte(nPrevLoadCell);

         break;

      case 'm':      //time in msecs

         usart_tx_16byte(nPrevTime);
         
         break;
   
      case 'n':      //Start sample

         bSampleFlg=1;
         putc('A');
         break;

      case 'z':

         nBit=0;
         putc('A');
         break;

      case 'r':         //Reload parameters

         nProxDelay=read_eeprom(PDELAY_ADDRS);
         nMotorCDelay=read_eeprom(MOTORC_ADDRS);
         putc('A');
         break;
   }

}

void process_command(char cCmd)
{

   switch (nUSARTCmd)
   {
      case 1: // Shield Data

            if (cCmd=='2')
            {
               if (input(SHIELD)==1)
                  putc('H');
               else
                  putc('L');
            }
            
            if (cCmd=='1')
               output_high(SHIELD);

            if (cCmd=='0')
               output_low(SHIELD);
   
            if (cCmd!='2')
               putc('A');


            nUSARTCmd=0;

            break;

      case 2:     // Collet Data

            if (cCmd=='2')
            {
               if (input(COLLET)==1)
                  putc('H');
               else
                  putc('L');
            }
            
            if (cCmd=='1')
               output_high(COLLET);

            if (cCmd=='0')
               output_low(COLLET);
   
            if (cCmd!='2')
               putc('A');


            nUSARTCmd=0;

            break;

      case 3:      //Ram data

            if (cCmd=='2')
            {
               if (input(RAM)==1)
                  putc('H');
               else
                  putc('L');
            }
            
            if (cCmd=='1')
               output_high(RAM);

            if (cCmd=='0')
               output_low(RAM);
   
            if (cCmd!='2')
               putc('A');


            nUSARTCmd=0;


            break;

      case 4:      //Motor data

            if (cCmd=='2')
            {
               if (input(MOTOR)==1)
                  putc('H');
               else
                  putc('L');
            }
            
            if (cCmd=='1')
            {
               output_high(MOTOR);
               bMotorCFlg=1;
            }


            if (cCmd=='0')
            {
               output_low(MOTOR);
               bMotorCFlg=0;
               putc('A');
            }
   
            
            nUSARTCmd=0;


            break;

      case 5:      //Location of EEPROM

            nLocation=cCmd;
            nUSARTCmd=0;
            putc('A');

            break;


      case 6:      //Data of EEPROM


            nData=cCmd;
            nUSARTCmd=0;
            putc('A');

            break;


      case 7:      //Operation

            if (cCmd=='W')
            {
               write_eeprom(nLocation,nData);
               putc('A');
            }
            
            if (cCmd=='R')
               putc(read_eeprom(nLocation));

               
            nUSARTCmd=0;

            break;



   }

}


void usart_rcvr()
{

   if (nUSARTCmd==0)
      get_command(cRcvData);
   else
      process_command(cRcvData);

   bRcvFlg=0;

   output_high(ONLINE);


}




void main()

{

   initialise();
   
   do
   {


      if (bProximityFlg==1)
      {

         disable_interrupts(INT_EXT);
         disable_interrupts(INT_TIMER2);
         disable_interrupts(INT_RDA);

         nPrevLPlaten=nLPlaten;
         nPrevUPlaten=nUPlaten;
         nPrevLoadCell=nLoadCell;
         nPrevTime=nTimeCntr;

         delay_ms(nProxDelay);
   
         nLoadCell=read_analog(LOADCELL_CHN);
         nUPlaten=read_analog(UPLATEN_CHN);
         nLPlaten=read_analog(LPLATEN_CHN);
                  
         bProximityFlg=0;
         bSampleFlg=0;

         usart_tx_16byte(nLoadCell);
//         putc('A');
         delay_ms(5);
         usart_tx_16byte(nLoadCell);
//         putc('a');
         delay_ms(5);

         usart_tx_16byte(nUPlaten);
//         putc('B');
         delay_ms(5);
         usart_tx_16byte(nUPlaten);
//         putc('b');
         delay_ms(5);

         usart_tx_16byte(nLPlaten);
//         putc('C');
         delay_ms(5);
         usart_tx_16byte(nLPlaten);
//         putc('c');
         delay_ms(5);

         usart_tx_16byte(nTimeCntr);
//         putc('D');
         delay_ms(5);
         usart_tx_16byte(nTimeCntr);
//         putc('d');
         delay_ms(5);

         nTimeCntr=0;
         bTimerFlg=1;
      
         enable_interrupts(INT_EXT);
         enable_interrupts(INT_TIMER2);
         enable_interrupts(INT_RDA);
         
   //      putc('R');
   
      }   

      if (bRcvFlg==1)
         usart_rcvr();

      if (bMotorCFlg==1)
      {
         motorc_delay(nMotorCDelay);
         bMotorCFlg=0;         
         
      }

      if (bLogFlg==1)
      {

         //The Interrupts are enabled here for the first time.

         if (bIntFlg==0)
         {

            ext_int_edge(L_TO_H);
            setup_timer_2(T2_DIV_BY_1,0xF9,4);

            bIntFlg=1;
            bSampleFlg=0;
            bProximityFlg=0;
            ext_int_edge(L_TO_H);            
            enable_interrupts(INT_EXT);
            enable_interrupts(INT_TIMER2);
   
         }
      }
      else
      {

         if (bIntFlg==1)
         {

            bIntFlg=0;
            bTimerFlg=0;
            bSampleFlg=0;
            bProximityFlg=0;
            disable_interrupts(INT_EXT);
            disable_interrupts(INT_TIMER2);
   
         }

      }

   
   
   } while(TRUE);


}


#int_rda

usart_rcv()

{
   bRcvFlg=1;
   cRcvData=getc();
}


#int_ext

proximity_isr()

{

//   if (bProximityFlg==0)
      bProximityFlg=1;

}

#int_timer2

time_count()
{

   if (bTimerFlg==1)
      nTimeCntr++;
   
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Mon Jan 10, 2005 12:27 pm     Reply with quote

In your main loop you disable the receive interrupt, do some stuff, and then reenable it. If data comes in, then you are going to miss it and an overrun is going to occur. You need to handle the overrun error. Many people put the ERRORS parameter in the #use RS232 statement. I prefer to handle the error myself.
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