8-串口通信

1.串口介绍

•串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。

•单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。

•51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。

2.硬件电路

•简单双向串口通信有两根通信线(发送端TXD和接收端RXD)

•TXD与RXD要交叉连接

•当只需单向的数据传输时,可以直接一根通信线

•当电平标准不一致时,需要加电平转换芯片

image-20240117150313548

3.电平标准

串口常用的电平标准有如下三种:

  • TTL电平:+5V表示1,0V表示0
  • RS232电平:-3-15V表示1,+3+15V表示0
  • RS485电平:两线压差+2+6V表示1,-2-6V表示0(差分信号)

4.常见通信接口

名称 引脚定义 通信方式 特点
UART TXD、RXD 全双工、异步 点对点通信
I²C SCL、SDA 半双工、同步 可挂载多个设备
SPI SCLK、MOSI、MISO、CS 全双工、同步 可挂载多个设备
1-Wire DQ 半双工、异步 可挂载多个设备

此外还有:CAN,USB等

•全双工:通信双方可以在同一时刻互相传输数据

•半双工:通信双方可以互相传输数据,但必须分时复用一根数据线,也就是同一时刻只有一方可以传输数据

•单工:通信只能有一方发送到另一方,不能反向传输

•异步:通信双方各自约定通信速率

•同步:通信双方靠一根时钟线来约定通信速率

•总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,使住户可以相互交流)

5.51单片机的UART

•STC89C52有1个UART

•STC89C52的UART有四种工作模式:

模式0:同步移位寄存器

模式1:8位UART,波特率可变(常用)

模式2:9位UART,波特率固定

模式3:9位UART,波特率可变

image-20240117161107203

6.串口参数及时序图

•波特率:串口通信的速率(发送和接收各数据位的间隔时间)

•检验位:用于数据验证

•停止位:用于数据帧间隔

image-20240117161721560

7.串口模式图

image-20240117163632937

•SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。写操作时,写入的是发送寄存器,读操作时,读出的是接收寄存器

8.串口和中断系统

image-20240117164122109

9.串口相关寄存器

image-20240117164634765

10.串行口控制寄存器SCON

根据手册内容来确定SCON的各个位是0还是1

image-20240117171546309

image-20240117171556455

image-20240117171608330

image-20240117171629287

根据手册内容,各个位的初始设置应该为SCON=01000000=0x40,工作在方式2,所以前4位为0100,发送中断和接受中断位刚开始都先初始化为0

SCON=0x40

11.定时器

16位定时器/计数器:两个寄存器当成一个,范围为0-65535,需要在中断程序中进行赋初值

8位自动重装模式:相当于一个寄存器用来重装(相当于赋初值),一个用来计数,虽然范围变小了,但是不需要手动重装了

12.通过串行口发送数据到电脑程序

每秒发送一个逐渐增大的数据

#include <STC89C5xRC.H>
#include "Delay.h"

unsigned char Sec;
void UART_Init()//4800bps@11.0592MHz
{
	SCON=0x40;
	PCON |= 0x80;
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x20;			//设置定时器模式(8位自动重装模式)
	TL1 = 0xF4;				//设置定时初始值
	TH1 = 0xF4;				//设置定时重载值
	ET1=0;					//禁止定时器1中断
	TR1=1;					//启动定时器1
}
void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}
void main()
{
	UART_Init();
	while(1)
	{
		UART_SendByte(Sec);
		Sec++;
		Delay(1000);
	}
}

可以像之前一样将它进行模块化

image-20240117210131707

13.电脑通过串行口控制LED

此时需要接受数据,根据手册,要把REN置为1

main.c

#include <STC89C5xRC.H>
#include "Delay.h"
#include "UART.h"


void main()
{
	UART_Init();
	while(1)
	{
		
	}
}

void UART_Routine() interrupt 4  //标志其为中断函数
{
	if(RI==1)
	{
		P2=SBUF;
		UART_SendByte(SBUF);
		RI=0;
	}	
}

UART.c

#include <STC89C5xRC.H>

/**
  * @brief  串口初始化,4800bps@11.0592MHz
  * @param  无
  * @retval 无
  */
void UART_Init()
{
	SCON=0x50;
	PCON |= 0x80;
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x20;			//设置定时器模式(8位自动重装模式)
	TL1 = 0xF4;				//设置定时初始值
	TH1 = 0xF4;				//设置定时重载值
	ET1=0;					//禁止定时器1中断
	TR1=1;					//启动定时器1
	EA=1;					//开始总中断
	ES=1;					//开启接受、发送中断
}

/**
  * @brief  串口发送一个字节数据
  * @param  Byte:要发送的一个字节数据
  * @retval 无 
  */
void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}

/*串口中断函数模板
void UART_Routine() interrupt 4  //标志其为中断函数
{
	if(RI==1)
	{
		RI=0;
	}	
}
*/

UART.h

#ifndef __UART_H__
#define __UART_H__

void UART_Init();
void UART_SendByte(unsigned char Byte);

#endif

14.波特率的计算

image-20240117233335514

posted @ 2024-01-17 23:55  Jinx8823  阅读(8)  评论(0编辑  收藏  举报