51单片机:06_串口通信

201 阅读7分钟

Pre

SCON Serial Control  控制单片机串行通信功能的寄存器
SM Serial Mode 设置串行通信的模式
SMOD Serial Mode Operation Double Baud Rate  单片机中用于控制串行通信波特率的一个标志位
TXD Transmit Data
RXD Receive Data
REN Receive Enable - 用于使能串行接收功能。
TB Transmit Buffer - 用于存储待发送的数据。
RB Receive Buffer - 用于存储接收到的数据。
TI Transmit Interrupt 发送中断标志位,指示发送缓冲区已准备好发送下一个字节。
RI Receive Interrupt 接收中断标志位,指示接收缓冲区中有新数据可读取。
THn/TLn Timer hight/Low n 的高位和低位
FOSC Frequency of Oscillator 振荡器频率

串口通信

按照数据传送方式分为:

串行通信、和并行通信。

按照同步方式:异步通信、同步通信。

按照传输方向:单工通信、半双工通信、全双工通信。

串行通信: 一条数据线、数据一位一位的依次发送。

1.png

并行通信: 多条线、多位发送。

异步通信 通信双方使用各自的时钟发送和接收数据、需要收发协调、双方时钟时间要相同。

2.png

同步通信 双方时钟相同。

自同步:发送方时钟控制接收方。

外同步:通过发送方,发送数据和时钟进行同步。

3.png

单工通信

只能一方发一方收。

半双工通信

同一时间内一段发一方收。

全双工通信

同一时间内 可发可收。

通信速率(比特率)

每秒传输 bit的数量。

2400bps(bit per second)

波特率

波特率(Baud Rate)是指每秒钟传输的符号(信号变化)的次数。对于大多数串口通信系统,波特率通常等同于每秒传输的比特数(bps,bits per second),因为每个符号通常代表一个比特。

波特率是串口通信中一个关键参数,它决定了数据传输的速度。常见的波特率值有9600、19200、38400、57600、115200等。选择合适的波特率需要考虑通信双方的硬件能力和应用需求

串口

RS232C 接口

DB25\DB9

公头、母头针角相反。

4.png

5.png

()的是DB9的定义、不带()的是DB25的定义。

串行通信中一般用到:TXD、RXD、GND。

双方波特率相同。

串口内部结构

6.png

SBUF 数据缓冲区

TH1\TL1 定时器1

SMOD 倍频、

RI:当SBUF接收完数据后、RI置1、做串口中断。(接收中断)

TI:当SBUIF发送完成后、TI置1、做串口中断。(发送中断)

相关寄存器

SCON (Serial Control) 串口控制寄存器。

1.SM0\SM1 工作方式

image.png

SM2:多机通信控制。只能用工作方式2-3。

SM2=1时(多机通讯)

当接收数据的某个机器 RB8=0时接收到数据就丢弃、忽略收到的信息。

当接收数据的某个机器 RB8=1时、接收到的数据放入SBUF中、并激活RI(接收中断)获取SBUF的数据。

当SM2=0时、不管RB8=多少、都接收数据到SBUF。

REN

接收数据使能

是否接收 发送过来的数据

RB8/TB8

在工作方式2、3时,发送数据的第9位

TI

发送中断标志位、在串行通讯时,发送完数据后发送停止位、硬件设置位1,向CPU发送中断请求,需要在中断函数处理结束后(软件)清0。

RI

在工作方式0、1时、当串行接收到第8位、或 工作方式2、3时接收到停止位,硬件设置为1,执行接收中断请求,需要在中断函数处理结束后(软件)清0。

SCON 01 0 1 00 00 工作方式1、单机通讯、发送中断请求中断为0

PCON 电源控制寄存器

只有最高位SMOD用到、波特率倍频的选择。 =1 倍频、=0步倍频。 为什么要倍频率。

  1. 提高通信速度:通过倍频,可以在相同的晶振频率下实现更高的波特率,从而提高数据传输速度。
  2. 兼容性:有些外部设备可能需要更高的波特率来进行通信,倍频可以帮助51单片机与这些设备兼容。
  3. 灵活性:倍频提供了一种灵活的方法来调整波特率,以适应不同的应用需求。
  4. 资源节省:在某些情况下,通过倍频可以避免更换晶振,从而节省硬件资源和成本。

