12 USART串口通讯

1 串口物理层

两个设备的“DB9接口”之间通过串口信号建立连接,串口信号线中使用“RS232标准”传输数据信号。由于RS232电平标准的信号不能直接被控制器直接识别,所以这些信号会经过“电平转换芯片”转换成控制器能识别的“TTL校准”的电平信号,才能实现通讯。 

通讯标准电平标准
5V TTL逻辑1:2.4v~5v;逻辑0:0v~0.5v
RS 232逻辑1:-15v~-3v;逻辑0:+3v~+15v

 2 串口协议层

串口通讯的数据包由发送设备通过自身的TXD接口传输到接收设备的RXD接口。在串口通讯的协议层中,规定了数据包的内容,他由起始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据。

 3 波特率

串口异步通讯中由于没有时钟信号,所以两个设备之间需要约定好波特率,以便对信号进行解码。

4 STM32 的USART

  • STM32 芯片具有多个USART外设用于串口通讯,即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。它还具有UART外设,是在USART基础上剪裁掉了同步通信功能,只有异步通信,简单区分就是看通信时需不需要对外提供时钟输出,平常用的串口通信基本都是UART。

5 USART 功能框图

 TX:发送数据输出数据引脚

RX:接收数据输入引脚

SW_RX:数据接收引脚,只能用于单线和智能卡模式,属于内部引脚,没有具体外部引脚

nRTS:请求以发送,n表示低电平有效。如果使能RTS流控制,当USART接收器准备好接收新数据时就会将nRTS变成低电平;当接收寄存器已满时,nRTS将被设置为高电平,该引脚只适用于硬件流控制。

nCTS:清除以发送,n表示低电平有效。如果使能CTS流控制,发送器在发送下一帧数据之前会检测nCTS引脚,如果为低电平,表示可以发送数据;如果为高电平则在发送完当前数据帧之后停止发送,该引脚只适用于硬件流控制。

SCLK:发送器时钟输出引脚,这个引脚仅适用于同步模式。

UART只是异步传输功能,所以没有SCLK、nCTS和nRTS功能引脚。

  • 数据寄存器

        USART_DR包含了已发送的数据或者接收到的数据。USART_DR实际是包含了两个寄存器,一个是专门用于发送的可写TDR,一个是专门用于接收的可读RDR。当进行发送操作时,往USART_DR写入数据会自动存储在TDR内;当进行读操作时,向USART_DR读取数据会自动提起RDR数据。

        TDR和RDR都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把TDR内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接收时把接收到的每一位顺序保存在接收移位寄存器内然后才转移大RDR。

  • 控制器

        USART有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等。使用USART之前需要向USART_CR1寄存器的UE位置1使能USART。发送或者接收数据字长可选8位或者9位,由USART_CR1的M位控制。

#include "stm32f4xx.h"
#include "stdio.h"
#include "USART.h"

#define DEBUG_USART              USART1
#define DEBUG_USART_CLK          RCC_APB2Periph_USART1
#define DEBUG_USART_BAUDRATE     115200
#define DEBUG_USART_RX_PORT      GPIOA
#define DEBUG_GPIO_RX_CLK        RCC_AHB1Periph_GPIOA
#define DEBUG_USART_RX_PIN       GPIO_Pin_10
#define DEBUG_USART_RX_AF        GPIO_AF_USART1
#define DEBUG_USART_TX_PORT      GPIOA
#define DEBUG_GPIO_TX_CLK        RCC_AHB1Periph_GPIOA
#define DEBUG_USART_TX_PIN       GPIO_Pin_9
#define DEBUG_USART_TX_AF        GPIO_AF_USART1
#define DEBUG_USART_BAUDRATE           115200


 
 //使能RX和TX引脚GPIO时钟和USART时钟
 
 //初始化GPIO,并将GPIO复用到USART上
 
 //配置USART参数
 
 //配置中断控制器并使能USART接收中断
 
 //使能USART;
 
 //在USART接收中断服务函数实现数据接收和发送
 

