本帖最后由 rankfyang 于 2009-9-9 09:06 编辑
小弟先谢谢您的关注了!
存在的问题:在多个中断函数中的数据共享,怎么才能正确解析从串口接收到的数据帧?
具体阐述:
小弟在做ATemga128的一个系统时,共使用了三个中断函数,三个中断函数和主要功能如下:
第一个中断(“选择”按钮对应的中断):
#pragma interrupt_handler select_isr:iv_INT4
这个中断通过ATemga128的PE4脚接了一个按键,用来触发LCD界面的光标位置的变化。
第二个中断(“确认”按钮对应的中断):
#pragma interrupt_handler enter_isr:iv_INT5
这个中断外部接了一个按键,接到ATemga128的PE5,通过按键动作改变LCD界面的显示图像。在其中一个图像变化的界面中会将中断三中收到的数据实时显示出来,并且在当前界面
按动“确认”按钮就会将中断三送过来的数据保存到片内RAM中。
第三个中断:
(串口1数据传送中断,这个中断每隔500毫秒会接收到从串口发送过来的数据,中间调用的子函数都在下面三个子函数中。)
#pragma interrupt_handler usart1_rx_isr:iv_USART1_RXC
void usart1_rx_isr(void)
{
float pressure;
float sink;
CLI();
storeReceivedChars(USART_RxDataBuf, 65);
copyRightData(USART_RxDataBuf, RxDProcessStk, 13);
pressure = char4_floatLittleEndian(&RxDProcessStk[3]);
sink = char4_floatLittleEndian(&RxDProcessStk[7]);
printf("\n pressure = %f", pressure);
printf("\n sink = %f", sink);
SEI();
}
这个中断函数用来接收从串口发送过来的数据并判断收到数据的准确性。如果收到的数据正确,我将这组收到的数据(包括两个浮点数)实时显示到LCD界面。中断三每隔500毫秒
从下位机收到一个包含以上涉及到的两个浮点数的数据帧。数据帧中有包括开始的起始标志,最后两个字节是校验字。如果每次起始标志和CRC校验结果都正确,则将当前接收到的
数据送到LCD显示。并且无论收发数据与否,都要在按动“确认”按钮按下之后将当前收到的正确数据保存到另外的存储空间。
可是小弟在处理的时候总是出现数据解析有问题,在希望按动“确认”按钮保存当前数据的时候总是将当前的数据冲断,致使读到的数据不正确,本来该从起始位开始读起的数据却从中途读起,致使报错!为什么会出现这种状况呀?
中断接收数据我是采用的以下三个子函数(三个子函数都定义在串口接收中断之前),:
//本子函数用于从USART1接收一个字符
unsigned char usart1_MCU_receiveCh(void)
{
while( !(UCSR1A & (1<<RXC1)));
return UDR1;
}//验证没问题
//本子函数用于从USART1接收一个包含size个字符的字符数组中,
//参数接收一个同名的全局变量USART_RxDataBuf
//其中USART_RxDataBuf是一个有100个字节的
//采用循环记录的方式将数据写入
void storeReceivedChars(unsigned char *USART_RxDataBuf, unsigned char size)
{
int i;
writeBufPtr = USART_RxDataBuf;
for(i = 0; i < size; i++)
{
*writeBufPtr = usart1_MCU_receiveCh();
writeBufPtr++;
if( (writeBufPtr - USART_RxDataBuf) == size )writeBufPtr = USART_RxDataBuf;
}
}
//本函数用于将全局变量USART_RxDataBuf中的数据拷贝到另外一个存储空间中
//该存储空间是一个长度为length的字符数组(也是定义的一个全局变量)
//
void copyRightData(unsigned char *USART_RxDataBuf, unsigned char *RxDProcessStk, unsigned char length)
{
unsigned char *srcRdPtr;
unsigned char *dstWrPtr;
int crcChkResult;
int RxD_CRC;
int i;
srcRdPtr = USART_RxDataBuf;
dstWrPtr = RxDProcessStk;
while( (*srcRdPtr) != 0x55 )srcRdPtr++;
while( (*srcRdPtr) == 0x55 )
{
crcChkResult = do_crc(srcRdPtr, 11);
RxD_CRC = chars2_intLittleEndian( srcRdPtr+11 );
if( crcChkResult == RxD_CRC)
{
for(i = 0; i < length; i++)
{
*dstWrPtr = *srcRdPtr;
dstWrPtr++;
srcRdPtr++;
}
}
}
}
//这个函数是用来处理小端模式下接收的数据,将接收到的数据帧中相应的字节还原成固有的浮点数
float char4_floatLittleEndian(unsigned char *charsArray)
{
unsigned char receivedArray[4];
int i;
float *finalResult;
for(i = 3; i > -1; i--, charsArray++)
receivedArray = *charsArray;
finalResult = (float *)receivedArray;
return *finalResult;
}
小弟承望各位指教!先行谢过了!!! |