51串口通信协议(新型篇)

合集下载

51串口协议的完整实现

51串口协议的完整实现
unsignedchar datlen;
unsignedchar dat[INBUF_LEN];
}cmdbuf,*pcmdbuf;
extern void init_serialcomm();
extern void send_char_com(unsigned charch);
extern void send_string_com(unsigned char*str,unsigned char strlen);
#endif
51单片机串口通信协议完整实现
51单片机编程经常使用到串口通信。在网上找了很久一直找不到完整的协议实现源码,分享一个我整理的51串口通信协议,方便以后能找到,也分享给有同样需要的人。
手机玩佳经营手机贴膜、手机保护套、手机移动电源、太阳能手机移动电源、手机配件,全店特价销售。
IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; // timer 1 run
}
//向串口发送一个字符
void send_char_com(unsigned char ch)
#define BAUD38400 6
#define BAUD57600 7
#define BAUD115200 8
typedef struct CMD_BUF
{
unsignedchar sync;
unsignedchar cmd;
{
unsignedchar ch;
staticunsigned char count3 = 0; //接收字节计数
if(RI)
{
Байду номын сангаас RI= 0; //RI清零

51单片机串口通信

51单片机串口通信

51单片机串口通信51单片机串口通信(转载)2009-03-03 18:22一、串口通信原理串口通讯对单片机而言意义重大,不但可以实现将单片机的数据传输到计算机端,而且也能实现计算机对单片机的控制。

由于其所需电缆线少,接线简单,所以在较远距离传输中,得到了广泛的运用。

串口通信的工作原理请同学们参看教科书。

以下对串口通信中一些需要同学们注意的地方作一点说明:1、波特率选择波特率(Boud Rate)就是在串口通信中每秒能够发送的位数(bits/second)。

MSC- 51串行端口在四种工作模式下有不同的波特率计算方法。

其中,模式0和模式2波特率计算很简单,请同学们参看教科书;模式1和模式3的波特率选择相同,故在此仅以工作模式1为例来说明串口通信波特率的选择。

在串行端口工作于模式1,其波特率将由计时/计数器1来产生,通常设置定时器工作于模式2(自动再加模式)。

在此模式下波特率计算公式为:波特率=(1+SMOD)*晶振频率/(384*(256-TH1))其中,SMOD——寄存器PCON的第7位,称为波特率倍增位;TH1——定时器的重载值。

在选择波特率的时候需要考虑两点:首先,系统需要的通信速率。

这要根据系统的运作特点,确定通信的频率范围。

然后考虑通信时钟误差。

使用同一晶振频率在选择不同的通信速率时通信时钟误差会有很大差别。

为了通信的稳定,我们应该尽量选择时钟误差最小的频率进行通信。

下面举例说明波特率选择过程:假设系统要求的通信频率在20000bit/s以下,晶振频率为12MHz,设置SMOD=1(即波特率倍增)。

则TH1=256-62500/波特率根据波特率取值表,我们知道可以选取的波特率有:1200,2400,4800,9600,19200。

列计数器重载值,通信误差如下表:因此,在通信中,最好选用波特率为1200,2400,4800中的一个。

2、通信协议的使用通信协议是通信设备在通信前的约定。

单片机、计算机有了协议这种约定,通信双方才能明白对方的意图,以进行下一步动作。

51单片机串口通信(相关例程)

51单片机串口通信(相关例程)

51单片机串口通信(相关例程) 51单片机串口通信(相关例程)一、简介51单片机是一种常用的微控制器,它具有体积小、功耗低、易于编程等特点,被广泛应用于各种电子设备和嵌入式系统中。

串口通信是51单片机的常见应用之一,通过串口通信,可以使单片机与其他外部设备进行数据交互和通信。

本文将介绍51单片机串口通信的相关例程,并提供一些实用的编程代码。

二、串口通信基础知识1. 串口通信原理串口通信是通过串行数据传输的方式,在数据传输过程中,将信息分为一个个字节进行传输。

在51单片机中,常用的串口通信标准包括RS232、RS485等。

其中,RS232是一种常用的串口标准,具有常见的DB-9或DB-25连接器。

2. 串口通信参数在进行串口通信时,需要设置一些参数,如波特率、数据位、停止位和校验位等。

波特率表示在单位时间内传输的比特数,常见的波特率有9600、115200等。

数据位表示每个数据字节中的位数,一般为8位。

停止位表示停止数据传输的时间,常用的停止位有1位和2位。

校验位用于数据传输的错误检测和纠正。

三、串口通信例程介绍下面是几个常见的51单片机串口通信的例程,提供给读者参考和学习:1. 串口发送数据```C#include <reg51.h>void UART_Init(){TMOD = 0x20; // 设置计数器1为工作方式2(8位自动重装) TH1 = 0xFD; // 设置波特率为9600SCON = 0x50; // 设置串口工作方式1,允许串行接收TR1 = 1; // 启动计数器1}void UART_SendChar(unsigned char dat){SBUF = dat; // 发送数据while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志}void main(){UART_Init(); // 初始化串口while (1){UART_SendChar('A'); // 发送字母A}}```2. 串口接收数据```C#include <reg51.h>void UART_Init(){TMOD = 0x20; // 设置计数器1为工作方式2(8位自动重装) TH1 = 0xFD; // 设置波特率为9600SCON = 0x50; // 设置串口工作方式1,允许串行接收TR1 = 1; // 启动计数器1}void UART_Recv(){unsigned char dat;if (RI) // 检测是否接收到数据{dat = SBUF; // 读取接收到的数据 RI = 0; // 清除接收中断标志// 处理接收到的数据}}void main(){UART_Init(); // 初始化串口EA = 1; // 允许中断ES = 1; // 允许串口中断while (1)// 主循环处理其他任务}}```3. 串口发送字符串```C#include <reg51.h>void UART_Init(){TMOD = 0x20; // 设置计数器1为工作方式2(8位自动重装) TH1 = 0xFD; // 设置波特率为9600SCON = 0x50; // 设置串口工作方式1,允许串行接收TR1 = 1; // 启动计数器1}void UART_SendString(unsigned char *str){while (*str != '\0')SBUF = *str; // 逐个发送字符while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志str++; // 指针指向下一个字符}}void main(){UART_Init(); // 初始化串口while (1){UART_SendString("Hello, World!"); // 发送字符串}}```四、总结本文介绍了51单片机串口通信的基础知识和相关编程例程,包括串口发送数据、串口接收数据和串口发送字符串。

fc51通讯协议数据位

fc51通讯协议数据位

fc51通讯协议数据位FC51通讯协议数据位FC51通讯协议是一种常用于工业自动化领域的通信协议,用于实现PLC(可编程逻辑控制器)与外部设备之间的数据交互。

在FC51通讯协议中,数据位是其中一个重要的概念。

数据位是指在通信数据中用来传输信息的最小单位。

在FC51通讯协议中,数据位通常是一个二进制数,用来表示某种特定的状态或值。

根据数据位的不同,可以实现对设备的控制、监测和数据传输等功能。

在FC51通讯协议中,数据位的取值范围通常为0或1,分别表示不同的状态。

例如,当数据位为0时,可以表示设备关闭或停止;当数据位为1时,可以表示设备打开或运行。

通过对不同数据位的组合与解读,可以实现复杂的控制和监测功能。

在使用FC51通讯协议进行数据传输时,需要注意以下几点:1. 数据位的顺序:在通讯协议中,数据位的顺序一般按照从低位到高位的顺序排列。

这样可以确保数据的传输和解读的准确性。

2. 数据位的编码:在FC51通讯协议中,数据位的编码方式有多种,可以根据具体的需求选择合适的编码方式。

常用的编码方式有二进制编码、BCD编码等。

3. 数据位的检验:为了确保数据传输的准确性,通常会在数据位中添加校验位。

校验位可以通过特定的算法计算得出,用于检测数据是否传输错误。

常用的校验算法有奇偶校验、循环冗余校验等。

4. 数据位的长度:在FC51通讯协议中,数据位的长度通常是固定的,根据具体的应用需求确定。

长度过长或过短都可能导致数据传输的错误或不完整。

FC51通讯协议中的数据位在工业自动化领域起到了至关重要的作用。

通过对数据位的灵活应用,可以实现对设备的精确控制和监测。

例如,可以通过数据位的组合来实现对温度、湿度、压力等参数的实时监测和报警;可以通过数据位的状态来控制设备的开关、速度和方向等。

在使用FC51通讯协议进行数据传输时,需要确保数据位的准确性和稳定性。

可以通过合理的设计和配置,选择合适的数据位长度、编码方式和校验算法,来确保数据的可靠传输和解读。

串口通讯协议书范本

串口通讯协议书范本

串口通讯协议书范本甲方(提供方):_________________________乙方(使用方):_________________________鉴于甲方拥有串口通讯技术,乙方有使用该技术的需求,双方本着平等互利的原则,经协商一致,就串口通讯技术的使用达成如下协议:第一条定义1.1 串口通讯:指通过串行接口进行数据传输的一种通讯方式。

1.2 数据格式:指在串口通讯中,数据的组织和编码方式。

1.3 通讯速率:指串口通讯中数据传输的速度。

1.4 通讯协议:指双方约定的串口通讯规则和标准。

第二条协议内容2.1 甲方同意向乙方提供符合本协议规定的串口通讯技术。

2.2 乙方同意按照本协议的规定使用甲方提供的串口通讯技术。

第三条通讯参数3.1 数据格式:采用_________标准。

3.2 通讯速率:_________ Baud。

3.3 校验方式:_________。

3.4 停止位:_________。

3.5 通讯协议:_________。

第四条权利与义务4.1 甲方应保证提供的串口通讯技术符合本协议规定的标准。

4.2 乙方应按照本协议规定的参数进行通讯,并保证通讯的合法性和安全性。

4.3 双方应共同维护通讯的稳定性和安全性,不得擅自更改通讯参数。

第五条保密条款5.1 双方应对在本协议履行过程中获知的对方的商业秘密和技术秘密负有保密义务。

5.2 保密期限为协议终止后_________年。

第六条违约责任6.1 如一方违反本协议规定,应承担违约责任,并赔偿对方因此遭受的损失。

第七条协议的变更和解除7.1 本协议的任何变更和补充均需双方书面同意。

7.2 如一方要求解除本协议,应提前_________天书面通知对方。

第八条争议解决8.1 双方因履行本协议所发生的任何争议,应通过友好协商解决。

8.2 如协商不成,任何一方均可向甲方所在地人民法院提起诉讼。

第九条其他9.1 本协议自双方签字盖章之日起生效。

9.2 本协议一式两份,甲乙双方各执一份,具有同等法律效力。

51单片机--串口通信

51单片机--串口通信

51单⽚机--串⼝通信基本介绍串⼝是⼀种应⽤⼗分⼴泛的通讯接⼝,串⼝成本低、容易使⽤、通信线路简单,可实现两个设备的互相通信。

单⽚机的串⼝可以使单⽚机与单⽚机、单⽚机与电脑、单⽚机与各式各样的模块互相通信,极⼤的扩展了单⽚机的应⽤范围,增强了单⽚机系统的硬件实⼒。

51单⽚机内部⾃带UART(Universal Asynchronous Receiver Transmitter,通⽤异步收发器),可实现单⽚机的串⼝通信。

基本接线简单双向串⼝通信有两根通信线(发送端TXD和接收端RXD)TXD与RXD要交叉连接当只需单向的数据传输时,可以直接⼀根通信线当电平标准不⼀致时,需要加电平转换芯⽚电平标准电平标准是数据1和数据0的表达⽅式,是传输线缆中⼈为规定的电压与数据的对应关系,串⼝常⽤的电平标准有如下三种:TTL电平:+5V表⽰1,0V表⽰0RS232电平:-3-15V表⽰1,+3+15V表⽰0RS485电平:两线压差+2+6V表⽰1,-2-6V表⽰0(差分信号)常见通信接⼝⽐较名称引脚定义通信⽅式特点UART TXD、RXD全双⼯、异步点对点通信I²C SCL、SDA半双⼯、同步可挂载多个设备SPI SCLK、MOSI、MISO、CS全双⼯、同步可挂载多个设备1-Wire DQ半双⼯、异步可挂载多个设备51单⽚机的UARTSTC89C52有1个UARTSTC89C52的UART有四种⼯作模式:模式0:同步移位寄存器模式1:8位UART,波特率可变(常⽤)模式2:9位UART,波特率固定模式3:9位UART,波特率可变串⼝模式图SBUF:串⼝数据缓存寄存器,物理上是两个独⽴的寄存器,但占⽤相同的地址。

写操作时,写⼊的是发送寄存器,读操作时,读出的是接收寄存器串⼝和中断系统串⼝相关寄存器SCON配置SCON:串⾏控制寄存器,可位寻址,⽤于选择串⾏通信的⼯作⽅式和某些控制功能。

SM0,SM1按下列组合确定串⾏⼝的⼯作⽅式:我们⼀般选择⽅式1,所以SM0=0,SM1=1.REN:1则启动串⾏接收器RXD,开始接收信息,0为禁⽌接收,我们先设置为1。

51单片机串口通信原理

51单片机串口通信原理

51单片机串口通信原理详解1. 引言串口(Serial Port)是一种常用于计算机与外部设备之间进行数据传输的接口,它是一种逐位传输的方式。

51单片机是一种非常常用的单片机,串口通信是其重要的通信方式之一。

本文将详细解释51单片机串口通信的基本原理,包括串口通信的定义、硬件连接示意图、通信协议、数据传输过程以及数据接收处理等方面的内容。

2. 串口通信定义串口通信是一种通过串行通路进行数据传输的通信方式。

它是一种点对点的通信协议,即通信的两端通过共享数据线进行数据交换。

3. 硬件连接示意图完成串口通信,需要将单片机与外部设备进行连接。

下图是一个常见的串口通信连接示意图:___| |TXD <-|---|---> RXD| |RXD <-|---|---> TXD|___|单片机外部设备通常,单片机的TXD引脚连接到外部设备的RXD引脚,而单片机的RXD引脚连接到外部设备的TXD引脚。

4. 串口通信协议串口通信需要明确一种通信协议,以规定数据的传输格式和相关参数。

在51单片机中,常用的串口通信协议有UART(Universal Asynchronous ReceiverTransmitter)和USART(Universal Synchronous Asynchronous Receiver Transmitter)。

UART是指不使用时钟信号而直接利用起始位、数据位和停止位来传输数据的协议,属于异步通信。

USART是指同步和异步传输都能实现的通信协议。

5. 数据传输过程串口通信的数据传输过程可以分为发送和接收两个部分。

5.1 发送数据发送数据的步骤如下:1.配置串口通信参数,包括波特率、数据位、停止位和校验位等。

2.将要发送的数据存放在发送缓冲区中。

3.设置发送开始标志位。

4.如果发送缓冲区为空,则等待直到缓冲区不为空。

5.将发送缓冲区中的数据通过串口发送出去。

6.等待发送完成。

51单片机串口通信(相关例程)

51单片机串口通信(相关例程)

51单片机串口通信1./*打开串口调试程序,将波特率设置为9600,无奇偶校验晶振11.0592MHz,发送和接收使用的格式相同,如都使用字符型格式,在发送框输入hello,I Love MCU ,在接收框中同样可以看到相同字符,说明设置和通信正确*/#include <REG52.H>/*主程序*/void main (void){SCON = 0x50; /* SCON: 模式1, 8-bit UART, 使能接收*/TMOD |= 0x20; /* TMOD: timer 1, mode 2,8-bit reload*/TH1 = 0xFD; /* TH1: **********************************/ TR1 = 1; /* TR1: timer 1 run */EA = 1; /*打开总中断*/ES = 1; /*打开串口中断*/while (1) /*主循环不做任何动作*/{}}void UART_SER (void) interrupt 4 //串行中断服务程序{unsigned char Temp; //定义临时变量if(RI) //判断是接收中断产生{RI=0; //标志位清零Temp=SBUF; //读入缓冲区的值P1=Temp; //把值输出到P1口,用于观察SBUF=Temp; //把接收到的值再发回电脑端}if(TI) //如果是发送标志位,清零TI=0;}2.51单片机与电脑串口通信的C程序,最好是中断方式的#include <reg51.h>#include <string.h>unsigned char ch;bit read_flag= 0 ;void init_serialcom( void ) //串口通信初始设定{SCON = 0x50 ; //UART为模式1,8位数据,允许接收TMOD |= 0x20 ; //定时器1为模式2,8位自动重装PCON |= 0x80 ; //SMOD=1;TH1 = 0xFD ; //Baud:19200 fosc="11".0592MHzIE |= 0x90 ; //Enable Serial InterruptTR1 = 1 ; // timer 1 run}//向串口发送一个字符void send_char_com( unsigned char ch){SBUF=ch;while (TI== 0);TI= 0 ;}void serial () interrupt 4 using 3 //串口接收中断函数{if (RI){RI = 0 ;ch=SBUF;read_flag= 1 ; //就置位取数标志}}main(){init_serialcom(); //初始化串口while ( 1 ){if (read_flag) //如果取数标志已置位,就将读到的数从串口发出{read_flag= 0 ; //取数标志清0send_char_com(ch);}}}3.// 单片机串行口发送/接收程序,每接收到字节即发送出去// 和微机相接后键入的字符回显示在屏幕上// 可用此程序测试#include <reg51.h>#define XTAL 11059200 // CUP 晶振频率#define baudrate 9600 // 通信波特率void main(void){unsigned char c;TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate))); // 定时器0赋初值SCON = 0x50;PCON = 0x00;TR1 = 1;IE = 0x00; // 禁止任何中断{while(RI == 0);RI = 0;c = SBUF; // 从缓冲区中把接收的字符放入c中SBUF = c; // 要发送的字符放入缓冲区while(TI == 0);TI = 0;}}4.//////////////// ///////////////////////////////////////////////////////////E51Pro.c//Easy 51Pro编程器主程序,负责通讯,管理编程操作/////////////////////////////////////////////////////////////////////////#include <E51Pro.h>BYTE ComBuf[18];//串口通讯数据缓存,发送和接收都使用UINT nAddress;//ROM中地址计数UINT nTimeOut;//超时计数ProWork pw;//编程器一般操作void Delay_us(BYTE nUs)//微秒级延时<255us{TH0=0;TL0=0;TR0=1;while(TL0<nUs)//利用T0做定时计数器,循环采样,直到达到定时值{}TR0=0;}void Delay_ms(UINT nMs)//豪秒级的延时<65535ms{UINT n=0;TR0=1;while(n<nMs)////利用T0做定时计数器,循环采样,直到达到定时值{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}BOOL WaitComm()//等待上位机的命令,18字节{RI=0;while(!RI){}//等待第一个字节ComBuf[n]=SBUF;RI=0;n++;for(n;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000)//后17个字节都有超时限制return 0;}ComBuf[n]=SBUF;RI=0;}return 1;}BOOL WaitResp()//等待上位机回应,1字节,有超时限制{nTimeOut=0;RI=0;while(!RI){nTimeOut++;if(nTimeOut>50000){return 0;}}RI=0;ComBuf[0]=SBUF;return 1;}BOOL WaitData()//写器件时等待上位机数据,18字节,有超时限制{BYTE n;RI=0;for(n=0;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000){return 0;}}RI=0;ComBuf[n]=SBUF;}return 1;}void SendData()//发送数据或回应操作完成,18字节{BYTE n=0;for(n;n<=17;n++){TI=0;SBUF=ComBuf[n];while(!TI){}TI=0;}}void SendResp()//回应上位机1个字节,在写器件函数中使用{TI=0;SBUF=ComBuf[0];while(!TI){}TI=0;}void SetVpp5V()//设置Vpp为5v{P3_4=0;P3_3=0;}void SetVpp0V()//设置Vpp为0v{P3_3=0;P3_4=1;}void SetVpp12V()//设置Vpp为12v{P3_4=0;P3_3=1;}void RstPro()//编程器复位{pw.fpProOver();//直接编程结束SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同}void ReadSign()//读特征字{pw.fpReadSign();SendData();//通知上位机,送出读出器件特征字}void Erase()//擦除器件{pw.fpErase();SendData();//通知上位机,擦除了器件}void Write()//写器件{BYTE n;pw.fpInitPro();//编程前的准备工作SendData();//回应上位机表示进入写器件状态,可以发来数据while(1){if(WaitData())//如果等待数据成功{if(ComBuf[0]==0x07)//判断是否继续写{for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块{if(!pw.fpWrite(ComBuf[n]))//<<< <<<<<<调用写该器件一个单元的函数{pw.fpProOver();//出错了就结束编程ComBuf[0]=0xff;SendResp();//回应上位机一个字节,表示写数据出错了WaitData();//等待上位机的回应后就结束return;}nAddress++;//下一个单元}ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续SendResp();}else if(ComBuf[0]==0x00)//写器件结束break;else//可能是通讯出错了{pw.fpProOver();return;}}else//等待数据失败{pw.fpProOver();return;}}pw.fpProOver();//编程结束后的工作Delay_ms(50);//延时等待上位机写线程结束ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}void Read()//读器件{BYTE n;pw.fpInitPro();//先设置成编程状态SendData();//回应上位机表示进入读状态while(1){if(WaitResp())//等待上位机回应1个字节{if(ComBuf[0]==0)//ComBuf[0]==0表示读结束{break;}else if(ComBuf[0]==0xff)//0xff表示重发{nAddress=nAddress-0x0010;}for(n=2;n<=17;n++)//ComBuf[2~17]保存读出的数据块{ComBuf[n]=pw.fpRead();//<<<<<<<<<<调用写该器件一个单元的函数nAddress++;//下一个单元}ComBuf[0]=6;//向上位机发送读出的数据块SendData();}elsebreak;//等待回应失败}pw.fpProOver();//操作结束设置为运行状态ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}void Lock()//写锁定位{pw.fpLock();SendData();}///////////////////////////////////////////////////////////////////////////////////所支持的FID,请在这里继续添加/////////////////////////////////////////////////////////////////////////////extern void PreparePro00();//FID=00:AT89C51编程器extern void PreparePro01();//FID=01:AT89C2051编程器extern void PreparePro02();//FID=02:AT89S51编程器void main(){SP=0x60;SetVpp5V();//先初始化Vpp为5vSCON=0x00;TCON=0x00;//PCON=0x00;//波特率*2IE=0x00;//TMOD: GATE|C/!T|M1|M0|GATE|C/!T|M1|M0// 0 0 1 0 0 0 0 1TMOD=0x21;//T0用于延时程序TH1=0xff;TL1=0xff;//波特率28800*2,注意PCON//SCON: SM0|SM1|SM2|REN|TB8|RB8|TI|RI// 0 1 0 1 0 0 0 0SCON=0x50;TR1=1;Delay_ms(1000);//延时1秒后编程器自举ComBuf[0]=0;SendData();while(1)//串口通讯采用查询方式{if(!WaitComm())//如果超时,通讯出错{Delay_ms(500);ComBuf[0]=0;//让编程器复位,使编程器就绪}switch(ComBuf[1])//根据FID设置(ProWork)pw中的函数指针{case 0: //at89c51编程器PreparePro00(); break;case 1: //at89c2051编程器PreparePro01(); break;case 2: //at89s51编程器PreparePro02(); break;//case 3:支持新器件时,请继续向下添加// break;//case 4:// break;default: ComBuf[0]=0xff;ComBuf[1]=0xff; //表示无效的操作break;}switch(ComBuf[0])//根据操作ID跳到不同的操作函数{case 0x00:RstPro();break; / /编程器复位case 0x01:ReadSign();break; //读特征字case 0x02:Erase();break;//擦除器件case 0x03:Write();break;//写器件case 0x04:Read();break;//读器件case 0x05:Lock();break;//写锁定位default: SendData();break;}}}5.v oid InitSerial(void){TMOD = 0x20; // T1 方式2PCON=0x00; // PCON=00H,SMOD=0 PD = PCON.2 = 1 进入掉电模式TH1 = TL1 = BAUD_9600; // BAUD: 9600SCON = 0x50; // 串行通信方式1 REN=1 允许接收ET1 = 0; // 不允许中断TR1 = 1; // 开启定时器1IE = 0; // 关闭所有中断允许位memset(&SerialBuf, 0x00, SERIAL_BUF_LEN); // 初始化SerialBuf[SERIAL_BUF_LEN] }/**********************************************************名称:SendByte()**功能:串口发送一个字节**输入:ucData**返回:无**说明:无********************************************************/void SendByte(unsigned char ucData){SBUF = ucData;while(!TI){_CLRWDT_;}TI = 0;}RS232串口通信程序#include <AT89X52.H>unsigned char code dispcode1[]={" welcome! "}; unsigned char code dispcode2[]={""}; unsigned char i,j,k,l,DData;sbit RS = P3^5;sbit RW = P3^6;sbit E = P3^7;unsigned char m=0;void delay(){for(l=0;l<=100;l++){}}void enable() //write order{RS=0;RW=0;E=0;delay();E=1;}void enable2() //write data{RS=1;RW=0;E=0;delay();E=1;}void initializtion() //lcd initializtion{for(i=0;i<=100;i++)P0=0x01;enable();P0=0x38;enable();P0=0x0f;enable();P0=0x06;enable();}void Display(m,DData) // display data{P0=0xC0+m; //write addressenable();P0=DData; //write dataenable2();}void Esisr() interrupt 4 //串口接收中断服务程序{unsigned char temp;ES=0;if(RI == 1){RI = 0;temp = SBUF; //接收数据SBUF=temp; //将接收到的数据发送至PC机Display(m,temp); //将接收到的数据送LCD显示while(!TI); //等待数据发送完成TI=0;m++;if(m>16)m=0;}ES=1;}void system_initial(void) //system initializtion{TMOD=0x21;// 定时器1工作方式2,定时器0工作方式1PCON=0x00;//数据传输率选择。

51单片机实现通讯协议的串口通讯编程

51单片机实现通讯协议的串口通讯编程

51 单片机实现通讯协议的串口通讯编程摘要: 我们以51 单片机为例。

51 中一般针对串口通讯编程,通常采取中断接受查询发送的方式。

中断函数在接受数据到达时被重复调用,其实是个重复入栈的过程,所以不宜将函数写的太长,函数太长一般会导致栈太深占用系统资源,...我们以51 单片机为例。

51 中一般针对串口通讯编程,通常采取中断接受查询发送的方式。

中断函数在接受数据到达时被重复调用,其实是个重复入栈的过程,所以不宜将函数写的太长,函数太长一般会导致栈太深占用系统资源,二是处理时间过长,可能导致通讯出错。

为了防止在处理数据过程中不受干扰,通常在处理接受数据前关闭中断,处理完后再开。

通常的的编程方式如下:STatic void UartInterruptService(void)interrupt 4{ES = 0;RI = 0;uart_process(SBUF);ES=1;}下面重点介绍数据处理函数uart_process(SBUF);其实很多时候,对于通讯传输的数据处理才是关键,尤其对于设计通讯协议而言。

笔者在刚刚做的一个系统上就碰到这样的问题,当系统庞大了,资源十分有限的情况下,数据处理一旦占用资源太多,效率太低将导致系统崩溃而无法运行。

到了这里,很多工程师可能会考虑开个大的缓冲区FIFO 将接收到的数据保存在缓冲区,然后对其进行解析、判断进行下一步程序编写,当然这在系统资源比较丰富的情况下是没有问题的,ARM 上采取的就是这样的方式。

但如何系统庞大呢,留给的资源缺乏则不行。

这样做的一个很大缺点必须是将数据帧接收完了才能够判断,降低了效率和运行速度。

其实还有另外的方式,可以采取在每接收一个字节就对其解析,解析完判断转到下一个状态,并将其中的有用数据存储在相应的数据结构中去,可以采取状态机实现。

将状态机设计为两个控制状态,一是串口状态——uart_state ,一是命令类型状态——CMD_state 。

51单片机的串口通信分析

51单片机的串口通信分析

51单片机的串口通信分析1. 简介串口通信是51单片机中常用的通信方式之一,它能够实现通过串行端口将数据传输到其他设备或与其他设备进行通信。

本文将对51单片机的串口通信进行分析与讨论。

2. 串口通信原理串口通信主要包括数据传输、数据格式和通信协议三个方面。

在51单片机中,串口通信使用了UART(通用异步收发传输)协议。

UART协议通过选择适当的波特率、数据位、校验位和停止位等参数,实现串口数据的稳定传输。

3. 串口通信硬件连接在51单片机中,串口通信需要将单片机的串行端口与外部设备连接起来。

一般情况下,串口通信需要使用串口线连接单片机的TXD引脚和RXD引脚与外部设备的对应引脚。

4. 串口通信程序设计51单片机的串口通信程序设计主要包括串口初始化和数据发送与接收两个步骤。

在程序设计中,需要设置适当的波特率、数据位、校验位和停止位等参数,并编写相应的发送和接收函数来实现数据的发送和接收功能。

5. 串口通信应用实例串口通信在51单片机的应用非常广泛,可以用于与PC机的通信、与传感器的通信、与其他单片机的通信等等。

在实际应用中,可以通过串口通信实现数据的传输、控制信号的发送与接收等功能。

6. 总结51单片机的串口通信是一种常用且有效的通信方式,通过合理设置通信参数和编写相应的程序,可以实现稳定的数据传输和通信功能。

在应用中,可以根据具体需求选择适当的串口方式和协议来实现串口通信功能。

以上为本文对51单片机的串口通信进行的简要分析与讨论,希望对读者有所帮助。

参考文献:1. 参考书籍12. 参考书籍2。

51的UART串口通信详细

51的UART串口通信详细

●TB8,在方式2或方式3中,是发送数据的 第九位,可以用软件规定其作用。可以用作 数据的奇偶校验位,或在多机通信中,作为 地址帧/数据帧的标志位。 在方式0和方式1中,该位未用。 ●RB8,在方式2或方式3中,是接收到数据 的第九位,作为奇偶校验位或地址帧/数据帧 的标志位。在方式1时,若SM2=0,则RB8 是接收到的停止位。
四、串行通信的错误校验
1、奇偶校验 在发送数据时,数据位尾随的1位为奇偶校验位(1或0)。奇 校验时,数据中“1”的个数与校验位“1”的个数之和应为奇 数;偶校验时,数据中“1”的个数与校验位“1”的个数之和 应为偶数。接收字符时,对“1”的个数进行校验,若发现不 一致,则说明传输数据过程中出现了差错。 2、代码和校验 代码和校验是发送方将所发数据块求和(或各字节异或), 产生一个字节的校验字符(校验和)附加到数据块末尾。接 收方接收数据同时对数据块(除校验字节外)求和(或各字 节异或),将所得的结果与发送方的“校验和”进行比较, 相符则无差错,否则即认为传送过程中出现了差错。 3、循环冗余校验 这种校验是通过某种数学运算实现有效信息与校验位之间的 循环校验,常用于对磁盘信息的传输、存储区的完整性校验 等。这种校验方法纠错能力强,广泛应用于同步通信中。
面向位的同步格式 :
8位 01111110 8位 地址场 8位 控制场 ≥0位 信息场 16位 校验场 8位 01111110
此时,将数据块看作数据流,并用序列01111110作为开始 和结束标志。为了避免在数据流中出现序列01111110时引起 的混乱,发送方总是在其发送的数据流中每出现5个连续的1 就插入一个附加的0;接收方则每检测到5个连续的1并且其后 有一个0时,就删除该0。 典型的面向位的同步协议如ISO的高级数据链路控制规程 HDLC和IBM的同步数据链路控制规程SDLC。 同步通信的特点是以特定的位组合“01111110”作为帧的 开始和结束标志,所传输的一帧数据可以是任意位。所以传 输的效率较高,但实现的硬件设备比异步通信复杂。

51单片机串口通信

51单片机串口通信

51单片机串口通信串行口通信是一种在计算机和外部设备之间进行数据传输的通信方式,其中包括了并行通信、RS-232通信、USB通信等。

而在嵌入式系统中,最常见、最重要的通信方式就是单片机串口通信。

本文将详细介绍51单片机串口通信的原理、使用方法以及一些常见问题与解决方法。

一、串口通信的原理串口通信是以字节为单位进行数据传输的。

在串口通信中,数据传输分为两个方向:发送方向和接收方向。

发送方将待发送的数据通过串行转并行电路转换为一组相对应的并行信号,然后通过串口发送给接收方。

接收方在接收到并行信号后,通过串行转并行电路将数据转换为与发送方发送时相对应的数据。

在51单片机中,通过两个寄存器来实现串口通信功能:SBUF寄存器和SCON寄存器。

其中,SBUF寄存器用于存储要发送或接收的数据,而SCON寄存器用于配置串口通信的工作模式。

二、51单片机串口通信的使用方法1. 串口的初始化在使用51单片机进行串口通信之前,需要进行串口的初始化设置。

具体的步骤如下:a. 设置波特率:使用波特率发生器,通过设定计算器的初值和重装值来实现特定的波特率。

b. 串口工作模式选择:设置SCON寄存器,选择串行模式和波特率。

2. 发送数据发送数据的过程可以分为以下几个步骤:a. 将要发送的数据存储在SBUF寄存器中。

b. 等待发送完成,即判断TI(发送中断标志位)是否为1,如果为1,则表示发送完成。

c. 清除TI标志位。

3. 接收数据接收数据的过程可以分为以下几个步骤:a. 等待数据接收完成,即判断RI(接收中断标志位)是否为1,如果为1,则表示接收完成。

b. 将接收到的数据从SBUF寄存器中读取出来。

c. 清除RI标志位。

三、51单片机串口通信的常见问题与解决方法1. 波特率不匹配当发送方和接收方的波特率不一致时,会导致数据传输错误。

解决方法是在初始化时确保两端的波特率设置一致。

2. 数据丢失当发送方连续发送数据时,接收方可能会出现数据丢失的情况。

51串口通信

51串口通信




SBUF 发送(99H)
逻辑门电路
发送控制器
TI
串行口中断
≥1
RI
接收控制器
SBUF 接收(99H)
移位寄存器
Байду номын сангаас
串 行 口 控 制 寄 存 器 SCON
TXD(P3.1)
RXD(P3.0)
2个物理上独立的接收、发送缓冲器SBUF,占用同一地 址99H ;接收器是双缓冲结构 。
2019/12/21
方式:
并行通信 串行通信
2019/12/21
3
并行通信:数据多位同时传送
8位同时传送 1
0

1

0
收 设
1

1 0


0

询问
应答
控制简单,传输速度快,传输线较多
2019/12/21
4
串行通信:数据字节一位一位在一条传输 线上逐个传送。



D0
D7

设 备
8位顺次传送
设 备
传输线少,可利用电话网,但传送控制复杂。
REN,允许串行接收位。
置REN=1,启动串口接收过程 置REN=0,则禁止串口接收
2019/12/21
18
TB8,在方式2、3中,是发送数据的第9位 数据的奇偶校验位 地址帧/数据帧的标志位
RB8,在方式2、3中,是接收到数据的第9位 奇偶校验位
地址帧/数据帧的标志位。
方式1时,若SM2=0,则RB8是接收到的停止位。
2019/12/21
自同步
8
面向字符的同步格式 :
SYN SYN SOH 标题 STX

51单片机串口通信原理

51单片机串口通信原理

51单片机串口通信原理一、概述串口通信是指通过串口进行数据传输的一种通信方式。

51单片机作为一种常见的嵌入式系统,其应用范围非常广泛,因此掌握51单片机串口通信原理是非常重要的。

本文将从串口通信的基本原理、51单片机串口硬件结构、51单片机串口软件实现等方面进行详细介绍。

二、串口通信基本原理1. 什么是串口?串行端口(Serial Port)又称为异步通讯端口(Asynchronous Communication Port),简称为COM端口。

它是计算机与外部设备之间进行数据传输的一个接口。

在计算机中,通过串行端口可以连接各种外部设备,如打印机、调制解调器等。

2. 什么是异步通讯?异步通讯(Asynchronous Communication)是指在数据传输时不需要事先建立一个稳定的连接,在发送数据前不需要接收方发送确认信息,也不需要预先定义传输时间。

因此,在异步通讯中,发送方和接收方之间没有任何同步关系。

3. 什么是波特率?波特率(Baud Rate)也称为比特率(Bit Rate),它表示每秒钟可以传输多少个二进制位。

在串行通讯中,波特率是数据传输的一个重要参数。

4. 什么是数据位、停止位和校验位?数据位(Data Bits)表示每个字符中包含的二进制位数,通常为5、6、7或8。

停止位(Stop Bits)表示每个字符后面要发送多少个停止位,通常为1或2个。

校验位(Parity Bit)用于检测数据传输中出现的错误。

常见的校验方式有奇偶校验、偶校验和无校验。

其中,奇偶校验和偶校验需要在每个字符的最高位添加一个校验位,使得每个字符中1的数量为奇数或偶数。

5. 串口通讯流程串口通讯流程大致分为以下几步:1)发送端将需要传输的数据按照一定格式进行编码,并通过串口发送给接收端;2)接收端接收到数据后,按照相同的格式进行解码,并进行错误检测;3)如果发现有错误,则可以向发送端请求重发;4)如果没有错误,则接收端可以对数据进行处理。

