单片机之串口通信 485多机通信 红外测试
单片机之串口通信 485多机通信 红外测试
串口通信是计算机与外部设备或计算机之间进行信息交换的基础技术之一。本文将详细介绍串行通信和并行通信的基本原理,以及串口通信的同步和异步方式。同时,本文还将通过具体的实验案例(串口通信、485多机通信和红外通信),帮助读者更好地理解串口通信技术。
计算机通信基础
计算机通信是将计算机技术和通信技术相结合,完成计算机与外部设备或计算机之间的信息交换。
并行通信
并行通信通常是将数据字节的各位用多条数据线同时进行传送。控制简单、传输速度快,但由于传输线较多,长距离传送时成本高且接收方的各位同时接收存在困难。
串行通信
串行通信将数据字节分成一位一位的形式在一条传输线上逐个地传送。传输线少,长距离传送时成本低,且可以利用电话网等现成的设备,但数据的传送控制比并行通信复杂(并串、串并转换)。
串行通信方式
串行通信包含同步通信和异步通信两种方式。
异步通信
- 是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。
- 以字符(构成的帧)为单位进行传输,字符与字符之间的间隙(时间间隔)是任意的,但每个字符中的各位是以固定的时间传送的,即字符之间不一定有“位间隔”的整数倍的关系,但同一字符内的各位之间的距离均为“位间隔”的整数倍。
- 不要求收发双方时钟的严格一致,实现容易,设备开销较小,但每个字符要附加2~3位用于起止位,各帧之间还有间隔,因此传输效率不高。
同步通信
要建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为“位间隔”的整数倍,同时传送的字符间不留间隙,即保持位同步关系,也保持字符同步关系。
发送方对接收方的同步可以通过两种方法实现:
- 面向字符的同步格式:传送的数据和控制信息都必须由规定的字符集(如ASCII码)中的字符所组成。帧头为1个或2个同步字符SYN(ASCII码为16H),SOH为序始字符(ASCII码为01H),标题中包含源地址、目标地址和路由指示等信息,STX为文始字符(ASCII码为02H),数据块是传送的正文内容,由多个字符组成,组终字符ETB(ASCII码为17H)或文终字符ETX(ASCII码为03H),校验码。
- 面向位的同步格式:将数据块看作数据流,并用序列01111110作为开始和结束标志。为了避免在数据流中出现序列01111110时引起的混乱,发送方总是在其发送的数据流中每出现5个连续的1就插入一个附加的0;接收方则每检测到5个连续的1并且其后有一个0时,就删除该0。
信号的调制与解调
利用调制器(Modulator)把数字信号转换成模拟信号,然后送到通信线路上去,再由解调器(Demodulator)把从通信线路上收到的模拟信号转换成数字信号。由于通信是双向的,调制器和解调器合并在一个装置中,这就是调制解调器MODEM。
传输速率与传输距离
- 比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps)。如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位、1个停止位、8个数据位),这时的比特率为:10位×240个/秒 = 2400 bps。
- 串行接口或终端直接传送串行信息位流的最大距离与传输速率及传输线的电气特性有关。
RS-232C与RS-485接口
RS-232C接口
RS-232C是一种常用的串行通信接口标准,其电平与TTL电平需要通过转换驱动电路进行转换。
RS-485接口
RS-485是一种多发送器标准,在通信线路上最多可以使用32 对差分驱动器/接收器。如果在一个网络中连接的设备超过32个,还可以使用中继器。RS-485的信号传输采用两线间的电压来表示逻辑1和逻辑0。由于发送方需要两根传输线,接收方也需要两根传输线。传输线采用差动信道,所以它的干扰抑制性极好,又因为它的阻抗低,无接地问题,所以传输距离可达1200米,传输速率可达1Mbps。
串口通信实验
实验现象
上位机向单片机发送数据:在发送缓冲区显示要发送的数据,按下按键1数据发送到单片机,并在数码管上显示相应的数据;下位机向上位机发送数据:在单片机数码管上显示要发送的数据,可以通过按键2、3进行调整,按下按键1数据发送到上位机,在接受缓冲区显示接收到的数据。
实验原理
单片机集成了USB转串口模块,对应使用RXD线接收数据,用TXD发送数据。每个串口由2个数据缓冲器(相互独立1收1发)、一个移位寄存器(一字节数据一位一位发送出去)、一个串行控制器和一个波特率发生器(这个比较重要,结合相关的定时器)组成。
对应发送、接收数据完成(RI、TI硬件置1)都会触发串口中断,但是无法确定是哪个触发的,所以在串口中断中我们要判断是接收数据产生的中断还是发送数据产生的中断,对于发送数据产生的中断,我们要软件将TI清0,并将数据就绪标志清0,允许下一字节数据发送,发送数据函数中通过while循环,等待发送数据准备就绪,完了将就绪的数据复制给SBUF;对于接收数据产生的中断,我们要软件将RI清0,并从SBUF中读取数据。
代码解析
程序设计流程图:
主函数部分:调用Init函数进行初始化,while(1)循环中,主要是判断按键是否按下,当按下Key1时进行对上位机发送数据,而Key2、Key3调整发送的数据的大小。
涉及的一些函数:
void Timer0() interrupt 1 //定时器0的中断响应函数
void Uart1_Init(void) //初始化串口1的相关设置,设定串口的波特率等
void SendData(unsigned char dat) //发送单个字符给UART1以发送到PC机
void Uart1_fun() interrupt 4 using 1 //串口1中断服务程序
void Init() //完成各部分功能模块的初始化
- void Uart1_fun() interrupt 4 using 1 串口中断程序
- TI:发送中断标志位,当发送完8位数据后,TI由硬件置位;TI=0,时,可申请中断,也可供软件查询用,在任何方式都必须由软件清除TI;
- RI:接收中断标志位,在方式0中,接受完8位数据后,有硬件置位;在其它方式中,在接受停止位的中间,由硬件置位。RI=1时,可申请中断,也可供软件查询用,在任何方式都必须由软件清除RI;
485多机通信实验
实验现象
将两块带有485模块的51单片机通过485外接引脚A、B连接起来,单片机上电烧写程序后485模块的D/R引脚所对应的二极管均点亮,然后通过按键KEY3、KEY2控制数码管上的数值进行加减处理,两块单片机起始都默认为接收状态,最后按下KEY1发送键,将数据传送给另一块单片机,而此时接收方数码管上的数值发生相应的改变,与发送方数码管上的数值一致。
注意事项
- RS485属于半双工通信,数据可以在一个信号载体的两个方向上传输,但是不能同时进行传输
- 电平转换采用差分电路方式,A、B两线的电压差大于0.2认为是逻辑“1”,小于-0.2认为是逻辑“0”,方便与TTL电路连接
- 使用RS485进行通信与RS232通信的逻辑是一致的,但RS485抗干扰性更强,传输距离更远
- MAX485芯片的功能是将TTL电平转换为RS485电平
实验原理
电路原理图如下:
引脚功能:
- 485 D/R输出、接收信号控制引脚:当该引脚为低电平时,485为接收态,MAX485通过485_RX、D把来自u总线的信号输出给单片机;当该引脚为高电平时,485为发送态,来自485_TXD的输出信号通过A、B引脚加载到总线上
- 485_RXD引脚接收数据,RX1 LED点亮时表示正在接收数据
- 485_TXD引脚发送数据,TX1 LED点亮时表示正在发送数据
- A、B端口与另一个开发板上的MAX485的A、B连接实现双机通信
使用RS485进行通信的大致步骤为:
- 初始化波特率,设置好串口通信模式
- 发送数据时将数据放入S2BUF,并软件清零S2RI
- 接收数据时从S2BUF读取数据,并软件清零S2TI
代码解析
设计总流程图:
一些需要用到的函数:
void Uart2Init(void); //串行口初始化函数
void CPUInit(void); //CPU初始化函数,配置相关寄存器和IO口模式
void delay(void); //延时函数
void ser2_int(void) interrupt 8 using 1 //串口中断处理函数
void ex_int0() interrupt 0 //外部中断0处理函数
这个比串口通信相对于简单一点,就不具体分析代码了,就提供一些基本思路
红外测试实验
实验现象
需要两个电路板,一个电路板用于发送,另一个用于接收。按下KEY1每100毫秒发送红外信号一次。接收方在接收到红外信号后,L0会发光。
红外接收头IR_R用于接收红外发光二极管IR_T发出的红外信号,从而达到一个通信的目的。但在自然环境中并非只有红外发光二极管能发出红外线,自然光、日光灯灯光等光线中都含有红外线,故红外接收头需要对红外信号进行区分,把无关信号过滤。
因此,红外接收头被设计为只能接受一定频率范围内的红外线脉冲。例如,当红外发光二极管每隔13us发出一次红外线脉冲,发光时间也为13us,即发出了一个38kHz的红外脉冲信号,而这个信号的频率恰好在接收头的接收范围内,接收头就会接收此红外信号并把这个38kHz的红外信号方波转换成电信号。而自然环境中的红外干扰信号不在接收头的接收频率内,接收头不会接收。
实验原理
电路原理图如下:
其中TXD 对应p3.5
RXD对应p3.6
- 发送:不断检测KEY1(P3.2引脚)的电平。当KEY1为低电平时,认为按键被按下,每隔一段时间设置一次标志位。定时器T0每13us检测一次标志位,若标志位为0则使P3.5引脚电平不断发生翻转,间歇地发出38kHz红外光。在KEY1没有被按下的时候确保标志位值1,使得P3.5引脚输出低电平。
- 接收:不断检测P3.6引脚的电平。若P3.6输入了低电平,则代表接收到了红外信号,点亮Led灯
代码解析
全局变量:
int flag = 1; //标记位,标记是否发出送脉冲。0:发送、1:不发送
函数:
void Timer0Init(); //定时器T0初始化
void Delay(); //延时100ms函数
void Timer0() interrupt 1//定时器0中断:可产生38kHz红外脉冲