STC89C52单片机学习——第19节: [8-1]串口通信

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.03.15

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始51单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习51单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。不再另外购买视频中的普中开发板了。
   原理图如下
在这里插入图片描述
视频中的都用这个开发板来实现,如果有资源就利用起来。
仔细看了看:开发板的晶振为:11.0592Mhz;12Mhz晶振是用来给CH340G芯片外置晶振;

下图是实物图
在这里插入图片描述

引用

51单片机入门教程-2020版 程序全程纯手打 从零开始入门
还参考了下图中的书籍:
手把手教你学51单片机(C语言版)
在这里插入图片描述

解答和科普

一、串口通信

通信,按照传统的理解就是信息的传输与交换。对于单片机来说,通信则与传感器、存储芯片、外围控制芯片等技术紧密结合,成为整个单片机系统的“神经中枢”。没有通信,单片机所实现的功能仅仅局限于单片机本身,就无法通过其它设备获得有用信息,也无法将自己产生的信息告诉其它设备。如果单片机通信没处理好的话,它和外围器件的合作程度就受到限制,最终整个系统也无法完成强大的功能,由此可见单片机通信技术的重要性。
UA(Universal Asynchronous Receiver/Transmitter,即通用异步收发器)串行通信是单片机最常用的一种通信技术,通常用于单片机和电脑之间以及单片机和单片机之间的通信。
在这里插入图片描述
通信按照基本类型可以分为并行通信和串行通信。并行通信时数据的各个位同时传送,可以实现字节为单位通信,但是通信线多占用资源多,成本高。比如我们前边用到的P0 = 0xFE;一次给P0 的8 个IO 口分别赋值,同时进行信号输出,类似于有8 个车道同时可以过去8 辆车一样,这种形式就是并行的,我们习惯上还称P0、P1、P2 和P3 为51 单片机的4 组并行总线。
而串行通信,就如同一条车道,一次只能一辆车过去,如果一个0xFE 这样一个字节的
数据要传输过去的话,假如低位在前高位在后的话,那发送方式就是0-1-1-1-1-1-1-1-1,一位一位的发送出去的,要发送8 次才能发送完一个字节。
在这里插入图片描述
STC89C52 有两个引脚是专门用来做UART 串行通信的,一个是P3.0 一个是P3.1,它们
还分别有另外的名字叫做RXD 和TXD,由它们组成的通信接口就叫做串行接口,简称串口。用两个单片机进行UART 串口通信,基本的演示图。

在这里插入图片描述
差分信号:两线压差,A-B 两个互相比较,完成一个线,CAN,USB, 485 1000m之上;
在这里插入图片描述
图中,GND 表示单片机系统电源的参考地,TXD 是串行发送引脚,RXD 是串行接收引脚。两个单片机之间要通信,首先电源基准得一样,所以我们要把两个单片机的GND 相互
连接起来,然后单片机1 的TXD 引脚接到单片机2 的RXD 引脚上,即此路为单片机1 发送
而单片机2 接收的通道,单片机1 的RXD 引脚接到单片机2 的TXD 引脚上,即此路为单片
机2 发送而单片机1 接收的通道。这个示意图就体现了两个单片机相互收发信息的过程。