51单片机通讯协议书

51单片机通讯协议书

51单片机通讯协议书甲方(以下简称甲方):地址:联系电话:乙方(以下简称乙方):地址:联系电话:鉴于甲方需开发一款基于51单片机的通讯设备,乙方具备相应的技术能力和经验,双方经友好协商,就51单片机通讯协议的制定与实施达成如下协议:第一条协议目的本协议旨在明确甲方与乙方在51单片机通讯协议开发过程中的权利、义务和责任,确保通讯协议的顺利制定和实施。

第二条协议范围1. 本协议涵盖51单片机通讯协议的制定、测试、优化及最终交付。

2. 乙方应根据甲方的技术要求和标准,开发符合甲方需求的通讯协议。

第三条技术要求1. 乙方应保证所开发的通讯协议满足甲方提出的技术参数和性能指标。

2. 通讯协议应支持至少两种以上的通讯方式,包括但不限于串行通讯、并行通讯等。

3. 乙方应确保通讯协议具有良好的稳定性和兼容性。

第四条交付成果1. 乙方应向甲方提供完整的通讯协议文档,包括但不限于协议说明、接口定义、数据格式等。

2. 乙方应提供通讯协议的源代码,并确保代码的可读性和可维护性。

3. 乙方应提供通讯协议的测试报告,包括测试环境、测试方法和测试结果。

