马伟力AVR笔异步串行通信USART实验Word文档下载推荐.docx
《马伟力AVR笔异步串行通信USART实验Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《马伟力AVR笔异步串行通信USART实验Word文档下载推荐.docx(28页珍藏版)》请在冰豆网上搜索。
本实例首先介绍单片机的串口,然后介绍单片机的串口转换电路。
最后介绍如何配置ATmega16单片机的串口寄存器从而实现一个串口发送一个字节的简单程序。
1、单片机的串口介绍
(1)什么是单片机的串口
单片机的串行接口是一个可编程的全双工串行通信接口。
可以用作异步通信方式(UART)与采用串行接口的外围设备相连接。
ATmga16单片机通过串行数据发送引脚TXD(PD1)和串行数据接收引脚RXD(PD0)与外界通信。
UDR是串行口数据寄存器。
UDR寄存器实际上是由两个物理上分离的寄存器RXB和TXB构成,他们使用相同的I/O地址。
写UDR的操作,是将发送的数据写入到寄存器TXB中;
读UDR的操作,读取的是接收寄存器RXB中的内容。
所以虽然他们使用相同的地址,但是并不会出现冲突,因为他们两个有一个只能读出数据,而另一个只能写入数据。
(2)如何使用单片机的串口
在前面的实例中,我们已经了解和掌握了单片机定时器和中断的使用方法。
和它们的使用方法一样,单片机的串口也是通过对串行口的控制与状态寄存器的操作完成串行通信的设置。
在稍后我们会对这些寄存器的作用和如何设置进行详细的说明。
2、单片机的串口电平转换电路
(1)为什么需要电平转换电路
我们知道,单片机系统一般使用的是TTL电平,单片机中的串口输出信号当然也是如此。
但是在串行通信中,一般使用的是RS-232通信协议,二者的电平并不相同,所以需要外接电平转换电路。
串行通信接口标准以RS-232C为主,RS-232C通信协议标准对电气特性、逻辑电平和各种信号线功能都做了规定。
其中对逻辑电平的规定是:
高电平(逻辑1)为-3V---15V,低电平(逻辑0)为+3V--+15V,对于RS232信号来讲,当传输电平的绝对值大于3V时,电路可以有效的检查出来,介于-3V--+3V之间以及低于-15V或高于+15V的电平都被认为是无意义的。
所以,RS-232C是用正负电压来表示逻辑电平状态,而TTL则是以高低电平表示逻辑状态。
这两者有着很大的不同。
为了能够同计算机接口或终端的TTL器件连接,必须在RS-232C与TTL电路之间进行电平和逻辑关系的变换。
(2)电平转换电路需要设计吗
作为单片机的标准外围电路,串口的电平转换有专用的芯片,所以我们可以不必花费力气去设计电平转换电路。
当然,如果我们对电路十分熟悉,那么也可以使用四个的、三极管就可以设计出一个电平匹配电路。
在本实例中,我们主要介绍采用专用芯片进行电平转换的方法。
目前较为广泛的是使用集成电路转换器件,有很多器件厂商都生产这类芯片。
其中MAXIM公司更是有多款RS232C电平转换芯片。
选择RS232C电平转换芯片时候应当根据需要选择,例如:
如果我们只需要通过单片机向RS232器件发送数据,那我们可以选择只有TTL电平到RS232电平转换的芯片就可以了。
在本实例中,我们需要向计算机(PC)发送数据,同时还要接受计算机(PC)发送过来的数据,所以我们需要选择可以实现TTL电平和RS232电平之间的双向电平转换的芯片。
这里我们选择MAX3232芯片。
同时以MAX3232芯片为例,介绍串口电平转换芯片的输入/输出工作原理。
MAX3232芯片的引脚排列我们可以在学习板的原理图上查找到。
其引脚主要分为5个部分:
●外接电容:
共需5个外接电容(均为无极性的104电容),功能是进行电压匹配和电源去耦。
●TTL的输入:
两路TTL电平的输入引脚9,12。
●TTL的输出:
两路TTL电平的输出引脚10,11。
●RS-232的输入:
两路RS-232电平的输入引脚8,13。
●RS-232的输出:
两路RS-232电平的输出引脚7,14。
在MAX3232芯片内部,自动实现了TTL电平和RS232电平的双向转换,自动的调节了单片机的TTL电平和计算机的RS232电平之间的匹配问题。
当然,我们还可以选择其他的串口电平转换芯片。
(3)电平转换芯片与单片机和计算机之间的连接
在学习板的原理图中,我们已经看到了,单片机的串口发送(TXD)和接收(RXD)引脚分别与串口转换芯片的11、12管脚相连。
计算机串口的2、3脚分别与串口转换芯片的13、14管脚相连。
(4)单片机与单片机之间进行串行通信时需要电平转换芯片吗?
我们已经从前面了解到,正是由于单片机和RS232的电平信号不同,才需要电平转换芯片,对于两个单片机而言,由于两者都是TTL电平,所以也就不必使用电平转换电路。
两个单片机的串口引脚可以直接用导线相连,不过需要注意的是,二者的TXD和RXD需要相互反接才能正常工作,也就是其中一个单片机的RXD要接到另一个单片机的TXD,而它的TXD要接到另一个单片机的RXD,这样才能使其中一个单片机发送数据,而另一个单片机从接收端接收发送过来的数据。
另外还需要设置两个单片机的波特率和通信格式等的一致。
3、ATmega16单片机的串口寄存器介绍
ATmega16单片机的串口寄存器主要有六个寄存器,分别是:
●USART数据寄存器UDR:
发送和接收的数据寄存器。
●USART波特率寄存器UBRRL、UBRRH:
分别存储波特率的低位和高位。
●USART控制和状态寄存器UCSRA:
主要设置接受和发送的数据校验情况。
●USART控制和状态寄存器UCSRB:
主要设置串口接收和发送的中断使能等。
●USART控制和状态寄存器UCSRC:
主要设置接受和发送的数据格式。
4、ATmega16单片机的串口寄存器设置
寄存器在不同模式下的设置各不相同,混在一起介绍不容易记住。
在这里只介绍本实例中用到的寄存器设置。
(1)
USART发送数据缓冲寄存器和USART接收数据缓冲寄存器共享相同的I/O地址,称为
USART数据寄存器或UDR。
将数据写入UDR时实际操作的是发送数据缓冲器存器(TXB),读UDR时实际返回的是接收数据缓冲寄存器(RXB)的内容。
在5、6、7位字长模式下,未使用的高位被发送器忽略,而接收器则将它们设置为0。
只有当UCSRA寄存器的UDRE标志置位后才可以对发送缓冲器进行写操作。
如果UDRE没有置位,那么写入UDR的数据会被USART发送器忽略。
当数据写入发送缓冲器后若移位寄存器为空,发送器将把数据加载到发送移位寄存器。
然后数据串行地从TxD引脚输出。
接收缓冲器包括一个两级FIFO,一旦接收缓冲器被寻址FIFO就会改变它的状态。
因此不要对这一存储单元使用读-修改-写指令(SBI和CBI)。
使用位查询指令(SBIC和SBIS)时也要小心,因为这也有可能改变FIFO的状态。
具体在编写程序的时候,我们可以不必理会过多,只要知道接收串口数据的时候,把UDR中的数据送到我们定义的接收变量中,发送数据的时候,把要发送的数据送入UDR中就可以了。
(2)
该寄存器主要是发送、接收结束的结束标志,以及各种数据错误检查方式。
在一般的串口通信中,我们可以不必关心。
一般我们只关心第五位的设置。
●Bit5–UDRE:
USART数据寄存器空
UDRE标志指出发送缓冲器(UDR)是否准备好接收新数据。
UDRE为1说明缓冲器为空,已准备。
在非中断方式发送数据的时候,每发送一个字节都要检测缓冲期是否为空,即检测UDRE是否为1,只有在UDRE为1的情况下,才能向缓冲器UDR中写入数据。
在本例中我们就用查询的方式发送数据,所以要检测这一位是否为1.
(3)
该寄存器主要设置接受和发送寄存器的使能以及接收和发送中断标志,在本例中我们只是采用查询方式发送一个字节,所以只要使能发送功能即可。
另外还有字符长度设置位,我们在下一个寄存器的介绍中一并介绍。
●Bit3–TXEN:
发送使能
置位后将启动将启动USART发送器。
TxD引脚的通用端口功能被USART功能所取代。
TXEN清零后,只有等到所有的数据发送完成后发送器才能够真正禁止,即发送移位寄存器与发送缓冲寄存器中没有要传送的数据。
发送器禁止后,TxD引脚恢复其通用I/O功能。
●Bit2–UCSZ2:
字符长度
UCSZ2与UCSRC寄存器的UCSZ1:
0结合在一起可以设置数据帧所包含的数据位数(字符长度)。
(4)
UCSRC寄存器与UBRRH寄存器共用相同的I/O地址。
对该寄存器的访问,由BIT位选择。
•Bit7–URSEL:
寄存器选择
通过该位选择访问UCSRC寄存器或UBRRH寄存器。
当读UCSRC时,该位为1;
当写UCSRC时,URSEL为1。
•Bit6–UMSEL:
USART模式选择
通过这一位来选择同步或异步工作模式。
•Bit5:
4–UPM1:
0:
奇偶校验模式
这两位设置奇偶校验的模式并使能奇偶校验。
如果使能了奇偶校验,那么在发送数据,发送器都会自动产生并发送奇偶校验位。
对每一个接收到的数据,接收器都会产生一奇偶值,并与UPM0所设置的值进行比较。
如果不匹配,那么就将UCSRA中的PE置位。
•Bit3–USBS:
停止位选择
通过这一位可以设置停止位的位数。
接收器忽略这一位的设置。
•Bit2:
1–UCSZ1:
UCSZ1:
0与UCSRB寄存器的UCSZ2结合在一起可以设置数据帧包含的数据位数(字符长度)。
•Bit0–UCPOL:
时钟极性
这一位仅用于同步工作模式。
使用异步模式时,将这一位清零。
UCPOL设置了输出数据的改变和输入数据采样,以及同步时钟XCK之间的关系。
本例中,我们使用异步通信模式,数据格式为:
一位停止位,无校验,8位数据位。
需要注意的是:
在写这个寄存器的时候,需要将bit7位置1.
(5)
●Bit15–URSEL:
当读UBRRH时,该位为0;
当写UBRRH时,URSEL为0。
●Bit14:
12–保留位
这些位是为以后的使用而保留的。
为了与以后的器件兼容,写UBRRH时将这些位清零。
●Bit11:
0–UBRR11:
USART波特率寄存器
这个12位的寄存器包含了USART的波特率信息。
其中UBRRH包含了USART波特率高4位,UBRRL包含了低8位。
波特率的改变将造成正在进行的数据传输受到破坏。
写UBRRL将立即更新波特率分频器。
本例中采用的波特率为9600.
5.1.3、电路
本实例的电路包含RS323的串口电平转换芯片MAX3232,电路图如下图所示。
1、电路原理
在本实例中利用MAX3232芯片使单片机输出的TTL电平转换为标准的RS232电平,从而使计算机能够识别。
同时将计算机输出的RS232电平转换为单片机可以识别的TTL电平。
2、电路连接
电路中MAX3232芯片的9、10引脚分别连接单片机的PD0、PD1端口,MAX3232的13、14引脚分别连接计算机串口线的3、2脚。
3、特别说明
本学习板采用的是串口插座是公头的,所以与计算机相连的串口连接线应该是交叉串口线,而不是串口延长线。
5.1.4、程序设计
1、程序功能
程序的功能是使用单片机的串行接口PD0、PD1设计串口通信程序,通过单片机向计算机发送一个字节的数据。
程序调试的时候需要在计算机上安装串口助手,以观察接收的串口数据。
2、单片机与计算机串行通信结果的观察
在本例中,只是简单的发送一个字节到计算机,由于单片机运行速度比较快,所以当程序烧写到单片机后再打开串口助手观察接收到的数据的时候,可能会看不到接收的数据,我们可以提前打开串口助手以便观察。
也可以按一下学习板上的复位按键,这时候程序会重新运行,这样就可以在串口助手上观察到接收的数据了
3、数据通信格式的设定
要实现单片机和计算机的串行通信,首先要使双方的通信波特率和数据格式一致,这样才能观察到正确的结果。
在本例中,单片机发送串口数据采用的波特率是9600bps,数据格式是8位数据位,1位停止位,无奇偶校验。
在计算机上的串口助手里面,我们也要将波特率和数据格式设置成一样的。
4、关于串行数据发送函数的编写
由于我们在这个实例中只是实现了从单片机发送一个字节的数据到计算机,所以编写起来相对比较简单。
首先我们要设置好串口寄存器的内容,然后查询数据缓冲器是否为空,如果数据缓冲器为空,则表示可以发送数据,这时候我们就可以将要发送的那个字节写入数据发送寄存器中。
5、程序的简单模块化
从这个程序开始,我们试着将程序模块化。
程序模块化有两个好处:
●程序结构清晰,容易读懂。
●程序便于移植
程序的模块化是一个系统的工程,在本实例中,我们先简单的把程序的不同功能封装成不同的函数,然后再主程序里面调用这些函数;
这样编写出来的程序,主程序比较简洁,并且易读。
而每一个函数都具有各自不同的功能,以后我们用到这些功能的时候,就可以直接调用这些函数了。
本实例用到了3个函数,分别是:
端口初始化函数,串口初始化函数,字节发送函数。
6、使用WINAVR开发环境,从这个例子开始,我们要使用外部晶振了,所以makefile文件中的时钟频率要修改一下,我们使用的是外部12M的晶振,所以需要将MAKEFILE文件中的时钟频率修改为12M。
另外在程序烧录到单片机的时候,熔丝位也要选择为外部12M晶振(注意是晶振,不是外部振荡器,一定不要选择错了,否则会导致单片机不能再烧写程序。
我今天就犯了这样的错误,最后只好用外部振荡器恢复了一下才把单片机弄正常了)。
7、程序代码
#include<
avr/io.h>
util/delay.h>
avr/interrupt.h>
//中断函数头文件
//常量声明
#defineBAUD9600//波特率定义
//全局变量声明
unsignedcharTransmit;
//函数声明
voidPort_Init(void);
//端口初始化配置
voidUsart_Init(void);
//USART寄存器设置
voidUsart_PutChar(unsignedcharcTXData);
//字节发送函数
intmain(void)
{
Port_Init();
Usart_Init();
Transmit=0X31;
Usart_PutChar(Transmit);
sei();
//使能全局中断
while
(1)
{
}
}
//端口状态初始化设置函数
voidPort_Init()
PORTD=0X00;
//USART的发送接收端口分别为PD0和PD1
DDRD|=(1<
<
PD1);
//PD0为接收端口,置为输入口;
PD1为发送端口,置为输出口
//USART寄存器配置函数
voidUsart_Init()
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<
TXEN);
//发送使能
//字节发送函数
voidUsart_PutChar(unsignedcharcTXData)
while(!
(UCSRA&
(1<
UDRE)));
//只有数据寄存器为空时才能发送数据
UDR=cTXData;
5.2USART的接收发送实验
5.2.1、实例功能
在上一个实例中,我们已经用单片机的串口实现了向计算机发送一个字节的例子。
在本实例中,我们将编写程序实现将计算机发送过来的串口数据原样再发送回计算机。
使用单片机的串口实现将接收到的数据原样发送回去的功能。
进一步熟悉单片机的串行通信
5.2.2、器件和原理
关于串行接口的原理已接单片机与计算机的串口的连接在上一实例中进行了描述,在本实例中不再重复。
本实例只介绍单片机在同时收发数据模式下寄存器的配置。
1、ATmega16单片机的串口收发模式时的寄存器设置
在编写程序的时候,我们可以不必理会过多,只要知道接收串口数据的时候,把UDR中的数据送到我们定义的接收变量中,发送数据的时候,把要发送的数据送入UDR中就可以了。
●Bit7–RXCIE:
接收结束中断使能
置位后使能RXC中断。
当RXCIE为1,全局中断标志位SREG置位,UCSRA寄存器
的RXC亦为1时可以产生USART接收结束中断。
●Bit4–RXEN:
接收使能
置位后将启动USART接收器。
RxD引脚的通用端口功能被USART功能所取代。
禁止
接收器将刷新接收缓冲器,并使FE、DOR及PE标志无效。
TXEN清零后,只有等到所有的数据发送完成后发送器才能够真正禁止,即发送移位寄存
器与发送缓冲寄存器中没有要传送的数据。
0结合在一起可以设置数据帧所包含的数据位数(字符
长度)。
该寄存器主要设置接受和发送寄存器的使能以及接收和发送中断标志,在本例中我们只是既用到了串口数据的发送功能,也用到了数据的接收功能,所以要将TXEN和RXEN这两位使能,同时我们还用到了数据接收中断,所以还要设置接收中断允许。
如果对UCSRC执行写操作,则URSEL应设置为1。
当
写UCSRC时,URSEL为1。
如果使能了奇偶校验,那么在发送数据,发
送器都会自动产生并发送奇偶校验位。
对每一个接收到的数据,接收器都会产生一奇偶
值,并与UPM0所设置的值进行比较。
0与UCSRB寄存器的UCSZ2结合在一起可以设置数据帧包含的数据位数(字符长
度)。
UCPOL设置了输出数据
的改变和输入数据采样,以及同步时钟XCK之间的关系。
•Bit15–URSEL:
•Bit14:
•Bit11:
5.2.3、电路
本实例的电路与上一实例完全相同,这里不再重复。
1、电