avr单片机USART串口通讯初始化配置说明

时间:2022-06-28 19:44:48

  avr atmega16 单片机通用同步和异步串行接收器和转发器 (USART) 
是一个高度灵活的串行通讯设备,其工作模式及其初始化,寄存器说明如下

 *****************************USART 控制和状态寄存器A(UCSRA)********************************

 USART 控制和状态寄存器A(UCSRA)
      bit7          bit6      bit5        bit4      bit3         bit2      bit1        bit0
      RXC       TXC       UDRE       FE       DOR        PE       U2X      MPCM
      RXC: USART 接收结束
          接收缓冲器中有未读出的数据时RXC 置位,否则清零。接收器禁止时,接收缓冲器被刷
          新,导致RXC 清零。RXC 标志可用来产生接收结束中断
      TXC: USART 发送结束
          发送移位缓冲器中的数据被送出,且当发送缓冲器 (UDR) 为空时TXC 置位。执行发送
          结束中断时TXC 标志自动清零,也可以通过写0进行清除操作。TXC 标志可用来产生发
          送结束中断( 见对TXCIE 位的描述)。
      UDRE: USART 数据寄存器空
           UDRE标志指出发送缓冲器(UDR)是否准备好接收新数据。UDRE为1说明缓冲器为空,已
           准备好进行数据接收。UDRE标志可用来产生数据寄存器空中断
           复位后UDRE 置位,表明发送器已经就绪。
      FE: 帧错误
          如果接收缓冲器接收到的下一个字符有帧错误,即接收缓冲器中的下一个字符的第一个
          停止位为0,那么FE 置位。这一位一直有效直到接收缓冲器(UDR) 被读取。当接收到的
          停止位为1 时, FE 标志为0。对UCSRA 进行写入时,这一位要写0。
      DOR: 数据溢出
          数据溢出时DOR 置位。当接收缓冲器满( 包含了两个数据),接收移位寄存器又有数据,
          若此时检测到一个新的起始位,数据溢出就产生了。这一位一直有效直到接收缓冲器
          (UDR) 被读取。对UCSRA 进行写入时,这一位要写0。
      PE: 奇偶校验错误
          当奇偶校验使能(UPM1 1),且接收缓冲器中所接收到的下一个字符有奇偶校验错误时
          UPE 置位。这一位一直有效直到接收缓冲器 (UDR) 被读取。对UCSRA 进行写入时,这
          一位要写0。
      U2X: 倍速发送
           这一位仅对异步操作有影响。使用同步操作时将此位清零。此位置1可将波特率分频因
           子从16降到8,从而有效的将异步通信模式的传输速率加倍。
      MPCM: 多处理器通信模式
           设置此位将启动多处理器通信模式。MPCM置位后,USART 接收器接收到的那些不包含
           地址信息的输入帧都将被忽略。发送器不受MPCM设置的影响。
  
***************************USART控制和状态寄存器 B(UCSRB)*******************
 USART控制和状态寄存器 B(UCSRB)
      bit7          bit6         bit5          bit4         bit3        bit2          bit1        bit0
      RXCIE     TXCIE     UDRIE      RXEN      TXEN     UCSZ2      RXB8      TXB8
      RXCIE: 接收结束中断使能
             置位后使能RXC中断。当RXCIE为1,全局中断标志位SREG置位,UCSRA寄存器的RXC
             亦为1时可以产生USART接收结束中断。
      TXCIE: 发送结束中断使能
             置位后使能TXC中断。当TXCIE为1,全局中断标志位SREG置位,UCSRA寄存器的TXC
             亦为1时可以产生USART发送结束中断。
      UDRIE: USART 数据寄存器空中断使能
             置位后使能UDRE中断。当UDRIE 为1,全局中断标志位SREG置位,UCSRA寄存器的UDRE
             亦为1时可以产生USART数据寄存器空中断。
      RXEN: 接收使能
             置位后将启动USART接收器。RxD 引脚的通用端口功能被USART功能所取代。禁止接
             收器将刷新接收缓冲器,并使 FE、DOR及PE标志无效。
      TXEN: 发送使能
             置位后将启动将启动USART发送器。TxD引脚的通用端口功能被USART功能所取代。
             TXEN 清零后,只有等到所有的数据发送完成后发送器才能够真正禁止,即发送移位
             寄存器与发送缓冲寄存器中没有要传送的数据。发送器禁止后,TxD引脚恢复其通用
             I/O功能。
      UCSZ2: 字符长度
             UCSZ2与UCSRC寄存器的UCSZ1:0结合在一起可以设置数据帧所包含的数据位数(字符
             长度)。
      RXB8: 接收数据位8
            对9位串行帧进行操作时,RXB8 是第9个数据位。读取UDR包含的低位数据之前首先
            要读取RXB8。
      TXB8: 发送数据位8
             对9位串行帧进行操作时,TXB8是第9个数据位。写UDR之前首先要对它进行写操作。

  
