|
|
View previous topic :: View next topic |
Author |
Message |
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
Avoiding Framing Errors. |
Posted: Sun Jan 09, 2005 10:11 pm |
|
|
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
|
|
Posted: Sun Jan 09, 2005 10:41 pm |
|
|
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
|
|
Posted: Mon Jan 10, 2005 2:13 am |
|
|
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
|
RE: Receive Buffer Overflow |
Posted: Mon Jan 10, 2005 12:21 pm |
|
|
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
|
|
Posted: Mon Jan 10, 2005 12:27 pm |
|
|
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. |
|
|
|
|
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
|