请教一个关于串口中断收发的问题

舟遥 2012-12-31 03:30:06
开发环境:迪文显示屏+C8051f340。串口发送数据没问题,显示屏可以正常显示,但是显示屏发送的数据,单片机总是接收不到,而且不是接收错误的数据或者接收的数据不完整,通过查看接收缓冲区可以看出,是一个数据也没接收到。
主程序的主要代码是这样的,第一个if是用于检验接收缓冲区内的数据的,第二个if用于清空接收缓冲区的,第三个if用于发送数据,我想知道我的程序有没有问题,此外,问题可能出现在什么地方:
        while(1){
if( UART_Buffer[0]== 0xAA && UART_Buffer[1] == 0x78
&& UART_Buffer[4] == 0xCC && UART_Buffer[5] == 0x33
&& UART_Buffer[6] == 0xC3 && UART_Buffer[7] == 0x3C)
{

switch(UART_Buffer[3])
{
case 0x02: continue_flag = 0 ;break;
case 0x03: continue_flag = 1 ;break;
default: break;
}
UART_Buffer_Size = 0 ;
}
if(UART_Buffer_Size==UART_BUFFERSIZE)
{
UART_Buffer_Size=0;
}
if(continue_flag)
{
SendBufferDat(flush,sizeof(flush));
SendBufferDat(end_pic,sizeof(end_pic));
Delay_ms(100);
}
};

数据缓冲区的定义以及串口UART的设置如下:
#define UART_BUFFERSIZE 64
unsigned char xdata UART_Buffer[UART_BUFFERSIZE];
unsigned char UART_Buffer_Size = 0;
unsigned char UART_Input_First = 0;
unsigned char Byte;


void UART0_Init (void)
{
SCON0 = 0x10;

TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0x0B;
CKCON |= 0x08;

TL1 = TH1; // init Timer1
TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
REN0 = 1 ;
IP |= 0x10;
ES0 = 1;
}

void send_byte(unsigned char i) //串口发送一个字节
{
SendbufferOver=0;
SBUF0=i;
while (SendbufferOver==0);
SendbufferOver=0 ;
}

void SendBufferDat(unsigned char *base, unsigned char size)
{
unsigned char m;
for(m=0;m<size;m++)
{
send_byte(*base);
base++;
}
}

void UART_ISR(void) interrupt 4
{

if (RI0 == 1)
{
if( UART_Buffer_Size == 0) { // If new word is entered
UART_Input_First = 0; }
RI0 = 0; // Clear interrupt flag
Byte = SBUF0;
if (UART_Buffer_Size < UART_BUFFERSIZE)
{
UART_Buffer[UART_Input_First] = Byte; // Store in array
UART_Buffer_Size++; // Update array's size
UART_Input_First++; // Update counter
}
}
if(TI0 == 1){
TI0 = 0 ;
SendbufferOver = 1 ;
}
}
...全文
832 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
舟遥 2013-01-06
  • 打赏
  • 举报
回复
引用 10 楼 power_mcu 的回复:
假定如何两个函数分别用于从串口缓冲区取数据和发送数据 drvComSendBytes(unsigned char* pData, unsigned char u8Length) //发送指定长度数据到串口缓冲区 drvComGetBytes(unsigned char* pData, unsigned char u8Length) //从串口缓冲区获取指定长度数据 ……
我仔细分析了你的方法,也采用了,不过依然是收不到数据,不过,你这思路很不错,就把分给你吧
power_mcu 2013-01-05
  • 打赏
  • 举报