第五条知识产权1. 乙方开发的通讯协议及其源代码的知识产权归甲方所有。

2. 乙方应保证所开发的通讯协议不侵犯任何第三方的知识产权。

第六条保密条款1. 乙方应对在协议开发过程中知悉的甲方商业秘密和技术秘密负有保密义务。

2. 未经甲方书面同意,乙方不得向任何第三方披露、提供或允许第三方使用甲方的商业秘密和技术秘密。

第七条违约责任1. 如乙方未能按照本协议约定的时间和要求完成通讯协议的开发,甲方有权要求乙方承担违约责任。

2. 如乙方开发的通讯协议侵犯了第三方的知识产权,乙方应负责解决相关纠纷,并赔偿甲方因此遭受的一切损失。

第八条协议变更和终止1. 本协议的任何变更或补充均需双方协商一致,并以书面形式确认。

2. 如一方严重违反本协议,另一方有权书面通知对方终止本协议。

第九条争议解决本协议在履行过程中如发生争议,双方应首先通过友好协商解决;协商不成时,任何一方均可向甲方所在地人民法院提起诉讼。

c51单片机实用通信协议

c51单片机实用通信协议

c51单片机实用通信协议一、基本格式:通信头->巴克码->地址字->长度字->命令字->信息位->校准字1. 通信头:占1~8个字节,表通信开始(0x00、0xff不能用作通信头);2.巴克码:占1字节,一般为0x72,表通信头结束;3.地址字:表终端的地址,占1字节(0x00作为广播地址);4.长度字:占1字节,表示从地址字到信息位之间的字节数;5.命令字:占1字节,指示终端的不同操作;6.信息位:不定长,从0~252字节;7.校验位:两个字节,采用和校验及CRC校验。