//配置嵌套向量中断控制器NVIC	
static void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
}

void USART_Config(void)
{
	GPIO_InitTypeDef   GPIO_InitStructure;
	USART_InitTypeDef  USART_InitStructure;
	
	//开启USART时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	//开启GPIOA时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	
	//将USART Tx的GPIO配置为推挽复用
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_PIN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;
	GPIO_Init(DEBUG_USART_TX_PORT,&GPIO_InitStructure);
	
	
	//将USART Rx的GPIO配置为浮空输入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_PIN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;
	GPIO_Init(DEBUG_USART_RX_PORT,&GPIO_InitStructure);
	
	//串口初始化配置
	USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	USART_Init(DEBUG_USART,&USART_InitStructure);
	
	//串口中断优先级配置
	NVIC_Configuration();
	
	//使能串口接收中断
	USART_ITConfig(DEBUG_USART,USART_IT_RXNE,ENABLE);
	
	//使能串口
	USART_Cmd(DEBUG_USART, ENABLE);

}

//发送一个字节
void Usart_SendByte(USART_TypeDef* USARTx, uint8_t ch)
{
	USART_SendData(DEBUG_USART, ch);
	
	while(USART_GetFlagStatus(DEBUG_USART,USART_FLAG_TC) == RESET);
	
}

//发送8位的数组
void Usart_SendArray(USART_TypeDef * pUSARTx,uint8_t *array,uint16_t num)
{
	uint8_t i;
	for(i=0;i<num;i++)
	{
		Usart_SendByte(DEBUG_USART,array[i]);
	}
	while(USART_GetFlagStatus(DEBUG_USART,USART_FLAG_TXE) == RESET);
}

//发送一个16位数
void Usart_SendHalfWord(USART_TypeDef * pUSARTx,uint16_t ch)
{
	uint8_t temp_h,temp_l;
	
	//取出高八位
	temp_h = (ch & 0XFF00)>>8;
	//取出低八位
	temp_l = ch & 0X00FF;
	
	//发送高八位
	USART_SendData(DEBUG_USART,temp_h);
	while(USART_GetFlagStatus(DEBUG_USART,USART_FLAG_TXE) == RESET );
	
	//发送低八位
	USART_SendData(DEBUG_USART,temp_l);
	while(USART_GetFlagStatus(DEBUG_USART,USART_FLAG_TXE) == RESET );
	
}

//重定向C库函数printf到串口,重定向后可使用printf函数
int fputc(int ch,FILE *f)
{
	USART_SendData(DEBUG_USART,(uint8_t)ch);
	
	while(USART_GetFlagStatus(DEBUG_USART,USART_FLAG_TXE) == RESET);
	
	return (ch);
}

//重定向C库函数scanf到串口,重写后可使用是scanf、getchar等函数
int fgetc(FILE *f)
{
	while(USART_GetFlagStatus(DEBUG_USART,USART_FLAG_RXNE) == RESET);
	
	return (int)USART_ReceiveData(DEBUG_USART);
}

//发送字符串
void Usart_SendString(USART_TypeDef * pUSARTx, char *str)
{
	unsigned int k = 0;
	do
	{
		Usart_SendByte(pUSARTx,*(str+k));
		k++;		
	}while(*(str+k)!='\0');
	
	while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
	
}

//当USART有接收到数据就会执行USART_IRQ_Handler函数,USART_GetITStatus和USART_GetFlagStatus函数类似用来获取标志位状态,
//但USART_GetITStatus函数是专门用来获取中断事件标志,并返回该标志位状态。
//使用if语句来判断是否是真的产生USART数据接收这个中断事件,
//如果是真的就使用USART数据读取函数USART_RecevieData读取数据到指定存储区,然后再调用USART数据发送噶部署USART_SendData把数据又发送给源设备 
void USART1_IRQHandler(void)
{
	uint8_t ucTemp;
	if(USART_GetITStatus(DEBUG_USART,USART_IT_RXNE) != RESET)
	{
		ucTemp = USART_ReceiveData(DEBUG_USART);
		USART_SendData(DEBUG_USART,ucTemp);
		
	}
	
}	

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/952052.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FreePBX 17 on ubuntu24 with Asterisk 20

