AVR单片机的串行通信模块全称为通用同步/异步收发器(Universal Synchronous Asynchronous Receiver Transmitter),简称USART或串行口。单片机通过串行通信接口,既可以与PC或其他设备组建起异步通信系统,也可以将其配置成与串行ADC、DAC、E2PROM等芯片间通信的半双工同步系统。本章重点介绍的就是AVR单片机的串行通信模块的原理和配置方法。
15.1
USART模块介绍
15.1.1
串行通信方式
串行通信的数据是逐位传送的。发送方发送的每一位数据都具有固定的时间间隔,接收方按照发送方同样的时间间隔来接收每一位,并且确定一个信息组的开始和结束,从而正确地解码发送方发送的数据。串行通信对传送的数据格式作了严格的规定,不同的串行通信方式具有不同的数据格式,常用的串行通信方式分为同步通信和异步通信两种。
1.同步通信
在同步通信方式下,要建立起发送方时钟对接收方时钟的直接控制,使收发双方达到同步状态,保证通信双方在发送和接收数据时具有完全一致的时间关系。同步通信时使用一根线传送数据,另外一根线传送时钟,其原理如图15-1所示。
2.异步通信
在异步通信方式下,发送方与接收方分别使用各自的时钟控制数据的发送和接收。为使双方收发协调,要求发送方和接收方的时钟尽可能一致,而且在每接收完一个数据后,接收方都要重新与发送方主同步一次,以确保对接收到的数据能正确地解码。异步通信的原理如图15-2所示。
15.1.2
USART模块的功能特点
ATmega32单片机的USART模块支持全双工同步及异步通信模式,模块配有高精度的波特率发生器,支持5~9个数据位和1~2个停止位的数据格式,并提供了硬件平台的奇偶校验等功能。ATmega32单片机USART模块的结构如图15-3所示。
从图中可以看出,ATmega32单片机的USART模块可以分成时钟发生器、发送器和接收器三个部分。三个控制和状态寄存器UCSRA、UCSRB和UCSRC管理和控制着这三个模块。时钟发生器用于产生串行通信的时钟。波特率寄存器UBRR用于保存波特率的值,波特率发生器根据UBRR寄存器中的值以及相关设置产生串行通信所需的波特率。
在同步通信模式下,XCK引脚为同步传输时钟端,如果是同步主机模式,XCK引脚用于输出时钟,而在同步从机模式下,XCK是时钟输入引脚,同步逻辑单元用于将波特率发生器同外部输入时钟进行同步。
发送器由一个写缓冲器UDR和一个发送移位寄存器构成。写缓冲器UDR用于暂时保存待发送的数据,并确保连续发送数据时不会在两个数据帧之间引入延迟。发送移位寄存器用于将写入UDR中的数据按位放置到数据线上,奇偶发生器根据待发送的数据,硬件自动产生校验代码,发送控制用于处理不同的帧格式所需的控制逻辑,发送移位寄存器中移出的数据由引脚控制电路将数据从TXD引脚送出。
接收器由接收移位寄存器和接收数据缓冲寄存器UDR构成,用于将RXD引脚接收到的串行数据正确解码并存入接收数据缓冲寄存器中。接收数据缓冲寄存器UDR是一个深度为二的先进先出队列(FIFO),可以连续存入两个接收到的数据。接收器配有时钟和数据恢复单元,在异步接收时,可以用于自动波特率校准和正确判断数据位。此外,接收器还包括奇偶校验、控制逻辑等部分,使接收器可以检测和处理因帧错误、数据过速和奇偶校验错误产生的数据传输问题。
15.1.3
串行通信的数据帧格式
USART模块的串行通信数据是由1个起始位、5~9个数据位、1个可选的奇偶校验位以及1或2个停止位构成的,其数据帧格式如图15-4所示。
串行通信的每个数据帧都是以低电平的起始位开始,之后是5~9位的数据位,且低位在前高位在后,如果使能了校验位,校验位将紧跟着数据位,最后是1~2个高电平的停止位。当一个完整的数据帧传输完毕后,可以立即开始传输下一个新的数据帧,或者使传输线处于高电平的空闲状态。
15.1.4
接收器FIFO队列
接收数据缓冲寄存器UDR、接收数据的第9位RXB8、帧错误标志位FE、数据溢出错误标志位DOR和奇偶校验错误标志位PE一同构成了USART模块的接收缓冲器,其结构如图15-5所示。
从图中我们不难看出,USART模块的接收数据缓冲寄存器是深度为两个单元的先进先出(FIFO)队列,当接收器完成数据接收并向UDR寄存器写入数据时,可以连续写入两个。当读取UDR寄存器时,先进入UDR寄存器中的数据会首先被读出,后进入的数据会在第二次读取时被读出。与UDR一样,RXB8位、FE位、DOR位以及PE位也都是两级深度的先进先出队列,与数据位一同保存在接收缓冲器中,反映着这一帧数据的整体状态。当UDR被读取后,这些位的状态也会随之改变,所反映的则是下一帧数据的情况。因此在读取UDR之前,要首先访问RXB8位和另外三个状态标志位,否则将丢失这些数据或状态位。
另外,在接收数据缓冲寄存器的两级先进先出队列(FIFO)基础上,接收移位寄存器中还可以作为第三级缓冲器,在两级数据缓冲寄存器装满时,数据可以暂时保存于串行移位寄存器中。接收器的这种数据缓冲结构可以大幅增强USART模块抵抗数据过速的能力。
15.2
USART模块的控制
15.2.1
波特率发生器
波特率是指每秒钟传输的数据位数(bps),它直接反映了数据通信位流的速度,波特率越高,数据传输速度越快。ATmega32单片机的USART模块有四种工作模式:异步正常模式、异步倍速模式、同步主机模式以及同步从机模式。其中前三种模式的时钟来自于片内波特率发生器,而在从机同步模式时其时钟则来自于片外。
USART模块的波特率发生器是由波特率寄存器UBRR和一个专用的降序计数器构成的,降序计数器会自动装载UBRR寄存器的值,并对系统时钟进行递减计数,当其计数到零时会产生一个时钟,该时钟即为波特率发生器的输出时钟,其时钟频率为fosc/(UBRR+1)。波特率发生器的输出时钟被直接用于接收器及数据恢复单元上,但作为串行通信的传输时钟,还要对波特率发生器所产生的时钟进行2、8或16的分频,具体分频情况取决于USART模块的工作模式。波特率的计算方法详见表15-1。
注:Fosc为系统时钟频率,BAUD为波特率,即每秒种位的传输速度(bps);UBRR是寄存器UBRRH与UBRRL的值(0~4095)。
当USART模块工作在异步倍速模式时,波特率分频器的分频值会从异步正常模式下的16降到8,这会使异步通信的传输速率加倍。USART模块在使用16MHz晶振时其波特率的设定值如表15-2所示。这里需要注意的是,波特率是有误差的,在一些精确的应用时,需要尽量使用误差较小的选项。
另外,当USART模块工作在同步模式时,XCK引脚的功能被使能,该引脚数据方向寄存器的设定决定了串行口同步通信时的工作模式。当XCK引脚设定为输出时,同步通信为主机模式,串行通信时钟由单片机内部产生。当XCK引脚设定为输入时,同步通信为从机模式,数据传输由外部时钟驱动。输入到XCK引脚的外部时钟由同步寄存器进行采样后用于数据的发送和接收。本书限于篇幅,只对USART模块的异步主机模式作重点介绍。
15.2.2
USART模块的控制寄存器
1.UDR寄存器
该寄存器是USART模块的I/O数据寄存器,用于保存接收或待发送的数据。
UDR寄存器:USART的I/O数据寄存器
USART模块的发送数据缓冲寄存器和接收数据缓冲寄存器共享相同的I/O地址,统称为I/O数据寄存器UDR。这看起来似乎是矛盾的,但其实不然。当数据写入UDR时,数据会写入到发送数据缓冲寄存器中,而当读取UDR时,保存于接收数据缓冲寄存器中的内容会被读出。
2.UCSRA寄存器
该寄存器是USART模块的控制和状态寄存器,包含了多个USART的控制和状态位。
UCSRA寄存器:USART的控制和状态寄存器A bit 7RXC:USART接收结束标志位。当接收缓冲器中有未读出的数据时,RXC位置1,否则该位清零。当接收器禁止时,接收缓冲器被刷新,RXC位硬件清零。RXC标志位置1时,如果该中断得到允许,单片机将产生接收结束中断并执行相应的中断服务程序。
bit 6TXC:USART发送结束标志位。当发送移位缓冲器中的数据被送出,而且发送缓冲器UDR同样为空时TXC位置1。如果该中断得到允许,单片机将产生发送结束中断并执行相应的中断服务程序。发送结束中断服务程序被执行后,TXC标志位自动清零,也可以通过对TXC位写1的方式将该位清零。
bit 5UDRE:发送缓冲器为空标志位。当UDRE位置1时,表示发送缓冲器为空,可以写入待发送的数据。如果此中断得到允许,单片机产生数据寄存器空中断并执行相应的中断服务程序。系统复位后UDRE位硬件置1,表明发送器已经就绪。
bit 4FE:帧错误标志位。如果接收缓冲器接收到的下一个字符有帧错误,即接收缓冲器中的下一个字符的第一个停止位为0,那么FE位置1。在接收缓冲器UDR被读取之前,该位会持续有效。当再次接收到的停止位为1时,FE标志位硬件清零。写入UCSRA寄存器时,这一位要写0。
bit 3DOR:数据溢出标志位。当接收缓冲器已满(包含了两个数据)时,接收移位寄存器又有新的数据,若此时USART又检测到一个新的起始位,表明又有一个新的数据等待接收,这时会发生数据溢出,DOR标志位置1。在接收缓冲器UDR被读取之前,该位会持续有效。写入UCSRA寄存器时,这一位要写0。
bit 2PE:奇偶校验错误标志位。当奇偶校验使能(UPM1=1),且接收缓冲器中所接收到的下一个字符有奇偶校验错误时UPE位置1。在接收缓冲器UDR被读取之前,该位会持续有效。写入UCSRA寄存器时,这一位要写0。
bit 1U2X:倍速发送使能位。在异步模式下,该位置1可将波特率分频因子从16降到8,异步通信模式传输速率加倍。使用同步数据传输模式时需将此位清零。
bit 0MPCM:多处理器通信模式使能位。该位置1时启动多处理器通信模式。此时USART模块接收到的所有不包含地址信息的帧都将被忽略。
3.UCSRB寄存器
该寄存器是USART模块的控制和状态寄存器,包含了多个USART的控制和状态位。
UCSRB寄存器:USART的控制和状态寄存器B bit 7RXCIE:接收结束中断使能位。该位置1时使能接收结束中断。
bit 6TXCIE:发送结束中断使能位。该位置1时使能发送结束中断。
bit 5UDRIE:发送缓冲器空中断使能位。该位置1时使能发送缓冲器空中断。
bit 4RXEN:接收使能位。该位置1时启动USART接收器功能,RXD引脚的通用I/O端口功能将被USART功能所取代。RXEN位清零时将关闭接收器,这会刷新接收缓冲器并使FE、DOR及PE标志位失效。
bit 3TXEN:发送使能位。该位置1时将启动USART发送器。TXD引脚的通用I/O端口功能被USART功能所取代。TXEN位清零后,只有等到所有的数据发送完成后发送器才能够真正禁止,TXD引脚恢复其通用I/O功能。
bit 2UCSZ2:字符长度设置位。UCSZ2位与UCSRC寄存器的UCSZ1:0位组合在一起,设置数据帧所包含的数据位数,具体设置详见表15-3。
bit 1RXB8:接收数据的第8位。在9位数据模式下,RXB8位保存的是接收数据的第9位。读取UDR之前首先要读取RXB8,否则RXB8中的数据会丢失。
bit 0TXB8:发送数据的第8位。在9位数据模式下,TXB8位保存的是待发送数据的第9位。写入UDR之前需要将待发送数据的第9位首先写入TXB8位中。
4.UCSRC寄存器
该寄存器同样是USART模块的控制和状态寄存器,包含了多个USART的控制和状态位。UCSRC寄存器与波特率寄存器UBRRH共用相同的I/O地址。在对该地址执行写操作时,USART寄存器选择位(URSEL)控制被写入的寄存器。若URSEL位为0,写入的是UBRRH寄存器,若URSEL位为1,则写入的是UCSRC寄存器。在大多数应用中,不需要对UBRRH和UCSRC寄存器进行读操作。
UCSRC寄存器:USART的控制和状态寄存器C bit 7URSEL:寄存器选择位。通过该位选择访问UCSRC寄存器或UBRRH寄存器,当URSEL位为0时,写入的是UBRRH寄存器;当URSEL位为1时,写入的是UCSRC寄存器。
bit 6UMSEL:USART模式选择位。该位清零时USART为异步模式,置1时为同步模式。
bit 5:4UPM1:UPM0:奇偶校验模式选择位。这两位用于设置奇偶校验的模式并使能奇偶校验。如果使能了奇偶校验,在发送数据时,发送器会自动产生并发送奇偶校验位。在接收数据时,对于每一个接收到的数据,接收器都会产生一个奇偶值,并与接收数据的校验位进行比较,如果不匹配,那么就将UCSRA寄存器的PE位置1。奇偶校验模式的设置详见表15-4。
bit 3USBS:停止位选择位。在发送数据时,该位清零时停止位为1位,置1时停止位为2位,接收数据时该位被忽略。
bit 2:1UCSZ1:UCSZ0:字符长度选择位。这两位与UCSRB寄存器的UCSZ2结合在一起可以设置数据帧包含的数据位数,具体设置详见表15-4。
bit 0UCPOL:时钟极性选择位。在同步模式时,该位用于设置输出数据的改变、输入数据采样以及同步时钟XCK之间的关系,具体详见表15-5。使用异步模式时需将这一位清零。
5.UBRRH寄存器和UBRRL寄存器
该寄存器是USART模块的波特率寄存器,用于保存波特率的设定值。
UBRRH寄存器:USART的波特率寄存器(高字节)
UBRRL寄存器:USART的波特率寄存器(低字节)
bit 15URSEL:寄存器选择位。通过该位选择访问UCSRC寄存器或UBRRH寄存器。当URSEL位为0时,写入的是UBRRH寄存器,而当URSEL位为1时,写入的是UCSRC寄存器。我们前面说过,UCSRC寄存器与UBRRH寄存器共用相同的I/O地址,当写入这两个寄存器时,URSEL位用于指定需要访问的寄存器。
bit 14-12保留位。
bit 11-0UBRR11-UBRR0:USART波特率寄存器。12位的寄存器用于保存USART模块的波特率信息。其中UBRRH寄存器包含了USART波特率的高4位,UBRRL寄存器包含了波特率的低8位。写入UBRRL将立即更新波特率分频器,从而改变当前波特率的值,此改变将破坏当前正在进行的数据传输。
15.3
USART模块的应用
15.3.1
USART模块的应用向导
1.USART的初始化
串行通信之前需要对USART模块的功能进行初始化,包括波特率的设定,帧结构的设定以及根据需要使能接收器或发送器等。如不使用中断,TXC标志位可以用来检验一个数据帧的发送是否已经完成,RXC标志位用来检验接收缓冲器中是否还有数据未被读出。在每次发送数据(写发送数据寄存器UDR)之前,都需要将TXC标志位清零。当写入UCSRC寄存器时,由于UBRRH与UCSRC共用相同的I/O地址,URSEL位必须置1。
2.USART模块的数据发送
1)将UCSRB寄存器的发送允许位TXEN置1,使能USART的数据发送功能,TXD引脚的通用I/O功能会被USART功能所取代成为发送器的串行输出引脚。将待发送的数据写入发送缓存器UDR中,即可启动数据的发送。
2)只有当UCSRA寄存器的UDRE标志位置1后才可以对发送缓冲器进行写操作。如果UDRE没有置位,那么写入UDR的数据会被USART发送器忽略。当数据写入发送缓冲器后,如果移位寄存器为空,发送器将把数据载入发送移位寄存器,数据串行地从TXD引脚输出。
3)当移位寄存器处于空闲状态(没有正在进行的数据传输),或前一帧数据的最后一个停止位传送结束时,它将加载新的数据。一旦移位寄存器加载了新的数据,就会按照设定的波特率完成数据的发送。
4)如果发送9位数据的数据帧(UCSZ=7),应先将数据的第9位写入寄存器UCSRB的TXB8位中,然后再将低8位数据写入发送数据寄存器UDR中。
5)USART模块的发送器有两个标志位:USART数据寄存器空标志位UDRE和数据传输结束标志位TXC,两个标志位都可以产生中断。数据寄存器空标志位UDRE表示发送缓冲器是否可以接收一个新的数据,该位在发送缓冲器空时被置1。当采用中断方式传输数据时,在数据寄存器空中断服务程序中,必须写一个新的数据到UDR中使UDRE位清零。
6)当整个数据帧移出发送移位寄存器后,发送缓冲器中又没有新的数据时,发送结束标志位TXC会置1。TXC位在传送结束中断服务程序执行时会自动清零,也可以对该位写1来清零该位。
7)奇偶校验位产生电路用于为串行数据帧生成相应的校验位。当校验使能位UPM1置1时,发送控制逻辑电路会在数据的最后一位与第一个停止位之间插入奇偶校验位。
3.USART模块的数据接收
1)将UCSRB寄存器的接收允许位RXEN置1,使能USART接收器。接收器使能后RXD引脚的普通I/O口功能被USART功能所取代,成为接收器的串行输入口。
2)当接收器检测到一个有效的起始位,便开始接收数据。起始位后的每一位数据都将以所设定的波特率或在XCK时钟驱动下进行接收,直到收到一帧数据的第一个停止位后,接收移位寄存器中的内容将被转移到接收缓冲器中,这时读取UDR就可以获得接收到的数据。
3)如果设定了9位数据接收模式(UCSZ=7),在从UDR寄存器中读取接收到的8位数据之前,必须先读取寄存器UCSRB的RXB8位以获得第9位数据,如需要还要读取FE、DOR以及UPE状态标志位。对UDR存储单元的读操作会改变接收缓冲器先进先出队列的状态,进而改变同样存储在队列中的TXB8、FE、DOR以及UPE位。这里需要注意的是,所有的错误标志位都不能产生中断。
4)使用中断方式进行数据接收时,数据接收结束中断服务程序必须从UDR中读取数据以清零标志位RXC,否则只要中断处理程序一结束,一个新的中断就会产生。
15.3.2
USART模块自收自发实验
USART模块是AVR单片机非常重要的通信接口,接下来我们要使用查询法来实现串行通信。实验的原理是将一个数据写入发送缓冲器以启动串行发送,之后将发送的数据由RXD引脚读回并显示在数码管上。完成这个实验需要使用一根杜邦线短接ATmega32单片机的TXD和RXD引脚,之后打开Atmel Studio 6.1软件,新建名为“USART1”的项目,保存在chapter15文件夹下,软件会自动将名为USART1.c的源文件添加到新建的项目中。编辑USART1.c源文件,具体代码详见代码清单15-1。
代码清单15-1
USART模块自收自发程序
/*
*
USART1.c *
串口自收发短接RXD 与TXD 引脚
*
Created: 2013/10/24
15:47:05
*
Author: GAO */
#include
//
包含AVR 头文件
#include
//
包含AVR 中断控制头文件
#define F_CPU 16000000UL //
定义系统时钟
#include
//
包含延时函数头文件
unsigned char table0[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f }; //
共阴无点
unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6, 0xed,0xfd,0x87,0xff,0xef }; //
共阴有点
void display(unsigned int NUM); //
数码管显示函数声明
void USART_init(void); //
串口初始化函数声明
unsigned char receive_onechar(void); //
串口接收函数声明
void transmit_onechar(unsigned char data); //
串口发送函数声明
unsigned int NUM,RCNUM; //
定义全局变量
int main(void)
{
DDRA=0xFF; //
设数码管段驱动端为输出
DDRB=0xFF; //
设数码管位驱动端为输出
USART_init(); //
串口初始化
while(1)
{
NUM++; //
让变量NUM 自加1
transmit_onechar(NUM); //
串口发送NUM _delay_ms(5); //
延时5ms RCNUM=receive_onechar(); //
串口接收数据
display(RCNUM); //
显示接收到的数据
}
}
/**********
数码管显示函数**********/
void display(unsigned int NUM)
{
unsigned char NUM4,NUM3,NUM2,NUM1; NUM1=NUM%10; NUM2=NUM%100/10; NUM3=NUM%1000/100; NUM4=NUM/1000; PORTA=table0[NUM1]; PORTB=0x10; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB=0x00; _delay_ms(1); //
延时1ms PORTA=table0[NUM2]; PORTB=0x20; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB=0x00; _delay_ms(1); //
延时1ms PORTA=table0[NUM3]; PORTB=0x40; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB=0x00; _delay_ms(1); //
延时1ms PORTA=table0[NUM4]; PORTB=0x80; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB=0x00; _delay_ms(1); //
延时1ms }
/**********
串口初始化函数**********/
void USART_init(void)
{
UBRRH=0; UBRRL=103; //
波特率9600
,标准速度模式
UCSRA=0x00; //
标准速度USART UCSRB=0x18; //8
位数据,接收使能,发送使能,禁止中断
UCSRC=0x86; //
异步串口,无校验位,1
停止位,8
数据位
}
/**********
串口接收函数**********/
unsigned char receive_onechar(void)
{
unsigned char TEMP; TEMP=0; if((UCSRA&0x80)==0x80)
//
当RXC 位置1
时表示接收完成
{
TEMP=UDR; //
读取UDR }
return TEMP; //
将读到的值返回
}
/**********
串口发送函数**********/
void transmit_onechar(unsigned char data)
{
UDR=data; //
数据写入UDR while((UCSRA&0x20)==0); //
等待UDR 为空
}
/**********
结束**********/
成功编译以上代码后,将其下载到AVR系统板中,程序运行后效果如图15-6所示。数码管显示数值从0至255不断地循环累加,这表明串行口所发送和接收到的数据也在不断变化。
15.3.3
USART模块与PC的通信
单片机与PC间的通信应用十分广泛,通过串行接口,可以实现PC对单片机的控制,也可以将单片机的数据传送给PC做数据的分析和处理。单片机的串口通信使用的是TTL电平方式,即用+5V表示逻辑“1”,用0V表示逻辑“0”,而PC的串行口通信则使用RS-232电平方式,用-5V至-15V表示逻辑“1”,用+5至+15V表示逻辑“0”。由于二者的逻辑电平不同,不能直接相连,必须在TTL与RS-232通信方式之间进行电平转换。常用作电平转换的集成电路是MAX232,其典型应用电路如图15-7所示。
近年来,PC上的串行接口(COM口)已经不再是标准的配置,在没有串口的PC上,可以使用USB转串口模块,在PC上使用USB接口模拟串口与单片机进行通信。USB转串口模块如图15-8所示。
使用USB转串口模块需要安装相应的驱动程序,驱动程序的种类与模块的转换芯片有关。本书中使用的USB转串口模块转换芯片为PL2303,所以需要安装PL2303芯片的驱动程序。驱动程序安装好以后,可以按图15-9所示的方式连接单片机与PC。
在图15-9所示的连接方式中,单片机与USB转串口模块的连接方式是通过TTL电平方式将单片机的TXD引脚与模块的RXD引脚相连,RXD引脚与模块的TXD引脚相连,并将二者的GND端连接在一起。USB转串口模块与PC的连接使用USB方式,将模块插入PC的USB接口即可。硬件连接好后,在PC的设备管理器中,可以查看USB模拟串口的端口号,如图15-10所示。
本章上一个串口实验使用的是查询法,这次我们要使用中断法编写程序。实验的目的是从PC发送一个十六进制的数给单片机,单片机收到这个数后,蜂鸣器响一声,并在数码管上以十进制的形式显示接收到的数字。打开Atmel Studio 6.1软件,新建名为“USART2”的项目,同样保存在chapter15文件夹下,软件会自动将名为USART2.c的源文件添加到新建的项目中。编辑USART2.c源文件,具体代码详见代码清单15-2。
代码清单15-2
PC与AVR系统板的通信
/*
*
USART2.c *
串口与PC 通信
*
Created: 2013/10/24
15:47:05
*
Author: GAO */
#include
//
包含AVR 头文件
#include
//
包含AVR 中断控制头文件
#define F_CPU 16000000UL //
定义系统时钟
#include
//
包含延时函数头文件
#define BEEP_SET (PORTB|=0x01)
//
置位PB0
(蜂鸣器)
#define BEEP_CLR (PORTB&=0xFE)
//
清零PB0
unsigned char table0[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f }; //
共阴无点
unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6, 0xed,0xfd,0x87,0xff,0xef }; //
共阴有点
void display(unsigned int NUM); //
数码管显示函数声明
void USART_init(void); //
串口初始化函数声明
void transmit_onechar(unsigned char data);//
串口发送函数声明
void USART_INT_init(void); //
串口接收中断初始化函数声明
unsigned char BEERUN,RCNUM; //
定义蜂鸣时间、串口接收数据变量
int main(void)
{
DDRA=0xFF; //
设数码管段驱动端为输出
DDRB=0xFF; //
设数码管位驱动端、蜂鸣器驱动端(PB0
)为输出
USART_init(); //
串口初始化
USART_INT_init(); //
串口接收中断初始化
while(1)
{
display(RCNUM); //
显示接收到的数据
if((PORTB&0x01)==1)
//
控制蜂鸣音时间
{
BEERUN++; if(BEERUN==10)
{
BEERUN=0; BEEP_CLR; }
}
}
}
/**********
数码管显示函数**********/
void display(unsigned int NUM)
{
unsigned char NUM4,NUM3,NUM2,NUM1; NUM1=NUM%10; NUM2=NUM%100/10; NUM3=NUM%1000/100; NUM4=NUM/1000; PORTA=table0[NUM1]; PORTB|=0x10; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB&=0xEF; _delay_ms(1); //
延时1ms PORTA=table0[NUM2]; PORTB|=0x20; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB&=0xDF; _delay_ms(1); //
延时1ms PORTA=table0[NUM3]; PORTB|=0x40; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB&=0xBF; _delay_ms(1); //
延时1ms PORTA=table0[NUM4]; PORTB|=0x80; _delay_ms(2); //
延时2ms PORTA=0x00; PORTB&=0x7F; _delay_ms(1); //
延时1ms }
/**********
串口初始化函数**********/
void USART_init(void)
{
UBRRH=0; UBRRL=103; //
波特率9600
,标准速度模式
UCSRA=0x00; //
标准速度USART UCSRB=0x18; //8
位数据,接收使能,发送使能,禁止中断
UCSRC=0x86; //
异步串口,无校验位,1
停止位,8
位数据
}
/**********
串口发送函数**********/
void transmit_onechar(unsigned char data)
{
UDR=data; //
数据写入UDR while((UCSRA&0x20)==0); //
等待UDR 为空
}
/**********
串口中断初始化函数**********/
void USART_INT_init(void)
{
SREG|=0x80; //
开全局中断
UCSRB|=0x80; //
开接收完成中断
}
/**********
串口接收中断服务函数**********/
ISR(USART_RXC_vect)
{
RCNUM=UDR; //
读取UDR BEEP_SET; //
启动蜂鸣器
}
/**********
结束**********/
程序正确编译后,将其下载到AVR系统板中,手动复位AVR系统板。在PC上启动串口调试助手,将波特率调整为9600bps、校验位无、数据位8位、停止位1位并打开串口,勾选“十六进制发送”选项。在发送窗口中输入要发送的数字,这里需要注意的是此处输入的数是十六进制的,例如输入“FE”,在数码管上显示的数值应该为“254”。单片机接收到来自PC发送的信息后,会发出嘀嘀声,并将数值显示在数码管上。串口调试助手的设定如图15-11所示,AVR系统板的状态如图15-12所示。