搜索
bottom↓
回复: 6

UART通信问题

[复制链接]

出0入0汤圆

发表于 2012-9-11 17:38:31 | 显示全部楼层 |阅读模式
      写了一个很简单的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;
          }
     }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2012-9-11 20:23:01 | 显示全部楼层
自己顶啊,有木有人给回答一下?
头像被屏蔽

出0入0汤圆

发表于 2012-9-11 20:57:30 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
头像被屏蔽

出0入0汤圆

发表于 2012-9-11 20:59:51 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
头像被屏蔽

出0入0汤圆

发表于 2012-9-11 22:11:09 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

 楼主| 发表于 2012-9-13 09:04:21 | 显示全部楼层
feifei1986 发表于 2012-9-11 20:59
USART_INIT();这个子函数没有啊.你觉得是哪个部分有问题,就把有问题的部分注释一下.不然看的人很麻烦的 ...

嗯,没贴那个子函数,不好意思了。ICC写的,问题找到,是波特率选定的问题,通信误差太大。
谢谢回复。

出0入0汤圆

 楼主| 发表于 2012-9-13 09:04:57 | 显示全部楼层
lvhoujun 发表于 2012-9-11 22:11
波特率是否误差过大?时钟1M时,若U2X=0,UBRR=6,9600的波特率误差是-7%;U2X=1,UBRR=12,9600的波特率误 ...

是这个问题,已经解决了。
谢谢回复。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-11 10:30

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表