****************************状态寄存器 C(UCSRC)*****************************
 状态寄存器 C(UCSRC)
         bit7           bit6           bit5         bit4         bit3         bit2         bit1          bit0
      URSEL     UMSEL          UPM1      UPM0      USBS     UCSZ1     UCSZ0      UCPOL
      UCSRC寄存器与UBRRH寄存器共用相同的I/O地址。对该寄存器的访问。
      URSEL: 寄存器选择
              通过该位选择访问UCSRC寄存器或UBRRH寄存器。 当读UCSRC时,该位为1 ;当写UCSRC
              时,URSEL为1。 URSEL 为 0 ,对UBRRH 值更新; 若 URSEL 为 1 ,对UCSRC 设置更新
      UMSEL: USART 模式选择
              通过这一位来选择同步或异步工作模式。
                                         UMSEL设置
                      UMSEL                                    模式
                        0                                      异步操作
                        1                                      同步操作
      UPM1:0: 奇偶校验模式
              这两位设置奇偶校验的模式并使能奇偶校验。如果使能了奇偶校验,那么在发送数
              据,发送器都会自动产生并发送奇偶校验位。对每一个接收到的数据,接收器都会
              产生一奇偶值,并与UPM0 所设置的值进行比较。如果不匹配,那么就将UCSRA 中
              的PE 置位。
                                         UPM 设置
           UPM1                       UPM0                     奇偶模式
                  0                          0                        禁止
                  0                          1                        保留
                  1                          0                       偶校验
                  1                          1                       奇校验
      USBS: 停止位选择
             通过这一位可以设置停止位的位数。接收器忽略这一位的设置。
                                         USBS 设置
                       USBS                                 停止位位数
                        0                                        1
                        1                                        2
      UCSZ1:0: 字符长度
              UCSZ1:0与UCSRB寄存器的 UCSZ2结合在一起可以设置数据帧包含的数据位数(字
              符长度)。
                                         UCSZ 设置
          UCSZ2           UCSZ1          UCSZ0         字符长度 
              0                   0                   0                   5
              0                   0                   1                   6
              0                   1                   0                   7
              0                   1                   1                   8
              1                   0                   0                 保留
              1                   0                   1                 保留
              1                   1                   0                 保留
              1                   1                   1                   9
      UCPOL: 时钟极性
             这一位仅用于同步工作模式。使用异步模式时,将这一位清零。UCPOL 设置了输出
             数据的改变和输入数据采样,以及同步时钟XCK 之间的关系。
                                        UCPOL 设置
      UCPOL    发送数据的改变(TxD引脚的输出)                  接收数据的采样(RxD 引脚的输入)
         0              XCK上升沿XCK                             下降沿
         1              XCK 下降沿XCK                            上升沿