当单片机1 想给单片机2 发送数据时,比如发送一个0xE4 这个数据,用二进制形式表
示就是0b11100100,在UART 通信过程中,是低位先发,高位后发的原则,那么就让TXD
首先拉低电平,持续一段时间,发送一位0,然后继续拉低,再持续一段时间,又发送了一
位0,然后拉高电平,持续一段时间,发了一位1……一直到把8 位二进制数字0b11100100
全部发送完毕,这里就涉及到了一个问题,就是持续的这“一段时间”到底是多久?由此便引入了通信中的一个重要概念——波特率,也叫做比特率。
波特率就是发送二进制数据位的速率,习惯上用baud 表示,即我们发送一位二进制数据
的持续时间=1/baud。在通信之前,单片机1 和单片机2 首先都要明确的约定好它们之间的通信波特率,必须保持一致,收发双方才能正常实现通信,这一点大家一定要记清楚。
约定好速度后,我们还要考虑第二个问题,数据什么时候是起始,什么时候是结束呢?
不管是提前接收还是延迟接收,数据都会接收错误。在UART 通信的时候,一个字节是8 位,
规定当没有通信信号发生时,通信线路保持高电平,当要发送数据之前,先发一位0 表示起
始位,然后发送8 位数据位,数据位是先低后高的顺序,数据位发完后再发一位1 表示停止
位。这样本来要发送一个字节的8 位数据,而实际上我们一共发送了10 位,多出来的两位
其中一位起始位,一位停止位。而接收方呢,原本一直保持的高电平,一旦检测到了一位低
电平,那就知道了要开始准备接收数据了,接收到8 位数据位后,然后检测到停止位,再准
备下一个数据的接收。我们图示看一下,如图所示。
在这里插入图片描述
上图 串口数据发送示意图,实际上是一个时域示意图,就是信号随着时间变化的对应关系。比如在单片机的发送引脚上,左边的是先发生的,右边的是后发生的,数据位的切换时间就是波特率分之一秒,如果能够理解时域的概念,后边很多通信的时序图就很容易理解
了。
在这里插入图片描述
比特率:传输多少个位;
奇偶检验:都约定奇校验,0000 0011 1;0000 0011 1;
1110 0000 0;1100 0000 0;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
RS232 通信接口
在这里插入图片描述
RS232 接口一共有9 个引脚,分别定义是:1、载波检测DCD;2、接收数据RXD;3、发送数据TXD;4、数据终端准备好DTR;5、信号地线SG;6、数据准备好DSR;7、请求发送RTS;8、清除发送CTS;9、振铃提示RI。我们要让这个串口和我们单片机进行通信,我们只需要关心其中的2 脚RXD、3 脚TXD 和5 脚GND 即可。
我们得慢慢知道,不是所有的电路都是5V 代表高电平而0V 代表低电平的。对于RS232 标准来说,它是个反逻辑,也叫做负逻辑。为何叫负逻辑?它的TXD 和RXD 的电压,-3V~-15V 电压代表是1,+3~+15V 电压代表是0。低电平代表的是1,而高电平代表的是0,所以称之为负逻辑。因此电脑的9 针RS232串口是不能和单片机直接连接的,需要用一个电平转换芯片MAX232 来完成。
在这里插入图片描述
这个芯片就可以实现把标准RS232 串口电平转换成我们单片机能够识别和承受的UART
0V/5V 电平。从这里大家似乎慢慢有点明白了,其实RS232 串口和UART 串口,它们的协议类型是一样的,只是电平标准不同而已,而MAX232 这个芯片起到的就是中间人的作用,它把UART 电平转换成RS232 电平,也把RS232 电平转换成UART 电平,从而实现标准RS232接口和单片机UART 之间的通信连接。
USB 转串口通信
我们只需要在电路上添加一个USB 转串口芯片,就可以成功实现USB 通信协议和标准
UART 串行通信协议的转换,在我们的开发板上,我们使用的是CH340T 这个芯片
在这里插入图片描述
图中左下方J1 和J2 是两个跳线的组合,大家可以在我们板子左下方的位置找到,我们需要用跳线帽把中间和下边的针短接在一起。右侧的CH340T 这个电路很简单,把电源、晶振接好后,6 脚和7 脚的DP 和DM 分别接USB 口的2 个数据引脚上去,3 脚和4 脚通过跳线接到了我们单片机的TXD 和RXD 上去。

CH340T 的电路里3 脚位置加了个4148 的二极管,是一个小技巧。因为STC89C52 这个
单片机下载程序时需要冷启动,就是先点下载后上电,上电瞬间单片机会先检测需要不需要
下载程序。虽然单片机的VCC 是由开关来控制,但是由于CH340T 的3 脚是输出引脚,如
果没有此二极管,开关后级单片机在断电的情况下,CH340T 的3 脚和单片机的P3.0(即RXD)引脚连在一起,有电流会通过这个引脚流入后级电路并且给后级的电容充电,造成后级有一定幅度的电压,这个电压值虽然只有两三伏左右,但是可能会影响到正常的冷启动。加了二极管后,一方面不影响通信,另外一个方面还可以消除这种不良影响。这个地方可以暂时作为了解,大家如果自己做这类电路,可以参考一下。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、IO 口模拟UART 串口通信

