专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

AVR单片机学习(七)异步串行口UART

作者:zww 1988   来源:本站原创   点击数:  更新时间:2014年04月18日   【字体:
串行通讯技术概述
  • 异步串行通讯原理
  • UART与电脑的通讯
  • M16的USART
  • 中断方式使用USART步骤
  • 一、串行通讯技术概述

    串行通讯的通俗定义:

         一位发送一位(相对与并行,)当然通过 位同步 帧同步

    串行通讯的分类

         同步串行通讯

    时钟线、数据线、通过时钟保持数据同步

       SPI,IIC 属于同步串口通讯

    异步串口通信

      只有一根数据线,通过波特率保证数据同步(顾名思义没有时钟线只有数据线)

    UART

      无线通信一般均为异步串行通信(相对于无形之中只能有一根天线)

    波特率

      每秒发送码元时间宽度为(1/9600)S   大概是在100个微妙左右

      发送方按照波特率发出数据

      接收方按照波特率确定码元时间宽度对数据进行采样

    帧格式

     8位数据格式

    idle 空闲时候保持高电平

    在发送数据的时候先发送一位起始位 低电平0

    然后数据 0 1 。。。。8 位 

    P这位是可选的一般在多级通讯的时候需要发送9位数据在第9位时候 是地址位

    SP1(必选的一位停止位 是1) 也可以选2位 加一个SP2  但是一般都是1位 起始位  1位停止位 8位数据位

    之后数据继续保持空闲高电平

     

     

    接线图

     发送端:TXD

     接收端:RXD

     交叉连接

    RS232电平标准

     逻辑1  :-15V

     逻辑0 :+15V

    DB9 接口定义

    TXD /RXD /GDN 三根线即可瞒足绝大数应用场合


    下面是开发板电路图


    MAX3232标示的是3.3V的芯片我们用的是5V MAX232 芯片标示错了 不论引脚封装还是顺序都是完全相同的。

    MAX 232 芯片能提供2路串口我们只用一个。由于这个电路图上是按照DB9定义的走线了所以我们就得用交叉线来跟PC通讯了。

    M16的USART特点

       全双工操作(独立的串行接受合发送寄存器,不像51是公用同一个寄存器,只能半双工)

       异步或同步操作(当然同步一般用不到。所以我们只当异步串行口使用)

       支持5,6,7,8或9个数据位和1个或2个停止位(一般用的最多是8位数据 1位停止)

       硬件支持的奇偶校验操作(一般用不到,有限的场合通信质量还是可靠的,没必要加上校验)

       三个独立的中断源(看技术文档《一》)

       噪声滤波,包括错误的起始位检测,以及数字低通滤波器

    USART 寄存器   universal (通用的大体的) synchronous(同步)   asynchronous(异步)R/T(接受/发送)

      UDR  

      UCSRA

      UCSRB

      UCSRC

      UBRRL与UBRRH

     

     
    《一》

     

    Three Separate Interrupts (3个 分离 独立的中断 ) TX complete 发送完成中断  ,TX Data Register Empty  发送数据寄存器空 中断   RX Complete 接受完成中断。

    以下是整段中文解释

    通用同步和异步串行接收器合转发器(USART)是一个高度灵活的串行通讯设备。主要特点为:

        全双工操作(独立的串行接收和发送寄存器)

        异步或同步操作

        主机或从机提供时钟的同步操作

        高精度的波特率发生器

        支持5,6,7,8,或9个数据位合1个 或 2个停止位

        硬件支持的奇偶数校验操作

         数据过渡检测

        侦错误检测

        噪声滤波,宝货粗无的起始位检测,以及数字低通滤波器

        三个独立的中断:发送结束中断,发送数据寄存器空中断,以及接受结束中断

        多处理器通讯模式

       倍速率异步通讯模式

     

     三个独立中断的前两个中断我们一般用不到的因为我们发送之前查询一下发送数据寄存器是否忙(可供使用)就可以了,没必要采用这两个中断,但是接受一般采用中断方式,因为我们不可能一直不停的查询。而查询发送终中断最多耽误发送一个字节的时间。

    噪声滤波使用起来通信质量相比其他单片机的通信质量大大提升,怎么操作USART呢 ?

    首先介绍下有关的寄存器

    第一个寄存器I/O 数据寄存器 UDR 

    share the same I/O address  共享相同的I/O地址 referred to as USART 称为USART 数据寄存器或 UDR  

    其实就是发送数据和接受数据寄存器都采样同一个名称UDR  但是怎么样区分呢? 

    写 就是 发送  读就是接受   第一段下面就是吧呵呵!本人英文不好呵呵  the Transmit Data Buffer Register(TXB)Will be the destination for data written to the UDR Register location ,Reading teh UDR Register location will return the contents of the Receive Data Buffer Register (RXB).

     

    第二个寄存器是 UCSRA  控制状态寄存器A


    第七位和第六位   接受完成(置位)   发送完成(置位)   这两段最后一句是说可以用接受中断标志合发送中断标志,自己慢慢看哦。

     

    第5位是 数据寄存器空 ,就是检测UDR 是否准备好接受新的数据。indicates 表明

    the UDRE flag indicates if the transmit buffer (UDR) is ready to receive new data 这个UDRE标志指出 发送缓冲器(UDR )是否准备号接受新数据 假如UDRE is one ,the buffer empty , and therefore ready to written 已准备好进行数据接受。所以这一位我们发送之前对这一位查询是否置位,如果置位了就可以往里写数据了,进行发送操作。


    第4位:帧错误   第三位数据溢出  第二位 :(parity)奇偶校验错误   一般我们是用不到的,没必要管他

     

    第1位:双 发送 速度  倍速发送跟设置波特率有影响的一般情况下把我们也是不用管的  如果将这位置位的话那么算出来的波特率就得乘以2.

    this bit only has effect for the asynchronous operation  这个位 仅对 有effect (效果) for the asynchronous operation 异步操作




    第0位:多处理器 communication 通讯 模式  这一位我们一般也是用不到的。

    所以这个UCSRA 这个控制状态寄存器一般用的最多的是第五位  UDRE 数据寄存器空

    第三个寄存器是控制状态寄存器B


    这个寄存器是平时用的最多的寄存器 

    第七位:RXCIE  :RX 结束中断使能

    如果是使用USART 的接受中断的话这一位必须置位 使能

    writing this bit to one enables interrupt on the RXC flag.写1 使能中断RXC 标志(置位后使能RXC中断)

    一个USART 接受中断结束  将生成 一个 RXCIE 位写1  ,这个全局中断标志SREG is 写  UCSRA 寄存器的RXC位置位1时可以产生USART 接受结束中断。

    第六位:TXCIE  TX 发送中断结束使能

    别人的解释:置位后使能TXC中断,当TXCIE 为1 时,全局中断标志位SREG 置位,UCSRA寄存器的TXC置为1时可以产生UCSRA发送结束中断。(看多经典比我上面的一个一个字解释好吧)

    当然第六位我们一边用不到的。

    第五位:USART 数据寄存器空中断使能   也不常用

     

    第4位:接受使能

    第3位:发送使能 

    这两位非常重要如果要用串行口 这两位必须使能。取代了通用端口了。



    第2位 :UCSZ2 字符长度

    这UCSZ2 位combined (结合)UCSRC寄存器的  UCSZ1:0在一起可以设置数据帧所包含的数据位数(字符长度)。

    一般我们用8位 。 可以设置成5--9位 当然在AVR 上电复位之后它的寄存器默认设置就是8位所以这我们也不用设置

     


    这个第1位和第0位分别是 :接受数据位8  和 发送数据位 8

    这两位仅仅对于数据长度设置成9位的时候才是有作用的他们分别是第9个数据位,所以我们这也是用不到。

    第四个寄存器:控制状态寄存器C
    第七位:寄存器选择

    这个位选择开始访问 UCSRC 或 UBRRH 寄存器。读UCSRC 该位为1  ,写UCSRC 时  URSEL为1.

    估计 UCSRC  和 UBRRH 共享一个地址。这一点对编程没有影响。所以这一位不管。


    第六位:USART 模式选择

    默认是置0 :异步操作   一般同步用不到。至少我用过的同步操作就用过一次就是对PS2键盘驱动的时候用到了同步模式一般是用不到同步模式的。


    第五位和第四位组合起来组成 奇偶数校验模式

    these bits enable and set type of parity generation and check .这两位设置奇偶校验模式并使能奇偶校验。

    Disabled (禁止)  Reserved(保留) Enabled ,Even parity 偶校验  Enabled ,odd parity (奇校验)

    一般我们不用校验 所以不用设置这两位



    第3位:停止位选择

     默认停止位是1位   一般不用设置 默认停止位1位



    第2位和第1位:设置字符长度

    可以看到 8位是 0 1 

    而我们去看看UCSRC 寄存器上电复位的初始值为  UCSZ1   UCSZ0 都是1  而UCSZ2 是0  所以默认为8位

     



    0 1  1 8位数据所以我们一般对这2位 不做设置的。默认就8位了。

    第0位:最后一位是 :时钟极性

    这一项仅对同步的时候有用,this bit is used for synchronous mode only. 同步模式我们也用不到所以这一位我们也不用管。

    第五个寄存器波特率寄存器  UBRRL  和  UBRRH


    相当于一个12位的二进制数:低8位是UBRRL       高4位是(8:11)是UBRRH的低四位。

    解释:UCSRC寄存器与UBRRH 寄存器公用相同的I/O地址。对该寄存器的访问,请参见P162 访问 UBRRH/RCSRC寄存器。

    我们计算波特率的时候只要将计算出的值的低8位写入这个UBRRL就行了。高8位写入UBRRH  URSEL 这位我们不用管编译器自动处理好。


    下面的表格就粘贴了太累了!!

    下面就讲讲怎样使用这个USART、、、

    ---------------------------------------------------------------

    第一步:设置波特率

    #define F_CPU 16000000

    #define BAUD 9600

    UBRRH = (FOSC / BAUD0/16-1)/256

    UBRRL = (FPSC/BAUD0/16-1)%6

    第二步:使能发送、接受接受完成中断

    UCSRB |= (1<< RXEN)|(1<<TXEN)|(1<<RXCIE);

    第三步:使能全局中断

    sei();

    第四步:查询方式发送、中断方式接受

    发送: while(!(UCSRA & (1<< UDRE))); UDR =c;

    接受中断:c = UDR ;

     

    波特率怎么算的呢?在UART 下的时钟产生 下有波特率发生器下图

    正常我们使用非倍速的时候

    equations 方程  calculating 计算
    一个是波特率的计算公式一个是UBRR值的计算公式  这个UBRR 就是上面那个波特率寄存器(UBRRL  UBRRH拼接起来显示的数值)。 UBRR 的值就等于主频除以波特率 再减 1. 而我们就是采用宏定义的方法定义主频 和 波特率

    UBRR  = 主频 / 波特率/ 16 -1  由于是UBBRH 整除256 取出高8位     可以理解右移掉低 8位

    UBRR  = 主频 / 波特率/ 16 -1  由于是UBBRH 求余256 取出高8位     左移掉 高8位

    用宏定义的好处 修改波特率方便。

    实际演示下

    编译如下代码:



    然后下载进入,打开串口调试工具  选择对应的COM我的COM3 和COM4 而COM4是仿真器用了所以我选择COM3  波特率选择9600 校验位  我们选NO 第四栏 8位 我们选1位 。我们一般把16进制给勾上 ,16进制显示 16进制发送给勾上。(不然的话它自动查找ASCII码表显示对应的字符,将字符显示出来)然后点击清空从填 ,现在验证下

    反正我测试接受到的都是0 不知道为什么?

    其实9600的波特率每秒最多发送多少字符 是9600 /10 960个字符因此串行速度还是非常快的

    这就是串口发送的程序我们通常写成一个函数

    中断方式使用USART步骤

    第一步:设置波特率

    #define F_CPU 16000000

    #define BAUD 9600

    UBRRH = (F_CPU/BAUD/16-1)/256

    UBRRL = (F_CPU/BAUD/16-1)%6

    第二步:使能发送  、接受、接受完成中断

    UCSRRB |= (1<<RXEN)|(1<<TXEN)|(1<<RICIE);

    第三步:使能全局中断

    sei();

    第四步:查询方式发送、中断方式接受

    发送: while(!(UCSRA &(1<<UDRE)));

    UDR =c;

    接受中断:c = UDR;

     

    如果用中断接受必须在GCC单片机程序 找中断向量名称  接受中断完成如下图



    SIG_UART_RECV呵呵

     给带更改如下



    中断接受、就讲到这里!

     气死人了,这个教程我实验不成功、、、

     

    关闭窗口

    相关文章