马潮老师,您好,我的串口中断一直丢包,麻烦帮忙分析
//===============串口初始化=============void uart0_init(void)
{
UCSR0B = 0x00; //禁止发送和接收
UCSR0A = 0x00; //倍速异步模式USX0=0
UCSR0C = 0x06; //0000 0110,UCSZ01=1,UCSZ00=1;1位起始位,8位字符,1位停止位
UBRR0L = 25; //设置波特率为19200
UBRR0H = 0; //
UCSR0B = 0x98; //使能发送和接收,使能串口中断
asm("sei");//打开全局中断
}
//*************** UART0 FUNCTION************************//
void UartSendHY502(unsigned char *cSendBuffer)
{
unsigned char i;
unsigned char cCheckSum = 0;
UCSR0B &= ~(1<<RXCIE0); //禁止串口接收
for(i=0;i<30;i++)
g_cReceBuf = 0;
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = 0xAA; //发送包头 0xAA
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = 0xBB; //发送包头 0xBB
for (i=0; i<cSendBuffer; i++)
{
cCheckSum ^= cSendBuffer;
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = cSendBuffer; //发送长度字、命令字、校验和
if (cSendBuffer == 0xAA)
{
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = 0x00; //在0xAA后加0x00
}
}
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = cCheckSum; //发送校验字
UCSR0B |= 1<<RXCIE0; //打开串口接收
}
SIGNAL(SIG_USART0_RECV)
{
unsigned char i;
unsigned char cReceivedData;
unsigned char cCheckSum = 0;
cReceivedData = UDR0;
if(g_bReceAA)
{
g_bReceAA = 0;
if(cReceivedData == 0xBB )
g_cReceNum = 0;
}//不接收包头AA BB
else
{
if (0xAA == cReceivedData)
g_bReceAA = 1;
g_cReceBuf = cReceivedData;
if (g_cReceNum > g_cReceBuf)//代表所有数据已经接收完毕
{
UCSR0B &= ~(1<<RXCIE0); //禁止串口接收,退出中断服务
cCheckSum = 0;
for (i=0; i <= g_cReceBuf; i++)
cCheckSum ^= g_cReceBuf;
if (0 == cCheckSum)
{
g_bReceCommandOk = 1;//表示数据接收完毕 ,且接收无误
}
g_cReceNum = 0;
g_bReceAA = 0;
}
}
}
/************************** main function start here *******************************/
int main(void)
{
uchar CardSN[] = {0x02,0x02};
uchar cStatus;
uchar *cPa;
uart0_init();
cPa = CardSN;
UartSendHY502(cPa); //发送指令
_delay_ms(200); // delay for module execution
cStatus = !g_bReceCommandOk;
//一下为显示部分
if((g_cReceBuf != cPa)|| (cStatus != 0x00)) //判断是否接收完毕,及接收的是否正确
{
……
}
else
{
……
}
} 期望马潮老师的回复,大家有经验的过来发表建议哦…… 你的每帧数据有且只有一个0xaa吗?
还有不要重复发帖子。 谢谢回复。
刚才我解决了困扰了两周的问题,不过还是很感谢您。
新手不了解这些规则,而且看马潮老师的那个帖子较晚,就又发了一遍。以后不会再犯这样的错误了。
关于这一类的帖子哪边有? 你可以上网搜下,这方面的问题大家问的很多
{:victory:} 应该是你程序的问题。
一个串口通讯方面的老手给你提提意见:
(1)、我从来不使用查询方式的发送数据
缺点:响应太慢,占用宝贵的CPU时间
我一直使用中断方式发送数据
(2)、我从来不在接收中断里做大量的判断和处理工作
缺点:可能会造成数据丢失
我一直在主程序中判断和处理接收的数据。
下面是我的接收中断代码
#pragma interrupt_handler USART1_RI_ISR:iv_USART1_RX
void USART1_RI_ISR(void)
{
INT8U ch;
INT8U status;
status = UCSR1A;
ch = UDR1;
if (USART1_receCount < MSCOMM_BUFFER_LENGTH)
USART1_mscomm_buffer = ch;
else
USART1_receCount = 0;
if (status & 0x1C)
USART1_checkoutError = 2;
}
下面是我的发送中断代码
#pragma interrupt_handler USART1_TX_ISR:iv_USART1_TX
void USART1_TX_ISR(void)
{
if (USART1_sendPosi < USART1_sendCount)
UDR1 = USART1_send_buffer;
else
RS485_RECIVE_enable();
}
//下面的代码在主程序中执行,用于发送第1个字节,同时开启发送中断
void USART1_Begin_Send(void)
{
RS485_SEND_enable();
NOP(); // --------|
NOP(); // |
NOP(); // |-----------等待总线释放
NOP(); // |
NOP(); // --------|
USART1_sendPosi = 0;
UDR1 = USART1_send_buffer;
} 十分感谢高手的建议,我一定谨记在心!
初学者,在这方面没有经验……
谢谢高手让我成长! 谢谢楼上的各位{:victory:} mark一下关于串口中断的,有空看看那 ba_wang_mao 发表于 2012-5-24 17:34 static/image/common/back.gif
应该是你程序的问题。
一个串口通讯方面的老手给你提提意见:
你好,能看到你的这个完整的代码吗,
我主要是想知道你的main函数中是怎么对
USART1_mscomm_buffer[]处理的,
假设你正在处理的过程中,又有新的接收中断到来, USART1_mscomm_buffer[]中的数据又变化了怎么做的 表示很钦佩!!!! mark 今天测试一下 ba_wang_mao 发表于 2012-5-24 17:34 static/image/common/back.gif
应该是你程序的问题。
一个串口通讯方面的老手给你提提意见:
你好,能够把你的RS485_RECIVE()这个函数是怎么实现的,给看看吗
页:
[1]