单片机通信协议---串口及串口通信

一. 通信协议

1.1 通信协议种类

UART( 异步) 、 I2C( 同步) 、 SPI( 同步) 、 ADC、 GPIO

1.2 通信方式

1.2.1 单工

1、数据的发送方和接收方固定

2、A只发,B只收

3、数据传输是通过一根信号线

1.2.2 半双工

1、收发双方通过一根信号线完成

2、但是数据的发送方和接收方不固定,双方既可以作为数据的发送方也可以作为接收方

数据传输双向

3、在同一时刻,数据传输单向 典型协议:I2C

1.2.3 全双工

1、通信双方既可以发送数据也可以接收数据

2、数据传输通过两根信号线实现,数据传输方向是双向的

3、串口为全双工

1.3 数据传输方式

1.3.1 串行传输

通过一根信号线传输数据,按照先后次序传输

特点: 传输速率慢

硬件成本低,实现简单

传输距离远,抗干扰性强(RS485 使用电压差传输 理论可以传1200米 双绞线)

1.3.2 并行传输

通过多根信号线同时传输数据

特点: 传输速率快

硬件成本高,实现复杂

传输距离近,抗干扰性差(30米以内)

二. 串口

2.1 串口基本知识

2.1.1 串口传输顺序

LSB: 数据最低位

MSB: 数据最高位

串口传输顺序: 串口是LSB优先原则,先发送数据低位

2.1.2 串口的通信时序

时序:

先发送一个bit低电平,代表起始位

再发送8bit数据

发送一个bit的校验位

发送一个bit的电平,代表停止位,表示串口通信结束

2.1.3 校验方式

校验方式:

1、累加和校验

2、奇偶校验

奇校验: 校验位是1,用数据位中bit1的个数加上校验位的1,如果1的个数是奇数个,代表奇校验通过,接收时也是一样

缺点: 若是有两个比特位一起出错则可能检查不出来,无法检测偶数个bit位出错

偶校验: 校验位是0,用数据位中bit1的个数加上校验位的0,如果1的个数是偶数个,代表偶校验通过,接收时也是一样

3、CRC校验

2.1.4 串口波特率

波特率bps:

每秒传输的bit数量

常见波特率:2400,4800,9600,115200

串口不同工作模式下的波特率:

工作模式1下的波特率计算公式(T1用做波特率发生器,工作在自动重装初值模式下):

推导出定时器初值的计算公式:

2.1.5 串口通信参数

eg:9600 8 N 1

波特率+数据位+无校验+停止位1位

若有校验位则:O(Odd)表示:奇校验 E(Even)表示偶校验

2.1.6 串口电平种类

TTL电平: 高电平1:5v 低电平0:0v 使用CH340芯片转换

RS232电平 (负逻辑):高电平1:-3~-15v

低电平0:3~15v

增加了传输距离

使用MAX232芯片转换

RS485电平 (两根线的差分信号):高电平1:2~6v

低电平0:-6~-2v

工业级,传输距离更远

2.2 串口结构

图中有两个物理上独立的接收、发送缓冲器SBUF,它们占用同一地址99H ,可同时发送、接收数据(全双工)。发送缓冲器只能写人,不能读出;接收缓冲器只能读出,不能写入。定时器T1作为串行通信的波特率发生器,T1溢出率先经过2分频(也可以不分频)再经16分频作为串行发送或接收的移位时钟。

接收时是双缓冲结构 ,由于在前一个字节从接收缓冲器SBUF读走之前,已经开始接收第二个字节(串行输入至移位寄存器),若在第二个字节接收完毕而前一个字节仍未被读走时,

就会丢失前一个字节的内容。串行口的发送和接收都是以SBUF的名称进行读或写的,当向SBUF发出"写"命令时,即是向发送缓冲器SBUF装载并开始由TXD引脚向外串行地发送一帧数据,发送完后便使发送中断标志T1=1

串行口接收中断标志RI=0 时,置允许接收位REN=1就会启动接收过程,一帧数据进人输入移位寄存器,并装载到接收SBUF中,同时使RI=1。执行读SBUF 的命令,则可以由接收缓冲器 SBUF 取出信息,并存于某个指定的位置。

对于发送缓冲器,因为发送时CPU是主动的,所以不会产生重叠错误。

2.3 与串口相关寄存器

2.3.1. SCON串口控制寄存器

|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| SM0/FE | 当PCON寄存器中的SMOD0/PCON.6位为1时, 该位用于帧错误检测。当检测到一个 无效停止位时,通过UART接收器设置该位。它必须由软件清零。 当PCON寄存器中的SMOD0/PCON.6位为0时,该位和SM1一起指定串行通信的工作 方式 |
| SM0 SM1 | 00 方式0 同步移位串行方式:移位寄存器 波特率是SYSclk/12, 01 方式1 8位UART,波特率可变 10 方式2 9位UART 11 方式3 9位UART,波特率可变 |
| SM2 | 多机通信控制位,用于方式2和方式3 |
| 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.位, |

2.3.2 PCON 电源控制寄存器

|-----------|---------------------------------------------------------------------------------------------------------------------|
| 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 |

2.4 串口配置流程

串口配置流程:

1、与串口相关

串口工作模式+波特率加倍

8位UART,波特率可变:SCON:bit6置1,bit7清零

允许串口接收数据:SCON中bit4置1

