3C51应用编程设计

上传人:dja****22 文档编号:242875045 上传时间:2024-09-10 格式:PPT 页数:50 大小:1.08MB
返回 下载 相关 举报
3C51应用编程设计_第1页
第1页 / 共50页
3C51应用编程设计_第2页
第2页 / 共50页
3C51应用编程设计_第3页
第3页 / 共50页
点击查看更多>>
资源描述
,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单片机C语言应用程序设计,3.1 MCS-51机间通信的C语言编程,3.2 键盘和数码显示人机交互的C语言编程,三 C51应用编程设计,1,3.1 MCS-51机间通信的C语言编程,3.1.1 点对点的串行异步通信,1通信双方的硬件连接,图 3.1 8031间RS232C电平信号的传,2,2通信双方的约定,图 3.2 点对点通信的程序框图,3,3. 点对点通信编程,点对点通信双方基本等同,只是人为规定一个为发送,一个为接收。要求两机串行口的波特率相同,因而发送和接收方串行口的初始化相同。可编制含有初始化函数、发送函数接收函数的程序,在主函数中根据程序的发送、接收设置TR,采用条件判别决定使用发送函数还是接收函数。这样点对点通信的双方都可运行此程序,只需在程序运行之前人为设置选择TR,一个令TR=0,一个令TR=1,然后分别编译,在两机上分别装入,同时运行。,4,例1,点对点通信。,点对点通信的程序如下:,#include,#define uchar unsigned char,#define TR 1 /*发送接收差别值TR=0发送*/,uchar idata buf10;,uchar pf;,void init(void) /*串行口初始化*/, TMOD=0x20; /*设T/C1为定时方式2*/,TH1=0xe8; /*设定波特率*/,5,TL1=0xe8;,PCON=0x00;,TR1=1; /*启动T/C1*/,SCON=0x50; /*串行口工作在方式1*/,void send(uchar idata *d), uchar i;,do ,SBUF=0xaa; /*发送联络信号*/,while(TI= =0); /*等待发送出去*/,TI=0;,6,while(RI= =0); /*等待B机回答*/,RI=0;,while(SBUF0xbb)!=0); /*B机未准备好,继续联络*/,do ,pf=0; /*清校验和*/,for ( i=0;i16;i+), SBUF=di; /*发送一个数据*/,pf+ =di; /*求校验和*/,while(TI= =0);TI=0;,SBUF=pf; /*发送校验和*/,7,while(TI= =0);TI=0;,while(RI= =0);RI=0; /*等待B机回答*/,while(SBUF!=0); /*回答出错,则重发*/,void receive (uchar idata *d), uchar i;,do ,while (RI= =0); RI=0;,while (SBUF0xaa)! =0); /*判A机请求否*/,SBUF=0xbb; /*发应答信号*/,8,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=0x00; break; /*校验和相同发00*/,else,SBUF=0xff; /*出错发FF,重新接收*/,9,while(TI= =0); TI=0;,void main (void), init ( );,if(TR= =0), send(buf);,else, receive(buf);,10,3.1.2 多机通信,1通信接口,图 3.3 总线式主从式多机系统,11,2通信协议,根据MCS-51串行口的多机通信能力,多机通信可以按照以下协议进行:,(1) 首先使所有从机的SM2位置1处于只接收地址帧的状态。,(2) 主机先发送一帧地址信息,其中8位地址,第9位为地址/数据信息的标志位,该位置1表示该帧为地址信息。,(3) 从机接收到地址帧后,各自将接收的地址与本机的地址比较。对于地址相符的那个从机,使SM2位清零,以接收主机随后发来的所有信息;对于地址不符的从机,仍保持SM2=1,对主机随后发来的数据不予理睬,直至发送新的地址帧。,12,(4) 当从机发送数据结束后,发送一帧校验和,并置第9位(TB8)为1,作为从机数据传送结束标志。,(5) 主机接收数据时先判断数据结束标志(RB8),若RB8=1,表示数据传送结束,并比较此帧校验和,若正确,则会送正确信号00H,此信号令该从机复位(即重新等待地址帧);若校验和出错,则发送0FFH,令该从机重发数据。若接收帧的RB8=0,则原数据到缓冲区,并准备接收下帧信息。,(6) 若主机向从机发送数据,从机在第(3)步中比较地址相符后,从机令SM2=0,同时把本站地址发回主机。作为应答之后才能收到主机发送来的数据。其它从机(SM2=1),无法收到数据。,13,(7) 主机收到从机的应答地址后,确认地址是否相符。如果地址不符,发复位信号(数据帧中TB8=1);如果地址相符,则清TB8,开始发送数据。,(8) 从机接收到复位命令后回到监听地址状态(SM2=1)。否则开始接收数据和命令。,14,3. 通信程序,设主机发送的地址联络信号00H,01H,02H为从机设备地址,地址FFH是命令各从机恢复SM2为1的状态,即复位。主机的命令编码为:,01H 请求从机接收主机的数据命令;,02H 请求从机向主机发送数据命令。,其它都按从机向主机发送数据命令02H对待。,15,从机的状态字节格式为:,ERR,0,0,0,0,0,TRDY,RRDY,D7 D6 D5 D4 D3 D2 D1 D0,RRDY=1:从机准备好接收主机的数据。,TRDY=1:从机准备好向主机发送数据。,ERR=1:从机接收到的命令是非法的。,通常从机以中断方式控制和主机的通信。程序可分成主机程序和从机程序,约定一次传送的数据为16个字节,以02H地址的从机为例。,16,1) 主机程序,图3.4 多机通信主机程序流程图,17,主机程序如下:,#include ,#define uchar unsigned char,#define SLAVE 0x02 /*从机地址*/,#define BN 16,uchar idata rbuf 16;,uchar idata tbuf 16=master transmit;,void err (void),SBUF=0xff;,while(TI!=1);TI=0;,18,uchar master (char addr, uchar command),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;,19,aa=SBUF; /* 接收状态 */,if(aa&0x08)= =0x08) TB8=1; err( ); /* 若命令未被接收,发复位信号 */,else ,if ( command= =0x01) /* 是发送命令 */,if (aa&0x01)= =0x01) /* 从机准备好接收 */,do ,p=0; /* 清校验和 */,for(i=0;iBN;i+), SBUF=tbufi; /* 发送一数据 */,p+=tbufi;,20,while(TI!=1);TI=0;,SBUF=p; /* 发送校验和 */,while (TI= =0);TI=0;,while (RI= =0);RI=0;,while (SBUF! =0); /* 接收不正确,重新发送 */,TB8=1; /* 置地址标志 */,return(0),else ,if(aa&0x02)= =0x02) /* 是接收命令,从机准备好发送 */,21,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;,22,else, SBUF=0xff; /* 校验和不同发0FF,重新接收 */,while(TI= =0);TI=0;,TB8=1; /* 置地址标志 */,Retuen(0);,23,void main (viod),TMOD=0x20; /* T/C1定义为方式2 */,TL1=0xfd;TH1=0xfd; /* 置初值 */,PCON=0x00;,TR1=1;,SCON=0xf0; /* 串行口为方式3 */,master(SLAVE,0x01);,master( SLAVE,0x02 );,24,2) 从机程序,图3.5 多机通信的从机中断程序流,25,从机程序如下:,#include ,#define uchar unsigned char,#define SLAVE 0x02,#define BN 16,uchar idata trbuf16;,uchar idata rebuf16;,bit tready;,bit rready;,void main (void),26,TMOD=0x20; /*T/C1定义为方式2*/,TL1=0xfd; /*置初值*/,TH1=0xfd;,PCON=0x00;,TR1=1;,SCON=0xf0; /*串行口为方式3*/,ES=1;EA=1; /*开串行口中断*/,while(1) tready=1; rready=1; /*假定准备好发送和接收*/,27,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 ; /* 从本地址发回 */,28,while ( TI ! =1 ) ;TI =0 ;,while ( RI !=1 ) ; RI =0 ;,if ( RB8 = 1 ) SM2=1 ; ES=1 ;goto reti ; /* 是复位信号,恢复监听 */,a=SBUF ; /* 接收命令 */,if (a =0x01 ) /* 从主机接收的数据 */,if ( rready = =1 ) SBUF =0x01 ; / * 接收准备好发状态 */,else SBUF=0x00 ;,while ( TI ! =1 ) ; TI=0 ;,while ( RI ! =1 ) ; RI =0 ;,if ( RB8= =1 ) SM2 =1 ;ES =1 ; goto reti ;,sre( ) ; /* 接收数据 */,29,else ,if( a= 0x02 ) /* 从机向主机发送数据*/,if ( tready = =1 ) SBUF =0x02 ; /* 发送准备好发状态 */,else SBUF=0x00 ;,while ( TI ! = 1 ) ; TI =0 ;,while ( RI ! =1 ) ;RI =0 ;,if ( RB8 = =1 ) SM2 =1 ; ES =1 ; goto reti ; ,str ( ) ; / * 发送数据 */,30,else,SBUF = 0x80 ; /* 命令非法 ,发状态 */,while ( TI ! =1 ) ; TI =0 ;,SM2 =1 ; ES =1 ; /* 恢复监听 */,reti:;,void str ( void ) /* 发数据块 */, uchar p ,i ;,tready =0 ;,do p=0 ; /* 清校验和 */,31,for ( i= 0; iBN ; i+ ), SBUF= trbuf i ; /* 发送一数据 */,p+=trbufi ;,while ( TI !=1 ) ;,TI =0 ;,SUBF= p ; /* 发送校验和 */,while ( TI = =0 ) ; TI =0;,while ( RI= =0 ); RI =0 ;, while ( SBUF !=0 ) ; /* 主机接收不正确,重新发送 */,SM2=1 ;,ES = 1 ;,32,void sre ( void ) / * 接收数据块 */, uchar p , i ;,rready = 0 ;,while ( 1 ), p= 0 ; /* 清校验和 */,for ( i =0 ; i0 ; i- -) ,uchar kbscan ( void ) /* 键扫描函数 */, uchar scode ,recode ;,P1=oxf0 ;,if ( (P1 & 0xf0 ) ! =0xf0 ) /* 若有键按下 */, dlms ( ) ; /* 延时去抖动 */,if ( P1 & 0xf0 )! = 0xf0 ), scode =0xfe ; /* 逐行扫描初值 */,while ( scode & 0x10 ) !=0 ), P1=scode ; /* 输出扫描码 */,41,if ( P1 & 0xf0 )! =0xf0 ) /* 本行有键按下 */, recode= ( P1 & 0xf0 ) | 0x0f ;,return ( scode ) + ( recode ) ) ; /* 返回特征字节码 */,else,scode = ( scode 1) | 0x01 ; /* 行扫描左移一位 */,return ( 0 ) ;,42,3.2.2 七段数码显示与8031的接口,数码显示器有静态显示和动态显示两种显示方式。,数码显示器有发光管的LED和液晶的LCD两种。,LED显示器工作在静态方式时,其阴极(或其阳极)点连接在一起接地(或+5 V),每一个的端选线(a,b,c,d,e,f,g,dp)分别与一个8位口相连。LCD数码显示只能工作在静态显示,并要求加上专门的驱动芯片4056。,LED显示器工作在动态显示方式时,段选码端口I/O1用来输出显示字符的段选码,I/O2输出位选码。I/O1不断送待显示字符的段选码,I/O2不断送出不同的位扫描码,并使每位显示字符停留显示一段时间,一般为15 ms,利用眼睛的视觉惯性,从显示器上便可以见到相当稳定的数字显示。,43,例3,8155控制的动态LED显示。,图 3.7 经8155扩展端口的6位LED动态显示,44,确定的8155片内4个端口地址如下:,命令/状态口 : FFF0H,口A: FFF1H,口B: FFF2H,口C: FFF3H,45,6位待显示字符从左到右依次放在dis_buf数组中,显示次序从右向左顺序进行。程序中的table 为段选码表,表中段选码表存放的次序为0F等。以下为循环动态显示6位字符的程序,8155命令字为07H。,# include ,# include ,#define uchar unsigned char,# define COM8155 XBYTE 0xfff0 ,# define PA8155 XBYTE 0xfff1 ,# define PB8155 XBYTE 0xfff2 ,# define PC8155 XBYTE 0xfff3 ,46,uchar idata dis_buf6 = 2,4,6,8,10,12 ;,uchar code table18 = 0x3f ,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00 ;,void dl_ms ( uchar d ) ;,void display ( uchar idata * p ), uchar sel ,i ;,COM8155 = 0x07 ; /* 送命令字 */,sel = 0x01 ; /* 选出右边的LED */,for ( i= 0 ; i6 ; i+ ),PB8155=table * p ; /* 送段码 */,47,PA8155=sel ; /* 送位选码 */,dl_ms ( 1 ) ;,p - - ; /* 缓冲区下移1位 */,sel =sel 1 /* 左移1 位 */,void main ( void ),display ( dis_buf +5 ) ;,48,例4,串行口控制的静态LCD显示。,图 3.8 串行口连接的静态LCD显示电路,49,输出两位显示,即一字节的程序如下:,# include ,# define uchar unsigned char,uchar byte=0x59 ;,void display ( uchar x ),SBUF=x ; /* 由串口输出 */,while ( TI = =0 ); /* 等待8位发送结束 * /,TI = 0 ;,void main ( void ),display( byte ),50,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!