*********************************USART波特率寄存器(UBRRL和UBRRH)*************************

 USART波特率寄存器(UBRRL和UBRRH)
      bit15     bit14     bit13     bit12     bit11     bit10      bit9     bit8
      URSEL       –         –         –                    UBRR[11:8]
                                        UBRR[7:0]
      UCSRC寄存器与UBRRH寄存器共用相同的I/O地址。对该寄存器的访问。
      URSEL: 寄存器选择
             通过该位选择访问UCSRC 寄存器或UBRRH 寄存器。当读UBRRH时,该位为0;当写
             UBRRH时, URSEL为0。
      Bit 14:12 – 保留位
             这些位是为以后的使用而保留的。为了与以后的器件兼容,写UBRRH时将这些位清零。
      UBRR11:0: USART 波特率寄存器
             这个12位的寄存器包含了USART的波特率信息。其中UBRRH包含了USART波特率高4
            位,UBRRL包含了低8位。波特率的改变将造成正在进行的数据传输受到破坏。写UBRRL
            将立即更新波特率分频器。

      波特率定义为每秒的位传输速度 (bps) 

      BAUD   波特率 ( bps) 
      fOSC   系统时钟频率 
      UBRR   UBRRH 与 UBRRL 的数值 (0-4095)

      异步正常模式 (U2X = 0)                                                 
                           FOSC                              FOSC 
      BAUD = --------------           UBRR = ------------    -1 
                   16( UBRR+ 1)                      16BAUD 
      异步倍速模式 (U2X = 1)                                                 
                          fOSC                               fOSC 
      BAUD   = --------------         UBRR =   ------------    -1 
                        8(UBRR+ 1)                     8BAUD 
      同步主机模式                      
                         fOSC                               fOSC 
      BAUD   = ---------------       UBRR = ------------   -1 
                      2(UBRR+ 1)                       2BAUD

