首页 51单片机应用开发范例代码10

51单片机应用开发范例代码10

举报
开通vip

51单片机应用开发范例代码10【实例73】单片机间双机通信 #include #define uchar unsigned char #define uint unsigned int uchar buf[16]; uchar chksum; /*校验和*/ (1)串口初始化子程序void init () void init(void) { TMOD = 0x20; TH1 = 0xFD; /*设定波特率*/ TL1 = 0xFD; PCON = 0X00; SCO...

51单片机应用开发范例代码10
【实例73】单片机间双机通信 #include #define uchar unsigned char #define uint unsigned int uchar buf[16]; uchar chksum; /*校验和*/ (1)串口初始化子程序void init () void init(void) { TMOD = 0x20; TH1 = 0xFD; /*设定波特率*/ TL1 = 0xFD; PCON = 0X00; SCON = 0X50; /*串行口工作在方式1,允许接收*/ } (2)甲机发送子程序void send () void send( void ) { uchar i; do { SBUF = 0XAA; /*发送联络信号 "0xAA" */ while( TI==0 ); /*等待发送结束*/ TI = 0; while(RI ==0 ); /*等待乙响应*/ RI = 0; } while( ( SBUF^0XDD)!=0); /*乙未准备好,继续联络*/ do { chksum = 0; for(i=0; i<16; i++) { SBUF = buf[i]; chksum += buf[i]; /*求校验和*/ while( TI == 0); TI = 0; } SBUF = chksum; /*发送校验和*/ while( TI == 0 ); TI = 0; while( RI == 0 ); /*等待乙响应*/ RI = 0; } while(SBUF!=0X00); /*出错则出重发*/ } (3)乙机接收程序void recv() void recv( void ) { uchar i; while(1) { while(RI==0); /* 等待接收数据 */ RI = 0; if (SBUF^0XAA!=0) /* 如果收到的不是0xAA */ { SBUF = 0XFF; while( TI == 0 ); TI=0; } else /*收到的是0xAA*/ { break; } } while(1) { chksum = 0; for(i=0; i<16; i++) { while(RI==0); RI = 0; buf[i] = SBUF; /*接受一个数据*/ chksum += buf[i]; /*计算校验和*/ } while( RI==0); /*接收校验和*/ RI = 0; if( (SBUF^chksum) == 0 ) /*比较校验和*/ { SBUF = 0X00; /*校验和相同则发0x00 */ while(TI==0); TI =0; break; } else { SBUF = 0XFF; /*出错则发0xFF,重新接收*/ while( TI == 0); TI = 0; } } } 【实例74】单片机间多机通信方法之一 主机的相关程序如下: #include #include #define BUF_MAX_LEN 3 #define ADDR_ACK 0x1A #define DATA_ACK 0x2A unsigned char send_buf[BUF_MAX_LEN]; /* 发送数据缓冲 */ void serial_init( void ); /* 串口初始化 */ void send_addrframe( unsigned char addr ); /* 发送地址帧 */ void send_data_frame( void); /* 发送数据帧 */ 主函数main()程序代码如下: void main( void ) { unsigned char recv_tmp=0; send_buf[0]=1; /* 发送数据缓冲,这里以1,2,4为例说明 */ send_buf[1]=2; send_buf[2]=3; serial_init(); while( recv_tmp!= ADDR_ACK ) { send_addrframe( 0x05 ); /*发送从机地址client_addr*/ RI = 0; while(!RI); /*接收从机发送的地址确认*/ RI = 0; recv_tmp = SBUF; } while( recv_tmp != DATA_ACK ) { send_data_frame(); RI =0; while(!RI); RI = 0; recv_tmp = SBUF; } /*其他程序等 */ } (1)串行口初始化程序serial_init() void serial_init( void ) { TMOD= 0x20 ; TH1 = 0xFD ; TL1 = 0xFD ; EA = 0; ET0 = 0; ES = 0; SCON= 0xD0 ; PCON= 0x00 ; TR1 =1; } (2)发送地址帧函数send_addrframe() void send_addrframe( unsigned char addr ) { TB8 = 1; /*址帧 标志*/ SBUF= addr; while( !TI ); /*待数据发送完成*/ TI = 0; TB8 = 0; } (3)发送数据帧函数send_addr_frame() void send_data_frame( void ) { unsigned char i; unsigned char check_sum=0; for( i=0;i #include /*伪定义*/ #define BUF_MAX_LEN 10 /*缓冲区的最大长度*/ #define ADDR_ACK 0x1A #define DATA_ACK 0x2A #define DATA_ERR 0x3A unsigned char recv_buf[BUF_MAX_LEN+1]; /*函数声明*/ unsigned char recv_data_frame( void ); /*接收数据帧*/ void send_ack( unsigned char ack ); /*发送应答信息*/ void recv_addrframe( void ); /*接收地址帧*/ void serial_init( void ); /*串口初始化*/ 主程序中serial_init()函数初始化完毕串行口后,等待主机发送的地址字节,若接收到与本机相同的地址字节,发送地址收到应答,然后再接收数据字节,接收完毕后对数据字节进行校验,校验正确则向主机发送数据正确数据,否则发送数据错误数据。程序代码如下: void main( void ) { unsigned char recv_tmp=0; serial_init(); while( 1 ) { recv_addrframe(); /*接收主机发送的地址帧*/ send_ack( ADDR_ACK ); /*发送地址收到应答*/ if( recv_data_frame() == DATA_ACK ) { send_ack( DATA_ACK ); } else if (recv_data_frame == DATA_ERR ) { send_ack( DATA_ERR ); } } } (1)接收地址帧函数recv_data_frame() unsigned char recv_data_frame( void ) { unsigned char i; unsigned char check_sum=0; SM2= 0; for( i=0;i #include #define uchar unsigned char #define uint unsigned int #define CHK_OK 0X01 #define CHK_ERR 0XFF #define CLIENT 0X0F #define HOST 0XF0 #define SYN 0XAA #define FIN 0XDD #define RECV_DATA_STAT 0x01 #define RECV_HDR_STAT 0X02 #define MAX_RECV_NUM 50 #define MAX_SEND_NUM 50 /*相关全局变量定义*/ uchar data client_addr; uchar data recv_tmp; uchar data recv_status; uchar data recv_counter; uchar idata recv_buf[ MAX_RECV_NUM ]; uchar idata send_buf[ MAX_SEND_NUM ]; bit recv_frame_ok; uchar calc_chksum( void ); void seri_init( void ); void seri_send( uchar *p,uchar data_len); void get_client_addr( void ); (1)串行中断服务子程序void seri_isr() void seri_isr( void ) interrupt 4 using 1 { if(1==TI) { TI=0; } if(0==RI) { return; } recv_tmp = SBUF; switch( recv_status ) { case RECV_DATA_STAT: { recv_buf[ recv_counter]=recv_tmp; recv_counter ++; if( recv_counter == recv_buf[4] ) { recv_status = RECV_HDR_STAT; } else { return; } break; } case RECV_HDR_STAT: { if( recv_tmp == SYN ) /* 如果是开始字节 */ { recv_buf[ recv_counter ] = recv_tmp; recv_counter ++; if( 6 == recv_counter ) { recv_status = RECV_DATA_STAT; } } else if( recv_tmp == FIN ) /* 如果是结束字节 */ { recv_buf[ recv_counter ] = recv_tmp; recv_counter ++; if( ( CHK_OK == calc_chksum() ) && ( recv_buf[5] == client_addr ) ) { recv_frame_ok = 1; } else { recv_counter = 0; recv_status = RECV_HDR_STAT; } } else { recv_counter = 0; recv_status = RECV_HDR_STAT; } break; } default: { recv_status = RECV_HDR_STAT; memset(recv_buf,0x00,MAX_RECV_NUM); recv_counter = 0; break; } } } (2)主程序void main() void main( void ) { seri_init(); get_client_addr(); seri_send("test",4); if( 1 == recv_frame_ok ) /* 接收到数据 */ { /* 对接收到数据进行处理 */ } /* 其他代码等 */ } (3)计算校验和子程序uchar calc_chksum() uchar calc_chksum( void ) { uchar i; uchar chksum2; if( ( recv_counter == 0 )|| ( recv_buf[4] != recv_counter) ) { return CHK_ERR; } chksum2 = 0; for( i=0; i>8 ); /* 表号高8位 */ send_buf[2] = (unsigned char )(meter_id&0xff); /* 表号低8位 */ send_buf[3] = (unsigned char )(room_id >>8 ); /* 房间号高8位 */ send_buf[4] = (unsigned char )(room_id &0xff); /* 房间号低8位 */ send_buf[5] = cmd; /* 命令字节 */ send_buf[6] = data_len; /* 数据域的长度 */ for( i=0;i
本文档为【51单片机应用开发范例代码10】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_536635
暂无简介~
格式:doc
大小:79KB
软件:Word
页数:17
分类:互联网
上传时间:2018-09-07
浏览量:12