51单片机串口多机通信的实现和编程
- 格式:docx
- 大小:17.75 KB
- 文档页数:8
51单片机双机串行通信设计51单片机是一款广泛应用于嵌入式系统中的微控制器,具有高性能和低功耗的特点。
在一些场景中,需要使用51单片机之间进行双机串行通信,以实现数据传输和协同工作。
本文将介绍51单片机双机串行通信的设计,包括硬件连接和软件编程。
一、硬件连接1.串行通信口选择:51单片机具有多个串行通信口,如UART、SPI 和I2C等。
在双机串行通信中,可以选择其中一个串行通信口作为数据传输的接口。
一般来说,UART是最常用的串行通信口之一,因为它的硬件接口简单且易于使用。
2.引脚连接:选定UART口作为串行通信口后,需要将两个单片机之间的TX(发送)和RX(接收)引脚相连。
具体的引脚连接方式取决于所使用的单片机和外设,但一般原则上是将两个单片机的TX和RX引脚交叉连接。
二、软件编程1.串行通信初始化:首先需要通过软件编程来初始化串行通信口。
在51单片机中,可以通过设置相应的寄存器来配置波特率和其他参数。
具体的初始化代码可以使用C语言编写,并根据所使用的开发工具进行相应的配置。
2.发送数据:发送数据时,可以通过写入相应的寄存器来传输数据。
在51单片机中,通过将数据写入UART的发送寄存器,即可将数据发送出去。
发送数据的代码通常包括以下几个步骤:(1)设置发送寄存器;(2)等待数据发送完成;(3)清除数据发送完成标志位。
3.接收数据:接收数据时,需要通过读取相应的寄存器来获取接收到的数据。
在51单片机中,可以通过读取UART的接收寄存器,即可获取到接收到的数据。
接收数据的代码通常包括以下几个步骤:(1)等待数据接收完成;(2)读取接收寄存器中的数据;(3)清除数据接收完成标志位。
4.数据处理:接收到数据后,可以进行相应的数据处理。
根据具体的应用场景,可以对接收到的数据进行解析、计算或其他操作。
数据处理的代码可以根据具体的需求进行编写。
5.中断服务程序:在双机串行通信中,使用中断可以提高通信的效率。
「51单⽚机」RS232串⼝通信代码分析想来想去不知道要怎么样把232串⼝通信说清楚,想想还是直接把代码分析⼀遍吧...重点是“常⽤波特率与定时器1的参数关系”这张表格!波特率的设置很重要!⼀、串⼝初始化void usart_init(){SCON = 0x50; //REN=1允许串⾏接受状态,串⼝⼯作模式1TMOD = 0x20; //定时器⼯作⽅式2PCON = 0x00;TH1 = 0xFD; //波特率9600、数据位8、停⽌位1。
效验位⽆ (11.0592M)TL1 = 0xFD;ES = 1; //开串⼝中断EA = 1; //开总中断TR1 = 1; //启动定时器}SCON寄存器1.SM0、SM1:串⾏⼝⼯作⽅式控制位2.SM2:多机通信控制位3.REN:允许接收位4.TB8:发送接收数据位85.RB8:接收数据位86.TI:发送中断标志位 TI=1表⽰帧发送结束7.RI:接收中断标志位 RI=1表⽰帧接收完成1.GATE:门控制位 GATE=0,仅受TRX控制 GATE=1,受TRX和外部中断引脚共同控制2.C/T:定时器模式和计数器模式选择器 C/T=1,计数器 C/T=0,定时器3.M1、M0:⼯作⽅式选择位PCON寄存器SMOD:是波特率是否加倍的选择位。
SMOD=0时:波特率不加倍。
SMOD=1时:波特率加倍。
⼆、串⼝数据发送void send_data(unsigned char a){SBUF = a; //SUBF接受/发送缓冲器while(0 == TI); //每次等待发送完毕,再执⾏下⼀条TI=0; //⼿动清0}SBUF:有两个物理上独⽴的接收、发送缓冲器SBUF,它们占⽤同⼀地址99H ;接收器是双缓冲结构;发送缓冲器,因为发送时CPU是主动的,不会产⽣重叠错误。
TI:发送中断标志位 TI=1表⽰帧发送结束三、串⼝中断程序void ser_int (void) interrupt 4using1{if(1 == RI) //RI接受中断标志{RI = 0; //清除RI接受中断标志ReData = SBUF; //SUBF接受/发送缓冲器Flag=1; //标志位置1表⽰有新数据进来}}RI:接收中断标志位 RI=1表⽰帧接收完成四、总代码#include<reg51.h>//变量声明unsigned char SenData, //发送数据Flag, //标志位ReData; //接收数据//函数声明void usart_init(); //串⼝中断初始化void send_data(unsigned char a); //串⼝数据发送//---------------------------//串⼝中断初始化//---------------------------void usart_init(){SCON = 0x50; //REN=1允许串⾏接受状态,串⼝⼯作模式1TMOD = 0x20; //定时器⼯作⽅式2PCON = 0x00;TH1 = 0xFD; //波特率9600、数据位8、停⽌位1。
一、多机通信原理在多机通信中,主机必须要能对各个从机进行识别,在51系列单片机中可以通过SCON 寄存器的SM2位来实现。
当串口以方式2或方式3发送数据时,每一帧信息都是11位,第9位是数据可编程位,通过给TB8置1或置0来区别地址帧和数据帧,当该位为1时,发送地址帧;该位为0时,发送数据帧。
在多机通信过程中,主机先发送某一从机的地址,等待从机的应答,所有的从机接收到地址帧后与本机地址进行比较,若相同,则将SM2置0准备接收数据;若不同,则丢弃当前数据,SM2位不变。
二、多机通信电路图此处,U1作为主机,U2为从机1,U3为从机2。
三、C语言程序(1)主机程序#include<reg51.h>#include<string.h>#define _SUCC_ 0x0f//数据传送成功#define _ERR_ 0xf0//数据传送失败unsigned char Table[9]={0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; unsigned char Buff[20]; //数据缓冲区unsigned char temp=0xff;sbit KEY1=P1^6;sbit KEY2=P1^7;//unsigned char addr;//延时1ms函数void delay_1ms(unsigned int t){unsigned int x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}//缓冲区初始化void Buff_init(){unsigned char i; //将Table里的数据放到缓冲区里for(i=0;i<9;i++){Buff[i]= Table[i];delay_1ms(100);}}//串口初始化函数void serial_init(){TMOD=0x20; //定时器1工作于方式2TH1=0xfd;TL1=0xfd; //波特率为9600PCON=0;SCON=0xd0; //串口工作于方式3TR1=1; //开启定时器TI=0;RI=0;}//发送数据函数void SEND_data(unsigned char *Buff){unsigned char i;unsigned char lenth;unsigned char check;lenth=strlen(Buff); //计算数据长度check=lenth;TI=0; //发送数据长度TB8=0; //发送数据帧SBUF=lenth;while(!TI);TI=0;for(i=0;i<lenth;i++) //发送数据{check=check^Buff[i];TB8=0;SBUF=Buff[i];while(!TI);TI=0;}TB8=0; //发送校验字节SBUF=check;while(!TI);TI=0;}//向指定从机地址发送数据void ADDR_data(unsigned addr){while(temp!=addr) //主机等待从机返回其地址作为应答信号{TI=0; //发送从机地址TB8=1; //发送地址帧SBUF=addr;while(!TI);TI=0;RI=0;while(!RI);temp=SBUF;RI=0;}temp=_ERR_; //主机等待从机数据接收成功信号while(temp!=_SUCC_){SEND_data(Buff);RI=0;while(!RI);temp=SBUF;RI=0;}}void main(){Buff_init();serial_init();while(1){if(KEY1==0){delay_1ms(5);if(KEY1==0){while(!KEY1);ADDR_data(0x01);}}if(KEY2==0){delay_1ms(5);if(KEY2==0){while(!KEY2);ADDR_data(0x02);}}}}(2)从机1程序#include<reg51.h>#include<string.h>#define addr 0x01//从机1的地址#define _SUCC_ 0x0f//数据传送成功#define _ERR_ 0xf0//数据传送失败unsigned char aa=0xff;//主机与从机之间通信标志unsigned char Buff[20];//数据缓冲区//串口初始化函数void serial_init(){TMOD=0x20; //定时器1工作于方式2TH1=0xfd;TL1=0xfd; //波特率为9600PCON=0;SCON=0xd0; //串口工作于方式3TR1=1; //开启定时器TI=0;RI=0;}//接收数据函数unsigned char RECE_data(unsigned char *Buff) {unsigned char i,temp;unsigned char lenth;unsigned char check;RI=0; //接收数据长度while(!RI);if(RB8==1) //若接收到地址帧,则返回0xfereturn 0xfe;lenth=SBUF;RI=0;check=lenth;for(i=0;i<lenth;i++) //接收数据{while(!RI);if(RB8==1) //若接收到地址帧,则返回0xfereturn 0xfe;Buff[i]=SBUF;check=check^(Buff[i]);RI=0;}while(!RI); //接收校验字节if(RB8==1) //若接收到地址帧,则返回0xfereturn 0xfe;temp=SBUF;RI=0;check=temp^check; //将从主机接收到的校验码与自己计算的校验码比对if(check!=0) //校验码不一致,表明数据接收错误,向主机发送错误信号,函数返回0xff {TI=0;TB8=0;SBUF=_ERR_;while(!TI);TI=0;return 0xff;}TI=0; //校验码一致,表明数据接收正确,向主机发送成功信号,函数返回0x00 TB8=0;SBUF=_SUCC_;while(!TI);TI=0;return 0;}void main(){serial_init();while(1){SM2=1; //接收地址帧while(aa!=addr) //从机等待主机请求自己的地址{RI=0;while(!RI);aa=SBUF;RI=0;}TI=0; //一旦被请求,从机返回自己的地址作为应答,等待接收数据 TB8=0;SBUF=addr;while(!TI);TI=0;SM2=0; //接收数据帧aa=0xff; //从机接收数据,并将数据保存到数据缓冲区while(aa==0xff){aa=RECE_data(Buff);}if(aa==0xfe)continue;P1=Buff[1]; //查看接收到的数据}}(3)从机2程序#include<reg51.h>#include<string.h>#define addr 0x02//从机2的地址#define _SUCC_ 0x0f//数据传送成功#define _ERR_ 0xf0//数据传送失败unsigned char aa=0xff;//主机与从机之间通信标志unsigned char Buff[20];//数据缓冲区//串口初始化函数void serial_init(){TMOD=0x20; //定时器1工作于方式2TH1=0xfd;TL1=0xfd; //波特率为9600PCON=0;SCON=0xd0; //串口工作于方式3TR1=1; //开启定时器TI=0;RI=0;}//接收数据函数unsigned char RECE_data(unsigned char *Buff){unsigned char i,temp;unsigned char lenth;unsigned char check;RI=0; //接收数据长度while(!RI);if(RB8==1) //若接收到地址帧,则返回0xfereturn 0xfe;lenth=SBUF;RI=0;check=lenth;for(i=0;i<lenth;i++) //接收数据{while(!RI);if(RB8==1) //若接收到地址帧,则返回0xfereturn 0xfe;Buff[i]=SBUF;check=check^(Buff[i]);RI=0;}while(!RI); //接收校验字节if(RB8==1) //若接收到地址帧,则返回0xfereturn 0xfe;temp=SBUF;RI=0;check=temp^check; //将从主机接收到的校验码与自己计算的校验码比对if(check!=0) //校验码不一致,表明数据接收错误,向主机发送错误信号,函数返回0xff {TI=0;TB8=0;SBUF=_ERR_;while(!TI);TI=0;return 0xff;}TI=0; //校验码一致,表明数据接收正确,向主机发送成功信号,函数返回0x00 TB8=0;SBUF=_SUCC_;while(!TI);TI=0;return 0;}void main(){serial_init();while(1){SM2=1; //接收地址帧while(aa!=addr) //从机等待主机请求自己的地址{RI=0;while(!RI);aa=SBUF;RI=0;}TI=0; //一旦被请求,从机返回自己地址作为应答,等待接收数据TB8=0;SBUF=addr;while(!TI);TI=0;SM2=0; //接收数据帧aa=0xff; //从机接收数据,并将数据保存到数据缓冲区while(aa==0xff){aa=RECE_data(Buff);}if(aa==0xfe)continue;P1=Buff[2]; //查看接收到的数据}}。
51单片机的多机通信原理1. 什么是51单片机的多机通信?51单片机的多机通信是指在多个51单片机之间进行数据传输和通信的过程。
通过多机通信,可以实现不同单片机之间的数据共享和协作,从而实现更加复杂的功能。
2. 多机通信的原理是什么?多机通信的原理是通过串口进行数据传输。
在多个单片机之间,可以通过串口进行数据的发送和接收。
通过定义好的协议,可以实现数据的传输和解析,从而实现多机之间的通信。
3. 多机通信的步骤是什么?多机通信的步骤包括以下几个方面:(1)定义好通信协议:在多机通信之前,需要定义好通信协议,包括数据的格式、传输方式等。
(2)设置串口参数:在单片机中,需要设置好串口的参数,包括波特率、数据位、停止位等。
(3)发送数据:在发送数据之前,需要将数据按照协议进行格式化,然后通过串口发送出去。
(4)接收数据:在接收数据之前,需要设置好串口的中断,然后在中断中接收数据,并按照协议进行解析。
(5)处理数据:在接收到数据之后,需要对数据进行处理,包括数据的存储、显示等。
4. 多机通信的应用场景有哪些?多机通信的应用场景非常广泛,包括以下几个方面:(1)智能家居系统:通过多机通信,可以实现智能家居系统中不同设备之间的数据共享和协作。
(2)工业控制系统:在工业控制系统中,多机通信可以实现不同设备之间的数据传输和控制。
(3)智能交通系统:在智能交通系统中,多机通信可以实现不同设备之间的数据共享和协作,从而实现更加智能化的交通管理。
(4)机器人控制系统:在机器人控制系统中,多机通信可以实现不同机器人之间的数据传输和控制,从而实现更加复杂的任务。
5. 多机通信的优缺点是什么?多机通信的优点包括以下几个方面:(1)实现数据共享和协作:通过多机通信,可以实现不同设备之间的数据共享和协作,从而实现更加复杂的功能。
(2)提高系统的可靠性:通过多机通信,可以实现数据的备份和冗余,从而提高系统的可靠性。
(3)提高系统的扩展性:通过多机通信,可以实现系统的模块化设计,从而提高系统的扩展性。
基于51单片机的多机通信系统设计多机通信系统是指通过一台主机与多台从机之间进行数据交互和通信的系统。
在本设计中,我们将使用51单片机实现一个基于串行通信的多机通信系统。
系统硬件设计如下:1.主机:使用一个51单片机作为主机,负责发送数据和接收数据。
2.从机:使用多个51单片机作为从机,每个从机负责接收数据和发送数据给主机。
3.串口:主机和从机之间通过串口进行通信。
我们可以使用RS232标准通信协议。
系统软件设计如下:1.主机设计:a.初始化串口:设置串口参数,如波特率、数据位、停止位等。
b.发送数据:将需要发送的数据存储在发送缓冲区中,通过串口发送给从机。
c.接收数据:接收从机发送的数据,并存储在接收缓冲区中。
2.从机设计:a.初始化串口:设置串口参数,如波特率、数据位、停止位等。
b.接收数据:接收主机发送的数据,并存储在接收缓冲区中。
c.发送数据:将需要发送的数据存储在发送缓冲区中,通过串口发送给主机。
系统工作流程如下:1.主机启动,执行初始化操作,包括初始化串口。
2.从机启动,执行初始化操作,包括初始化串口。
3.主机发送数据给从机:主机将需要发送的数据存储在发送缓冲区中,通过串口发送给从机。
4.从机接收并处理数据:从机接收主机发送的数据,并存储在接收缓冲区中,对接收到的数据进行处理。
5.从机发送数据给主机:从机将需要发送的数据存储在发送缓冲区中,通过串口发送给主机。
6.主机接收并处理数据:主机接收从机发送的数据,并存储在接收缓冲区中,对接收到的数据进行处理。
7.主机和从机循环执行步骤3-6,实现多机之间的数据交互和通信。
多机通信系统的设计考虑到以下几个方面:1.硬件设计:需要合理选择单片机和串口的类型和参数,确保系统的稳定性和可靠性。
2.软件设计:需要设计适应系统需求的通信协议和数据处理提取方法,保证数据的准确性和完整性。
3.通信协议:需要定义主机和从机之间的通信协议,包括数据的格式、传输方式等,以便实现正确的数据交互。
51单片机双机通信原理(一)51单片机双机通信简介•什么是51单片机双机通信•双机通信的作用和应用场景基本原理•单片机串口通信原理–串口通讯协议–数据帧的构成•串口通信的硬件连接–引脚连接方式–串口信号格式设置单向通信实现•主从模式–主机发送数据–从机接收数据•编程实现–主机端程序设计–从机端程序设计双向通信实现•主从模式–主机发送数据–从机接收数据–主机接收数据–从机发送数据•编程实现–主机端程序设计–从机端程序设计通信协议的设计•自定义通信协议–协议的格式–数据的解析与封装高级功能扩展•多机通信实现•数据加密与解密•异常处理与误码纠错总结•51单片机双机通信的基本原理和实现方式•可能遇到的问题及解决方案•双机通信的进一步应用展望简介51单片机双机通信是指使用51系列单片机实现两台或多台单片机之间的数据传输和通信。
双机通信可以实现在多个单片机之间传递数据、完成控制指令的下发、数据的采集和处理等功能。
在各种电子设备和嵌入式系统中,双机通信被广泛应用,可以实现设备之间的互联和协同工作,提高系统的灵活性和智能化水平。
基本原理单片机串口通信原理串口通信是一种将数据通过串行线路进行传输的通信方式。
在51单片机的串口通信中,常用的是UART(通用异步收发传输器)通信协议。
UART通信采用的是异步传输方式,数据按照固定的数据帧格式进行传输。
串口通信的硬件连接在51单片机的串口通信中,需要将主机和从机的UART引脚连接起来。
常用的连接方式是通过一对直线的串行数据线(TXD和RXD)连接主从机,其中TXD是发送数据的引脚,RXD是接收数据的引脚。
为了确保数据的正确传输,还需要进行串口信号格式的设置,包括波特率、数据位数、停止位数和校验位等。
单向通信实现主从模式在单向通信中,主机负责发送数据,从机负责接收数据。
主机通过串口发送数据帧,从机通过串口接收数据帧,并进行相应的处理。
编程实现在主机端程序设计中,需要配置串口通信的参数,并使用串口发送数据的相关函数来发送数据。
51单片机多机通信程序(主机部分) /* multi_m.c *//* 多机通信的主机部分*/#ifndef __MULTI_M_C__#define __MULTI_M_C__#include <AT89X51.H>#include <STRING.H>#define __MAX_LEN_ 64 // 数据最大长度#define _MHZ_ 11 // 设置单片机使用的晶振频率(11.0592MHz) /* 以下为程序协议中使用的握手信号*/#define __SUCC_ 0x0f // 数据传送成功#define __ERR_ 0xf0 // 数据传送错误void init_serial(); // 串口初始化void send_data(unsigned char *buf); // 发送数据void delay10ms(unsigned int count); // 延时子程序(10ms) void main(){char buf[__MAX_LEN_];unsigned char i = 0;unsigned char tmp;unsigned char addr; // 该字节用于保存要通信的从机地址/* 为缓冲区赋初值*/P0 = 0xff;while(P1 != 0) // 每隔100ms从P0口读取,若读取到0则表明数据采集结束{*(buf+i) = P0;delay10ms(10); // 延时100msP0 = 0xff;i++;}*(buf+i) = 0; // 缓冲区最后一个字节为0表示数据结束/* 读要访问的分机地址*/P0 = 0xff;addr = P0;/* 串口初始化*/init_serial(); // 初始化串口EA = 0; // 关闭所有中断/* 发送地址帧并接收应答信息,如果接收的信号与发送的地址信息不同,则重新发送地址帧*/tmp = addr-1;while(tmp != addr){/* 发送从机地址*/TB8 = 1; // 发送地址帧SBUF = addr;while(!TI);TI = 0;/* 接收从机应答*/RI = 0;while(!RI);tmp = SBUF;RI = 0;}/* 发送数据并接收校验信息,如果接收的信号为0FH,表示从机接收成功,否则将重新发送该组数据*/tmp = __ERR_;while(tmp != __SUCC_){send_data(buf); // 发送数据RI = 0;while(!RI);tmp = SBUF;RI = 0;}while(1); // 程序结束,进入死循环}/* 初始化串口*/void init_serial(){TMOD = 0x20; //定时器T1使用工作方式2TH1 = 250; // 设置初值TL1 = 250;TR1 = 1; // 开始计时PCON = 0x80; // SMOD = 1SCON = 0xd0; //工作方式3,9位数据位,波特率9600bps,允许接收}/* 发送数据*/void send_data(unsigned char *buf){unsigned char len; // 保存数据长度unsigned char ecc; // 保存校验字节len = strlen(buf); // 计算要发送数据的长度ecc = len; // 开始进行校验字节计算/* 发送数据长度*/TB8 = 0; // 发送数据帧SBUF = len; // 发送长度while(!TI);TI = 0;/* 发送数据*/for(i=0; i<len; i++){ecc = ecc^(*buf); // 计算校验字节TB8 = 0; // 发送数据帧SBUF = *buf; // 发送数据buf++;while(!TI);TI = 0;}/* 发送校验字节*/TB8 = 0; // 发送数据帧SBUF = ecc; // 发送校验字节while(!TI);TI = 0;}/* 延时10ms,精度较低,参数count为延时时间*/ void delay10ms(unsigned int count){unsigned int i, k;unsigned char j;unsigned int tmp;tmp = (int)((100*_MHZ_)/12);for(i=0; i<count; i++)for(j=0; j<100; j++)for(k=0; k<tmp; k++);}#endif51单片机多机通信程序(从机部分)/* multi_s.c *//* 多机通信的从机部分*/#ifndef __MULTI_S_C__#define __MULTI_S_C__#include <AT89X51.H>#include <STRING.H>#define __MAX_LEN_ 64 // 数据最大长度#define _MHZ_ 11 // 设置单片机使用的晶振频率(11.0592MHz)/* 以下为程序协议中使用的握手信号*/#define __SUCC_ 0x0f // 数据传送成功#define __ERR_ 0xf0 // 数据传送错误void init_serial(); // 串口初始化unsigned char recv_data(unsigned char *buf); // 接收数据void Beep_ok(); // 蜂鸣表示数据接收ok,该函数代码未给出void main() {char buf[__MAX_LEN_];unsigned char i = 0;unsigned char tmp = 0xff;unsigned char addr; // 保存本机地址/* 从P1口读取本机地址*/P1 = 0xff;addr = P1;/* 串口初始化*/init_serial(); // 初始化串口EA = 0; // 关闭所有中断/* 进入设备应答阶段*/while(1){SM2 = 1; // 只接收地址帧/* 如果接收到的地址帧不是本机地址,则继续等待*/ tmp = addr-1;while(tmp != addr){RI = 0;while(!RI);tmp = SBUF;RI = 0;}/* 发送应答信号,并做好接收数据的准备*/TI = 0;TB8 = 0; // 主机不检测该位SBUF = addr;while(!TI);TI = 0;SM2 = 0; // 允许接收数据信息/* 数据接收*/tmp = 0xff;while(tmp == 0xff) // 如果数据校验失败则重新接收数据{tmp = recv_data(buf); // 校验失败返回0xff,检测到地址帧则返回0xfe,接收成功则返回0}if(tmp == 0xfe) // 在数据接收过程中,如果发现地址帧,则重新开始整个接收过程continue;Beep_ok(); // 蜂鸣表示数据接收成功}}/* 初始化串口*/void init_serial(){TMOD = 0x20; //定时器T1使用工作方式2TH1 = 250; // 设置初值TL1 = 250;TR1 = 1; // 开始计时PCON = 0x80; // SMOD = 1SCON = 0xd0; //工作方式3,9位数据位,波特率9600bps,允许接收}/* 接收数据,注意该函数使用buf指向的缓冲区保存数据,在数据末尾使用’\0’表示数据结束* 返回值为0,数据校验成功,返回值为0xfe,接受过程中接收到地址帧,返回值为0xff,数据校验失败*/unsigned char recv_data(unsigned char *buf){unsigned char len; // 该字节用于保存数据长度unsigned char ecc; // 该字节用于保存校验字节unsigned char i,tmp;/* 接收数据长度*/RI = 0;while(!RI);if(RB8 == 1) // 若当前接收为地址帧则返回0xfereturn 0xfe;len = SBUF;RI = 0;/* 使用len的值为校验字节ecc赋初值*/ecc = len;/* 接收数据*/for(i=0; i<len; i++){while(!RI);if(RB8 == 1) // 若当前接收为地址帧则返回0xfe return 0xfe; *buf = SBUF; // 接收数据ecc = ecc^(*buf); // 进行字节校验RI = 0;buf++;}*buf = 0; // 表示数据结束/* 接收校验字节*/while(!RI);if(RB8 == 1) // 若当前接收为地址帧则返回0xfe return 0xfe; tmp = SBUF;RI = 0;/* 进行数据校验*/ecc = tmp^ecc;if(ecc != 0) // 校验失败{*(buf-len) = 0; // 清空数据缓冲区TI = 0; // 发送校验失败信号TB8 = 0;SBUF = __ERR_;while(!TI);TI = 0;return 0xff; // 返回0xff表示校验错误} TI = 0; // 校验成功TB8 = 0;SBUF = __SUCC_;while(!TI);TI = 0;return 0; // 校验成功,返回0}#endif。
51单片机的2个串口资源分别通信的方法当使用51单片机的2个串口资源进行通信时,比如用一个串口与PLC的串口使用RS485协议通信,一个串口通过蓝牙模块和另一个单片机无线通信时,该如何处理呢?传统的51单片机只有1个串口资源,只能采用分时复用的方法。
STC的15系列增强版51单片机具有多个串口资源,本文将描述如何使用IAP15W4K58S单片机用一个串口资源与PLC的RS485有线通信,另一个串口资源与Arduino单片机通过蓝牙模块无线通信,该通讯连接过程中PLC作为主机,IAP15W4K58S作为中间机,Arduino单片机作为最低层级。
工作过程是按下启动按键,PLC发信息给IAP15W4K58S单片机发高速脉冲控制步进电机驱动的机械臂运动取走货物,当货物取走后,IAP15W4K58S单片机通过蓝牙模块通知Arduino单片机控制的小车将新货物运送过来。
连接结构示意图如下图所示。
本例程使用的单片机型号为:IAP15W4K58S,该单片机有4个采用UART 工作方式的全双工异步串行通信接口(分别为串口1、串口2、串口3和串口4),每个串行口由2个数据缓冲器、1个移位寄存器、1个串行控制寄存器和1个波特率发生器等组成。
本项目使用串行口1和串行口2。
串行口1的两个缓冲器共用寄存器SBUF (99H),串行口2的两个缓冲器共用寄存器S2BUF(9BH)。
10位(1起始位,8位数据位,1停止位)可变波特率(9600)。
串口1对应的硬件部分是TxD和RxD,串行口2对应硬件部分是TxD2和RxD2。
串口1选择引脚P3.0(RxD)和P3.1(TxD),串口2选择引脚P1.0(RxD)和P1.1(TxD)。
串口1既可以选择T1作为波特率发生器,也可以选择T2作为波特率发生器。
本文串口1提供2个选择(T1和T2),串口2只能选择T2作波特率发生器。
但是当串口1和串口2的波特率相同时,可以共用T2作为波特率发器,当T2工作在1T模式时,串行口1的波特率=SYSclk/(65536-[RL_TH2,RL_TL2])/4,SYSclk表示系统时钟频率,[RL_TH2,RL_TL2]表示T2H,T2L的定时初值设置值。
51单片机的串口双机通讯一、什么是串口串口是串行发送数据的接口,是相对于并口来说的,是一个广泛的定义。
本期我们说的串口指的是指UART或是RS232。
二、什么是波特率波特率是指串行端口每秒内可以传输的波特位数。
这里所指的波特率,如标准9600不是每秒种可以传送9600个字节,而是指每秒可以传送9600个二进位。
一个字节需要8个二进位,如用串口模式1来传输,那么加上起始位和停止位,每个数据字节就要占用10个二进位。
9600bps用模式1传输时,每秒传输的字节数是9600÷10=960个字节,发送一个字节大概需要1ms时间。
三、51单片机串口相关寄存器1、SCON串口控制寄存器(1)SM0和SM1:方式选择寄存器SM0 SM1 工作方式功能波特率0 0 方式0 8位同步移位寄存器晶振频率/ 120 1 方式1 10位UART 可变1 0 方式2 11位UART 晶振频率/32或晶振频率/64 1 1 方式3 11位UART 可变多机通信是工作在方式2和方式3的,所以SM2主要用于方式2和方式3,多级通信时,SM2=1,当SM2=1时,只有当接收到的数据帧第9位(RB8)为1时,单片机才把前八位数据放入自己的SBUF中,否则,将丢弃数据帧。
当SM2=0时,不论RB8的值是什么,都会把串口收到的数据放到SBUF中。
(3)REN:允许接收位REN用于控制是否允许接收数据,REN=1时,允许接收数据,REN=0时,拒绝接收数据。
(4)TB8:要发送的第9位数据位在方式2和方式3中,TB8是要作为数据帧第9位被发送出去的,在多机通信中,可用于判断当前数据帧的数据是地址还是数据,TB8=0为数据,TB8=1为地址。
(5)RB8:接收到的第9位数据位当单片机已经接收一帧数据帧时,会把数据帧中的第9位放到RB8中。
方式0不使用RB8,在方式2和方式3中,RB8为接收到的数据帧的第9位数据位。
(6)TI:发送中断标志位方式0中,不用管他。
51单片机多机通信过程51单片机具有多机通信的功能,可实现一台主机于多台从机的通信。
多机通信充分利用了单片机内部的多机通信控制位SM2。
当从机SM2,1时,从机只接收主机发出的地址帧(第九位为1),对数据帧(第九位为0)不予理睬;而当SM2=0时,可接收主机发送过来的所有信息。
多机通信的过程如下:(1)所有从机SM2均置1,处于只接收地址帧状态。
(2)主机先发送一个地址帧,其中前8位数据表示地址,第9位为1表示该帧为地址帧。
(3)所有从机接收到地址帧后,进行中断处理,把接收到的地址与自身地址相比较。
地址相符时将SM2清成0,脱离多机状态,地址不相符的从机不作任何处理,即保持SM2,1。
(4)地址相符的从机SM2=0,可以接收到主机随后发来的信息,即主机发送的所有信息。
收到信息TB8=0,则表示是数据帧,而对于地址不符的从机SM2=1,收到信息TB8=0,则不予理睬,这样就实现了主机与地址相符的从机之间的双机通信。
(5)被寻址的从机通信结束后置SM2=1,恢复多机通信系统原有的状态。
主机:设置为SM2=0。
这是双机通信的形式,可以任意的发送和接收发送:以TB8=1发送,将发送到所有SM2=1的分机。
这是呼叫某个从机。
以TB8=0发送,将发送到SM2=0的分机。
这是双机通信的形式。
------从机:先设置为SM2=1。
这是多机通信的形式,只能收到RB8=1的。
接收:仅能收到RB8=1的数据,确认是呼叫本机时,令SM2=0。
设置为SM2=0后,是双机通信的形式。
追问那从机的RB8要怎么设,是需要软件设置还是单片机自己识别,在编程的时候要怎么写, 回答从机的RB8,不需要编程。
从机的RB8,是接收到的,它是主机发送出来的TB8。
想要对TB8进行控制,需要在主机中编程。
单片机多机通讯说明:该程序为多机通讯程序,最多可以挂255个从机。
该程序主机发送端与多个从机的接收端相接,主机的接收端与多个从机的发送端相接。
• 178•串口是单片机与其他单片机或计算机系统进行异步串行通信的标准I/O 接口,在系统设计中应用非常广泛。
以教学中使用的CPU 字长是8位的51单片机为例,实现双机间多数据串行传输,在多数据发送时为每个数据增加特征值,接收的时候通过特征值判断接收的数据,此方法最多可以实现双机间16个数据的传送,适用于5-8个通道的数据采集系统。
将此设计思想应用在0-999s 的秒表系统设计中,系统运行稳定,实现预期效果。
单片机串口是异步串行通信,发送方发送数据并不考虑接收方什么时候接收,如果是传送1个数据比较好处理,串口无论工作在查询方式下还是中断方式下,接收方的CPU 只要检测RI =1,就可以接收数据。
如果发送方发送的是多个数据,接收方接收的是发送方发送的多个数据的哪一个?发送方发送的多个数据是动态变化的,尽管发送方发送多个数据的顺序在编程中是固定不变的,但是串口通信是异步的,接收方接收时,无法知道此次接收的数据是发送方发送的哪一个数据,所以接收方必须有能力判断接收到的是哪一个数据才能真正实现异步串行通信多数据的正确传送。
1 发送数据的加密原理及编程实现要想让接收方有能力判断接收的数据是哪一个数据,可以对要发送的数据做加密处理,数据加密技术是网络中最基本的安全技术,主要是通过对网络中传输的信息进行数据加密来保障其安全性。
本设计借用数据加密的思想,对要发送的数据采用增加特征值的加密处理方法,乙机接收数据后,通过解密获取特征值,就可以知道接收的是哪一个数据了。
特征值的选取要视发送数据的范围,本文以发送压缩BCD 码说明数据加密的原理及编程实现。
1.1 发送数据的加密原理压缩BCD 码是用4位二进制表示1位十进制,由于设计中使用的单片机CPU 的字长是8位的,所以一次可以处理1个字节数据,用字节表示1位BCD 码的时候,高4位一定是“0”,低4位是”0-9”中的1个数字,这样用高4位的“0”就可以实现对数据加密处理。
串口屏(触摸屏)组态软件+多台51单片机MODBUS RTU多机串口通信程序源码串口屏(触摸屏)组态软件+多台51单片机MODBUS RTU多机串口通信程序源码实现触摸屏(串口屏)与单片机的通讯,主要是解决通讯协议的问题。
本文使用开放的Modbus通讯协议,以广州易显的HMImaker触摸屏作主机(Master),单片机作从机(Slaver)。
HMImaker触摸屏本身支持Modbus通讯协议,只要单片机按照Modbus 协议进行收发数据,就可以进行通信了。
触摸屏与单片机之间采用RS-485标准接口直接连接,与多台51单片机MODBUS RTU多机串口通信一、包括如下实例:二、串口屏(触摸屏)组态软件HMImaker实现功能:01、对4台51单片机4路数字量输入实现读操作,通过MODBUS RTU的02功能码实现; 02、对4台51单片机4路继电器输出实现读操作,通过MODBUS RTU的01功能码实现; 03、对4台51单片机4路模拟量输入实现读操作,通过MODBUS RTU的04功能码实现; 04、对4台51单片机4路模拟量输出实现读操作,通过MODBUS RTU的03功能码实现; 05、对4台51单片机4路继电器输出实现写操作,通过MODBUS RTU的05功能码实现; 06、对4台51单片机4路模拟量输出实现写操作,通过MODBUS RTU的06功能码实现; 07、组态工程以串口屏(触摸屏)组态软件HMImaker为例,如下所示:三、单片机从站支持的MODBUS RTU功能码:01、功能码01:此功能可对单片机4路(甚至更多,可扩展)数字量输出多路进行读操作; 02、功能码02:此功能可对单片机4路(甚至更多,可扩展)数字量输入多路进行读操作; 03、功能码03:此功能可对单片机4路(甚至更多,可扩展)模拟量输出多路进行读操作; 04、功能码04:此功能可对单片机4路(甚至更多,可扩展)模拟量输入多路进行读操作; 05、功能码05:此功能可对单片机4路(甚至更多,可扩展)数字量输出一路进行写操作; 06、功能码06:此功能可对单片机4路(甚至更多,可扩展)模拟量输出一路进行写操作; 07、功能码15:此功能可对单片机4路(甚至更多,可扩展)数字量输出多路进行写操作; 08、功能码16:此功能可对单片机4路(甚至更多,可扩展)模拟量输出多路进行写操作。
8. 结构实例6:单片机串口通信虽然那个流水灯游戏的可玩性和按键手感问题还值得再好好提升一下,但小月更希望调剂一下,转而开始了对手头烧写板上关于RS-232转换部分的学习。
小月的做法并不难以理解,毕竟与RS-232转换的相关电路在原理图中还是相当显眼的,甚至于他手头编程器的别名就是RS-232转换器。
图8.1 单片机中负责RS-232通讯的电路在烧写器一端与电脑连接的两个接头中,9针的RS-232接口就是串口通信线,而另一个USB口仅接通了+5V和GND,只有给烧写器供电的作用。
这样就可以知道,电脑可以通过RS-232对单片机的内部程序进行改写。
那么,这就意味着单片机与电脑间必然可以进行数据的交换,这种交换,就叫做通信。
所谓串口通信,就是指这种基于RS-232串口的通信方式。
RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准。
最早是为使电脑通过电话线系统相互通信的调制解调器上而是设计的。
后来发展到连接鼠标或打印机上,目前已经被支持设备的即插即用和热插拔功能的USB所替代,但仍广泛的用于工业仪器仪表中,同时也是单片机最基础和最常见的通信方式。
不过要把“最基础和最常见”这两个最拆开来说,就要在后面加上“之一”了。
虽然目前的通信技术日新月异,但这种说法在今后很长一段时期内都是成立的,也正因为这样的特点,STC的51系列单片机都是默认通过RS-232方式进行烧写的。
作为两台设备之间进行的通信,必然需要共同遵守某种规定或规则,包括交流什么、怎样交流及何时交流。
这个规则就是通信协议。
RS-232通信中通信协议的原则就是串口按位(bit)发送和接收数据。
线路上,RS-232通信使用3根线完成,分别是地线、发送、接收。
端口能够在一根线上发送数据的同时在另一根线上接收数据,即全双工传输。
全双工传输是传输制式的一种分类方式中的一类,除此还有单工传输和半双工传输。
单工传输,是指消息只能单方向传输的工作方式。
51 单片机串口多机通信的实现和编程
一、51 单片机的主从模式,首先要设定工作方式3:(主从模式+波特率可变)
SCON 串口功能寄存器:SM0=1;SM1=1(工作方式3)
注:主机和从机都要为工作方式3。
【工作方式2 (SM0 SM1 :1 0):串行口为11 位异步通信接口。
发送或接收
一帧信息包括1 位起始位0、8 位数据位、1 位可编程位、1 位停止位1。
发
送数据:发送前,先根据通信协议由软件设置TB8 为奇偶校验位或数据标识位,然后将要发送的数据写入SBUF,即能启动发送器。
发送过程是由执行任何一条以SBUF 为目的寄存器的指令而启动的,把8 位数据装入SBUF,
同时还把TB8 装到发送移位寄存器的第9 位上,然后从TXD(P3.1)端口输出
一帧数据。
接收数据:先置REN=1,使串行口为允许接收状态,同时还要将RI 清0。
然后再根据SM2 的状态和所接收到的RB8 的状态决定此串行口在
信息到来后是否置R1=1,并申请中断,通知CPU 接收数据。
当SM2=0 时,
不管RB8 为0 还是为1,都置RI=1,此串行口将接收发送来的信息。
当
SM2=1 时,且RB8=1,表示在多机通信情况下,接收的信息为地址帧, 此时
置RI=1,串行口将接收发来的地址。
当SM2=1 时,且RB8=0,表示在多机通
信情况下,接收的信息为数据帧, 但不是发给本从机的,此时RI 不置为1,。