《Uart串口收发程序ppt课件.ppt》由会员分享,可在线阅读,更多相关《Uart串口收发程序ppt课件.ppt(50页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、单片机C语言应用程序设计 3.1 MCS-51机间通信的机间通信的C语言编程语言编程3.2 键盘和数码显示人机交互的键盘和数码显示人机交互的C语言编程语言编程三 C51应用编程设计单片机C语言应用程序设计 3.1 MCS-51机间通信的机间通信的C语言编程语言编程3.1.1 点对点的串行异步通信点对点的串行异步通信1通信双方的硬件连接通信双方的硬件连接 图 3.1 8031间RS232C电平信号的传 单片机C语言应用程序设计 2通信双方的约定通信双方的约定图图 3.2 点对点通信的程序框图点对点通信的程序框图单片机C语言应用程序设计 3. 点对点通信编程点对点通信编程 点对点通信双方基本等同,
2、只是人为规定一个为发送,一个为接收。要求两机串行口的波特率相同,因而发送和接收方串行口的初始化相同。可编制含有初始化函数、发送函数接收函数的程序,在主函数中根据程序的发送、接收设置TR,采用条件判别决定使用发送函数还是接收函数。这样点对点通信的双方都可运行此程序,只需在程序运行之前人为设置选择TR,一个令TR=0,一个令TR=1,然后分别编译,在两机上分别装入,同时运行。单片机C语言应用程序设计 例例1 点对点通信。点对点通信的程序如下:#include#define uchar unsigned char#define TR 1 /*发送接收差别值TR=0发送*/uchar idata bu
3、f10;uchar pf;void init(void) /*串行口初始化*/ TMOD=0 x20; /*设T/C1为定时方式2*/ TH1=0 xe8; /*设定波特率*/单片机C语言应用程序设计 TL1=0 xe8; PCON=0 x00; TR1=1; /*启动T/C1*/ SCON=0 x50; /*串行口工作在方式1*/ void send(uchar idata *d) uchar i; do SBUF=0 xaa; /*发送联络信号*/ while(TI= =0); /*等待发送出去*/ TI=0;单片机C语言应用程序设计 while(RI= =0); /*等待B机回答*/ R
4、I=0; while(SBUF0 xbb)!=0); /*B机未准备好,继续联络*/ do pf=0; /*清校验和*/ for ( i=0;i16;i+) SBUF=di; /*发送一个数据*/ pf+ =di; /*求校验和*/ while(TI= =0);TI=0; SBUF=pf; /*发送校验和*/单片机C语言应用程序设计 while(TI= =0);TI=0; while(RI= =0);RI=0; /*等待B机回答*/ while(SBUF!=0); /*回答出错,则重发*/ void receive (uchar idata *d) uchar i; do while (RI=
5、 =0); RI=0; while (SBUF0 xaa)! =0); /*判A机请求否*/ SBUF=0 xbb; /*发应答信号*/单片机C语言应用程序设计 while (TI= =0); TI=0; while (1) pf=0; /*清校验和*/ for ( i=0;i16;i+) while (RI= =0); RI=0; d i =SBUF; /*接收一个数据*/ pf+ =di; /*求校验和*/ while (RI= =0); RI=0; /*接收A机校验和*/ if (SBUF pf) = =0) /*比较校验和*/ SBUF=0 x00; break; /*校验和相同发00
6、*/ else SBUF=0 xff; /*出错发FF,重新接收*/单片机C语言应用程序设计 while(TI= =0); TI=0; void main (void) init ( ); if(TR= =0) send(buf); else receive(buf); 单片机C语言应用程序设计 3.1.2 多机通信多机通信1通信接口通信接口图 3.3 总线式主从式多机系统 单片机C语言应用程序设计 2通信协议通信协议 根据MCS-51串行口的多机通信能力,多机通信可以按照以下协议进行: (1) 首先使所有从机的SM2位置1处于只接收地址帧的状态。 (2) 主机先发送一帧地址信息,其中8位地址
7、,第9位为地址/数据信息的标志位,该位置1表示该帧为地址信息。 (3) 从机接收到地址帧后,各自将接收的地址与本机的地址比较。对于地址相符的那个从机,使SM2位清零,以接收主机随后发来的所有信息;对于地址不符的从机,仍保持SM2=1,对主机随后发来的数据不予理睬,直至发送新的地址帧。 单片机C语言应用程序设计 (4) 当从机发送数据结束后,发送一帧校验和,并置第9位(TB8)为1,作为从机数据传送结束标志。 (5) 主机接收数据时先判断数据结束标志(RB8),若RB8=1,表示数据传送结束,并比较此帧校验和,若正确,则会送正确信号00H,此信号令该从机复位(即重新等待地址帧);若校验和出错,则
8、发送0FFH,令该从机重发数据。若接收帧的RB8=0,则原数据到缓冲区,并准备接收下帧信息。 (6) 若主机向从机发送数据,从机在第(3)步中比较地址相符后,从机令SM2=0,同时把本站地址发回主机。作为应答之后才能收到主机发送来的数据。其它从机(SM2=1),无法收到数据。单片机C语言应用程序设计 (7) 主机收到从机的应答地址后,确认地址是否相符。如果地址不符,发复位信号(数据帧中TB8=1);如果地址相符,则清TB8,开始发送数据。 (8) 从机接收到复位命令后回到监听地址状态(SM2=1)。否则开始接收数据和命令。单片机C语言应用程序设计 3. 通信程序通信程序 设主机发送的地址联络信
9、号00H,01H,02H为从机设备地址,地址FFH是命令各从机恢复SM2为1的状态,即复位。主机的命令编码为:01H 请求从机接收主机的数据命令;02H 请求从机向主机发送数据命令。 其它都按从机向主机发送数据命令02H对待。单片机C语言应用程序设计 从机的状态字节格式为:ERR00000TRDYRRDYD7 D6 D5 D4 D3 D2 D1 D0 RRDY=1:从机准备好接收主机的数据。 TRDY=1:从机准备好向主机发送数据。 ERR=1:从机接收到的命令是非法的。 通常从机以中断方式控制和主机的通信。程序可分成主机程序和从机程序,约定一次传送的数据为16个字节,以02H地址的从机为例。
10、单片机C语言应用程序设计 1) 主机程序主机程序图图3.4 多机通信主机程序流程图多机通信主机程序流程图 单片机C语言应用程序设计 主机程序如下:#include #define uchar unsigned char#define SLAVE 0 x02 /*从机地址*/#define BN 16uchar idata rbuf 16;uchar idata tbuf 16=master transmit;void err (void) SBUF=0 xff;while(TI!=1);TI=0;单片机C语言应用程序设计 uchar master (char addr, uchar comma
11、nd)uchar aa, i,p; while(1) SBUF=SLAVE; /* 发呼叫地址 */ while (TI!=1);TI=0; while (RI!=1);RI=0; /* 等待从机回答 */ if(SBUF!=addr) err( )/* 若地址错,发复位信号 */ else /* 地址相符 */ TB8=0; /* 清地址标志 */ SBUF=command; /* 发命令 */ while (TI!=1);TI=0; while (RI!=1);RI=0;单片机C语言应用程序设计 aa=SBUF; /* 接收状态 */ if(aa&0 x08)= =0 x08) TB8=1
12、; err( ); /* 若命令未被接收,发复位信号 */ else if ( command= =0 x01) /* 是发送命令 */ if (aa&0 x01)= =0 x01) /* 从机准备好接收 */ do p=0; /* 清校验和 */ for(i=0;iBN;i+) SBUF=tbufi; /* 发送一数据 */ p+=tbufi; /*校验和相加;*/单片机C语言应用程序设计 while(TI!=1);TI=0; SBUF=p; /* 发送校验和 */ while (TI= =0);TI=0; while (RI= =0);RI=0; while (SBUF! =0); /*
13、接收不正确,重新发送 */ TB8=1; /* 置地址标志 */ return(0) else if(aa&0 x02)= =0 x02) /* 是接收命令,从机准备好发送 */单片机C语言应用程序设计 while(1) p=0; /* 清校验和 */ for(i=0;iBN;i+) while (RI! =1); RI=0; rbufi=SBUF; /* 接收一数据 */ P+=rubfi; while(RI= =0);RI=0; if(SBUF= =p) SBUF=0X00; /* 校验和相同发00 */ while(TI= =0);TI=0; break; 单片机C语言应用程序设计 el
14、se SBUF=0 xff; /* 校验和不同发0FF,重新接收 */ while(TI= =0);TI=0; TB8=1; /* 置地址标志 */ Retuen(0); 单片机C语言应用程序设计 void main (viod) TMOD=0 x20; /* T/C1定义为方式2 */ TL1=0 xfd;TH1=0 xfd; /* 置初值 */ PCON=0 x00; TR1=1; SCON=0 xf0; /* 串行口为方式3 */ master(SLAVE,0 x01); master( SLAVE,0 x02 ); 单片机C语言应用程序设计 2) 从机程序图3.5 多机通信的从机中断程
15、序流单片机C语言应用程序设计 从机程序如下: #include #define uchar unsigned char #define SLAVE 0 x02 #define BN 16 uchar idata trbuf16; uchar idata rebuf16; bit tready; bit rready; void main (void) 单片机C语言应用程序设计 TMOD=0 x20; /*T/C1定义为方式2*/ TL1=0 xfd; /*置初值*/ TH1=0 xfd; PCON=0 x00; TR1=1; SCON=0 xf0; /*串行口为方式3*/ ES=1;EA=1;
16、 /*开串行口中断*/ while(1) tready=1; rready=1; /*假定准备好发送和接收*/ 单片机C语言应用程序设计 void ssio (void ) interrupt 4 using 1 void str(void); void sre(void); uchar a,i; RI=0; ES=0; /*关串行口中断*/ if(SBUF! =SLAVE) ES=1;goto reti; /*非本机地址,继续监听*/ SM2=0 ; /* 取消监听状态 */ SBUF=SLAVE ; /* 从本地址发回 */单片机C语言应用程序设计 while ( TI ! =1 ) ;T
17、I =0 ; while ( RI !=1 ) ; RI =0 ; if ( RB8 = 1 ) SM2=1 ; ES=1 ;goto reti ; /* 是复位信号,恢复监听 */ a=SBUF ; /* 接收命令 */ if (a =0 x01 ) /* 从主机接收的数据 */ if ( rready = =1 ) SBUF =0 x01 ; / * 接收准备好发状态 */ else SBUF=0 x00 ; while ( TI ! =1 ) ; TI=0 ; while ( RI ! =1 ) ; RI =0 ; if ( RB8= =1 ) SM2 =1 ;ES =1 ; goto
18、reti ; sre( ) ; /* 接收数据 */ 单片机C语言应用程序设计 else if( a= 0 x02 ) /* 从机向主机发送数据*/ if ( tready = =1 ) SBUF =0 x02 ; /* 发送准备好发状态 */ else SBUF=0 x00 ; while ( TI ! = 1 ) ; TI =0 ; while ( RI ! =1 ) ;RI =0 ; if ( RB8 = =1 ) SM2 =1 ; ES =1 ; goto reti ; str ( ) ; / * 发送数据 */ 单片机C语言应用程序设计 else SBUF = 0 x80 ; /*
19、命令非法 ,发状态 */ while ( TI ! =1 ) ; TI =0 ; SM2 =1 ; ES =1 ; /* 恢复监听 */ reti:; void str ( void ) /* 发数据块 */ uchar p ,i ; tready =0 ; do p=0 ; /* 清校验和 */ 单片机C语言应用程序设计 for ( i= 0; iBN ; i+ ) SBUF= trbuf i ; /* 发送一数据 */ p+=trbufi ; while ( TI !=1 ) ; TI =0 ; SUBF= p ; /* 发送校验和 */ while ( TI = =0 ) ; TI =0
20、; while ( RI= =0 ); RI =0 ; while ( SBUF !=0 ) ; /* 主机接收不正确,重新发送 */ SM2=1 ; ES = 1 ; 单片机C语言应用程序设计 void sre ( void ) / * 接收数据块 */ uchar p , i ; rready = 0 ; while ( 1 ) p= 0 ; /* 清校验和 */ for ( i =0 ; i BN ; i+) while ( RI !=1 );RI =0 ; rebuf i =SBUF ; /* 接收数据 * / p+=rebuf i ; 单片机C语言应用程序设计 while ( RI
21、!=1 ) ;RI =0 ; if ( SBUF = = p ) SBUF= 0 x00 ; break ; /* 校验和相同发00*/ else SBUF=0 xff ; /* 校验和不同发0FF,重新接收 */ while ( TI = = 0 ) ;TI=0; SM2 = 1 ; ES = 1 ; 单片机C语言应用程序设计 3.2 键盘和数码显示人机交互的键盘和数码显示人机交互的C语言编程语言编程3.2.1 行列式键盘与行列式键盘与8031的接口的接口 键盘输入信息的主要过程是: (1) 单片机判断是否有键按下。 (2) 确定按下的是哪一个键。 (3) 把此步骤代表的信息翻译成计算机所能
22、识别的代码,如ASCII或其它特征码。单片机C语言应用程序设计 图3.6 8031与行列式键盘的接口 单片机C语言应用程序设计 例例2 44键盘的扫描程序。 扫描程序查询的内容为: (1) 查询是否有键按下。首先单片机向行扫描P1.0 P1.3输出全为0扫描码F0H,然后从列检查口P1.4 P1.7输入列扫描信号,只要有一列信号不为1,即P1口不为F0H,则表示有键按下。接着要查出按下键所在的行、列位置。单片机C语言应用程序设计 (2) 查询按下键所在的行列位置。单片机将得到的信号取反,P1.4P1.7中的为1的位便是键所在的列。接下来要确定键所在的行,需要进行逐行扫描。单片机首先使P1.0为
23、0,P1.1P1.7为1,即向P1口发送扫描码FEH,接着输入列检查信号,若全为1,表示不在第一行。接着使P1.1接地,其余为1,再读入列信号这样逐行发0扫描码,直到找到按下键所在的行,将该行扫描码取反保留。当各行都扫描以后仍没有找到,则放弃扫描,认为是键的误动作。单片机C语言应用程序设计 (3) 对得到的行号和列号译码,得到键值。 (4) 键的抖动处理。当用手按下一个键时,往往会出现所按键在闭合位置和断开位置之间跳几下才稳定到闭合状态的情况。在释放一个键时,也会出现类似的情况,这就是键抖动,抖动的持续时间不一,通常不会大于10 ms,若抖动问题不解决,就会引起对闭合键的多次读入,对于键抖动最
24、方便的解决方法就是当发现有键按下后,不是立即进行逐行扫描,而是延时10 ms后再进行。由于键按下的时间持续上百毫秒,延时后再也不迟。单片机C语言应用程序设计 扫描函数的返回值为键特征码,若无键按下,返回值为0。程序如下:# include # define uchar unsigned char # define uint unsigned int void dlms( void )void kbscan( void ) ;void main ( void ) uchar key ;while( 1 ) key =kbscan ( ) ; dlms( ) ; 单片机C语言应用程序设计 void
25、 dlms( void ) uchar i ; for ( i=200 ; i0 ; i- -) uchar kbscan ( void ) /* 键扫描函数 */ uchar scode ,recode ; P1=oxf0 ; if ( (P1 & 0 xf0 ) ! =0 xf0 ) /* 若有键按下 */ dlms ( ) ; /* 延时去抖动 */ if ( P1 & 0 xf0 )! = 0 xf0 ) scode =0 xfe ; /* 逐行扫描初值 */ while ( scode & 0 x10 ) !=0 ) P1=scode ; /* 输出扫描码 */单片机C语言应用程序设
26、计 if ( P1 & 0 xf0 )! =0 xf0 ) /* 本行有键按下 */ recode= ( P1 & 0 xf0 ) | 0 x0f ; return ( scode ) + ( recode ) ) ; /* 返回特征字节码 */ else scode = ( scode 1) | 0 x01 ; /* 行扫描左移一位 */ return ( 0 ) ; 单片机C语言应用程序设计 3.2.2 七段数码显示与七段数码显示与8031的接口的接口 数码显示器有静态显示和动态显示两种显示方式。 数码显示器有发光管的LED和液晶的LCD两种。 LED显示器工作在静态方式时,其阴极(或其阳
27、极)点连接在一起接地(或+5 V),每一个的端选线(a,b,c,d,e,f,g,dp)分别与一个8位口相连。LCD数码显示只能工作在静态显示,并要求加上专门的驱动芯片4056。 LED显示器工作在动态显示方式时,段选码端口I/O1用来输出显示字符的段选码,I/O2输出位选码。I/O1不断送待显示字符的段选码,I/O2不断送出不同的位扫描码,并使每位显示字符停留显示一段时间,一般为15 ms,利用眼睛的视觉惯性,从显示器上便可以见到相当稳定的数字显示。单片机C语言应用程序设计 例例3 8155控制的动态LED显示。图图 3.7 经经8155扩展端口的扩展端口的6位位LED动态显示动态显示 单片机
28、C语言应用程序设计 确定的8155片内4个端口地址如下:命令/状态口 : FFF0H口A: FFF1H口B: FFF2H口C: FFF3H单片机C语言应用程序设计 6位待显示字符从左到右依次放在dis_buf数组中,显示次序从右向左顺序进行。程序中的table 为段选码表,表中段选码表存放的次序为0F等。以下为循环动态显示6位字符的程序,8155命令字为07H。# include # include #define uchar unsigned char# define COM8155 XBYTE 0 xfff0 # define PA8155 XBYTE 0 xfff1 # define P
29、B8155 XBYTE 0 xfff2 # define PC8155 XBYTE 0 xfff3 单片机C语言应用程序设计 uchar idata dis_buf6 = 2,4,6,8,10,12 ;uchar code table18 = 0 x3f ,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f, 0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71,0 x40,0 x00 ;void dl_ms ( uchar d ) ;void display ( uchar idata * p ) uchar sel
30、,i ; COM8155 = 0 x07 ; /* 送命令字 */ sel = 0 x01 ; /* 选出右边的LED */ for ( i= 0 ; i6 ; i+ ) PB8155=table * p ; /* 送段码 */单片机C语言应用程序设计 PA8155=sel ; /* 送位选码 */ dl_ms ( 1 ) ; p - - ; /* 缓冲区下移1位 */ sel =sel 1 /* 左移1 位 */ void main ( void ) display ( dis_buf +5 ) ; 单片机C语言应用程序设计 例例4 串行口控制的静态LCD显示。图 3.8 串行口连接的静态LCD显示电路 单片机C语言应用程序设计 输出两位显示,即一字节的程序如下:# include # define uchar unsigned char uchar byte=0 x59 ;void display ( uchar x ) SBUF=x ; /* 由串口输出 */ while ( TI = =0 ); /* 等待8位发送结束 * / TI = 0 ;void main ( void ) display( byte )