首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

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

2013-01-26 
请教一个关于串口中断收发的问题开发环境:迪文显示屏+C8051f340。串口发送数据没问题,显示屏可以正常显示,

请教一个关于串口中断收发的问题
开发环境:迪文显示屏+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 ;
}
}

buffer uart c8051f340
[解决办法]
但是显示屏发送的数据 --

可以先使用串口工具查看数据格式是否正确 迪文光盘里面有SSCOM 或者可以先使用光盘里面的软件对显示屏进行配置 也带有串口发送数据
[解决办法]
是不是你的MCU的串口收数据线接线有问题。
[解决办法]
假定如何两个函数分别用于从串口缓冲区取数据和发送数据
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。

热点排行