为了让大家充分理解UART 串口通信的原理,我们先把P3.0 和P3.1 当做IO 口来进行模拟实际串口通信的过程,原理搞懂后,我们再使用寄存器配置实现串口通信过程。对于UART 串口波特率,常用的值是300、600、1200、2400、4800、9600、14400、19200、28800、38400、57600、115200 等速率。IO 口模拟UART 串行通信程序是一个简单的演示程序,我们使用串口调试助手下发一个数据,数据加1 后,再自动返回。
串口调试助手,这里我们直接使用STC-ISP 软件自带的串口调试助手,先把串口调试助
手的使用给大家说一下,如图 所示。第一步要选择串口助手菜单,第二步选择十六进制显示,第三步选择十六进制发送,第四步选择COM 口,这个COM 口要和自己电脑设备管理器里的那个COM 口一致,波特率按我们程序设定好的选择,我们程序中让一个数据位持续时间是1/9600 秒,那这个地方选择波特率就是选9600,校验位选N,数据位8,停止位1。
在这里插入图片描述
串口调试助手的实质就是利用电脑上的UART 通信接口,发送数据给我们的单片机,也
可以把我们的单片机发送的数据接收到这个调试助手界面上。

变量定义部分就不用说了,直接看main 主函数。首先是对通信的波特率的设定,在这里我们配置的波特率是9600,那么串口调试助手也得是9600。配置波特率的时候,我们用的是定时器T0 的模式2。模式2 中,不再是TH0 代表高8 位,TL0 代表低8 位了,而只有TL0 在进行计数,当TL0 溢出后,不仅仅会让TF0 变1,而且还会将TH0 中的内容重新自动装到TL0 中。这样有一个好处,就是我们可以把想要的定时器初值提前存在TH0 中,当TL0溢出后,TH0 自动把初值就重新送入TL0 了,全自动的,不需要程序中再给TL0 重新赋值了,配置方式很简单,大家可以自己看下程序并且计算一下初值。

波特率设置好以后,打开中断,然后等待接收串口调试助手下发的数据。接收数据的时
候,首先要进行低电平检测while (PIN_RXD),若没有低电平则说明没有数据,一旦检测到
低电平,就进入启动接收函数StartRXD()。接收函数最开始启动半个波特率周期,初学可能
这里不是很明白。大家回头看一下我们的图11-2 里边的串口数据示意图,如果在数据位电平变化的时候去读取,因为时序上的误差以及信号稳定性的问题很容易读错数据,所以我们希望在信号最稳定的时候去读数据。除了信号变化的那个沿的位置外,其它位置都很稳定,那么我们现在就约定在信号中间位置去读取电平状态,这样能够保证我们读的一定是正确的。
一旦读到了起始信号,我们就把当前状态设定成接收状态,并且打开定时器中断,第一次是半个周期进入中断后,对起始位进行二次判断一下,确认一下起始位是低电平,而不是一个干扰信号。以后每经过1/9600 秒进入一次中断,并且把这个引脚的状态读到RxdBuf 里边。等待接收完毕之后,我们再把这个RxdBuf 加1,再通过TXD 引脚发送出去,同样需要先发一位起始位,然后发8 个数据位,再发结束位,发送完毕后,程序运行到while (PIN_RXD),等待第二轮信号接收的开始。

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"


sbit  PIN_RXD =P3^0 ;	//接收引脚定义
sbit  PIN_TXD=P3^1;		//发送引脚定义

bit RxdOrTxd =0;		//指示当前状态为接收还是发送
bit RxdEnd=0;			//接收结束标志
bit TxdEnd=0;			//发送结束标志

unsigned char RxdBuf=0;  //接收缓冲器
unsigned char TxdBuf=0;		//发送缓冲器

