嵌入式之硬件学习(三)通信方式、串口通信
目录
一、通信种类
1、并行通信
2、串行通信
3、单工模式(Simplex Communication)
4、半双工通信(Half-Duplex Communication)
5、全双工通信(Full-Duplex Communication)
6、串行的异步通信与同步通信
(1)异步通信
(2)同步通信
二、串行口通信
(一)UART定义(串行通信协议)
(二)串口通信通信时序(底层逻辑)
1、空闲时
2、起始位
3、数据位
4、校验位
5、停止位
6、简述串口通信的通信逻辑(面问)
(三)波特率(bps)
三、三种串行通信方式在物理表现形式的不同
(一)TTL(Transistor-Transistor Logic)
(二)RS232标准
(三)RS485标准
四、串行口寄存器
(一)SBUF寄存器(串行口数据缓冲寄存器)
(二)串行口控制寄存器SCON
(三)电源控制寄存器PCON
五、USB下载电路模块
六、练习(实现51单片机与电脑之间的通信)
uart.c
main.c
xdata 的作用
计算定时器初值的计算公式
七、MODBUS通信协议
一、通信种类
1、并行通信
并行通信是指多个比特同时通过并行线进行传输,这种方式的传输速率较高,但会占用大量的芯片资源;
2、串行通信
串行通信是指将数据拆分成一个个比特,按照先后次序在一根总线上进行发送,串行通信有着系统占用资源少,结构简单等优点,是主机间通信的常用方式。
注:串口通信(Serial Port)是串行通信的一种,属于串行通信中的异步通信。我们经常听到的RS232、RS485、RS422都是串行通信。
3、单工模式(Simplex Communication)
主机间通信时如果一方固定为发送端另外一方固定为接收端,通过一根总线实现数据通信。这种通信方式就像是你只能听别人说话,但无法回答他们一样,只能单向传递信息。
4、半双工通信(Half-Duplex Communication)
半双工通信是一种通信方式,其中数据传输可以在两个方向之间交替进行,但不能同时进行。换句话说,通信双方可以既发送数据又接收数据,但不能同时进行这两种操作。比方说,就像你可以和别人交替说话和倾听对方说话一样。当你在说话时,对方在听你说;当对方在说话时,你在倾听对方。这种方式允许双方之间在发送和接收数据之间切换,但不能同时进行。半双工通信常用于对话式交流和一些简单的通信场景中。
5、全双工通信(Full-Duplex Communication)
全双工通信是一种通信方式,其中数据传输可以同时在两个方向进行,允许通信双方同时发送和接收数据,实现双向通信。就像打电话一样,你可以同时说话也可以听对方说话,双方可以同时进行数据传输,实现双向沟通。
6、串行的异步通信与同步通信
(1)异步通信
指通信中两个字符(8位)之间的时间间隔是不固定的,而在一个字符内各位的时间间隔是固定的;
收发双方的波特率必须是事先约定好的;
(2)同步通信
要求发收双方具有同频同相的同步;
用专用时钟信号线来控制时钟的节奏,以为例:
- SDA(数据线)
- SCL(时钟线):用于同步双方时钟的节奏,一般由发送方决定;
异步通信
串口通信时,收发双方的波特率必须是事先约定好的,否则数据传输就会出现混乱。很明显,为保证每个比特占用数据线的时间,发送方和接收方需按照各自的系统计时且双方之间的误差不能太大。通常不能超过(6%)。这种双方各自“计时”的方式称为异步。就好比在打字一样,每次敲击键盘发送一个字母,速度快慢由打字者自己控制,没规定每敲击一个字母之间要等多久,只要保证接收端能够正确识别并解析即可。
同步通信
同步通信设备之间除了有数据线(SDA)以为还有一条时钟线(SCL)。其中SCL就是时钟线(serial clock)。发送方负责控制时钟线的变化,每发送一个比特,都需要将时钟线按照规则进行改变。就好比在合唱团里,大家一起唱歌的节奏是由指挥员指挥的,每个人都按照指挥员的节奏唱歌,保证大家唱的是同一首歌且节奏一致。这种通信方式就称为同步通信。譬如IIC、SPI等。
注:同步串行通信方式与异步串行通信方式的区别:存在时钟线的为同步串行
通信方式通信,没有时钟线的为异步串行通信方式。
二、串行口通信(全双工串行通信,异步通信)
(一)UART定义(串行通信协议)
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种广泛使用的串行通信协议。它用于在计算机或其他设备之间传输数据。UART通信协议通过两根线(通常称为TXD和RXD)实现数据的异步传输。
TXD(Transmit,发送)线:用于从设备发送数据到另一设备。
RXD(Receive,接收)线:用于从另一设备接收数据到本设备。
(二)串口通信通信时序(底层逻辑)
作为常用的串行通信方式,以TTL为例,串口通信在不同主机之间的数据格式为:
1、空闲时
空闲时数据线为高电平;
2、起始位
发送放发送一个低电平表示起始位;
3、数据位
依据低位先行原则(发送的第一个比特是最低位(最右边))发送;
4、校验位
分为奇校验,偶校验和无校验;校验位可发可不发
奇校验是指确保数据位加上校验位中"1",1的总数为奇数;
偶校验是指确保数据位加上校验位中"1",1的总数为偶数;
5、停止位
为保证下一个字节发送前的起始位能够表现出来(把两个数据二者之间分隔开),校验位之后发送一个停止位1。(停止位也可是1个、1.5个、2个)
6、简述串口通信的通信逻辑(面问)
双方在空闲时数据线保持高电平;发送数据时发送方先要发送一个起始位,起始位为低电平;发送数据位(8个bit)以低位先行原则发送(从右往左发);发完后有一个可以选择的校验位,校验分三种,分别为奇校验、偶校验、无校验,奇校验是数据位加校验位中1的个数总数为奇数,偶校验数据位加校验位1的总数为偶数;校验位结束后还要发送一个停止位,停止位为高电平。
(三)波特率(bps)
串口通信用波特率来描述数据的传输速率问题:
很明显上图的纵坐标为电压值,横坐标就是时间了。无论起始位、数据为还是停止位、校验位,每个比特在数据线上的时间决定了数据传输的速率。
串行通信用波特率(bit per second)来描述数据传输的速率,记作bps。
常见的波特率有1200、2400,4800,9600,115200等,表示每秒钟传输的比特数。以9600为例,表明每秒能传输9600个比特。每个比特传输时所需的时间为1/9600秒=1.041*10-4秒。
三、三种串行通信方式在物理表现形式的不同
主机间通信无论采用并行还是串行方式,都无法避免一个物理现象:导线内阻不为零造成的电压衰减。以之前讨论的TTL电平为例,主机之间的距离会造成高电平在接收端出现衰减现象和串扰(指不同信号之间相互干扰导致信号失真)影响。
(一)TTL(Transistor-Transistor Logic)
TTL(Transistor-Transistor Logic)通常指的就是芯片引脚产生的电压,这个电压值跟选择的芯片有关,在51单片机系统下是5v;在2440下是3.3v等等。5vTTL通信距离通常被限制在10~20米之间。(使用TTL方式进行数据传输距离受到很大限制)
逻辑0:0V低电压
逻辑1:取决于芯片本身(供电电压)
(二)RS232标准
5vTTL通信距离通常被限制在10~20米之间,如果需要更远的距离,怎么解决呢?为解决这个问题IEEE(Institute of Electrical and Electronics Engineers)颁布了RS232标准,其中规定了:
逻辑高电平(逻辑1):在-3V到-15V之间
逻辑低电平(逻辑0):在+3V到+15V之间
收发主机间有三根线,分别是收、发和地,因此RS232是全双工的。
理论上RS232能够传输20~30米。
(三)RS485标准
同理RS485使用两根信号线(A和B)来传输数据,通过比较A和B之间的电压差来识别信息,电压范围分别为+7V到+12V和-7V到-12V。正电压表示高电平,负电压表示低电平。这种差分信号传输方式提高了抗干扰能力。RS485的传输距离可达1200米,适用于大范围的数据传输需求。由于采用的是压差,RS485在传输数据的某一时刻,两根线都要用到,所以它是半双工的。
比较A和B之间的电压差:
逻辑1:+7V到+12V
逻辑0:-7V到-12V
四、串行口寄存器
(一)SBUF寄存器(串行口数据缓冲寄存器)
(二)串行口控制寄存器SCON
(三)电源控制寄存器PCON
五、USB下载电路模块
六、练习(实现51单片机与电脑之间的通信)
uart.c
void init_uart(void)
{
//串口接收
SCON &= ~(3 << 6);
SCON |= (1 << 6) | (1 << 4);//使参数生效
PCON &= ~(1 << 6);
PCON |= (1 << 7);//设置波特率,51单片机使用定时器1
TMOD &= ~(0x0F << 4);
TMOD |= (2 << 4); //1<<5 与其效果是一样的,改变第四位和第五位,2为0000 0010
TL1 = 232;//计算出的定时器初值
TH1 = 232;// 打开定时器1
TCON |= (1 << 6);//打开中断控制位及串口控制位
IE |= (1 << 7) | (1 << 4);
}
/*
//全局变量字符型数组
char rcv_buffer[32];
*/
//数组不放到内部RAM放到外部扩展RAM(扩展内存不清0,数组内都是随机数)
xdata char rcv_buffer[32];
unsigned int pos = 0;//中断服务函数(TI RI都会导致中断);接收需要使用中断
void uart_handler(void) interrupt 4
{
if((SCON & (1 << 0)) == 1)
{
if(pos < 32) //防止越界访问
{
rcv_buffer[pos++] = SBUF;//接收的数据依次存入到该数组
rcv_buffer[pos] = 0; //接收的字符串后加/0标志
}
//P2 = SBUF;
SCON &= ~(1 << 0);//软件复位RI(接收中断请求标志位)清0
}
}//发送(轮询)
void send_char(char ch)
{
SBUF = ch;
while((SCON & (1 << 1)) == 0);
SCON &= ~(1 << 1); //软件复位TI(发送中断请求标志位)清0
}void send_buffer(const char *p, unsigned int len)
{
while(len--)
{
send_char(*p++);
}
}// 发送字符串函数
void send_str(const char *str)
{
unsigned int len = 0;
while (str[len] != '\0') // 计算字符串长度
{
len++;
}
send_buffer(str, len); // 调用send_buffer函数发送字符串
}
main.c
int main(void)
{
const char *s = "Hello World!"; //不常用
//char buffer[] = {0xAA ,0xBB, 0x00, 0x1A};
xdata char buffer[16]; //???
init_uart();
while(1)
{
if(pos != 0)//至少收到一个字节
{
delay(0xAFFF);//保证数据全部收完,有延迟
if(strcmp(rcv_buffer,"Hello") == 0)
{
send_str("Hi");
}
else if(strcmp(rcv_buffer,"See You Later") == 0)
{
send_str("Bye");
}
/*
send_buffer(rcv_buffer, pos);
*/
pos = 0;//保证下一轮从头开始收
}
//send_buffer(buffer, sizeof(buffer) / sizeof(*buffer));
//send_buffer(s,strlen(s));
//send_char('A');
//delay(0xAFFF);
}
}
xdata 的作用
不将内容放在芯片内部的RAM中,放在扩展的RAM中 ;
计算定时器初值的计算公式
2^8-2^smod * focs / 32 / bps / 12
其中smod表示PCON的B7,根据实际情况带入,不是0就是1(SMOD=1波特率翻倍);
focs晶振频率,我们这是11.0592M;
bps目标波特率我们这是2400
2^8 这里的8来自定时器的工作方式,因为我们使用的是8位自动重装方式,所以是8
按照我们的要求2400bps,smod=1时,该公式计算结果为:232。
七、MODBUS通信协议
modbus协议:
unsigned char s[xx] = ......
该协议对数组每个元素内容都做了定义