[AVR单片机] 使用USART0通信一直通信失败,用仿真器看UDR0的值一直为零

[复制链接]
3481|3
 楼主| icome321 发表于 2013-11-27 17:03 | 显示全部楼层 |阅读模式
程序是挺大众的USART0的通信程序,片子是128。串口线是好用的。通信的时候用串口调试助手给板子发数据,用仿真器看UDR0的值一直为0,奇怪的是temp还会显示一个数(错误的),最后在1602上显示错误。程序如下:

  1. #define uchar unsigned char
  2. #define uint unsigned int
  3. #define UDRE 5
  4. #define RXC 7

  5. //+++++++++1602_LCD功能引脚宏定义+++++++++++++++
  6. #define LCD_DATA PORTB
  7. #define LCD_RS PORTA_Bit4
  8. #define LCD_RW PORTA_Bit5
  9. #define LCD_EN PORTA_Bit6

  10. //+++++++++++++++++通讯引脚宏定义++++++++++++++++++
  11. #define TXDIN        DDRD=DDRD|0x02                          // TXD 设置为输出
  12. #define RXDIN        DDRD=DDRD&0xFE;PORTD=PORTD|0x01        // RXD 设置为输入,且内部上拉有效

  13. void LCD_init();
  14. void write_com(uchar com);
  15. void write_data(uchar data);
  16. void delay(uint z);
  17. /***************************************/
  18. void port_init(void)//I/O口初始化
  19. {
  20.     PORTA = 0xFF;
  21.     DDRA  = 0xff;
  22.     PORTB = 0xFF;
  23.     DDRB  = 0xFF;
  24.    
  25.     TXDIN;    // TXD 设置为输出
  26.     RXDIN;   // RXD 设置为输入,且内部上拉有效
  27.     //PORTD = 0xFF;
  28.     //DDRD  = 0x02;
  29. }
  30. /**************************************/
  31. void uart0_init(void) //uart 初始化
  32. {
  33.     UCSR0B = 0x00;
  34.    
  35.     UCSR0A = 0x00;
  36.    
  37.     UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);//异步模式(默认) 无校验位 一位停止位 接收数据长度为8
  38.     //UCSR0C = 0x06;//异步模式(默认) 无校验位 一位停止位 接收数据长度为8
  39.    
  40.     UBRR0L = 51; //波特率为 9600
  41.     UBRR0H = 0x00;
  42.    
  43.     UCSR0B = (1<<RXEN0)|(1<<TXEN0);//接收允许 发送允许
  44.     //UCSR0B = 0x18;
  45. }

  46. void init_devices(void)
  47. {
  48.     __disable_interrupt();
  49.     port_init();
  50.     uart0_init();
  51. }

  52. /********************************/
  53. void uart0_send(unsigned char i)//数据发送
  54. {
  55.     while(!(UCSR0A&(1<<UDRE0)));
  56.     UDR0=i;
  57. }

  58. /************************************************/
  59. unsigned char uart0_receive(void) //数据接收
  60. {
  61.     while(!(UCSR0A&(1<<RXC0)));
  62.     return UDR0;
  63. }
  64. /******************************************/
  65. void main(void)
  66. {
  67.     unsigned char temp=0;
  68.     delay(50);
  69.     init_devices();
  70.     LCD_init();
  71.     while(1)
  72.     {
  73.         temp=uart0_receive(); //接收数据
  74.         
  75.         write_com(0x80+0x06);
  76.       
  77.         write_data(temp); //1602液晶显示
  78.         
  79.         uart0_send(temp);//数据发送
  80.     }
  81. }
  82. void LCD_init()
  83. {
  84.     LCD_RW=0;
  85.     LCD_EN=0;
  86.     write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口
  87.     write_com(0x0c);//设置开显示,不显示光标
  88.     write_com(0x06);//写一个字符后地址指针加1
  89.     write_com(0x01);//显示清零,数据指针清零
  90.     write_com(0x80);
  91. }
  92. void write_com(uchar com)
  93. {
  94.     LCD_RS=0;        //选择写命令模式
  95.     LCD_DATA=com;     //将要写的命令送到数据总线上
  96.     delay(5);           //稍作延时以待数据稳定
  97.     LCD_EN=1;     //时能端给以高脉冲,因为初始化函数中已经将lcden置0
  98.     delay(5);         //稍作延时
  99.     LCD_EN=0;      //将使能端置0已完成高脉冲
  100.     LCD_RS=1;  
  101. }
  102. void write_data(uchar data)
  103. {
  104.     LCD_RS=1;
  105.     LCD_DATA=data;
  106.     delay(5);
  107.     LCD_EN=1;
  108.     delay(5);
  109.     LCD_EN=0;
  110.     LCD_RS=0;
  111. }
  112. void delay(uint z)     //晶振8M
  113. {
  114.     uint x,y;
  115.     for(x=0;x<z;x++)
  116.        for(y=0;y<1141;y++);
  117. }
用串口调试助手往里发数字“1”,变量和寄存器如图:

实在不知道是怎么回事。。球问各位大师呀。。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
mcuzone_mcu4 发表于 2013-11-28 10:00 | 显示全部楼层
#define BAUD 38400

void Usart_Init(void)
{
        PORTD = 0X00;          //USART的发送接收端口分别为PD0和PD1
        DDRD |= (1 << PD1);   //PD0为接收端口,置为输入口;PD1为发送端口,置为输出口

        UCSRA = 0X00;       
        UCSRC |= (1<<URSEL) | (1 << UCSZ1) | (1 << UCSZ0);  //异步,数据格式8,N,1
             //UCSRC寄存器与UBRRH寄存器共用相同的I/O地址,写 UCSRC 时, URSEL 应设置为 1。
        UBRRL = (F_CPU / BAUD / 16 - 1) % 256;    //波特率设置
        UBRRH = (F_CPU / BAUD / 16 - 1) / 256;
        UCSRB |= (1 << RXCIE) | (1 << RXEN) | (1 << TXEN);    //发送使能
        sei();
}
void Usart_PutChar(unsigned char TXData)
{
        while( !(UCSRA & (1 << UDRE)) );  //只有数据寄存器为空时才能发送数据
        UDR = TXData;       
}
int main(void)
{
    Usart_Init();
    while(1);
}
ISR(USART_RXC_vect)
{
    unsigned char RxData;
        RxData = UDR;
        Usart_PutChar( RxData );              
}


一段mega16的串口代码,希望对你有用
liaowencong 发表于 2014-3-2 14:59 | 显示全部楼层
应该是仿真软件的问题。看不到UDR寄存器的值,但是实际不是0
airwill 发表于 2014-3-4 16:14 | 显示全部楼层
估计仿真器不能访问 UDR0, 因为随意造访会导致程序的异常, UDR0 一旦读过, 数据就没有了.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

8

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部