UART通信问题

2019-03-24 20:48发布

写了一个很简单的UART的程序,就是按照“0xBB 八位数据 0xEE”的数据帧格式通过串口给mega16发数据,(数据在0-9之间),然后通过数码管显示。
      UART设置是9600波特率,1M时钟。
      现在问题是:
                       1.发送数据总是发好几遍才可以使数码管值改变
                       2.发数据0x01总是显示溢出
                       3.用proteus仿真,显示数据帧格式不对


        不知道是什么原因,想请指教,程序如下:
   #include <iom16v.h>
#include <macros.h>


#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1 << FE)
#define PARITY_ERROR (1 << UPE)
#define DATA_OVERRUN (1 << OVR)
#define RX_COMPLETE (1<<RXC)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define UART_BEGIN_STX 0xBB
#define UART_END_STX 0xEE

#define TX_BUFFER_SIZE 5
#define RX_BUFFER_SIZE 5
unsigned char tx_buffer[TX_BUFFER_SIZE];
unsigned char tx_wr_index,tx_rd_index,tx_counter;
unsigned char rx_buffer[RX_BUFFER_SIZE];
unsigned char rx_counter;
unsigned char Uart_RecvFlag;
unsigned char a;
unsigned char led[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

#pragma interrupt_handler USART_RXC_isr:iv_USART_RXC
void USART_RXC_isr(void)
{
   
      unsigned char status,data;
      status = UCSRA;
      data = UDR;
      if(!Uart_RecvFlag)                       //判断是否可以接收一个新的数据包
            {
                if((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
                    {
                         rx_buffer[rx_counter] = data;
                         rx_counter++;
                         switch(rx_counter)
                           {
                               case 1:                          //校检起始字符
                                        if(data != UART_BEGIN_STX) rx_counter = 0;
                                        break;
                               case 3:
                                        if(data == UART_END_STX) Uart_RecvFlag = 1;
                                        rx_counter = 0;
                                        break;                  //表示正确接受到一个数据包
            
                            }
                   }
        
            }
        
}

void main(void)
{
  DDRB = 0xff;
  PORTA = 0x01;
  DDRA |= 0xFF;                                     //初始化数码管输出使能和段选信号口
  
  //UART initialization
  CLI();
  USART_INIT();
  SEI();                           //Global enable interruPts

    while(1)
    {
       if(Uart_RecvFlag)
          {
            PORTB = led[rx_buffer[1]];
            Uart_RecvFlag = 0;
          }
     }
} 此帖出自小平头技术问答
0条回答

一周热门 更多>