串口通信(通过stc模拟与电脑通信)

发布时间:2024年01月23日


一、串口接介绍

在这里插入图片描述

硬件电路

在这里插入图片描述

电平标准

在这里插入图片描述
差分信号
即通过两根线的电压差与地线比较。

常见通信接口比较

在这里插入图片描述
术语解释
在这里插入图片描述

51单片机的UART

在这里插入图片描述
由于我们使用的是USB接口,单片机还有一个USB转串口电路,如下
在这里插入图片描述

串口参数及时序图
在这里插入图片描述

串口模式图

在这里插入图片描述
总的连接线路如图:
在这里插入图片描述
串口的相关寄存器
在这里插入图片描述
寄存器详情(来源于官方文档)
在这里插入图片描述

二、使用串口向电脑收发数据案例

1.配置寄存器

我这里使用的是11.0592MHz的晶振频率,借助stc配置波特率,然后再让电脑波特率与其一致(异步通信)
在这里插入图片描述
然后根据自己的需求完善,完整的串口初始化代码(UART_Init.c)如下:

#include <REGX52.H>


// 初始化串口
void UART_Init(){
  	// 配置SCON寄存器
	/*
		SM0/FE 0,不需要帧错误检测
		SM0 SM1组合确定串口工作方式,使用方式1,给1,
	8位UART,波特率为(2^SMOD/32)*(定时器1的溢出率), 
	<(定时器1的溢出率)12T为SYSclk/12/(256-TH1),6T为SYSclk/6/(256-TH1)>>
		SM2	用于方式2、3,给0
		REN 允许/进制串行接收控制位,由软件置位、复位,给0
		TB8	用于方式2、3,给0
		RB8	用于方式2、3,给0
		TI 发送中断请求,开始由内部硬件置位,由软件复位,给0
	*/
	SCON = 0X40;  // 0100 0000

	// 配置电源控制寄存器PCON
	/*
		SMOD 波特率选择,为1是方式1、2、3波特率加倍,为0全部方式加倍
		SMOD0 帧错误检查,目前不需要,给0
	*/
	PCON |= 0x80;

	// 暂时不需要使用中断,不用配置其他的寄存器
	// 配置定时器1,串口使用的是8位自动重载
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x20;			//设置定时器模式
	TL1 = 0xF4;			//设置定时初始值
	TH1 = 0xF4;			//设置定时重载值
	TR1 = 1;				//定时器0开始计时
	ET1 = 0;				// 禁止TF0的中断请求
	
}

波特率计算

以上面代码配置为例解释波特率的计算过程
使用的是8位自动重载,赋值为0xf4,即244,每个盒子为8位,即256,所以每256-244 = 12um溢出一次,所以此时的溢出率为11.0592/12/12 = 0.0768,然后0.0768/16= 0.0048MHz,即4800Hz
在这里插入图片描述

2.配置发送数据的函数

数据首先要发送到串口的缓冲区,然后才会发送,将函数封装于主函数中,主函数(main.c)如下:

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


// 发送数据
void UART_sendByte(unsigned char byte){
	SBUF = byte; // 将数据写入串口缓冲区
	while(TI == 0); // 数据发出去即跳出循环
	TI = 0;	   // 需手动复位

}  

unsigned char count = 0;
void main(){
	UART_Init(); 
	// 每隔1s发送递增数据
	while(1){
	 	UART_sendByte(count);
		count++;
		Delayms(1000);		
	}
}

3.使用stc用串口模拟电脑接收数据

点击USB-CDC/串口助手,配置正确后打开串口,即可接收数据,如果选择的是文本模式,会通过ASCII码编码后显示
在这里插入图片描述

三、电脑通过串口控制LED

1.配置串口

由于电脑发送数据没有固定时间,所以需要使用中断来接收数据,需要对初始化函数进行更新,UART_Init.c如下:

#include <REGX52.H>


// 初始化串口
void UART_Init(){
  	// 配置SCON寄存器
	// 使用方式1,允许中断
	SCON = 0X50;  // 0101 0000

	// 配置电源控制寄存器PCON
	/*
		SMOD 波特率选择,为1是方式1、2、3波特率加倍,为0全部方式加倍
		SMOD0 帧错误检查,目前不需要,给0
	*/
	PCON |= 0x80;

	// 暂时不需要使用中断,不用配置其他的寄存器
	// 配置定时器1,串口使用的是8位自动重载
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x20;			//设置定时器模式
	TL1 = 0xF4;			//设置定时初始值
	TH1 = 0xF4;			//设置定时重载值
	TR1 = 1;				//定时器0开始计时
	ET1 = 1;				// 允许TF0的中断请求
	EA = 1;				   	// 打开中断
	ES = 1;					// 打开中断总开关
}

2.查看中断函数

在这里插入图片描述

3.配置中断函数

main.c配置如下:

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


// 发送数据
void UART_sendByte(unsigned char byte){
	SBUF = byte; // 将数据写入串口缓冲区
	while(TI == 0); // 数据发出去即跳出循环
	TI = 0;	   // 需手动复位

}  

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

// 配置中断函数
void UART_Routine()	interrupt 4
{
	// 只要RI>=1(收)或者TI>=1(发)就会触发串口中断。前提是程序打开了总中断和串口中断。
	// 串口接收数据后,硬件会自动将RI置1
	if(RI == 1){
		P2 = SBUF; // 从缓冲区读取数据
		UART_sendByte(SBUF); // 发回数据
		RI = 0;
	}
}

验证结果
在这里插入图片描述


文章来源:https://blog.csdn.net/qq_53922901/article/details/135745822
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。