基于c51单片机的串行通信模块.docx
- 文档编号:24393963
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:23
- 大小:192.64KB
基于c51单片机的串行通信模块.docx
《基于c51单片机的串行通信模块.docx》由会员分享,可在线阅读,更多相关《基于c51单片机的串行通信模块.docx(23页珍藏版)》请在冰豆网上搜索。
基于c51单片机的串行通信模块
工程5基于C51单片机的“串行通信〞模块
1.任务
任务一:
应用通用异步收发器〔UART〕实现串行通信;
任务二:
应用通用I/O口“模拟串口〞实现串行通信;
2.要求
〔1〕能够在串口调试工具窗口中正确显示轮式教育机器人的状态信息;
〔2〕能够实现轮式教育机器人与PC机的全双工串行通信;
5.1功能描述
本案例模块的主要内容是:
利用单片机的通用异步收发器〔UART〕或通用I/O口“模拟串口〞实现点对点的双机通信,使轮式教育机器人能够与PC机〔上位机〕进展异步通信,在PC机上显示轮式教育机器人的状态信息,通过该工程的学习与实践,可以让读者获得如下知识和技能:
•掌握单片机通用异步收发器〔UART〕的根本原理和应用方法;
•掌握超点对点的异步通信协议和通用I/O口“模拟串口〞编程应用技能;
5.2必备知识
5.2.1串口通信协议简介
通信协议是对数据传送方式的规定,包括数据格式定义和数据位定义等,通信双方必须遵守统一的通信协议,串行通信协议包括同步协议和异步协议两种,本章只介绍异步串行通信协议和异步串行协议规定的数据传送格式。
1〕起始位:
通信线上没有数据被传送时处于逻辑1状态,当发送设备要发送一个字符数据时,首先发出一个逻辑0信号,这个逻辑低电平就是起始位。
起始位通过通信线传向接收设备,接收设备检测到这个逻辑低电平后,就开场准备接收数据位信号。
起始位起的作用就设备同步,通信双方必须在传送数据位前协调同步。
2〕数据位
当接收设备收到起始位后,紧接着就会收到数据位。
数据位的位数可以是5、6、7或8位,.IBM-PC中经常采用7位或者8位数据传送,80C51串行口采用8位或9位数据传送。
这些数据位被承受到移位存放器中,构成传送数据字符。
在字符数据传送过程中,数据位从最低有效位开场发送,依次顺序在承受设备中被转换为并行数据。
3〕奇偶校验位
数据位发送完之后,可以发送奇偶校验位。
奇偶校验用于有限过失检测,通过双方须约定一致的奇偶校验方式。
如果选择偶校验,那么组成数据位和奇偶位的逻辑1的个数必须是偶数;如果选择是奇校验,那么逻辑1的个数必须是奇数。
4〕停顿位
在奇偶位或数据位〔当无奇偶校验时〕之后发送的是停顿位。
停顿位是一个字符数据的完毕标志,可以是1位、位或2位的高电平。
接收设备收到停顿位之后,通信线路上便恢复逻辑1状态,直至下一个字符数据的起始位到来。
5)波特率设置
通信线上传输的所有为信号都保持一致的信号持续时间,每一位的信号持续时间都由数据传送速度确定,而传送速度是以每秒多少个二进制位来衡量的,这个速度叫波特率。
如果数据以每秒9600个二进制在通信线上传送,那么传送速度为9600波特,通常记9600b/s,通信双方必须设置一样的波特率。
图5-1异步串行通信数据格式
5.2.2RS232电平与TTL电平转换
在单片机与PC机通信时,接口电路必须要进展电平转换,因为PC机采用的是RS232标准,而单片机采用的是TTL标准,这是其一。
第二是单片机与单片机之间的串行通信如果采用直接传输信息,其传输距离一般不超过1.5m,假设要实现更远距离的通信,那么接口电路也必须要进展电平转换。
RS232标准是1969年由美国电子工业协会〔EIA〕联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。
它的逻辑“1”电平是-5V--15V,逻辑“0”电平是+5V-+15V。
TTL〔Tansistor-TransistorLogic〕,是指三极管-三极管逻辑电路。
它规定:
逻辑“0”:
<0.4V;逻辑“1”:
+3V~+5V。
因此,RS-232不能和TTL电平直接相连,使用时必须进展电平转换,否那么将使TTL电路烧坏,为了让单片机与PC机能相互通信,必须让这两种电平相互转换。
6.3设计案例
5.3.1系统设计方案
电平转换可以由分立的三极管电路来完成也可以是采用专用转换芯片来完成。
本设计案例采用MAX232电平转换芯片构成电平转换电路,相对于分立元件构成的电平转换电路来说,它具有电路简单,稳定可靠等优点。
PC机与单片机串行通信框图如图5-2所示。
图5-2PC机与单片机串行通信框图
5.3.2硬件电路设计
C51单片机与PC机通信的接口电路设计如图x-3所示。
其中Max232是专用的电平转换芯片,与PC机接口一般采用三线制连接串口,也就是说和PC机的9针串口只用其中的3根线:
分别是第5脚的GND、第2脚的RXD、第3脚的TXD,Max232的第9脚和第10脚分别连接到单片机的RXD和TXD引脚。
图5-3RS232与TTL电平转换电路
5.3.3软件设计
任务一、应用UART实现单片机与PC机通信
本任务是编程单片机内部的通用异步收发器〔UART〕,使其发送和接收数据,实现与PC机〔上位机〕的异步通信。
1、源程序
/*=========================================================
程序名:
uart.c
功能:
串口初始化程序、轮式教育机器人向PC机〔上位机〕发送数据
〔注:
系统晶振频率为11.0592MHz,波特率设为9600bps〕
===========================================================*/
#include
#include
#defineOLEN8//串行发送缓冲区大小
unsignedcharostart;//发送缓冲区起始索引
unsignedcharoend;//发送缓冲区完毕索引
charidataoutbuf[OLEN];//发送缓冲区存储数组
#defineILEN8//串行接收缓冲区大小
unsignedcharistart;//接收缓冲区起始索引
unsignedchariend;//接收缓冲区完毕索引
charidatainbuf[ILEN];//接收缓冲区存储数组
bitbdatasendfull;//发送缓冲区满标志
bitbdatasendactive;//发送有效标志
voiduart_Init();
voidmain(void)
{
uart_Init();
printf("Helloworld!
\n");
while
(1);
}
/*串行中断效劳程序*/
staticvoid_isr(void)interrupt4using1
{
//-------------接收数据----------------
charc;
if(RI)//接收中断置位
{
c=SBUF;//读字符
RI=0;//清接收中断标志
if(istart+ILEN!
=iend)
inbuf[iend++&(ILEN-1)]=c;//缓冲区接收数据
}
//-------------发送数据----------------
if(TI)
{
TI=0;//清发送中断标志
if(ostart!
=oend)
{
SBUF=outbuf[ostart++&(OLEN-1)];//向发送缓冲区传送字符
sendfull=0;//设置缓冲区满标志位
}
else
sendactive=0;//设置发送无效
}
}
//PUTBUF:
写字符到SBUF或发送缓冲区
voidputbuf(charc)
{
if(!
sendfull)//如果缓冲区不满就发送
{
if(!
sendactive)
{
sendactive=1;//直接发送一个字符
SBUF=c;//写到SBUF启动缓冲区
}
else
{
ES=0;//暂时串行口关闭中断
outbuf[oend++&(OLEN-1)]=c;//向发送缓冲区传送字符
if(((oend^ostart)&(OLEN-1))==0)
sendfull=1;//设置缓冲区满标志
ES=1;//翻开串行口中断
}
}
}
//替换标准库函数putchar程序
//printf函数使用putchar输出一个字符
charputchar(charc)
{
if(c=='\n')//增加新的行
{
while(sendfull);//等待发送缓冲区空
putbuf(0x0D);//对新行在LF前发送CR
}
while(sendfull);
putbuf(c);
return(c);
}
//替换标准库函数_getkey程序
//getchar和gets函数使用_getkey
char_getkey(void)
{
charc;
while(iend==istart)//判断接收缓冲区起始索引是否等于接收缓冲区完毕索引
{;}
ES=0;
c=inbuf[istart++&(ILEN-1)];
ES=1;
return(c);
}
/*初始化串行口和UART波特率函数*/
void_initialize(void)
{
TMOD|=0x20;//设置定时器1工作在方式2,自动重载模式
SCON=0x50;//设置串行口工作方式1,即SM0=0,SM1=1,REN=1
TH1=0xfd;//波特率9600
TL1=0xfd;
TR1=1;//启动定时器
ES=1;//开串行口中断
}
voiduart_Init()
{
_initialize();
EA=1;//开总中断
}
2、程序运行
按图2-5所示的连接电平转换硬件电路,用串口线连接轮式机器人和PC机的串口,编译以上程序,将产生的可执行文件烧写到单片机程序存储器,开机运行,在PC机上翻开串口调试工具,可以看到在串口调试窗口显示“Helloworld!
〞
3、程序设计思路
串口初始化函数及主函数的程序流程图如下列图所示,它描述uart.c的根本设计思路。
图5-4串口初始化流程图图5-5主函数流程图
下面主要通过分析printf()函数及scanf()的执行过程,来加深对串口工作的理解:
C51库函数中包含有字符的I/O函数,他们通过单片机串口来工作,这些I/O函数都依赖于两个函数:
putchar()函数和_getkey()函数。
你可以在“C:
\ProgramFiles\Keil\C51\LIB〞目录下找到这两个函数的定义。
其中getkey()函数前面加了下划线“_〞,表示该函数并不是标准的C库函数。
uart.h头文件修改了这两个函数用来满足自己的需求。
例printf(“Hello,world\n〞);
printf()函数调用putchar()函数将第一个字符〔字符‘H’〕发送到存放器SBUF中;SBUF满,TI置位,进入中断处理函数发送该字符;之后,字符‘H’通过串口线到达PC机串口,串口调试窗口进展接收处理,并将字符‘H’在接收区内显示。
如此往复,直到printf()函数发送最后一个字符‘\n’——回车命令,将光标置位在下一行,发送工作才完毕。
整个发射流程如示意图7-4。
图5-6串口发射流程示意
例scanf("%d",&PulseDuration);
当你在串口调试窗口“发送区〞内写入整数1700并点击“发送〞按钮时,调试窗口会将字符‘6’〔整数1700在十六进制的表示下为6A4,转换过程由调试窗口程序完成〕通过串口线发送到单片机的串口。
scanf()函数通过调用getkey()函数从单片机串口处接收字符‘6’,接收缓冲存放器SBUF满,RI置位,进入中断处理函数,取出字符‘6’;如此循环,直到全部数据接收完。
最后,scanf()函数再将接收到的数据,即1700赋给变量PulseDuration。
串口接收流程如示意图7-5。
图5-7串口接收流程示意
任务二、用I/O口“模拟串口〞实现串行通信
在具体应用中,有时串行口的RXD和TXD被占用,此时也可以用通用I/O口来“模拟〞串口来完成通信,在本任务中,用轮式机器人〔上位机〕的P3_6来模拟串口中的TXD向下位机发送控制指令,下位机是直流电机控制模块,它能够根据上位机发来的控制指令控制直流电机的旋转方向和速度,关于直流电机控制模块控制原理此处不作介绍,我们这里只要知道根据上下位机的通信协议,如何编程实现控制命令的发送就可以了。
上下位机的通信双方约定如下:
1)采用9600bps,8位数据位、1位停顿位、无校验位;
2)控制命令字采用5字节,如下表所示:
头部(0XAA)
电机设定:
mand
速度:
Speed
时间:
Time
尾部(0XBB)
如发送指令“0xAA,0x38,0xff,0x1f,0xBB〞,可以控制左右两个直流电机全速反转。
1、源程序
/*=============================================================
Imitate.c
功能:
上位机程序,能利用通用I/O口作为串行通信口向下位机发送控制指令
==============================================================*/
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitbit_TXD=P3^6;
sbitbit_RXD=P3^7;
bitflag;
sbitACC0=ACC^0;
sbitACC1=ACC^1;
sbitACC2=ACC^2;
sbitACC3=ACC^3;
sbitACC4=ACC^4;
sbitACC5=ACC^5;
sbitACC6=ACC^6;
sbitACC7=ACC^7;
voiddelay_nµs(uinti)//延时:
i>=12,i的最小延时单12us
{
i=i/10;
while(--i);
}
voiddelay_nms(uintn)//延时nms
{
n=n+1;
while(--n)
delay_nµs(900);//延时1ms,同时进展补偿
}
voidInt_Timer0()interrupt1using1//定时器0中断函数
{
flag=1;
}
voidsend_one_byt(char_bit)
{
ACC=_bit;
flag=0;
bit_TXD=0;
TL0=TH0;
TR0=1;
while(!
flag);
bit_TXD=ACC0;
flag=0;
while(!
flag);
bit_TXD=ACC1;
flag=0;
while(!
flag);
bit_TXD=ACC2;
flag=0;
while(!
flag);
bit_TXD=ACC3;
flag=0;
while(!
flag);
bit_TXD=ACC4;
flag=0;
while(!
flag);
bit_TXD=ACC5;
flag=0;
while(!
flag);
bit_TXD=ACC6;
flag=0;
while(!
flag);
bit_TXD=ACC7;
flag=0;
while(!
flag);
bit_TXD=1;
flag=0;
while(!
flag);
TR0=0;
}
voidmain()
{
uchart;
ucharmand[]={0xAA,0x38,0xff,0x1f,0xBB};
TMOD|=0x22;
TR0=0;
TF0=0;
TL0=(255-96);
TH0=TL0;
ET0=1;
EA=1;
for(t=0;t<5;t++)
send_one_byt(mand[t]);
while
(1);
}
2、程序运行
连接轮式机器人控制板〔上位机〕单片机的P3_6引脚和直流电机控制模块〔下位机〕的RXD端,编译以上程序,将产生的可执行文件烧写到上位机单片机程序存储器〔下位机已经准备就绪〕,开机运行,可见连接直流电机控制模块的两个直流电机开场全速反转。
3、程序设计思路
下面简要分析以上程序中用通用I/O口模拟串口的根本思路,主函数及发送子函数的程序流程图如下:
图5-8主函数流程图图5-9发送子函数流程图
因为设计定波特率为9600bps,即每秒传送9600位(bit)数据,那么每传送1位数据所需的时间为1s/9600=104.167us,因此,要用P3_6 引脚模拟TXD,关键要保证每隔104.167us往P3_6引脚传送1位数据,程序中采用定时中断完成104.167us延时,定时器是对机器周期进展计数,而机器周期T=12/fosc=12/11.0592MHz,为延时104.167us,设定时器需计数X个机器周期,那么有:
T*X=104.167us→X=104.167*11.0592/12=96,所以,定时器初值应设为255-96。
5.4相关知识
通过上述案例学习和实践,在对单片机通用异步收发器〔UART〕的编程应用有了直观认识之后,我们下面再来介绍有关单片机UART更详细的内容。
6.4.1AT89C51单片机串行口构造
AT89C51单片机UART内部构造框图如下列图所示。
图5-10通用异步收发器内部框图
5.4.2与串行通信有关的特殊功能存放器
1.数据缓冲器SBUF
串行口缓冲器SBUF是可直接寻址的特殊功能存放器,其内部RAM字节地址是99H。
在物理上,它对应着两个独立的存放器,一个发送存放器,一个接收存放器。
发送时:
CPU执行一条写SBUF指令便启动了串行口发送,数据从TXD〔P3.1〕输出。
在指令执行期间,CPU送来“写SBUF〞信号,将并行数据送入SBUF,并启动发送控制器。
从TXD端逐位输出一帧信息。
一帧信息发送完毕后,发送控制器硬件置中断标志TI=1,向CPU申请中断,通知CPU可以发送下一个数据。
接收时:
就是读取SBUF的过程,外界数据通过RXD〔P3.0〕输入,输入数据先进入移位存放器,再送入接收SBUF。
在接收器中采用了双缓冲构造,以防止在接收到第二帧数据之前,CPU来不及响应前一帧中断请求,而造成两帧数据重叠的错误。
2.串行口控制存放器SCON
SCON可以位寻址。
复位时,SCON所有位均清“0”。
SM0、SM1:
由软件置位或清零,用于选择串行口四种工作方式。
表5-1串行口的工作方式
SM0
SM1
工作方式
功能
波特率
0
0
方式0
同步移位存放器
fosc/12
0
1
方式1
10位通用异步收发器
由定时器控制
1
0
方式2
11位通用异步收发器
fosc/32或fosc/64
1
1
方式3
11位通用异步收发器
由定时器控制
SM2:
多机通信控制位。
REN:
允许串行接收控制位。
假设REN=0,那么制止接收;REN=1,那么允许接收,该位由软件置位或复位。
TB8:
发送数据D8位。
在方式2和方式3时,TB8为所要发送的第9位数据。
在多机通信中,以TB8位的状态表示主机发送的是地址还是数据:
TB8=0为数据,TB8=1为地址;也可用作数据的奇偶校验位。
该位由软件置位或复位。
RB8:
接收数据D8位。
在方式2和方式3时,接收到的第9位数据,可作为奇偶校验位或地址帧或数据帧的标志。
方式1时,假设SM2=0,那么RB8是接收到的停顿位。
在方式0时,不使用RB8位。
TI:
发送中断标志位。
在方式0时,当发送数据第8位完毕后,或在其它方式发送停顿位后,由内部硬件使TI置位,向CPU请求中断。
CPU在响应中断后,必须用软件清零。
TI可供查询。
RI:
接收中断标志位。
在方式0时,当接收数据的第8位完毕后,或在其它方式接收到停顿位后,由内部硬件使RI置位,向CPU请求中断。
同样,在CPU响应中断后,也必须用软件清零。
RI也可供查询。
3.电源控制存放器PCON
与串行口有关的位是:
SMOD为波特率倍增位。
当SMOD=1时,波特率加倍
6.4.2串行口的工作方式
1、方式0
在方式0下,串行口作同步移位存放器用,以8位数据为一帧,先发送或接收最低位,波特率为fosc/12,即每个机器周期发送或接收一位,。
串行数据由RXD〔P3.0〕端输入或输出。
同步移位脉冲由TXD〔P3.1〕端送出。
这种方式常用于扩展I/O口。
发送时,当一个数据写入发送缓冲器SBUF〔99H〕,串行口即把8位数以fosc/12的波特率从RXD端送出,发送完置中断标志TI为“1”。
接收时,REN是允许接收控制位。
REN=0,制止接收;REN=1,允许接收。
当软件置REN为“1〞时,即开场从RXD端以fosc/12的波特率输入数据,当接收到8位数据时,置中断标志RI为“1〞。
CPU响应TI或RI中断请求时,不会去除TI或RI标志,必须由用户用软件清“0”。
方式0时,SM2位必须为0。
2、方式1
在方式1下,串行口为10位通用异步接口。
发送或接收一帧数据,包括1位起始位“0〞、8位数据位和1位停顿位“1〞,传送波特率可调。
发送时,数据从引脚TXD〔P3.1〕端输出,当数据写入发送缓冲器SBUF时,就启动发送器发送。
发送完一帧数据后,把TI标志置“1”,并申请中断,通知CPU可以发送下一个数据。
接收时,使REN置“1〞允许接收,串行口采样引脚RXD〔P3.0〕。
当采样到1至0的跳变时,确认是起始位“0〞,就开场接收一帧数据。
当停顿位到来之后把停顿位送入RB8位,中断标志RI置“1〞,申请中断,通知CPU从SBUF取走接收到的一个数据。
3、方式2
方式2下串行口为11位异步通信接口。
发送或接收一帧信息包括1位起始位“0”、8位数据位、1位可编程位和1位停顿位“1”。
其信息传送波特率与SMOD〔波特率倍增位〕有关。
方式2的波特率为fosc/32〔SMOD=1时〕或fosc/64〔SMOD=0时〕。
方式2发送、接收数据的过程与方式1根本一样,所不同的仅在于对第9位数据的处理上。
发送时,第9位数据由SCON中的TB8位提供。
接收数据时,当第9位数据移入移位存放器后,将8位数据装入SBUF,第9位数据装入SCON中的RB8。
发送前,先根据通信协议由软件设置TB8〔如作奇偶校验位或地址/数据标识位〕,然后将要发送的数据写入SBUF即能启动发送器。
发送过程是由执行“写SBUF〞指令把8位数据装入SBUF,同时把TB8装到发送移位存放器的第9
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 c51 单片机 串行 通信 模块