单片机 通信协议有哪些_单片机通信协议 - CSDN
精华内容
参与话题
  • 单片机各种通信协议详解

    千次阅读 2019-04-12 16:23:21
    一、IIC通信协议 ** (1)概述 I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由 NXP(原 PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能一个...

    **

    一、IIC通信协议

    **
    (1)概述

    • I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由 NXP(原 PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。
    • 经常 IIC 和 SPI 接口被认为指定是一种硬件设备,但其实这样的说法是不尽准确的,严格的说他们都是人们所定义的软硬结合体,分为物理层(四线结构)和协议层(主机,从机,时钟极性,时钟相位)。
      -IIC, SPI 的区别不仅在与物理层, IIC 比 SPI 有着一套更为复杂的协议层定义。下面来分别说明一下 IIC 的物理层和协议层

    (2) IIC 的物理层

    • a.只要求两条总线线路,一条是串行数据线SDA,一条是串行时钟线SCL,(IIC 是半双工,而不是全双工)。
    • b.每个连接到总线的器件都可以通过唯一的地址和其它器件通信,主机/从机角色和地址可配置,主机可以作为主机发送器和主机接收器。
    • c.IIC 是真正的多主机总线,(而这个 SPI 在每次通信前都需要把主机定死,而 IIC 可以在通讯过程中,改变主机),如果两个或更多的主机同时请求总线,可以通过冲突检测和仲裁防止总线数据被破坏。
    • d.传输速率在标准模式下可以达到 100kb/s,快速模式下可以达到 400kb/s。
    • e.连接到总线的 IC 数量只是受到总线的最大负载电容 400pf 限制。
    • 一个典型的 IIC 接口如下图所示
      在这里插入图片描述

    二、 SPI 协议

    • 通常 SPI 通信要求 4 根线,分别是 MOSI(mast output salve input), MISO, CLK, CS。
    • 当发送和接受数据的工作都准备好了,只要有时钟 CLK,就发送数据,没有时钟就不发送,而且一个时钟周期发送一位(bit)数据,所以发送数据的快慢由时钟频率来控制。
    • 至于时钟和数据的相位没有特别严格的要求(而 IIC 中,数据的变化只能在 SCL 是低电平的时候发生), SPI数据的变化是一个时钟周期一次,这样的方法来传输数据就简单多了。我们可以根据需求对时钟的极性和相位做调整,看看是在时钟上升沿还是下降沿来发送数据,还有停止发送时时钟的极性,是保持高电平还是低电平。
    • 另外在多机通信时, SPI 只是简单的通过一个片选信号来选择哪个设备占用总线,但是 IIC 是通过发送从设备地址来自动选择的。

    三、 什么是 TTL 电平、 CMOS 电平?

    • TL 电平信号被利用的最多是因为通常数据表示采用二进制规定, +5V 等价于逻辑"1", 0V 等价于逻辑"0",这被称做
      TTL(晶体管-晶体管逻辑电平)信号系统,这是计算机处理器控制的设备内部各部分之间通信的标 准技术。
    • CMOS 电平和 TTL 电平: CMOS 电平电压范围在 3~15V,比如: 当 5V 供电时,输出在 4.6 以上为高电平,输出在
      0.05V 以下为低电平。输入在 3.5V 以上为高电平,输入在 1.5V 以下为低电平。而对于 TTL 芯片,供电范围在 0~5V,常见都是 5V,如 74 系列 5V 供电,输出在2.7V 以上为高电平,输出在 0.5V 以下为低电平,输入在 2V 以上为高电平,在 0.8V 以下为低电平。因此, CMOS 电路与 TTL 电路就有一个电平转换的问题,使两者电平域值能匹配
    • TTL 高电平 3.6~5V,低电平 0V~2.4V
    • CMOS 电平 Vcc 可达到 12V

    四、 RS-232 协议

    • RS232(异步传输标准接口),是个人计算机上的通讯接口之一,也称串口或串行通讯接口。
    • 由电子工业协会(Electronic Industries Association, EIA) 所制定的异步传输标准接口。通常 RS-232 接口以9 个引脚 (DB-9) 或是 25 个引脚 (DB-25) 的型态出现,一般个人计算机上会有两组 RS-232 接口,分别称为COM1 和 COM2。是目前最常用的一种串行通讯接口。
    • 标准 RS232 接口: 常用串口只需要 TX 与 RX 即可。
      在这里插入图片描述

    五、 CAN 总线

    • CAN 是控制器局域网络(Controller Area Network, CAN)的简称,是由以研发和生产汽车电子产品著称的德国BOSCH 公司开发的,并最终成为国际标准(ISO 11898),是国际上应用最广泛的现场总线之一。 在北美 和西欧, CAN总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以 CAN 为底层协议专为大型货车和重工机械车辆设计的J1939 协议。
    • CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议。在汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来由于这些系统之间通信所用的数据类型及对可靠性的要求不尽相同,由多条总线构成的情况很多,线束的数量也随之增加。为适应“减少线束的量”、“通过多个 LAN,进行大量数据的高速通信”的需要,1986 年德国电气商博世公司开发出面向汽车的 CAN 通信协议。此后, CAN 通过 ISO11898 及 ISO11519 进行了标准化,在欧洲已是汽车网络的标准协议。
    • CAN 的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。现场总线是当今自动化领域技术发展的热点之一,被誉为自动化领域的计算机局域网。它的出现为分布式控制系统实现各节点之间实时、可靠的数据通信提供了强有力的技术支持。

    CAN 的报文格式

    • 在总线中传送的报文,每帧由 7 部分组成。 CAN 协议支持两种报文格式,其唯一的不同是标识符(ID)长度不同,标准格式为 11位,扩展格式为 29 位。
    • 在标准格式中,报文的起始位称为帧起始(SOF),然后是由 11 位标识符和远程发送请求位 (RTR)组成的仲裁场。 RTR 位标明是数据帧还是请求帧,在请求帧中没有数据字节。
    • 控制场包括标识符扩展位(IDE),指出是标准格式还是扩展格式。它还包括一个保留位 (ro),为将来扩展使用。它的最后四个位用来指明数据场中数据的长度(DLC)。数据场范围为 0~8 个字节,其后有一个检测数据错误的循环冗余检查(CRC)。
    • 应答场(ACK)包括应答位和应答分隔符。发送站发送的这两位均为隐性电平(逻辑 1),这时正确接收报文的接收站发送主控电平(逻辑 0)覆盖它。用这种方法,发送站可以保证网络中至少有一个站能正确接收到报文。
    • 报文的尾部由帧结束标出。在相邻的两条报文间有一很短的间隔位,如果这时没有站进行总线存取,总线将处于空闲状态。

    六、 485 总线

    • 在要求通信距 离为几十米到上千米时,广泛采用 RS-485 串行总线标准。 RS-485采用平衡发送和差分接收,因此具有抑制共模干扰的能力。
    • RS232 串口可以与 485 之间互转, 在单片机上使用 485 总线与使用 RS232 串口一样, 需要使用芯片转换电平即可!

    七、 Modbus 通讯协议

    • Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。它已经成为一种通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一个控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。
    • 当在同一 Modbus 网络上通信时,此协议决定了每个控制器需要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制器将生成反馈信息并用 Modbus 协议发出。在其它网络上,包含了 Modbus 协议的消息转换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。
    • 此协议支持传统的 RS-232、 RS-422、 RS-485 和以太网设备。许多工业设备,包括 PLC, DCS,智能仪表等都在使用 Modbus 协议作为他们之间的通信标准。
      Modbus 具有以下几个特点:
    • 标准、开放,用户可以免费、放心地使用 Modbus 协议,不需要交纳许可证费,也不会侵犯知识产 权。目前,支持 Modbus 的厂家超过400家,支持 Modbus 的产品超过 600 种。
    • Modbus 可以支持多种电气接口,如 RS-232、 RS-485 等,还可以在各种介质上传送,如双绞线、光纤、无线等。
    • Modbus 的帧格式简单、紧凑,通俗易懂。用户使用容易,厂商开发简单。
      在这里插入图片描述
    展开全文
  • 单片机的应用中,通信协议是其中必不可少的一部分,上位机与下位机,单片机单片机单片机与外设模块之间的通信都需要通信协议实现信息交换和资源共享。由于设备之间不同的传输速率、电气特性、可靠性要求的不同...

    在单片机的应用中,通信协议是其中必不可少的一部分,上位机与下位机,单片机与单片机,单片机与外设模块之间的通信都需要通信协议实现信息交换和资源共享。由于设备之间不同的传输速率、电气特性、可靠性要求的不同,也产生了许多类型的适用于不同情况的通信协议,并被广泛的接受和使用。其实使用率最高的主要有以下几种:

    o4YBAF3FKEmALlptAAFRZyX5Yzw313

      一、UART和USART

      分别名为通用异步收发器和通用同步异步收发器,速率不快,可全双工,结构上一般由波特率产生器、UART/USART发送器、UART/USART接收器组成,硬件上两线,一收一发。

      二、I2C(IIC)

      双向、两线、串行、多主控接口标准。速率不快,半双工,同步接口,具有总线仲裁机制,非常适合器件间近距离经常性数据通信,可实现设备组网。

      总线仲裁:线与,谁发0就仲裁成功。

      三、SPI

      高速同步串行口,高速,可全双工,收发独立,同步接口,可实现多个SPI设备互联,硬件3~4线;也是所有基于SPI的设备公共有的,他们是SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)。

      四、USB

      高速同步串行口,高速,可全双工,由主机、hub、设备组成。设备可以与下级的hub相连构成星型结构。一条USB的传输线分别由地线、电源线、D+、D-四条线构成,D+、D-是差分输入线,它使用的是3.3V的电压。数据在USB线里传送是由低位到高位发送的。

      五、CAN

      采用双线传输,两根导线分别作为CAN_H、CAN_L,并在终端配备有120Ω的电阻。收到总线信号时,CAN收发器将信号电平转化为逻辑状态,即CAN_H与CAN_L电平相减后,得到一个插值电平。各种干扰在两根导线上的作用相同,相减后的插值电平可以滤过这些干扰。

      六、DMA

      DMA是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。这样数据的传送速度就取决于存储器和外设工作速度。

      通常系统总线是由CPU管理的,在DMA方式时,就希望CPU把这些总线让出来,即CPU连到这些总线上的线处于第三态(高阻状态),而由DMA控制器接管,控制传送的字节数,判断DMA是否结束,以及发出DMA结束信号。

    本文来自:http://www.ebyte.com/    成都亿佰特

     

     

    展开全文
  • 单片机C语言之串口通信协议

    万次阅读 多人点赞 2017-06-20 14:24:47
    本文详细讲述串口通信的基本原理,分析了51单片机串口协议。适合于入门。
    现实生活中, 我们总是要与人打交道,互通有无。单片机也一样,需要跟各种设备交互。例如汽车的显示仪表需要知道汽车的转速及电动机的运行参数,那么显示仪表就需要从汽车的底层控制器取得数据。而这个数据的获得过程就是一个通信过程。类似的例子还有控制器通常是单片机或者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),则视为发送方将要发送数据,迅速启动自己的定时器,从而保证了收发双方定时器同步定时。

    (6)、停止信号。发送方发送完最后一个有效位时,必须再将Tx保持1位的时间,即为停止位。


    好了,理论暂时到这里,现在我们要做一个实验,将一个字节从51单片机发送到电脑串口调试助手上。这个实验的目的是为了掌握串口通信协议的收发过程。

    虚拟串口

    实验一、虚拟串口实验

    一般单片机都有专门的串口引脚,51里面分别是P3.0和P3.1,这些引脚拥有串口的硬件电路,因此使用它们并不需要设置信号的发送停止。为了掌握协议,我们使用其他的引脚来模拟串口,所以也叫虚拟串口。这里我们选用P1.0,然而注意到我们51单片机要发送数据给电脑,必须经过一个串口转USB设备(即TTL电平转换为RS232电平),而限于我们的开发板只有P3.0与P3.1连接到了串口转USB设备,所以我们可以将P1.0短接到P3.1 。 下图是这个串口转USB的原理图。


    好了直接上代码吧。

    #include "reg51.h"
    /*
      将P1.0虚拟成串口发送脚TX
      以9600bit/s的比特率向外发送数据
      因为波特率是	9600bit/s
      所以me发送一位的时间是 t=1000000us/9600=104us
    */			
    sbit TX=P3^1; //P1^0 output TTL signal, need to transferred to rs232 signal, can be connected to P3^1
    #define u16 unsigned int //宏定义
    #define u8 unsigned char
    u8 sbuf;
    bit ti=0;
    
    void delay(u16 x)
    {
    	while(x--);
    }
    void Timer0_Init()
    {
    	TMOD |= 0x01;
    	TH0=65440/256;
    	TH0=65440%256;
    	TR0=0;
    }
    
    void Isr_Init()
    {
    	EA=1;
    	ET0=1;
    }
    
    void Send_Byte(u8 dat)
    {
    	sbuf=dat;//通过引入全局变量sbuf,可以保存形参dat
    	TX=0; //A 起始位
    	TR0=1;
    	while(ti==0);	 //等待发送完成
    	ti=0; //清除发送完成标志
    }
    
    void TF0_isr() interrupt 1	   //每104us进入一次中断
    {
    	static u8 i; //记录进入中断的次数
    
    	TH0=65440/256;
    	TL0=65440%256;
    	i++;
    	if(i>=1 && i<=8)
    	{
    		if((sbuf&(1<<(i-1)))==0)  // (sbuf&(1<<(i-1)))表示取出i-1位
    		{
    			TX=0;
    		}
    		else
    		{
    			TX=1;
    		}
    	}
    	if(i==9)  //停止位
    	{
    		TX=1;
    	}
    	if(i==10)	
    	{
    		TR0=0;
    		i=0;
    		ti=1; //发送完成
    	}
    }
    
    void main()
    {
    	TX=1; //使TX处于空闲状态
    	Timer0_Init();
    	Isr_Init();
    	while(1)
    	{
    		Send_Byte(65); //0x41
    		delay(60000);
    	}
    }
    实验引入了定时器0来控制发送线上的各个位的保持时间。首先main函数进入,TX置1则使发送线处于空闲,这时候发送方和接受方都处于空闲。接下来初始化定时器0,TR0置0表示还不要启动定时器0。接着中断系统初始化,此时中断系统已经开启。进入while循环,先进Send_Byte()函数,将65传给形参dat,dat再将65赋值给sbuf,到这里准备工作就做好了。接着TX置0,这个是起始位,要保持这个起始位104us。于是就启动定时器TR0置1,计时器开始计数。当第一次溢出的时候,也就是过了104us,进入中断,同时接收方也侦测到了这个突然被拉低的信号,于是迅速启动自己的定时器。进入中断子函数后,先是重装定时器初值,然后i加1,也就是当i=1时,就应该发送数据的最低位了,总共有8位数据,所以使用条件语句if(i>=1 && i<=8)来判断是否发送完数据位。然后再通过if(i==9) 来发送停止位,最后当i=10时,也就是发送完了,这时候要关闭定时器(那么程序也就),同时i置0,ti置1(才能跳出while(ti==0)循环),最后将ti置0,保证下次要发送字节时让程序停留在while(ti==0)。


    片上串口

    以上说的是虚拟串口,上文中谈到与串口相关的引脚P3.0与P3.1,事实上51单片机自带片上串口,那这个串口又该怎么使用呢?

    片上串口支持同步模式与异步模式。简单来说同步模式就是指有时钟线,而异步模式无时钟线。这里的时钟线是指在同步通信时,用一根线专门传输时钟信号,这个信号用来与要发送的每一位保持同步,这样就避免了例如异步通信中因为采用定时器而引入的时间误差。

    片上串口还支持8位模式和9位模式。如下图所示


    其中D0-D7是一个字节的8个位。9位模式只是多了一个位TB8,这个TB8的作用是奇偶校验或多机通信。奇偶校验原理这不加分析。多机通信时比如主机只发送数据给网络中的一台地址为0x02的设备,这时候先让TB8为1,前面的D0-D7则为地址即0x02,之后再让TB8为0,前面的D0-D7则为数据了。

    上面设置了片上串口的模式,另外还要设置串口的波特率。

    片上串口的波特率等于定时器1工作在方式2时溢出率的32分频。如果要定时器1工作在方式2,那么TMOD=0x20。另外要保证为32分频,我们还必须设置计数器初值。设晶振为11.0592Mhz,则定时器的计数脉冲为F=f/12,则定时器每计一个脉冲的时间为T=12/f。又令计数器的起点为x,则溢出一次要计的脉冲数为(256-x)。所以在计数起点为x时,溢出一次的时间为t=12/f*(256-x)。则对应的溢出率为1/t=f/(12*(256-x))。对应的波特率就为b=f/(384*(256-x))。

    x=256-f/(384*b)

    其中f为晶振频率,b为希望的波特率,x为定时器的计数起点TH1的值。

    例如当晶振为11.0592M,希望波特率为9600bit/s,则TH1=253。题外话,我们同样可以演算出在其他常用波特率情况下,TH1始终为一个整数。这里也就解释了为什么51里面选用了11.0592M的晶振而不是12M,这样就保证了串口的时序更加准确,虽然牺牲了定时器的准确度。

    实验二,片外串口发送一个字节。

    好了现在开始我们的实验之旅。直接看代码吧。

    #include "reg51.h"
    #define u16 unsigned int
    #define u8 unsigned char
    
    void delay(u16 x)
    {
    	while(x--);
    }
    
    void Uart_Init() //串口初始化
    {
    	SCON=0x50; //8位异步模式
    	TMOD|=0x20;	//定时器1工作方式2
    	TH1=253;//9600bit/s
    	TR1=1;
    }
    
    void Send_Byte(u8 dat)
    {
    	SBUF=dat; //启动发送,只需要把发送内容给SBUF这个寄存器
    	while(TI==0); //等待发送完成,因为TI为1时表示在发送停止位
    	TI=0;
    }
    
    void main()
    {
    	Uart_Init();
    	while(1)
    	{
    	   Send_Byte('m');
    	   delay(60000);
    	}
    }

    实验二较之实验一,代码减少了很多,而且不用考虑繁琐的位发送时序。只需要明白各个寄存器SCON,TMOD,TCON,SBUF的用法。TI是SCON中的第一位,为发送中断请求标志位。在本方式中,在停止位开始发送时由内部硬件置位,响应中断后TI必须又软件清零。

    实验三、片上串口发送一个字符串

    上面介绍了如何发送一个字节,那如何发送一个字符串甚至文本呢?这里我们首先介绍下字符串的概念。

    字符串:从存储器的某个地址开始,连续存放多个字符的ASCII码,并且在最后一个字符的后面存放一个0,这段连续的内存空间就叫字符串,最后的0叫字符串的结束符。注意这里的0和加单引号的0不是一个概念,加单引号的0是指0的ASCII码。

    数组与字符串的关系:字符串是数组的一种特殊情况,数组在特定条件下可当做字符串用。C语言用双引号描述一个字符串,如“abcd”。

    下面我们通过一个实验来展示如何发送字符串。我们实验的目标是打印字符串“Hello World ! 第一!”到打印机。直接上代码。

    #include "reg51.h"
    #define u16 unsigned int
    #define u8 unsigned char
    
    void delay(u16 x)
    {
    	while(x--);
    }
    
    void Uart_Init() //串口初始化
    {
    	SCON=0x50; //8位异步模式
    	TMOD|=0x20;	//定时器1工作方式2
    	TH1=253;//9600bit/s
    	TR1=1;
    }
    
    void Send_Byte(u8 dat)	  //串口发送一个字节
    {
    	SBUF=dat; //启动发送,只需要把发送内容给SBUF这个寄存器
    	while(TI==0); //等待发送完成,因为TI为1时表示在发送停止位
    	TI=0;
    }
    
     void Send_String(u8 *str)	 //发送一个字符串	*str为字符串第一个字符的地址
     {
        abc:      //标号
     	if(*str != 0)
    	{
    		Send_Byte(*str);
    		str++;
    		goto abc;	
    	}
     }
    
    void main()
    {
    	Uart_Init();
    	while(1)
    	{
    	   Send_String("Hello World! 第一!");
    	   Send_Byte(10);
    	   delay(60000);
    	   delay(60000);
    	}
    }

    实验效果


    这里就不再讲述代码了,如有问题,请及时联系。谢谢观看本文!转载此文请联系本人!
    展开全文
  • c#与单片机串口通信 自己项目用的一个程序 用串口助手测试过没问题 用的serialport控件 需要注意的是用serialport时需要调用委托 里面有通信协议 可以直接更改通信协议拿来用
  • 单片机: 自定义串口通信协议的实现

    万次阅读 2015-12-09 20:20:25
    使用51单片机完成一个简单的串口通信协议。 要求: 一个协议帧为8个字节,其中头部两个字节,分别是0xFF,0xFE; 第3个字节代表第一个数据,第4个字节代表第二个数据(均为正数); 第5个字节如果是0,代表两个数据...
    使用51单片机完成一个简单的串口通信协议。
    要求:
    一个协议帧为8个字节,其中头部两个字节,分别是0xFF,0xFE;
    第3个字节代表第一个数据,第4个字节代表第二个数据(均为正数);
    第5个字节如果是0,代表两个数据的和,1的话代表两个数据的差;
    第6个字节为0,代表使用十进制显示,为1代表十六进制显示;
    最后两个字节代表协议尾部,值分别为0xFD,0xFC。


    将传输的两个数据和他们的计算结果分别显示在数码管上。
    注意,如果差为负数,要将负号显示出来。


    思路:使用串口中断,先接收8个字节至数组保存,最后再分析处理数据,具体
    见代码,注释很详细。
     
    /*-----------------------------------------------
      名称:串口通信
      内容:连接好串口或者usb转串口至电脑,下载该程序,打开电源
            打开串口调试程序,将波特率设置为9600,无奇偶校验
            晶振11.0592MHz,发送和接收使用的格式相同,如都使用
            字符型格式,按复位重启程序,可以看到接收到 RST
    		然后在发送区发送任意信息,接收区返回同样信息,表明串口收发无误
    ------------------------------------------------*/
    
    #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义   
    
    sbit WEI=P2^7;
    sbit DUAN=P2^6;
    
    unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};// 显示段码值0~9
    unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
    
    void delay(int t)
    {
       while(t--);
    }
    
                         
    
    /*------------------------------------------------
                       函数声明
    ------------------------------------------------*/
    void SendStr(unsigned char *s);
    
    /*------------------------------------------------
                        串口初始化
    ------------------------------------------------*/
    void InitUART  (void)
    {
        SCON  = 0x50;		        // SCON: 模式 1, 8-bit UART, 使能接收  
        TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重装
        TH1   = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
        TR1   = 1;                  // TR1:  timer 1 打开                         
        EA    = 1;                  //打开总中断
        ES    = 1;                  //打开串口中断
    }   
    
    
    //参数含义:i为第几号数码管,n为要显示的值
    void Screen(int i,int n)
    {
    
         P0=0;
         DUAN=1;
    	 DUAN=0;
         
         P0=dofly_WeiMa[i];
         WEI=1;
    	 WEI=0;
        
         P0=dofly_DuanMa[n]; 
         DUAN=1;  
         DUAN=0;
    
    }
                             
    /*------------------------------------------------
                        主函数
    ------------------------------------------------*/
    int flag=0;
    int num1,num2;
    int res;
    
    int judge[8];
    int cnt=0;
    int is_fd;
    int hex_mod; 
    void main (void)
    {
      
       num1=0;
       num2=0;
       //res=0;
       InitUART();
    
       ES= 1;//打开串口中断
       is_fd=0;
      while (1)                       
        {
          
           if(judge[0]==0xFF&&judge[1]==0xFE&&judge[6]==0xFD&&judge[7]==0xFC)
    	   { 
    
    	     if(judge[5]==0x01)
    		 {
    		    hex_mod=16;
    		 }
    		 else
    		 {
    		    hex_mod=10;
    		 }
    
    	    if(judge[2]/hex_mod>0)
    	    Screen(6,judge[2]/hex_mod);
            Screen(7,judge[2]%hex_mod);
    
    	    if(judge[3]/hex_mod>0)
    	    Screen(4,judge[3]/hex_mod);
    	    Screen(5,judge[3]%hex_mod);
           
            if(judge[4]==0x00)
    	    {
    		   res=judge[2]+judge[3];
    		   is_fd=0;
    		 }
    		else
    		{
    		  res=judge[2]-judge[3];
    		  if(res<0)
    		  {
    	         is_fd=1;
    			 res=-res;
    		  }
    		  else
    		  is_fd=0;
    		 
    		}
            
    	     if(res/hex_mod>0)
    	     Screen(2,res/hex_mod);
    	     Screen(3,res%hex_mod);
    		 delay(10);
    		 if(is_fd) //判断负号
    		 {
    		    Screen(1,16);
    		 }
    
    	  }
    
        }
    }
    
    
    
    /*------------------------------------------------
                        发送一个字节
    ------------------------------------------------*/
    void SendByte(unsigned char dat)
    {
     SBUF = dat;
     while(!TI);
          TI = 0;
    }
    /*------------------------------------------------
                        发送一个字符串
    ------------------------------------------------*/
    void SendStr(unsigned char *s)
    {
     while(*s!='\0')// \0 表示字符串结束标志,通过检测是否字符串末尾
      {
      SendByte(*s);
      s++;
      }
    }
    
    
    /*------------------------------------------------
                         串口中断程序
    ------------------------------------------------*/
    void UART_SER (void) interrupt 4 //串行中断服务程序
    {
        unsigned char Temp;          //定义临时变量 
       
       if(RI)                        //判断是接收中断产生
         {
    	  RI=0;                      //标志位清零
    	  Temp=SBUF;                 //读入缓冲区的值
    	                     
    	  judge[cnt++]=Temp; 
    
          //报头不满足或者一个协议帧发送完毕
          if(cnt==8||judge[0]!=0xFF)	  
          cnt=0;
    
          SBUF=Temp;     //把接收到的值再发回电脑端
    	 }
       if(TI)                        //如果是发送标志位,清零
         TI=0;
    } 
    


    展开全文
  • 单片机的串口通信协议

    千次阅读 2015-03-03 14:12:14
    单片机的选择和串行通信协议的设计_高怀举
  • 组态王与单片机通信,使用ASCII通信协议,完整的源代码,
  • 单片机通信协议设计

    千次阅读 2009-07-02 20:55:00
    现在大部分的仪器设备都要求能过通过上位机... 自定义数据通信协议 这里所说的数据协议是建立在物理层之上的通信数据包格式。所谓通信的物理层就是指我们通常所用到的RS232、RS485、红外、光纤、无线等等通信方式。
  • PIC单片机通信协议

    千次阅读 2013-04-23 11:47:44
    当人们晚上迷失在野外手上只有一个手电筒,此时直升机飞过。人们用手电筒发出三短三长三短的光线。用这个国际通用的SOS求救信号,告诉飞行员来救你。人们规定的三短三长三短的光线,代表SOS就是一种通讯协议。  ...
  • 单片机串口通信协议的实现

    千次阅读 2017-12-14 09:33:21
    单片机串口通信协议的实现 单片机上的串口是日常调试和做一些简单人机交互的一种重要的通信方式,其原理网上一大堆,这里就不再赘述了,下面主要和大家分享一种我在实际项目中经常用到的一个简单的串口通信协议...
  • 组态王与单片机通信协议3

    千次阅读 2015-11-03 21:37:22
    此浮点数格式的转换: 1)ASCII码到浮点数:   float C4toD(char * c) {  BYTE Hd[30], Jiema[30];  float DTc[30];  float Decimal = 0;    memset(Hd, 0, sizeof(Hd));
  • PC机和单片机通信协议 接收后数据校验正确且数据在范围内:F1 55 AA F2 接收后数据检验正确但数据不在范围内:F1 55 BB F2 接收后数据校验不正确:F1 AA AA F2
  • 单片机通信协议处理

    千次阅读 2014-05-06 15:01:34
    1、自定义数据通信协议 这里所说的数据协议是建立在物理层之上的通信数据包格式。所谓通信的物理层就是指我们通常所用到的RS232、RS485、红外、光纤、无线等等通信方式。在这个层面上,底层软件提供两个基本的操作...
  • 一个单片机和ARM cpu之间通信协议的示例 在进行soc之间进行通信时,往往需要制定通信协议,以下是我制定的一个示例,供大家参考: 格式: 1)magicmagic头长度为2字节,内容为0x55,0xAA,这是字节出现顺序,不区分...
  • 前面说了信息与数据的概念,这里要说的是与之关系密切的问题——通信通信 何为通信?在英文中,通信用Communication表示,这个词也交流的意思。实际上,通信和交流确实是一样的意思。不过在汉语中,交流...
  • 基于Freescal单片机的LIN通信协议C语言开发(一)

    千次阅读 热门讨论 2018-11-08 18:54:03
    基于Freescal单片机的LIN通信协议C语言开发(一) 要全部pdf文档可以留言!基于Freescal单片机的LIN通信协议C语言开发(一)                         ...
  • 51单片机编写的标准modbus协议通信模版,非常经典
  • 单片机通信的加密和解密

    千次阅读 2018-11-20 11:25:27
    通信时候为了保证截获方即使得到了数据包,也不知道内容,所以加密传输即可;但时候不需要知道数据包的内容,只要知道知道数据包能干嘛即可,比如发指令,此种情况单单对数据包进行加密就不够了。   基础...
  • 关于通信方面的总结(通信协议、通信端口)简介串行通信协议(数据怎么传输)同步串行通信协议异步串行通信协议串行接口标准(接口由多少根信号线、信号的电平类型,不考虑数据怎么控制传输) 简介 本文主要讨论...
1 2 3 4 5 ... 20
收藏数 14,172
精华内容 5,668
关键字:

单片机 通信协议有哪些