回复
假定如何两个函数分别用于从串口缓冲区取数据和发送数据 drvComSendBytes(unsigned char* pData, unsigned char u8Length) //发送指定长度数据到串口缓冲区 drvComGetBytes(unsigned char* pData, unsigned char u8Length) //从串口缓冲区获取指定长度数据 unsigned char drvComGetRecvCount() //获取接收缓冲区已接收到数据长度 typedef enum { SYN_0 = 0, SYN_1, SYN_2, DATA, PACKET_END, }RECV_STATE; static RECV_STATE s_RecvState = SYN_0; while(1) { switch(s_RecvState ) { case SYN_0: if(drvComGetRecvCount() >= 1) { //串口有数据到达 //获取一个字节数据 drvComGetBytes(&u8Data, 1); if(u8Data == 0xAA) { //包头同步字节1到达 //状态跳转 s_RecvState = SYN_1; } } break; case SYN_1: if(drvComGetRecvCount() >= 1) { //串口有数据到达 //获取一个字节数据 drvComGetBytes(&u8Data, 1); if(u8Data == 0x78) { //包头同步字节2到达 //状态跳转 s_RecvState = SYN_2; } else { //异常情况,也许干扰,也许掉电,也许屏挂了 //可以考虑是否清空接收缓冲区 //回状态SYN_0; s_RecvState = SYN_0; } } else { //开启超时定时器 if(超时定时器溢出) { //异常情况,也许干扰,也许掉电,也许屏挂了 //可以考虑是否清空接收缓冲区 //回状态SYN_0; s_RecvState = SYN_0; } } break; case SYN_2: break; case DATA: break; case PACKET_END: break; default: break; } } 其它几个状态处理流程同SYN_2。
power_mcu 2013-01-04
  • 打赏
  • 举报
回复
这个解析程序非常的糟糕。没有做任何错误,超时处理,只要有一次错误发生,以后基本不会受到正确的数据帧。需要重新写串口协议解析部分,一个字节一个字节判断,用状态机方式。
舟遥 2013-01-04
  • 打赏
  • 举报
回复
波特率是正常的,不然也不会能发送但是不能接收啊
fang 2013-01-04
  • 打赏
  • 举报
回复
你两边收发的波特率是一致的吗?波特率不一致也应该有乱码的现象,你现在是没收到任何数据,我建议你还是用视波仪监视下你的串口发数据的情况。
aydf1 2013-01-04
  • 打赏
  • 举报
回复
这个解析程序非常的糟糕。没有做任何错误,超时处理,只要有一次错误发生,以后基本不会受到正确的数据帧。需要重新写串口协议解析部分,一个字节一个字节判断,用状态机方式。
舟遥 2013-01-04
  • 打赏
  • 举报
回复
引用 7 楼 power_mcu 的回复:
这个解析程序非常的糟糕。没有做任何错误,超时处理,只要有一次错误发生,以后基本不会受到正确的数据帧。需要重新写串口协议解析部分,一个字节一个字节判断,用状态机方式。
什么叫状态机方式,求指教。我这个如果数据正确返回的话会是 AA 78 00 xx CC 33 C3 3C 这八个字节的数据,xx那一个字节是可变的,其他是固定的,求写串口接收数据解析的方法
舟遥 2012-12-31
  • 打赏
  • 举报
回复
引用 3 楼 fang098 的回复:
是不是你的MCU的串口收数据线接线有问题。
不清楚,引脚的连接应该是对的,而且之前也做过串口接收的测试,数据也正确,只是使用中断收发的时候有问题。感觉一个简单的中断收发没啥特别难的,怎么就老是通不过呢。
fang 2012-12-31
  • 打赏
  • 举报
回复
是不是你的MCU的串口收数据线接线有问题。
舟遥 2012-12-31
  • 打赏
  • 举报
回复
引用 1 楼 woshi_ziyu 的回复:
但是显示屏发送的数据 -- 可以先使用串口工具查看数据格式是否正确 迪文光盘里面有SSCOM 或者可以先使用光盘里面的软件对显示屏进行配置 也带有串口发送数据
之前测试过了,使用迪文自带的迪文工具箱发现显示屏传回的数据是正常的。但是就是单片机接收不到。 而且使用串口调试助手通信的话,有时单品阿基能接收到串口调试助手发送的数据,有时接收不到,就是根本没反应,对此很是迷茫,端口配置什么的一行行查看了,都正常,感觉中断程序也没错,就是不知道为啥接收不到数据
woshi_ziyu 2012-12-31
  • 打赏
  • 举报
回复
但是显示屏发送的数据 -- 可以先使用串口工具查看数据格式是否正确 迪文光盘里面有SSCOM 或者可以先使用光盘里面的软件对显示屏进行配置 也带有串口发送数据

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