void ConfigUART(unsigned int baud);
void StartTXD(unsigned char dat);
void StartRXD();


void main()
{
	EA=1;				//开总中断
	ConfigUART(9600);	//配置波特率为9600
	
	while(1)
	{
		while(PIN_RXD);		//等待接受引脚出现低电平,即起始位
		StartRXD();			//	启动接收
		while(!RxdEnd);		//等待接收完成
		StartTXD(RxdBuf+1); //接收到的数据+1后,发送回去
		while(!TxdEnd);		//等待发送完成
		
	}
}

//串口配置函数
void  ConfigUART(unsigned int baud)
{
	TMOD&=0xF0;//清零TO的控制位
	TMOD|=0x02;//配置T0为模式2
	TH0=256-(11059200/12)/baud;

}

//启动串行接受
void StartRXD()
{
	TL0=256-((256-TH0)>>1);	//接收启动时的T0定时为半个波特率周期
	ET0=1;		//使能T0中断
	TR0=1;		//启动T0
	RxdEnd=0;   //清零接收结束标志
	RxdOrTxd=0;	//设置当前状态为接收
	
}
//启动串行发送,dat——待发送字节数据
void StartTXD(unsigned char dat)
{
	TxdBuf=dat;	//待发送数据保存到发送缓冲器
	TL0=TH0;	//T0计数初值为重载值
	ET0=1;		//使能T0中断
	TR0=1;		//启动T0
	PIN_TXD=0;	//发送起始位
	TxdEnd=0;	//清零发送结束标志
	RxdOrTxd=1;	//设置当前状态为发送

}

//T0中断服务函数,处理串行发送和接受

void Timer0_Routine()   interrupt  1	//跳转到这里,触发中断
{
	static unsigned char cnt=0; 	//位接收或发送计数
		
	if(RxdOrTxd)	//串行发送处理
	{
		cnt++;
		if(cnt<=8)	//低位在先依次发送8bit数据位
		{
			PIN_TXD=TxdBuf&0x01;
			TxdBuf>>=1;
		}	
		else if(cnt==9)	//发送停止位
		{
		PIN_TXD=1;
		}
		else //发送结束
		{
		cnt=0;	//复位bit计数器
		TR0=0;	//关闭T0
		TxdEnd=1;//置发送结束标志
		
		}
	
	}
	
	else	//串行接受处理
	{
		if(cnt==0)	//处理起始位
		{
			if(!PIN_RXD)	//起始位为0时,清零接收缓冲器,准备接收数据位
			{
			RxdBuf=0;
			cnt++;
			}
			else		//起始位不为0时,中止接受
			{
			TR0=0; //关闭T0
			}
		}
		else if(cnt<=8)	//处理8位数据位
		{
		RxdBuf>>=1;  //低位在先,所以将之前接收的位向右移
			if(PIN_RXD)	//接受脚为1时,缓冲器最高位置1,
			{
				RxdBuf |=0x80;
			}
			cnt++;
		}
		else	//停止位处理
		{
			cnt=0;	//复位bit计数器
			TR0=0;	//关闭T0
			if(PIN_RXD)	//停止位为1时,方能认为数据有效
			{
				RxdEnd=1;  	//	置接收结束标志
			}
		}
	
	
	}	
	
	
}

实验现象:

在这里插入图片描述
在这里插入图片描述

问题

1、咱也是用上示波器了,哈哈。

在这里插入图片描述
9600
发送:9
在这里插入图片描述
在这里插入图片描述
发送:0x14
在这里插入图片描述
在这里插入图片描述

4800
发送:0x09
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

本节课主要学了串口通信,并简单的用电脑的串口助手完成了单片机把发送的数据+1给返回过了。
1、串口通信的简单介绍
2、串口通信的类型和分类,注意电平协议,不同的需要转换
3、常用的通信从传输方向上可以分为单工通信、半双工通信、全双工通信三类。
4、RS232 通信接口,USB 转串口通信,IO 口模拟UART 串口通信。

鸡汤时刻

在这里插入图片描述
珍惜当下的时间,永远要有勇气,永远要保持活力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值