二、应答1.如果终端接收正确,则应答ACK;如果终端接收错误,则应答NAK;2.发送方收到ACK,此次通信结束;3.发送方收到NAK,重发刚才的命令字(最多7次);4.如果发送方发完数据后无应答,隔0.5~1S后重发(最多7次)。

三、ACK/NAK的格式通信头->巴克码->地址字->长度字->命令字->0x06、0x06、、0x06(1~8个)(若信息位长时,分包传输,信息位的第一位是包号0x01,最后1包为0xff)============================================================= =============================================================单片机多机并行通讯的一种方法1 简介本文介绍的单片机多机并行通讯系统,使用89C51作为主机,多片89C2051作为从机。

(89C2051为20脚300MIL封装,带有2K FLASH E2PROM的单片机,除了少了两个并口外,具备MCS-51系列单片机所有功能。

因为其体积小,功能强,必将在单片机应用领域内广泛使用)。

这种并行通讯方法适用于在多站点,多层次的检测和控制系统中充当通信控制器的角色;也适合于用作单片机串行口扩充电路。

51单片机通信协议

51单片机通信协议

单片机通信协议现在大部分的仪器设备都要求能过通过上位机软件来操作,这样方便调试,利于操作。

其中就涉及到通信的过程。

在实际制作的几个设备中,笔者总结出了通信程序的通用写法,包括上位机端和下位机端等。

