各位大侠,我用AVR ATMEGA16的UART来接收上位机串口调试助手发来的数据,假设为0x53,0x26,0x53,0x89,0x47,前面两个数据总是对的,然后第三位就接到了最后一个数据,中间的数据就丢失了。
接收中断程序如下:
#pragma interrupt_handler uart_rx_isr:12
void uart_rx_isr(void)
{
if(!rx_isfull)
{
*rx_pointer = UDR;
rx_pointer++;
if(rx_pointer == rx_buffer + RX_BUFFER_LEN)
rx_pointer = rx_buffer;
if(rx_pointer == get_pointer)
rx_isfull = TRUE;//rx_pointer加1的情况下,追上了get_pointer,说明缓冲区已满
update = TRUE;
}
}
接收程序如下:
char uart_receive_byte(void)
{
char c;
while((!rx_isfull) && (get_pointer == rx_pointer)); // wait until rx_buffer is not empty
CLI();
c = *get_pointer;
get_pointer++;
if(get_pointer == rx_buffer + RX_BUFFER_LEN)
get_pointer = rx_buffer;
rx_isfull = FALSE;
SEI();
return c;
}
通过JTAGICE设置断点去查看rx_buffer中的值就出现rx_buffer[0] = 0x53,rx_buffer[1] = 0x26,rx_buffer[2] = 0x47,也就是前面两个和最后一个是对的,中间的数据丢失了
波特率是没问题的,这个我已经检查过了,9600,如果串口调试助手一次发一个字节,接收是完全没有问题的,
RX_BUFFER_LEN增加到32(64)看看。
这个?................哎。程序好好检查一下。
好久不搞单片机。
看看是不是中断的问题,有没有使用其他优先级高的中断,如果用的话可能会出现丢包,AVR的就这点不好,优先级不能调整。我以前也遇到类似的情况,定时器中断设的时间太短,老是把串口中断打断造成丢包,后来把定时器定时改长就好多了。还有,中断服务程序尽量简短,否则可能也会出现问题,一般我是如下:
void uart0_rx_isr(void)
{
inbuf[receivelen] = UDR;
receivelen++;
}
然后在主程序中判断,比如判断第一个字节是否是需要的,否则receivelen清零;如果在包头正确的情况下接收到你需要的长度,再进行数据包的解析。