版本配置&#xff1a; FreePBX 17&#xff08;最新&#xff09; Asterisk 20&#xff08;最新Asterisk 22&#xff0c;但是FreePBX 17最新只支持Asterisk 21&#xff0c;但是21非LTS版本&#xff0c;所以选择Asterisk 20&#xff09; PHP 8.2 Maria DB (v10.11) Node J…

搜广推面经五

饿了么推荐算法 一、介绍InfoNCE Loss、InfoNCE温度系数的作用 InfoNCE Loss&#xff08;Information Noise Contrastive Estimation Loss&#xff09;是一种常用于自监督学习和对比学习中的损失函数&#xff0c;特别是在信息论和无监督学习中有广泛应用。 它的核心思想是通过…

机器学习免费使用的数据集及网站链接

机器学习领域存在许多可以免费使用的数据集&#xff0c;这些数据集来自于学习、研究、比赛等目的。 一、综合性数据集平台 1.Kaggle 网址&#xff1a;Kaggle 数据集https://www.kaggle.com/datasets Kaggle是一个数据科学竞赛和社区平台&#xff0c;提供了大量的数据集供用…

浅尝Appium自动化框架

浅尝Appium自动化框架 Appium自动化框架介绍Appium原理Appium使用安装平台驱动实战 坑 Appium自动化框架介绍 Appium 是一个开源的自动化测试框架&#xff0c;最初设计用于移动应用的测试&#xff0c;但现在它也扩展了对桌面端应用的支持。Appium 使得自动化测试变得更加简单&…

ubuntu 20.04 安装docker--小白学习之路

更新包 sudo apt-get update # 安装需要的软件包以使apt能够通过HTTPS使用仓库 sudo apt-get install ca-certificates curl gnupg lsb-release 使用清华大学源 # 添加Docker官方的GPG密钥 curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo…

MMDetection框架下的常见目标检测与分割模型综述与实践指南

目录 综述与实践指南 SSD (Single Shot MultiBox Detector) 基本配置和使用代码 RetinaNet 基本配置和使用代码 Faster R-CNN 基本配置和使用代码 Mask R-CNN 基本配置和使用代码 Cascade R-CNN 基本配置和使用代码 总结 综述与实践指南 MMDetection是一个基于Py…

语音机器人外呼的缺点

也许是因为经济形式变差&#xff0c;大部分都是消费降级的策略。企业也一样&#xff0c;开源不行就只能重点节流。以前10个人做的工作&#xff0c;希望能用2个语音机器人就能完成。确实语音机器人是可以大幅提升外呼效率的&#xff0c;节约成本也很明显&#xff0c;但是今天不说…

微机原理期末复习(一)

编程题 汇编语言程序的整体结构 STACK SEGMENT STACK STACKDW 100H DUP(?) TOP LABEL WORD ; 使用LEBEL获取栈的尾部偏移地址存储到TOP中&#xff0c;以便初始化sp STACK ENDSDATA SEGMENT... ; 用户定义的变量 DATA ENDSCODE SEGMENTASSUME CS: CODE, DS: DATA, ES: DATA, …

UML(统一建模语言)

目录 一、用例图&#xff08;Use Case Diagram&#xff09; 二、类图&#xff08;Class Diagram&#xff09; 2.1、泛化&#xff08;Generalization&#xff09; 2.2、实现&#xff08;Realization&#xff09; 2.3、关联&#xff08;Association&#xff09; 2.4、聚合&…

流浪猫流浪狗领养PHP网站源码

源码介绍 流浪猫流浪狗领养PHP网站源码&#xff0c;适合做猫狗宠物类的发信息发布。当然其他信息发布也是可以的。 导入数据库&#xff0c;修改数据库配置/application/database.php 设置TP伪静态&#xff0c;设置运行目录&#xff0c; 后台&#xff1a;/abcd.php/dashboard?…