1.自定义数据通信协议这里所说的数据协议是建立在物理层之上的通信数据包格式。

所谓通信的物理层就是指我们通常所用到的RS232、RS485、红外、光纤、无线等等通信方式。

在这个层面上,底层软件提供两个基本的操作函数:发送一个字节数据、接收一个字节数据。

所有的数据协议全部建立在这两个操作方法之上。

通信中的数据往往以数据包的形式进行传送的,我们把这样的一个数据包称作为一帧数据。

类似于网络通信中的TCPIP协议一般,比较可靠的通信协议往往包含有以下几个组成部分:帧头、地址信息、数据类型、数据长度、数据块、校验码、帧尾。

帧头和帧尾用于数据包完整性的判别,通常选择一定长度的固定字节组成,要求是在整个数据链中判别数据包的误码率越低越好。

减小固定字节数据的匹配机会,也就是说使帧头和帧尾的特征字节在整个数据链中能够匹配的机会最小。

通常有两种做法,一、减小特征字节的匹配几率。

二、增加特征字节的长度。

通常选取第一种方法的情况是整个数据链路中的数据不具有随即性,数据可预测,可以通过人为选择帧头和帧尾的特征字来避开,从而减小特征字节的匹配几率。

使用第二种方法的情况更加通用,适合于数据随即的场合。

