十三、串口通信和RS485 ?? ?1、通信有关的常见概念 ?? ??? ?a、什么是通信 ?? ??? ??? ?(1)人和人之间的通信:说话、写信、狼烟、手势 ?? ??? ??? ?(2)人和计算机之间的通信:按键、显示屏、鼠标、触摸屏等。 ?? ??? ??? ?(3)计算机和计算机之间的通信?
?? ??? ?b、通信的关键 ?? ??? ??? ?(1)事先约定 ?? ??? ??? ?(2)基本信息单元 ?? ??? ??? ?(3)有效信息的编码、传输和解码
?? ??? ?c、通信的专业性概念 ?? ??? ??? ?(1)同步和异步 ?? ??? ??? ?(2)单工、半双工、全双工 ?? ??? ??? ?(3)并行和串口 ?? ??? ??? ?(4)电平信号和差分信号 ?? ??? ??? ??? ?电平信号:用电平的高低来组成信号,即信号是有一系列高低电平组成了。 ?? ??? ??? ??? ?差分信号:两根线为一组,测量两根线电压差,电压差大的为1,小的为0。 ?? ??? ??? ??? ?差分信号抗干扰的能力比电平信号强,传输速度快,传输距离远。
?? ?2、什么是串行通信 ?? ??? ?a、串口通信基础 ?? ??? ??? ?(1)一种特定的通信协议 ?? ??? ??? ?(2)串行通信、串口通信、UART、USART ?? ??? ??? ?(3)异步、串行、全双工
?? ??? ?b、串行通信的主要用途 ?? ??? ??? ?(1)早期:计算机之间短距离通信(1.5米之内),完备通讯机制 ?? ??? ??? ?(2)现在:CPU之间近距离通信、调试信息输入输出,非完备通信
?? ??? ?c、串行通信的工作方式 ?? ??? ??? ?(1)3根线(GND、RxD、TxD)或者九根线 ?? ??? ??? ??? ?注意:3PIN接口的时候,GND和GND相连,一端的R接另一端的T,两边的R和T线都是如此链接的。 ?? ??? ??? ? 在这里,R代表receive;T代表transmit ?? ??? ??? ?(2)发送方有发送移位寄存器,接收方有接收移位寄存器 ?? ??? ??? ?(3)数据在发送方和接收方的CPU中都以字节为单位整字节处理 ?? ??? ??? ?(4)数据在通信线上以位为单位逐个bit的传输
?? ??? ?d、串行通信的主要概念 ?? ??? ??? ?(1)起始位、数据位、奇偶校验位、停止位(帧) ?? ??? ??? ?(2)波特率:一秒钟传输多少个bit位,发送方和接收方必须保持波特率一致。 ?? ??? ??? ?(3)流控:速率协商,现在一般禁用掉。
?? ?3、51单片机的串行通信 ?? ??? ?a、先搞清楚这几个问题 ?? ??? ??? ?(1)串行通信功能是SoC的一个(内部)外设提供的,与CPU本身无关 ?? ??? ??? ?(2)各种不同的SoC的串行通信大同小异 ?? ??? ??? ?(3)串行通信经常作为主控SoC与其他外部芯片之间的通信接口
?? ??? ?b、STC51单片机的串行通信简介 ?? ??? ??? ?(1)STC89C51RC/RD+系列单片机内部集成了一个功能很强的全双工串行通信口,与传统8051单片机 ?? ??? ? 的串口完全兼容。 ?? ??? ? ?? ?(2)设有两个互相独立的接收、发送缓冲区,可以同时发送和接收数据。发送缓冲区只能写入而不能读 ?? ??? ? 出,接收缓冲区只能读出而不能写入,因此两个缓冲区可以共用一个地址码(99H)。两个缓冲区统称串行 ?? ??? ? 通信特殊功能寄存器SBUF。 ?? ??? ? ?? ?(3)设有四种工作模式,其中两种波特率可变,另外两种是固定的。 ?? ??? ? ?? ?(4)波特率是由定时器/计数器产生的,由软件来设置不同的波特率和不同的工作方式。 ?? ??? ? ?? ?(5)主机可以通过查询或者中断的方式对接收/发送进行程序处理,使用十分灵活。
?? ?4、STC51的串行通信相关寄存器1 ?? ??? ?a、总体浏览 ?? ??? ??? ?(1)SCON,Serial Control ?? ??? ??? ?(2)SBUF,Serial Buffer ?? ??? ??? ?(3)PCON,Power Control ?? ??? ??? ?(4)IE,Interrupt Enable ?? ??? ??? ?(5)IPH,中断优先级寄存器 ?? ??? ??? ?(6)IP,中断优先级寄存器 ?? ??? ??? ?(7)SADEN,Slave Address Mask ?? ??? ??? ?(8)SADDR,Slave Address
?? ??? ?b、SCON ?? ??? ??? ?(1)STC89C51RC/RD+系列单片机的串行口设有两个控制寄存器:串行控制寄存器SCON和波特率选择 ?? ??? ? 特殊功能寄存器PCON。 ?? ??? ? ?? ?(2)串行控制寄存器SCOON用于选择串行通信的工作方式和某些控制功能。其格式如下: ?? ??? ? SCON:串行控制寄存器(可位寻址) ?? ??? ? |SFR name |Address |bit ? |B7 ?? ? ? |B6 ?? ? |B5 ?|B4 ?? ?|B3 ?|B2 ? |B1 | B0 ?? ?| ?? ??? ? |------------------------------------------------------------------- ?? ??? ? |SCON ?? ? ? ? | ?98H?? ? ? |name |SM0/FE |SM1?? ? |SM2 |REN |TB8 |RB8 |TI |RI ?? ?|
?? ??? ? SM0/FE:当PCON寄存器中的SMOD0/PCON.6位为1时,该位用于帧错误检测,当检测到一个无效停止位的 ?? ??? ? ?? ??? ? ?时候,通过UART接收器设置该位。它必须由软件清零。 ?? ??? ? ?? ??? ? ?当PCON寄存器中的SMOD0/PCON.6位为0的时候,该位和SM1一起指定串行通信的工作方式。
?? ??? ? ?? ??? ? 其中SM0、SM1按下列组合确定串行口的工作方式: ?? ??? ? ?? ??? ??? ?1、SM0=0,SM1=0时。工作方式为方式0,功能为同步移位寄存器的方式,波特率是SYSclk/2。 ?? ??? ? ?? ??? ??? ?2、SM0=0,SM1=1时。工作方式为方式1,功能为8位UART,波特率可变,波特率为 ?? ??? ? ?? ??? ??? ??? ?(2^SMOD/32)*(定时器1的溢出率) ?? ??? ? ?? ??? ??? ?3、SM0=1,SM1=0时。工作方式为方式2,功能为9位UART,波特率为(2^SMOD/64)*SYSclk系 ?? ??? ? ?? ??? ??? ??? ?统工作时钟频率 ?? ??? ? ?? ??? ??? ?4、SM0=1,SM1=1时。工作方式为方式3,功能为9位UART,波特率可变,波特率为 ?? ??? ? ?? ??? ??? ??? ?(2^SMOD/32)*(定时器1的溢出率) ?? ??? ? ?? ??? ??? ?5、当单片机工作在12T模式的时候,定时器1的溢出率=SYSclk/12/(256-TH1); ?? ??? ? ?? ??? ??? ??? ?当单片机工作在6T模式的时候,定时器1的溢出率=SYSclk/6/(256-TH1)
?? ??? ? SM2:允许方式2或者方式3多机通信控制位。在方式2或者方式3时,如SM2位为1,REN位为1,则从处于只 ?? ??? ? ?? ? ?有接收RB位为1(地址帧)时才激活请求标志位RI为1,并向主机请求中断处理。被确认为寻址的从机 ?? ??? ? ?? ? ?则复位SM2为0,从而才接收RB8为0的数据帧。 ?? ??? ? ?? ? ?在方式1的时候,如果SM2位为1,则只有在接收到有效的停止位时才置位中断请求标志位RI为1;在方 ?? ??? ? ?? ? ?式0时,SM2应为0。
?? ??? ? REN:允许/禁止串行接收控制位。由软件置位REN,即REN=1的时候允许串行接收状态,可启动串行接收器 ?? ??? ? ?? ? ?RxD,开始接收信息。软件复位REN,即REN=0,则禁止接收。
?? ??? ?TB8:在方式2或者方式3,它为要发送的第9位数据,按需要由软件置位或清0.譬如,可用作数据的校验位或 ?? ??? ??? ? ?多机通信中表示地址帧/数据帧的标志位。
?? ??? ? RB8:在方式2或者方式3,是接收到的第9位数据。在方式1,若SM2=0,则RB8是接收到的停止位。方式0 ?? ??? ? ?? ? ?不用RB8。
?? ??? ? TI:发送中断请求标志位。在方式0,当串行发送数据第8位结束的时候,由内部硬件自动置位,即TI=1,向 ?? ??? ? ?? ? ?主机请求中断,响应中断后必须用软件复位,即TI=0。在其他方式中,则在停止位开始发送时由内部硬 ?? ??? ? ?? ? ?件置位,必须用软件复位。
?? ??? ? RI:接收中断请求标志位。在方式0,当串行接收到第8位结束时由内部硬件自动置位RI=1,向主机请求中断 ?? ??? ? ?? ? ?,响应中断后必须用软件复位,即RI=0。在其他方式中,串行接收到停止位的中间时刻由内部硬件置位, ?? ??? ? ?? ? ?即RI=1(例外在SM2中有详细说明),必须由软件复位,即RI=0。
?? ??? ? ?? ?(3)SCON的所有位可以通过整机复位信号复位全“0”。SCON的字节地址位98H,可位寻址,各地址位为 ?? ??? ? 98H~9FH,可用软件实现位设置。当用指令改变SCON的有关内容时,其改变的状态将在下一条指令的第一个 ?? ??? ? 机器周期的S1P1状态发生作用。如果一次串行发送已经开始,则输出TB8将是原先的值,不是新改变的值。 ?? ??? ? ?? ?(4)串行通信的中断请求:当一帧发送完成,内部硬件自动置位T1,即T1=1,请求中断处理;当接收完 ?? ??? ? 一帧信息的时候,内部硬件自动置位RI,即RI=1,请求中断处理。由于TI和RI以“或逻辑”关系向主机请求中 ?? ??? ? 断,所以主机响应中断时事先并不知道是TI还是RI请求的中断,必须在中断服务程序中查询TI和RI进行判别, ?? ??? ? 然后分别处理。因此,两个中断请求标志位均不能由硬件自动置位,必须通过软件清0,否则将出现一次请求 ?? ??? ? 多次响应的错误。 ?? ??? ? ?? ? ?? ??? ? ?? ?(5)串口发送时的软硬件协作方式 ?? ??? ? ?? ??? ?1、查询方式。硬盘在发送完一帧数据后会将一个标志位置位(标志位本来为0),软件需要不断读 ?? ??? ? 取这个标志位的值来判断硬件是否完成了发送(如果读出来是0就表示硬件还在发送数据当中,就不能给硬件 ?? ??? ? 安排下一帧数据的发送;如果读出来是1则说明硬件已经发送完了上一帧数据,这个时候软件就应当安排一帧 ?? ??? ? 数据去发送)。因为串口发送对于CPU来说是一个异步事件,所以这里使用查询方式来处理和之前讲过的查询 ?? ??? ? 方式处理按键是相似的。 ?? ??? ? ?? ? ?? ?2、中断方式。查询方式处理劣势是CPU必须一直守着串口发送,在串口发送完所有字节之前CPU不 ?? ??? ? 能去做其他事情,这对CPU来说是极大的浪费(因为CPU的速度比串口发送的速度快多了)。因此用中断的方 ?? ??? ? 式处理串口发送时非常合适的,可以提升CPU使用率。 ?? ??? ? ?? ? ?? ?3、在常见的情况下:串口发送会使用查询方式,而串口接收会使用中断方式。
?? ?5、STC51的串行通信相关寄存器2 ?? ??? ?a、SBUF ?? ??? ??? ?STC89xx系列单片机的串行口缓冲寄存器(SBUF)的地址是99H,实际是2个缓冲器,写SBUF的操作完 ?? ??? ? 成待发送数据的加载,读SBUF的操作可获得已接收到的数据。两个操作分别对应两个不同的寄存器,1个是 ?? ??? ? 只写寄存器,1个是只读寄存器。 ?? ??? ? ?? ?串行通道内设有数据寄存器。在所有的串行通信方式中,在写入SBUF信号的控制下,把数据装入相同的 ?? ??? ? 9位移位寄存器,前面8位为数据字节,其最低位为移位寄存器的输出位。根据不同的工作方式将“1”或者TB8 ?? ??? ? 的值装入移位寄存器的第9位,并进行发送。 ?? ??? ? ?? ?串行通道的接收寄存器是一个输入移位寄存器。在方式0时它的字长为8位,其他方式则为9位。当一帧接 ?? ??? ? 收完毕,移位寄存器中的数据字节装入串行数据缓冲器SBUF中,其第9位则装入SCON寄存器中的RB8位。如 ?? ??? ? 果由于SM2使得已接收到的数据无效时,RB8和SBUF中内容不变。 ?? ??? ? ?? ?由于接收通道内设有输入移位寄存器和SBUF缓冲器,从而能使一帧接收完将数据有移位寄存器装入SBUF ?? ??? ? 后,可立即开始接收下一帧信息,主机应在该帧接收结束前从SBUF缓冲器中将数据取走,否则前一帧数据将 ?? ??? ? 丢失。SBUF以并行方式送往内部数据总线。
?? ??? ?b、PCON ?? ??? ??? ?电源控制寄存器PCON中的SMOD/PCON.7用于设置方式1、方式2、方式3的波特率是否加倍。 ?? ??? ??? ?电源控制寄存器PCON格式如下: ?? ??? ? PCON:电源控制寄存器(不可位寻址) ?? ??? ? |SFR name |Address |bit ? |B7 ?? ? ?|B6 ?? ? ?|B5 |B4 ?? ?|B3 ?|B2 ? |B1 | B0 ?? ?| ?? ??? ? |------------------------------------------------------------------- ?? ??? ? |PCON ?? ? ? ? | ?87H?? ? ? |name |SMOD ?|SMOD0 |- ?|POF |GF1 |GF0 |PD |IDL ?? ?|
?? ??? ? SMOD:波特率加倍选择位。当用软件设置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波特率加倍; ?? ??? ? ?? ??? ?SMOD=0,则各工作方式的波特率加倍。复位时SMOD=0。 ?? ??? ? SMOD0:帧错误检测有效控制位。当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能;当 ?? ??? ? ?? ??? ? SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式。复位时 ?? ??? ? ?? ??? ? SMOD0=0。 ?? ??? ? 波特率加倍:所谓波特率加倍,就是正常计算出的波特率假设是2400,那么SMOD=1的时候,则实际的波特率为 ?? ??? ? ?? ??? ? 4800;当SMOD=0的时候不加倍,也就是2400还是2400。 ?? ??? ? ?? ??? ?c、IE ?? ??? ??? ?串行口中断允许位ES位于中断允许寄存器IE中,中断允许寄存器的格式如下: ?? ??? ? IE:中断允许寄存器(可位寻址) ?? ??? ? |SFR name |Address |bit ? |B7 ?? ? ?|B6 |B5 ? |B4 |B3 ?|B2 ? |B1 ?| B0 ?? ?| ?? ??? ? |------------------------------------------------------------------- ?? ??? ? |?? ? ?IE ? ?| ?A8H?? ? ? |name |EA ? ? |- ?|ET2 ?|ES |ET1 |EX1 |ET0 |EX0 ?? ?|
?? ??? ? EA:CPU的中断允许控制位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。EA的作用是使中断 ?? ??? ? ?? ? ?允许形成多级控制。即个中断源首先受EA控制;其次还受各个中断源自己的中断允许位控制。
?? ??? ? ES:串行口中断允许位,ES=1,允许串行口中断,ES=0,禁止串行口中断。
?? ??? ?d、IPH&IP ?? ??? ??? ?串行口的中断允许优先级控制位PS/PSH位于中断优先级控制器IP、IPH中。
?? ?6、STC51的串行通信实战1 ?? ??? ?a、硬件接线分析 ?? ??? ??? ?(1)目标:将PC机与51单片机通过串口链接起来 ?? ??? ??? ?(2)PC机的串口情况分析 ?? ??? ??? ?(3)开发板原理图分析
?? ??? ?b、接线方案 ?? ??? ??? ?(1)使用板载CH340:什么都不用动,开发板默认就是这种,最简单最省事,最推荐 ?? ??? ??? ?(2)使用DB9接口USB转串口线:用DB9接口的USB转串口线,注意跳线帽接到?? ?RTXD和RRXD一侧 ?? ??? ??? ?(3)使用TTL接口USB串口线:只接三根线:TxD、RxD、GND
?? ?7、STC51的串行通信实战2 ?? ??? ?a、使用板载CH340进行实验 ?? ??? ??? ?(1)接线+下载程序 ?? ??? ??? ?(2)查设备管理器确定COM号 ?? ??? ??? ?(3)使用普中下载软件自带的串口助手监视 ?? ??? ??? ?(4)使用第三方串口助手软件监视 ?? ??? ??? ?(5)使用SecureCRT软件监视
?? ??? ?b、使用DB9接口USB转串口线 ?? ??? ??? ?(1)接线+跳线帽调整 ?? ??? ??? ?(2)注意对下载程序的影响 ?? ??? ??? ?(3)使用各种方式进行监视
?? ??? ?c、使用TTL接口USB串口线 ?? ??? ??? ?(1)注意接线 ?? ??? ??? ?(2)确定COM号 ?? ??? ??? ?(3)利用软件进行监视
?? ?8、STC51的串行通信实战3 ?? ??? ?a、串口初始化 ?? ??? ??? ?代码: ?? ??? ??? ??? ?//串口初始化 ?? ??? ??? ??? ?//预设一个串口状态:8数据位、1停止位、0校验位、波特率9600 ?? ??? ??? ??? ?//初始化的只要工作就是预设相关的寄存器 ?? ??? ??? ??? ?void uart_init(void) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?SCON = 0x50;?? ??? ?//串口工作在模式1(8位串口)、允许接收 ?? ??? ??? ??? ??? ?PCON = 0x80; ?? ??? ?//波特率加倍,意思是本来需要波特率4800, ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//等下计算的时候按照2400去计算就可以了 ?? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?//通信波特率相关的设置,本次实验使用的是11.0592MHz的晶振,计算波特率无误差。用12MHz的晶振 ?? ??? ??? ??? ??? ?//计算出来会有误差 ?? ??? ??? ??? ??? ?TMOD = 0x20; ?? ??? ?//设置T1为模式2 ?? ??? ??? ??? ??? ?TH1 ?= 250; ?? ??? ??? ??? ??? ?TL1 ?= 250;?? ??? ??? ?//8位自动重装,意思就是TH1用完之后狭义走起TL1会自动重装到TH1去 ?? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?TR1 ? = 1; ?? ??? ??? ?//开启T1让它开始工作 ?? ??? ??? ??? ?}
?? ??? ?b、波特率计算:在这次试验中工作方式是方式1,因此波特率为(2^SMOD/32)*(SYSclk/12/(256-TH1)) ?? ??? ??? ??? ??? ? ? 带入数值,可得9600=(2/32)*(11.0592*10^6/12/(256-TH1) ?? ??? ??? ??? ??? ? ? 可以推出TH1 = 256-((11.0892*10^6)/(16*12*9600))=256 - 6 = 6 ?? ??? ??? ??? ??? ? ? 因此在初始化中关于波特率设置的TH1和TL1都是250
?? ??? ?c、串口发送字符/字符串 ?? ??? ??? ?完整代码: ?? ??? ??? ??? ??? ?#include <REGX51.H>
?? ??? ??? ??? ??? ?//函数声明 ?? ??? ??? ??? ??? ?void uart_init(void); ?? ??? ??? ??? ??? ?void uart_send_byte(unsigned char c); ?? ??? ??? ??? ??? ?void delay(unsigned int t);
?? ??? ??? ??? ??? ?unsigned char china[20]="往生堂第七十七代堂主";
?? ??? ??? ??? ??? ?void main(void) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?unsigned char i; ?? ??? ??? ??? ??? ??? ?//第一步:初始化好串口到正确状态 ?? ??? ??? ??? ??? ??? ?uart_init(); ?? ??? ??? ??? ??? ??? ?//通过串口发送信息出去 ?? ??? ??? ??? ??? ??? ?while(1) ?? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ?for(i=0; i<20; i++) ?? ??? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ??? ?uart_send_byte(china[i]); ?? ??? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ??? ??? ?delay(500);?? ??? ??? ??? ??? ?//此处延时不建议太小,否则会出错 ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?//串口初始化 ?? ??? ??? ??? ??? ?//预设一个串口状态:8数据位、1停止位、0校验位、波特率9600 ?? ??? ??? ??? ??? ?//初始化的只要工作就是预设相关的寄存器 ?? ??? ??? ??? ??? ?void uart_init(void) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?SCON = 0x50;?? ??? ?//串口工作在模式1(8位串口)、允许接收 ?? ??? ??? ??? ??? ??? ?PCON = 0x80; ?? ??? ?//波特率加倍,意思是本来需要波特率4800, ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//等下计算的时候按照2400去计算就可以了 ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ??? ?//通信波特率相关的设置,本次实验使用的是11.0592MHz的晶振,计算波特率无误差。用12MHz的晶振 ?? ??? ??? ??? ??? ??? ?//计算出来会有误差 ?? ??? ??? ??? ??? ??? ?TMOD = 0x20; ?? ??? ?//设置T1为模式2 ?? ??? ??? ??? ??? ??? ?TH1 ?= 250; ?? ??? ??? ??? ??? ??? ?TL1 ?= 250;?? ??? ??? ?//8位自动重装,意思就是TH1用完之后狭义走起TL1会自动重装到TH1去 ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ??? ?TR1 ? = 1; ?? ??? ??? ?//开启T1让它开始工作 ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?//串口发送函数 ?? ??? ??? ??? ??? ?void uart_send_byte(unsigned char c) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?//第一步,丢一个字节给串口 ?? ??? ??? ??? ??? ??? ?SBUF = c; ?? ??? ??? ??? ??? ??? ?//第二步,先确认串口在不在忙 ?? ??? ??? ??? ??? ??? ?while(!TI); ?? ??? ??? ??? ??? ??? ?//第三步,软件复位标志位 ?? ??? ??? ??? ??? ??? ?TI = 0; ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?void delay(unsigned int t) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?while(t--) ?? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ?unsigned char i = 2; ?? ??? ??? ??? ??? ??? ??? ?unsigned char j = 239; ?? ??? ??? ??? ??? ??? ??? ?do ?? ??? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ??? ?while(--j); ?? ??? ??? ??? ??? ??? ??? ?}while(--i);?? ??? ? ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?}
?? ?9、STC51的串行通信实战4 ?? ??? ?a、串口发送字符串 ?? ??? ? ? 方法1: ?? ??? ??? ??? ?(1)在程序开头添加字符串数组:unsigned char china[20]="往生堂第七十七代堂主"; ?? ??? ??? ??? ?(2)给串口发送函数添加循环: ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?for(i=0; i<20; i++) ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?uart_send_byte(china[i]); ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?delay(200); ?? ??? ??? ??? ?(3)在循环后的延时函数不可少,不然会出错
?? ??? ??? ?方法2: ?? ??? ??? ??? ??? ?(1)将字符串发送变为函数: ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?void uart_send_string(unsigned char *str) ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?while(*str != '\0') ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?uart_send_byte(*str); ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?str++; ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?(2)主函数直接调用: ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?while(1) ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?uart_send_string(china); ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//也可以直接输入字符串不用定义数组 ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//uart_send_string("一二三四五六七八红红火火恍恍惚惚"); ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//这种形式也可以。 ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?delay(200); ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?}
?? ??? ?b、串口接收函数编写 ?? ??? ??? ?代码: ?? ??? ??? ??? ?void uart_isr(void) interrupt 4 using 1 ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?unsigned char temp; ?? ??? ??? ??? ??? ?if (RI == 1) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?temp =SBUF; ?? ??? ?//读取SBUF,其实就是读出了出啊口接收到的字节 ?? ??? ??? ??? ??? ??? ?RI ? = 0; ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?//至此已经读到了PC发给单片机的1个字节,但是单片机没有显示器没法显示给人看 ?? ??? ??? ??? ??? ?//用最简单的方法来测试,就是直接回发 ?? ??? ??? ??? ??? ?uart_send_byte(temp); ?? ??? ??? ??? ?}
?? ?10、RS485介绍 ?? ??? ?a、UART的缺陷:传输距离受限 ?? ??? ??? ?(1)理论上RS232传输距离不超过15米 ?? ??? ??? ?(2)理论上TTL电平的传输距离更短 ?? ??? ??? ?(3)实际上几百米也有人宣传做到了,但是稳定性不能保证 ?? ??? ??? ?(4)波特率越高通信距离越短
?? ??? ?b、远距离传输怎么办? ?? ??? ??? ?(1)提高电压标准 ?? ??? ??? ?(2)提高通信线抗干扰能力、降低阻抗 ?? ??? ??? ?(3)使用差分信号
?? ??? ?c、RS485(RS422) ?? ??? ??? ?(1)最大通信距离1200多米,最快通信速率10Mbps,距离和速度成反比 ?? ??? ??? ?(2)差分信号负逻辑 ?? ??? ??? ?(3)更远距离可以加中继器 ?? ??? ??? ?(4)半双工 ?? ??? ??? ?(5)RS485只提供物理层通信能力,不提供数据层协议,需要用户自定义,或者使用标准协议如MODBUS ?? ??? ??? ??? ?协议。
?? ??? ?d、MAX485介绍 ?? ??? ??? ?(1)CPU本身只会提供UART接口,而不会提供RS485接口。CPU根本不认识RS485。 ?? ??? ??? ?(2)RS485的使用场景是:CPUA -> UART转RS485----远距离通信----RS485转UART -> CPUB ?? ??? ??? ?(3)大家对RS485的理解,应该是这样的:RS485是纯硬件实现的,硬件芯片如MAX485来管理的,根 ?? ??? ??? ??? ?本不涉及软件编程。软件工程师只关注串口,只通过串口将数据发送出去或者接收回来即可。UART ?? ??? ??? ??? ?转RS485和RS485转UART对于CPU来说是透明的。
|