程序例子:
      #include<iom16v.h>
      #include<macros.h>
      #pragma interrupt_handler UDR_empty:iv_USART_UDRE
      #pragma interrupt_handler RXC_END:iv_USART_DRE
      #pragma interrupt_handler TXC_END:iv_USART_TX
      unsigned char UASART_DATA=0;
      void USART_Init( unsigned int baud,unsigned char digit,unsigned char mode,unsigned char checkout)//详细初始化模式
      {

   SREG&=0x7F;
           UCSRC&=~(1<<URSEL);//写UBRRH
           /* 设置波特率 */ 
          UBRRH = (unsigned char)(baud>>8);
          UBRRL = (unsigned char)baud;
          /* 接收器与发送器使能 */ 
          UCSRB = (1<<RXEN)|(1<<TXEN);
          /*UDR数据寄存器为空时中断使能 */
          UCSRB = (1<<UDRIE);//最好不用。根据需要打开此中断使能

          switch(mode)//异同模式选择
          {
               case 0:UCSRB&=~(1<<UMSEL);break;//异步模式
               case 1:UCSRB|=1<<UMSEL;break;//同步模式
               default :UCSRB&=~(1<<UMSEL);break;
          }
          UCSRC|=1<<URSEL;//写UCSRC。
         /* 如果发送9位数据的数据帧(UCSZ = 7), 应先将数据的第9位写入寄存器UCSRB的TXB8, 然后再将低8位数据写入发送数据寄存器UDR, */
          switch(digit)//// 设置帧格式 : digit数据位5-9,
         {
               case 5:UCSRB&=~(1<<UCSZ2);UCSRC&=~(3<<UCSZ0);break;
               case 6:UCSRB&=~(1<<UCSZ2);UCSRC&=~(1<<UCSZ1);UCSRC|=1<<UCSZ0;break;
               case 7:UCSRB&=~(1<<UCSZ2);UCSRC|=1<<UCSZ1;UCSRC&=~(1<<UCSZ0);break;
               case 8:UCSRB&=~(1<<UCSZ2);UCSRC|=3<<UCSZ0;break;
               case 9:UCSRB|=1<<UCSZ2;UCSRC|=3<<UCSZ0;break;
               default:UCSRB&=~(1<<UCSZ2);UCSRC|=(3<<UCSZ0);break; 
          }
          switch(checkout)//checkout校验模式
         {
              case 0:UCSRC&=~(1<<UPM1);UCSRC&=~(1<<UPM0);break;//禁止校验。
              case 2:UCSRC|=1<<UPM1;UCSRC&=~(1<<UPM0);break;//偶校验 
              case 3:UCSRC|=(3<<UPM0);break;//奇校验
              default:UCSRC&=~(1<<UPM1);UCSRC&=~(1<<UPM0);break; 
          }
          UCSRC|=1<<USBS;//2个停止位
          //UCSRC&=~(1<<USBS);//1个停止位
          UCSRC&=~(1<<UCPOL); //时钟极性设置
          //***************
          //UCSRA|=1<<U2X;//打开此行倍速模式
          //UCSRA|=1<<MPCM;//打开此行,是多处理器通信模式
          SREG|=0x80;//使能全局中断
        }

      /************UBRR的baud设置参数表*****************************/
      //U2X=0;8mhz晶振9600:UBRR=51;误差:0.2%。4800:UBRR=103;误差:0.2%.2400:UBRR=207;误差:0.2%
      //U2X=1;8mhz晶振9600:UBRR=103;误差:0.2%。4800:UBRR=207;误差:0.2%.2400:UBRR=416;误差:-0.1%
      //U2X=0;11.0592mhz晶振9600:UBRR=71;误差:0.0%。4800:UBRR=143;误差:0.0%.2400:UBRR=287;误差:0.0%
      //U2X=1;11.0592mhz晶振9600:UBRR=143;误差:0.0%。4800:UBRR=287;误差:0.0%.2400:UBRR=575;误差:0.0%
      void USART_Init_commonage(unsigned int baud)//通用初始化
      {

           /* 设置波特率 */
          SREG&=0x7F;
          UBRRH = (unsigned char)(baud>>8); 
          UBRRL = (unsigned char)baud; 
          /* 接收器与发送器使能 数据寄存器空使能禁止*/ 
          UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE); 
          /* 设置帧格式 : 8个数据位 , 2个停止位 ,禁止校验,XCK上升沿发送数据下降沿接收数据,异步模式*/ 
          UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); 
       //UCSRA=0;单机处理模式。中断标志清零,波特率的普通模式(非加倍,倍速模式)
          SREG|=0x80;//使能全局中断
      }
      /*
      USART数据寄存器空标志UDRE及传输结束标志TXC,两个标志位都可以产生中断。
      */
      void UDR_empty()
      //使能要求:全局中断使能,数据寄存器空中断使能位 UDRIE置位。 UDRE 被置位(自动)。
      //对寄存器 UDR 执行写操作将清零 UDRE
      {

           unsigned char data;
           UDR = data;
           //add your code here
      }
      void TXC_END()
      {

            UDR =UASART_DATA;

            //add your code here
      }
      void RXC_END()
      {
            UASART_DATA=UDR;
            //add your code here
      }
      void USART_Transmit5_8( unsigned char data )//对 UDRE标志采用轮询方式发送数据(发送5-8位数据)
      { 

            /* 等待发送缓冲器为空 */ 
           while ( !( UCSRA & (1<<UDRE)) ) ;
           /* 将数据放入缓冲器,发送数据 */ 
           UDR = data; 
      }
      void USART_Transmit_9( unsigned int data )//用查询法发送9位数据的数据帧
      {

             /* 等待发送缓冲器为空 */ 
            while ( !( UCSRA & (1<<UDRE))) ;
            /* 将第 9 位复制到 TXB8 */ 
            UCSRB &= ~(1<<TXB8); 
            if ( data & 0x0100 ) 
            UCSRB |= (1<<TXB8); 
            /* 将数据放入缓冲器,发送数据 */ 
            UDR = data; 
      }
      unsigned char USART_Receive5_8( void )//用查询RXC接受5-8位的数据
      {
             /*等待接收数据*/
            while ( !(UCSRA & (1<<RXC)) );
            /* 从缓冲器获得数据并返回数据*/
             return UDR;
      }
      unsigned int USART_Receive_9( void )//接受9位的数据帧
      {
             unsigned char status, resh, resl;
            /*等待接收数据 */
            while ( !(UCSRA & (1<<RXC)) );
             /*从缓冲器获得状态及其第九位数据*/ 
            /* from buffer */
            status = UCSRA;
            resh = UCSRB;
            resl = UDR;
           /* 如果出错返回*/
            if ( status & (1<<FE)|(1<<DOR)|(1<<PE) )
                  return 255;
           /* 过滤第九位数据然后返回*/
            resh = (resh >> 1) & 0x01;
            return ((resh << 8) | resl);
      }
      /*
      禁止接收器时缓冲器 FIFO 被刷新,缓冲器被清空。导致未读出的数据丢失。如果由于出错而必须在正常操作下刷新缓冲器?
      则需要一直读取 UDR 直到 RXC 标志清零。
      */
      void USART_Flush( void )
      {
             unsigned char dummy;
             while ( UCSRA & (1<<RXC) ) dummy = UDR;
      }