通过增加特征字节的长度减小匹配几率,虽然不能够完全的避免匹配的情况,但可以使匹配几率大大减小,如果碰到匹配的情况也可以由校验码来进行检测,因此这种情况在绝大多说情况下比较可靠。

地址信息主要用于多机通信中,通过地址信息的不同来识别不同的通信终端。

在一对多的通信系统中,可以只包含目的地址信息。

同时包含源地址和目的地址则适用于多对多的通信系统。

数据类型、数据长度和数据块是主要的数据部分。

数据类型可以标识后面紧接着的是命令还是数据。

数据长度用于指示有效数据的个数。

51单片机的串口通信协议的6个特征

51单片机的串口通信协议的6个特征

51单片机的串口通信协议的6个特征现实生活中,我们总是要与人打交道,互通有无。

单片机也一样,需要跟各种设备交互。

例如汽车的显示仪表需要知道汽车的转速及电动机的运行参数,那么显示仪表就需要从汽车的底层控制器取得数据。

而这个数据的获得过程就是一个通信过程。

类似的例子还有控制器通常是单片机或者PLC与变频器的通信。

通信的双方需要遵守一套既定的规则也称为协议,这就好比我们人之间的对话,需要在双方都遵守一套语言语法规则才有可能达成对话。

通信协议又分为硬件层协议和软件层协议。