轻量级适合阅读的优秀 C++ 开源项目

CTPL 这是一个现代简易版的、高效的C线程池库&#xff0c;代码行数500行左右。 代码示例&#xff1a; void first(int id) { std::cout << "hello from " << id << \n; } struct Second { void operator()(int id) const { std::cout << &q…

下载导出Tomcat上的excle文档,浏览器上显示下载

目录 1.前端2.Tomcat服务器内配置3.在Tomcat映射的文件内放置文件4.重启Tomcat&#xff0c;下载测试 1.前端 function downloadFile() {let pictureSourceServer "http://192.168.1.1:8080/downFile/";let fileName "测试文档.xlsx";let fileURL pictu…

winform第三方界面开源库AntdUI的使用教程保姆级环境设置篇

1. AntdUI 1.1. 导入项目 1.1.1. 首先新建一个空白的基于.net的Winfrom项目1.1.2. 复制AntdUI中src目录到我们的解决方案下面1.1.3. 解决方案下添加现有项目1.1.4. 添加项目引用 1.2. 编写代码 1.2.1. 改写Form1类&#xff0c;让其继承自public partial class Form1 : AntdUI.W…

【DES加密】

什么是DES DES(Data Encryption Standard) 是一种对称加密算法。它的设计目标是提供高度的数据安全性和性能。 DES的概念 DES使用56位的密钥和64位的明文块进行加密。DES算法的分组大小是64位&#xff0c;因此&#xff0c;如果需要加密的明文长度不足64位&#xff0c;需要进…

【FPGA】时序约束与分析

设计约束 设计约束所处环节&#xff1a; 约束输入 分析实现结果 设计优化 设计约束分类&#xff1a; 物理约束&#xff1a;I/O接口约束&#xff08;例如引脚分配、电平标准设定等物理属性的约束&#xff09;、布局约束、布线约束以及配置约束 时序约束&#xff1a;设计FP…

docker搭建atlassian-confluence:7.2.0

文章目录 引言I 部署前准备数据库镜像准备自己构建镜像dockerhub第三方镜像II 安装启动容器基础配置(获取服务器ID)授权码获取集群选择设置数据库配置管理员账号引言 准备数据库、镜像启动容器获取服务器ID根据服务器ID等信息,基于atlassian-agent.jar 授权I 部署前准备 数…

征战越南电商直播,SD - WAN 专线赋能企业带货新征程

在当今数字化商业浪潮中&#xff0c;越南电商市场正经历着蓬勃发展与激烈变革。根据 Sapo Technology Joint Stock Company 对全国 15,000 名卖家的深度调查&#xff0c;2024 年零售业务的直播领域呈现出多元竞争态势。Facebook Live 强势占据多渠道或仅在线销售卖家总直播会话…

软件测试之黑盒测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 概念与定义 黑盒测试&#xff1a;又称功能测试、数据驱动测试或基于需求规格说明书的测试。通过黑盒测试来检测每个功能是否都能正常使用。黑盒测 试把测试对象看…

熵与交叉熵:从不确定性角度理解 KL 散度

从不确定性减少视角理解KL散度 【 Transformer 系列&#xff0c;故事从 d k \sqrt{d_k} dk​ ​说起】 LLM这么火&#xff0c;Transformer厥功甚伟&#xff0c;某天心血来潮~&#xff0c;再去看看&#xff01; 它长这个样子&#xff1a; 深入浅出 Transformer 看完后&#xff…

【Unity3D】导出Android项目以及Java混淆

Android Studio 下载文件归档 | Android Developers Android--混淆配置&#xff08;比较详细的混淆规则&#xff09;_android 混淆规则-CSDN博客 Unity版本&#xff1a;2019.4.0f1 Gradle版本&#xff1a;5.6.4&#xff08;或5.1.1&#xff09; Gradle Plugin版本&#xff…