串口工作方式

方式0(同步) 输出

8.png

1.数据写入到SBUF中。

2.由RXD输入和输出数据、TXD一次脉冲 数据整体向左移动一位、先发送高位数据、后发低位数据、一次发8位。

3.发送完毕后 TI 硬件自动设置为1。

4.将TI设置为0。进入下一次数据输出。

方式0(同步) 输入

10.png

1.REN 接收使能设置为1 允许接收数据

2.在TXD的脉冲中、一位一位的获取RXD中的数据。由高到低读取。

方式1(异步) 输出

11.png

12.png

一共10位数据 开始1+数据8+停止1=10

1.数据写入到SBUF中

2.TXD设置起始=0,然后依次将数据一位一位的(高到低)输入到TXD中,再接收到停止位1

3.TI 硬件设置1、进入中断函数

4.处理中断函数、TI设置0

完成一次发送

方式1(异步) 输入

13.png

  1. 设置REN=1。
  2. 0读取到起始位置、+8位高到低的数据+1停止位。
  3. 硬件设置RI=1、将数据装入SBUF中,进入接收中断函数。
  4. 处理完接收中断函数、读取SBUF中的数据,设置RI=0。

方式2\方式3 输出

和方式1对比、在8位数据中多了TB8(在SCON里面)

014.png

14.png

方式2\方式3 输入

和方式1对比、在8位数据中多了RB8(在SCON里面)

15.png

波特率怎么计算

方式0 波特率 = fosc/12

方式2 波特率 = (2SMOD/64)*fosc

方式1 波特率 = (2SMOD/32)*T1溢出率

方式3 波特率 = (2SMOD/32)*T1溢出率 T1溢出率=fosc/{12 * [256-(TH1)] }

。。。

太麻烦了 直接用软件来计算。

16.png

串口通信初始化步骤

1.确定T1的工作方式 TMOD寄存器(定时器中断那边的知识点)

2.确定串口工作方式、SCON寄存器

3.计算T1的初始值(设定波特率)装载TH1\TL1;

4.启动T1(TCON的TR1=1 定时器中断那边的知识点)

5.如果使用中断、需开启串口中断控制位IE寄存器 ES=1(定时器中断那边的知识点)

void UART_Init(u8 baud){
    TMOD |=0X20; //计数器工作方式2
    SCON = 0X50; //sm0 sm1 = 01 Ren=1 工作方式1、接收数据使能打开
    PCON = 0X80; //TMOD =1 波特率加倍
    TH1 = baud; // 计数器初始值 高位
    TL1= baud;  // 低位
    ES =1;//IE寄存器(Intertupt Enable)中断使能寄存器的 串口使能中断打开
    EA =1;//打开总中断
    TR1 =1;//### TCON(timer config) 的 启动定时器1 TR1
}

硬件电路设计

17.png

使用CH340G芯片 模拟串口、将USB和串口进行互相转换。

程序

【串口助手】向【单片机】发送数据、【单片机】将【串口助手】的数据转发回去。 main.c

#include <REGX52.H>

typedef unsigned char u8;
typedef unsigned int u16;

u8 rec_data=0;

void UsartInit()
{
	SCON=0X50;			//设置为工作方式1
	TMOD=0X20;			//设置计数器工作方式2
	PCON=0X80;			//波特率加倍
	TH1=0XF3;				//计数器初始值设置,注意波特率是4800的
	TL1=0XF3;
	ES=1;						//打开接收中断
	EA=1;						//打开总中断
	TR1=1;					//打开计数器
}

void main()
{	
	UsartInit();  //	串口初始化
	while(1);		
}
/**
	*
	* @brief 串口中断,接收到串口数据后、会进入这个中断
	* @param
	* @retval
	*/
void Usart() interrupt 4
{
	u8 receiveData;

	receiveData=SBUF;//出去接收到的数据
	RI = 0;//清除接收中断标志位
	SBUF=receiveData;//将接收到的数据放入到发送寄存器
	while(!TI);			 //等待发送数据完成
	TI=0;						 //清除发送完成标志位
}