硬件层协议主要规范了物理上的连线,传输电平信号及传输的秩序等硬件性质的内容。

常用的硬件协议有串口,IIC,SPI,RS485,CAN和USB。

软件层协议则更侧重上层应用的规范,比如modbus协议。

好了,那这里我们就着重介绍51单片机的串口通信协议,以下简称串口。

串口的6个特征如下。

(1)、物理上的连线至少3根,分别是Tx数据发送线,Rx数据接收线,GND共用地线。

(2)、0与1的约定。

RS232电平,约定﹣5V至﹣25V之间的电压信号为1,﹢5V至﹢25V之间的电压信号为0 。

TTL电平,约定5V的电压信号为1,0V电压信号为0 。

CMOS 电平,约定3.3V的电压信号为1,0V电压信号为0 。

其中,CMOS电平一般用于ARM 芯片中。

(3)、发送秩序。

低位先发。

(4)、波特率。

收发双方共同约定的一个数据位(0或1)在数据传输线上维持的时间。

也可理解为每秒可以传输的位数。

常用的波特率有300bit/s, 600bit/s, 2400bit/s, 4800bit/s, 9600bit/s。

(5)、通信的起始信号。

发送方在没有发送数据时,应该将Tx置1 。

当需发送时,先将Tx置0,并且保持1位的时间。