PCON中的bit6清零:为了使SCON中的SM1 SM0指定工作方式

PCON的bit7置1,串口波特率翻倍

2、与定时器相关

定时器1工作模式+定时器1计数,定时器1作为串口的波特率发生器

TMOD中的bit5置1,bit4清零,定时器1工作在八位自动重装模式

TH1:230 232(bps= 2400)(注意不同单片机的晶振频率对应不同的初值)

TL1:230 232

TCON的bit6置1,定时器1开始计数

晶振: 12M算定时器为整数

11.0592M算波特率为整数

3、与中断相关

串口中断+CPU中断

将IE中的bit7,bit4置1,打开串口与CPU中断

示例代码:

cpp 复制代码
/初始化串口
void Uart_init()
{
	/波特率加倍
	PCON |= (1 << 7);
	/允许SCON中的SM0和SM1一起指定串口的工作模式
	PCON &= ~(1 << 6);
	/配置串口工作模式:8位UART,波特率可变
	SCON &= ~(3 << 6);
	SCON |= (1 << 6);
	/允许串口接收数据
	SCON |= (1 << 4);
	/定时器1配置工作模式:8位重装
	TMOD &= ~(0x0F << 4);
	TMOD |= (1 << 5);
	/波特率2400对应的初值
	TL1 = 232;
	TH1 = 232;
	/定时器1开始定时
	TCON |= (1 << 6);
	/开启CPU总中断与定时器1对应的中断
	IE |= (1 << 4) | (1 << 7);
}

2.5 串口发送数据

发送数据时,只要向SUBF中写一个字节,就自动启动了发送

**注意:**在发送了一字节的数据后,发送中断请求标志位TI会被自动置位,但是要由软件清零

示例代码:

cpp 复制代码
/串口发送单字节
void Uart_sendchar(unsigned char ch)
{
	SBUF = ch;
	while( 0 == (SCON & (1 << 1)) );/还处在发送中状态
	SCON &= ~(1 << 1);/软件清零
}
/串口发送字符串
void Uart_sendstr(const char *p)
{
	while(*p)
	{
		Uart_sendchar(*p++);
	}
}
/串口发送数组中指定长度数据
void Uart_sendbuffer(const char *p, int len)
{
	while(len--)
	{
		Uart_sendchar(*p);
		p++;
	}
}

2.6 串口接收数据

串口在接收数据时,由于不知道数据到来的时机,故要使用中断

要使用串口中断函数

注意:在51单片机中RAM只有256字节

在定义数组char buff32时,最好加关键字:xdata

加关键字:xdata

xdata char buff32

就放在了内部扩展的RAM中

内部扩展RAM:0x0000-0xFFFF可以存64字节

示例代码:

cpp 复制代码
xdata unsigned char recv_buff[32];
unsigned int pos;

/串口接收数据中断服务函数
void Uart_recv_handler(void) interrupt 4
{
	/判断接收中断请求标志位 RI 是否被置1
	if( SCON & (1 << 0) == 1 )
	{
		/防止越界
		if(pos < 32)
		{
			/每次接收一字节
			recv_buff[pos] = SBUF;
			pos++;
			/向末尾增加'\0'
			recv_buff[pos] = 0;
		}
		/必须由软件清零此标志位
		SCON &= ~(1 << 0);
	}
}

三. 主从应答模式

主从应答

应用层:
Modbus协议

上位机/主机:根据协议的格式 发送控制指令,

Modbus协议

eg:

起始码:

0xAA

地址码:

0x01

功能码:

0x01:控制LED灯

02:控制数码管

03:控制蜂鸣器

04:传感器温度采集

数据位1 高位

0x00

数据位2 低位

0x42

校验码

CRC校验

累加和校验

0xEE

结束码

0xBB

从机:根据主机发的数据,解析数据,完成控制 ,完成应答

回复应答也是这种格式去回复

注意:功能码:0x81

功能码最高位表示数据流向位

0:主->从
1:从->主

校验码也变

超过一个字节时保留低位即可

相关推荐
蓝斯4978 小时前
从.到实现一个Windows上的虚拟hid键盘设备
windows·单片机·计算机外设
熙芯XiChip9 小时前
硬实时与软实时RTOS核心区别
嵌入式硬件
伟大的前程9 小时前
unsigned int 定义的变量 在 电脑的 64 位系统中 和 32 位 cortex-m0 和 8 位的 51 单片机
单片机·嵌入式硬件
小渔村的拉线工9 小时前
1.HPM6E80 解析芯片整体工作原理和存储架构
单片机·嵌入式硬件·mcu·架构·hpm6e80
熙芯XiChip10 小时前
CAN与CANopen的本质区别
单片机
lilihewo11 小时前
Altium Designer 封装库的创建(分享pcb 3D封装库)
嵌入式硬件·51单片机
神罚天下ET12 小时前
典型arm位单片机启动流程(从上电到main.c)
c语言·arm开发·单片机
碧海银沙音频科技研究院12 小时前
蓝牙耳机使用WSDF5361锂保芯片进入船运模式实现方法
嵌入式硬件·算法
Zevalin爱灰灰13 小时前
模拟信号链电路——基于TL431的电压基准电路
单片机·嵌入式硬件
csdn杰哥14 小时前
瑞萨单片机开发教程[二十七] DTC 外部中断触发传输实验
单片机·嵌入式硬件·mongodb·瑞萨·ra6m5