1模块6基于C51单片机的“串行通信”模块项目5基于C51单片机的“串行通信”模块1.任务任务一:应用通用异步收发器(UART)实现串行通信;任务二:应用通用I/O口“模拟串口”实现串行通信;2.要求(1)能够在串口调试工具窗口中正确显示轮式教育机器人的状态信息;(2)能够实现轮式教育机器人与PC机的全双工串行通信;2单片机应用技术5.1功能描述本案例模块的主要内容是:利用单片机的通用异步收发器(UART)或通用I/O口“模拟串口”实现点对点的双机通信,使轮式教育机器人能够与PC机(上位机)进行异步通信,在PC机上显示轮式教育机器人的状态信息,通过该项目的学习与实践,可以让读者获得如下知识和技能:掌握单片机通用异步收发器(UART)的基本原理和应用方法;掌握超点对点的异步通信协议和通用I/O口“模拟串口”编程应用技能;3模块6基于C51单片机的“串行通信”模块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,通信双方必须设置相同的波特率。4单片机应用技术图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所示。电平转换电路PC机串口单片机串口RXDRXDTXDTXDGNDGND图5-2PC机与单片机串行通信框图5模块6基于C51单片机的“串行通信”模块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)===========================================================*/#includeAT89X51.h6单片机应用技术#includestdio.h#defineOLEN8//串行发送缓冲区大小unsignedcharostart;//发送缓冲区起始索引unsignedcharoend;//发送缓冲区结束索引charidataoutbuf[OLEN];//发送缓冲区存储数组#defineILEN8//串行接收缓冲区大小unsignedcharistart;//接收缓冲区起始索引unsignedchariend;//接收缓冲区结束索引charidatainbuf[ILEN];//接收缓冲区存储数组bitbdatasendfull;//发送缓冲区满标志bitbdatasendactive;//发送有效标志voiduart_Init();voidmain(void){uart_Init();printf(Helloworld!\n);while(1);}/*串行中断服务程序*/staticvoidcom_isr(void)interrupt4using1{//-------------接收数据----------------charc;if(RI)//接收中断置位{c=SBUF;//读字符RI=0;//清接收中断标志if(istart+ILEN!=iend)7模块6基于C51单片机的“串行通信”模块inbuf[iend++&(ILEN-1)]=c;//缓冲区接收数据}//-------------发送数据----------------if(TI){TI=0;//清发送中断标志if(ostart!=oend){SBUF=outbuf[ostart++&(OLEN-1)];//向发送缓冲区传送字符sendfull=0;//设置缓冲区满标志位}elsesendactive=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;//打开串行口中断8单片机应用技术}}}//替换标准库函数putchar程序//printf函数使用putchar输出一个字符charputchar(charc){if(c=='\n')//增加新的行{while(sendfull);//等待发送缓冲区空putbuf(0x0D);//对新行在LF前发送CR}while(sendfull);putbuf(c);return(c);}//替换标准库函数_getkey程序//getchar和gets函数使用_getkeychar_getkey(void){charc;while(iend==istart)//判断接收缓冲区起始索引是否等于接收缓冲区结束索引{;}ES=0;c=inbuf[istart++&(ILEN-1)];ES=1;return(c);}/*初始化串行口和UART波特率函数*/voidcom_initialize(void){TMOD|=0x20;//设置定时器1工作在方式2,自动重载模式9模块6基于C51单片机的“串行通信”模块SCON=0x50;//设置串行口工作方式1,即SM0=0,SM1=1,REN=1TH1=0xfd;//波特率9600TL1=0xfd;TR1=1;//启动定时器ES=1;//开串行口中断}voiduart_Init(){com_initialize();EA=1;//开总中断}2、程序运行按图2-5所示的连接电平转换硬件电路,用串口线连接轮式机器人和PC机的串口,编译以上程序,将产生的可执行文件烧写到单片机程序存储器,开机运行,在PC机上打开串口调试工具,可以看到在串口调试窗口显示“Helloworld!”3、程序设计思路串口初始化函数及主函数的程序流程图如下图所示,它描述uart.c的基本设计思路。开始设置定时器工作方式设置串口工作方式设置波特率启动定时器1开中断开始串口初始化调用printf()函数写SBUF中断处理(串口发射)图5-4串口初始化流程图图5-5主函数流程图下面主要通过分析printf()函数及scanf()的执行过程,来加深对串口工作的理解:10单片机应用技术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。Printf()“Hello,world\n”SBUF中断处理,串口发送串口接收显示Putchar()TI=1单片机AT89C51PC机串口调试窗口图5-6串口发射流程示意例scanf(%d,&PulseDuration);当你在串口调试窗口“发送区”内写入整数1700并点击“发送”按钮时,调试窗口会将字符‘6’(整数1700在十六进制的表示下为6A4,转换过程由调试窗口程序完成)通过串口线发送到单片机的串口。scanf()函数通过调用getkey()函数从单片机串口处接收字符‘6’,接收缓冲寄存器SBUF满,RI置位,进入中断处理函数,取出字符‘6’;如此循环,直到全部数据接收完。最后,scanf()函数再将接收到的数据,即1700赋给变量PulseDuration。串口接收流程如示意图7-5。中断处理SBUF串口接收串口发射RI=1单片机AT89C51PC机串口调试窗口scanf()getkey()图5-7串口接收流程示