接受方不断地侦测Rx,如果发现Rx常时间变高后,突然被拉低(置为0),则视为发送方将要发送数据,迅速启动自己的定时器,从而保证了收发双方定时器同步定时。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51串口通信协议(新型篇)C51编程:这是网友牛毅编的一个C51串口通讯程序!//PC读MCU指令结构:(中断方式,ASCII码表示)//帧:帧头标志|帧类型|器件地址|启始地址|长度n|效验和|帧尾标志//值: 'n' 'y'| 'r' | 0x01 | x | x | x |0x13 0x10//字节数: 2 | 1 | 1 | 1 | 1 | 1 | 2//求和:///////////////////////////////////////////////////////////////////////公司名称:***//模块名:protocol.c//创建者:牛毅//修改者://功能描述:中断方式:本程序为mcu的串口通讯提供(贞结构)函数接口,包括具体协议部分//其他说明:只提供对A T89c51具体硬件的可靠访问接口//版本:1.0//信息:QQ 75011221/////////////////////////////////////////////////////////////////////#include <reg51.h>#include <config.h>//预定义//帧#define F_ST1 0x6e //帧头标志n#define F_ST2 0x79 //帧头标志y#define F_R 0x72 //帧类型读r#define F_W 0x77 //帧类型写w#define F_D 0x64 //帧类型数据帧d#define F_B 0x62 //帧类型写回应帧b#define F_C 0x63 //帧类型重发命令帧c#define F_Q 0x71 //帧类型放弃帧q#define F_ADDR 0x31 //器件地址0-9#define F_END 0x7a //帧尾标志z#define F_SPACE 0x30 //空标志0#define F_ERR1 0x31 //错误标志1,flagerr 1#define F_ERR2 0x32 //错误标志2 2//常数#define S_MAXBUF 16 //接收/发送数据的最大缓存量#define FIELD_MAXBUF 48 //最小场缓存,可以大于48字节,因为协议是以20字节为#define communicationing P1_7 //正在通讯(1)标志#define ERRFRAME_MAX 5 //连续NOFRAME_CNT次帧不正确#define ERR_NOCNTMAX_RESEND if(++errframe_cnt<=ERRFRAME_MAX)resend_frame(); else errframe_cnt=communicationing=0;//若超过ERRFRAME_MAX 次则令通讯停止ERR_NOCNTMAX_RESEND//public 变量unsigned char databuf[FIELD_MAXBUF],errframe_cnt;//函数///////////////////////////////////////////////////////////////////////函数名:send()//功能描述:向串口发送一个字符//函数说明://调用函数://全局变量://输入:ch-要发送的ASCII字符//返回:无//设计者:牛毅//修改者://版本://///////////////////////////////////////////////////////////////////void send(unsigned char ch){SBUF=ch;while(TI==0);TI=0;}///////////////////////////////////////////////////////////////////////函数名:receive()//功能描述:从串口接收一个字符//函数说明://调用函数://全局变量://输入:无//返回:一个ASCII字符//设计者:牛毅//修改者://版本://///////////////////////////////////////////////////////////////////unsigned char receive(void){RI=0;return SBUF;}///////////////////////////////////////////////////////////////////////函数名:CharToHex()//功能描述:把ASCII字符转换为16进制//函数说明://调用函数://全局变量://输入:ASCII字符//返回:16进制//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// unsigned char CharToHex(unsigned char bChar) {if((bChar>=0x30)&&(bChar<=0x39))bChar -= 0x30;else if((bChar>=0x41)&&(bChar<=0x46))//大写字母bChar -= 0x37;else if((bChar>=0x61)&&(bChar<=0x66))//小写字母bChar -= 0x57;else bChar = 0xff;return bChar;}///////////////////////////////////////////////////////////////////////函数名:HexToChar()//功能描述:把16进制转换为ASCII字符//函数说明://调用函数://全局变量://输入:16进制//返回:ASCII字符//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// unsigned char HexToChar(unsigned char bHex) {if((bHex>=0)&&(bHex<=9))bHex += 0x30;else if((bHex>=10)&&(bHex<=15))//大写字母bHex += 0x37;else bHex = 0xff;return bHex;}///////////////////////////////////////////////////////////////////////函数名:com_int()//功能描述:初始化串口//函数说明:默认其他参数为[baud_rate],n,8,1//调用函数://全局变量://输入:baud_rate 波特率//返回:无//设计者:牛毅//修改者://版本://///////////////////////////////////////////////////////////////////void com_init(unsigned int baud_rate){EA=1;ES=1;//ET1=1;SCON = 0x50; /* 0x52;//SCON */TMOD = 0x20; /*0x20;// TMOD */TCON = 0x60; /*0x60;// TCON */PCON=PCON&0x7f;switch(baud_rate){ //波特率设置case 1200:TL1=0xe8;TH1=0Xe8;break; //1200case 2400:TL1=0xf4;TH1=0Xf4;break; //2400case 4800:TL1=0xfa;TH1=0Xfa;break; //4800case 9600:TL1=0xfd;TH1=0Xfd;break; //9600case 19200:PCON=PCON|0x80;TL1=0xfd;TH1=0Xfd;break; //19200 case 38400:PCON=PCON|0x80;TL1=0xfe;TH1=0Xfe;break; //38400 default:TL1=0xfd;TH1=0Xfd;break;//9600}}//函数名:resend_frame()//功能描述:发送重发帧//函数说明:通知PC重发//调用函数://全局变量://输入:无//返回:无//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// void resend_frame(void){send(F_ST1);send(F_ST2);send(F_C);send(F_SPACE);send(F_SPACE);//发送效验和send(F_END);}///////////////////////////////////////////////////////////////////// //函数名:quit_frame()//功能描述:发送放弃帧//函数说明:通知PC放弃通讯//调用函数://全局变量://输入:无//返回:无//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// void quit_frame(void){send(F_ST1);send(F_ST2);send(F_Q);send(F_ERR1);send(F_ERR1);//发送效验和send(F_END);}//函数名:com_int()//功能描述:串口中断//函数说明://调用函数://全局变量://输入:无//返回:无//设计者:牛毅//修改者://版本://///////////////////////////////////////////////////////////////////void com_int()interrupt 4{unsigned char i,csaddr,clen,csum,tempbuf[S_MAXBUF]; csum=0;if(receive()==F_ST1){//是侦if(receive()==F_ST2){//头判断完communicationing=1;//设置通讯状态为正常即启动通讯switch(receive()){case F_R://是读指令帧rif(receive()==F_ADDR){P1_2=!P1_2;//地址正确csaddr=CharToHex(receive())<<4;csaddr+=CharToHex(receive());clen=CharToHex(receive())<<4;clen+=CharToHex(receive()); csum=csaddr+clen;i=CharToHex(receive())<<4;i+=CharToHex(receive());if(i==csum){//效验和正确if(receive()==F_END){//结束标志正确//开始发送数据帧csum=0;send(F_ST1);send(F_ST2);send(F_D);send(HexToChar((clen&0xf0)>>4));send(HexToChar(clen&0x0f));csum+=clen;for(i=0;i<clen;i++)send(HexToChar((databuf[i+csaddr]&0xf0)>>4)); send(HexToChar(databuf[i+csaddr]&0x0f));csum+=databuf[i+csaddr];}//if(csum>127)csum-=128;send(HexToChar((csum&0xf0)>>4));send(HexToChar(csum&0x0f));send(F_END);//发送数据帧完毕P1_0=!P1_0;}else{ERR_NOCNTMAX_RESEND break;}//结束标志错误}else{ERR_NOCNTMAX_RESENDbreak;}//效验和错误}//地址不正确break;case F_W://是PC写指令帧wif(receive()==F_ADDR){//地址正确csaddr=CharToHex(receive())<<4;csaddr+=CharToHex(receive());clen=CharToHex(receive())<<4;clen+=CharToHex(receive());csum=csaddr+clen;for(i=0;i<clen;i++){tempbuf[i+csaddr]=CharToHex(receive())<<4; tempbuf[i+csaddr]+=CharToHex(receive());csum+=tempbuf[i+csaddr];}i=CharToHex(receive())<<4;i+=CharToHex(receive()); if(csum!=i){ERR_NOCNTMAX_RESEND break;}//效验和错误if(F_END!=receive())ERR_NOCNTMAX_RESENDbreak;}//结束标志错误for(i=csaddr;i<clen+csaddr;i++)databuf[i-csaddr]=tempbuf[i-csaddr];//正确则保存数据}//从PC获得数据写完毕//开始发送写回应帧send(F_ST1);send(F_ST2);send(F_B);send(F_SPACE);send(F_SPACE);//发送效验和send(F_END);//写回应帧发送完毕P1_1=!P1_1;break;case F_Q://检测接收放弃帧csaddr=receive();csum+=csaddr;//csaddr兼做放弃帧码标志if(csaddr!=F_ERR1 && csaddr!=F_ERR2){ERR_NOCNTMAX_RESEND break;}if(csum!=receive()){ERR_NOCNTMAX_RESENDbreak;}if(F_END!=receive()){ERR_NOCNTMAX_RESENDbreak;}communicationing=0;//出错退出通讯break;default:resend_frame();//要求从发}}//忽略}//忽略if(!communicationing)quit_frame();//调用放弃帧,通知PC 放弃通讯}///////////////////////////////////////////////////////////////////主函数/////////////////////////////////////////////////////////////////void main(void){unsigned char i;for (i=0;i<FIELD_MAXBUF;i++) databuf=i+0x30;com_init(38400);while(1){/*可以处理非串口任务*/}。

相关文档
最新文档