STM32学习笔记(九)--串口 UART/USART详解

news2024/11/20 23:38:11

(1)配置步骤
1.开启RCC外设时钟 开启GPIO以及USART外设
2.初始化GPIO 配置TX复用输出 RX输入
3.配置USART初始化结构体
4.配置串口中断 ITConfig以及NVIC(如果需要USART中断)
5.开启USART

(2)代码示例
案例1  串口异步通信PA9(USART1_TX) 串口发送

void Serial_Init(void)
{
//打开对应总线外设usart以及gpio
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//配置引脚作为TX时用复用式推挽输出
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
//波特率设置
	USART_InitStructure.USART_BaudRate = 9600;
//硬件流控制
	USART_InitStructure.USART_HardwareFlowControl=
USART_HardwareFlowControl_None;
//选择发送模式还是接收模式TX还是RX 如果都需要就或起来
	USART_InitStructure.USART_Mode = USART_Mode_Tx;
//选择校验 无 奇偶校验
	USART_InitStructure.USART_Parity = USART_Parity_No;
//选择停止位 一般都是一位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
//发送字节长度 8位(一个字节) 或者 9位
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1, &USART_InitStructure);
//打开串口
	USART_Cmd(USART1, ENABLE);
}


void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);//写入DR
//等待标志位清零
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
//发送一个数组
void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Array[i]);
	}
}
//发送一个字符串
void Serial_SendString(char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i ++)
	{
		Serial_SendByte(String[i]);
	}
//注意要善用sprintf
}

uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y --)
	{
		Result *= X;
	}
	return Result;
}
//发送一个整型数字
void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
	}
}
//可利用printf输出
int fputc(int ch, FILE *f)
{
	Serial_SendByte(ch);
	return ch;
}
//对于sprintf进行封装
void Serial_Printf(char *format, ...)
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	Serial_SendString(String);
}

案例2  串口中断PA9 10(USART1_TX RX) 串口发送接收

uint8_t Serial_RxData;
uint8_t Serial_RxFlag;
void Serial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用式推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1, &USART_InitStructure);
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	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);
	
	USART_Cmd(USART1, ENABLE);
}

void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Array[i]);
	}
}

void Serial_SendString(char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i ++)
	{
		Serial_SendByte(String[i]);
	}
}

uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y --)
	{
		Result *= X;
	}
	return Result;
}

void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
	}
}

//接收部分
uint8_t Serial_GetRxFlag(void)
{
	if (Serial_RxFlag == 1)
	{
		Serial_RxFlag = 0;
		return 1;
	}
	return 0;
}

uint8_t Serial_GetRxData(void)
{
	return Serial_RxData;
}

void USART1_IRQHandler(void)
{
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		Serial_RxData = USART_ReceiveData(USART1);
		Serial_RxFlag = 1;
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}
//中断方式接收到的数据回传电脑
int main(void)
{
	OLED_Init();
	OLED_ShowString(1, 1, "RxData:");
	
	Serial_Init();
	
	while (1)
	{
		if (Serial_GetRxFlag() == 1)
		{
			RxData = Serial_GetRxData();
			Serial_SendByte(RxData);
			OLED_ShowHexNum(1, 8, RxData, 2);
		}
	}
}

案例3  串口数据包收发流程HEX

uint8_t Serial_TxPacket[4];				//FF 01 02 03 04 FE
uint8_t Serial_RxPacket[4];
uint8_t Serial_RxFlag;

void Serial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1, &USART_InitStructure);
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	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);
	
	USART_Cmd(USART1, ENABLE);
}

void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Array[i]);
	}
}

void Serial_SendPacket(void)
{
	Serial_SendByte(0xFF);
	Serial_SendArray(Serial_TxPacket, 4);
	Serial_SendByte(0xFE);
}

uint8_t Serial_GetRxFlag(void)
{
	if (Serial_RxFlag == 1)
	{
		Serial_RxFlag = 0;
		return 1;
	}
	return 0;
}

void USART1_IRQHandler(void)
{
	static uint8_t RxState = 0;
	static uint8_t pRxPacket = 0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		uint8_t RxData = USART_ReceiveData(USART1);
		
		if (RxState == 0)
		{
			if (RxData == 0xFF)
			{
				RxState = 1;
				pRxPacket = 0;
			}
		}
		else if (RxState == 1)
		{
			Serial_RxPacket[pRxPacket] = RxData;
			pRxPacket ++;
			if (pRxPacket >= 4)
			{
				RxState = 2;
			}
		}
		else if (RxState == 2)
		{
			if (RxData == 0xFE)
			{
				RxState = 0;
				Serial_RxFlag = 1;
			}
		}
		
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

uint8_t KeyNum;
int main(void)
{
	OLED_Init();
	Key_Init();
	Serial_Init();
	OLED_ShowString(1, 1, "TxPacket");
	OLED_ShowString(3, 1, "RxPacket");
	Serial_TxPacket[0] = 0x01;
	Serial_TxPacket[1] = 0x02;
	Serial_TxPacket[2] = 0x03;
	Serial_TxPacket[3] = 0x04;
	while (1)
	{
		KeyNum = Key_GetNum();
		if (KeyNum == 1)
		{
			Serial_TxPacket[0] ++;
			Serial_TxPacket[1] ++;
			Serial_TxPacket[2] ++;
			Serial_TxPacket[3] ++;
			Serial_SendPacket();
			OLED_ShowHexNum(2, 1, Serial_TxPacket[0], 2);
			OLED_ShowHexNum(2, 4, Serial_TxPacket[1], 2);
			OLED_ShowHexNum(2, 7, Serial_TxPacket[2], 2);
			OLED_ShowHexNum(2, 10, Serial_TxPacket[3], 2);
		}
		if (Serial_GetRxFlag() == 1)
		{
			OLED_ShowHexNum(4, 1, Serial_RxPacket[0], 2);
			OLED_ShowHexNum(4, 4, Serial_RxPacket[1], 2);
			OLED_ShowHexNum(4, 7, Serial_RxPacket[2], 2);
			OLED_ShowHexNum(4, 10, Serial_RxPacket[3], 2);
		}
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

配对交换00

题目链接 配对交换 题目描述 注意点 num的范围在[0, 2^30 - 1]之间&#xff0c;不会发生整数溢出 解答思路 第一个思路是每次取奇数位和偶数位&#xff0c;将两位上的数字交换并根据其所处的位置求得的值与res相加&#xff0c;重复此过程即可第二个思路是将所有的奇数位和…

Python酷库之旅-比翼双飞情侣库(16)

目录 一、xlwt库的由来 1、背景和需求 2、项目启动 3、功能特点 4、版本兼容性 5、与其他库的关系 6、示例和应用 7、发展历史 二、xlwt库优缺点 1、优点 1-1、简单易用 1-2、功能丰富 1-3、兼容旧版Excel 1-4、社区支持 1-5、稳定性 2、缺点 2-1、不支持.xls…

仓库管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;公告管理&#xff0c;物资管理&#xff0c;基础数据管理&#xff0c;用户管理 用户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公告管理&#xff0c;物…

华为HCIP Datacom H12-821 卷5

1.单选题 下列哪种工具不能被 route-policy 的 apply 子句直接引用? A、IP-Prefix B、tag C、community D、origin 正确答案&#xff1a; A 解析&#xff1a; 因route-policy工具中&#xff0c; apply 后面跟的是路由的相关属性。 但是ip-prefix是用来匹配路由的工具。 2…

Java基础学习-流程控制语句-顺序结构-分支结构-循环结构

目录 顺序结构&#xff1a; 分支结构&#xff1a; if语句&#xff1a; 第一种格式&#xff1a; if第二种格式&#xff1a; 案例练习 if第三种格式&#xff1a; switch语句&#xff1a; 格式&#xff1a; switch其他知识点&#xff1a; 循环结构&#xff1a; for循环…

[保姆级教程]uniapp配置vueX

文章目录 注意新建文件简单的使用 注意 uniapp是支持vueX的只需配置一下就好 新建文件 在src文件中&#xff0c;新建一个store&#xff08;如果有的话跳过&#xff09; 在store中新建一个js文件&#xff0c;修改js文件名称和选择模板为default 在 uni-app 项目根目录下&…

【C++】拷贝构造函数、拷贝赋值函数与析构函数

C中的拷贝构造函数、拷贝赋值函数与析构函数详解 一、拷贝构造函数&#xff08;Copy Constructor&#xff09;二、拷贝赋值函数&#xff08;Copy Assignment Operator&#xff09;三、析构函数&#xff08;Destructor&#xff09;四、总结 在C中&#xff0c;拷贝构造函数、拷贝…

java-SpringBoot执行定时任务-任务调度-@EnableScheduling和@Scheduled

文章目录 java借助springBoot框架&#xff0c;执行定时任务0. 项目地址1. 需求分析2、新建springBoot项目3. 编写定时任务3.1 开启调度任务3.2 编写定时任务方法 java借助springBoot框架&#xff0c;执行定时任务 0. 项目地址 https://github.com/OrangeHza/JavaDemo 1. 需求…

vue2 TypeError: compiler.plugin is not a function

俩个命令解决&#xff1a; npm i webpack-clilatest npm i webpacklatest

AI项目二十三:危险区域识别系统

若该文为原创文章&#xff0c;转载请注明原文出处。 一、介绍 在IPC监控视频中&#xff0c;很多IPC现在支持区域检测&#xff0c;当在区域内检测到有人闯入时&#xff0c;发送报警并联动报警系统&#xff0c;以保障生命和财产安全具有重大意义。它能够在第一时间检测到人员进入…

提升人工智能大模型的智能

前言 提升人工智能大模型的智能是一个涉及到多方面挑战和策略的复杂问题。下面是一些关键的策略和挑战&#xff0c;可以帮助我们更好地理解和处理这一问题。 策略 模型架构与深度优化&#xff1a; 深度学习架构优化&#xff1a;设计更深、更复杂的神经网络结构&#xff0c;如…

python GUI开发: tkinter菜单创建,记事本和画图软件综合项目的实战演练

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【Nginx系列】反向代理在现代网络架构中的重要性

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

电动汽车厂商Rivian将全新设计元素融入由虚幻引擎驱动的车机界面

Rivian Automotive&#xff08;简称&#xff1a;“Rivian”&#xff09;&#xff0c;是美国一家电动汽车厂商&#xff0c;该品牌创办于2009年&#xff0c;总部位于加州埃尔文&#xff0c;专注于生产电动皮卡车Rivian R1T和电动SUV Rivian R1S。 Rivian的车主们正追寻这样一条道…

做动画?Animatediff 和 ComfyUI 更配哦!

如果从工作流和内存利用率的角度来说&#xff0c;Animatediff 和 ComfyUI 可能更配一些&#xff0c;毕竟制作动画是一个很吃内存的操作。 首先&#xff0c;我们需要在管理器中下载 Animatediff 插件&#xff0c;当然也可以直接导入听雨的工作流&#xff0c;然后在管理器的安装…

Chromium 开发指南2024 Mac篇-开始编译Chromium(五)

1.引言 在之前的指南中&#xff0c;我们已经详细介绍了在 macOS 上编译和开发 Chromium 的准备工作。您学会了如何安装和配置 Xcode&#xff0c;如何下载和配置 depot_tools&#xff0c;以及如何获取 Chromium 的源代码。通过这些步骤&#xff0c;您的开发环境已经搭建完毕&am…

压力应变桥信号变送光电隔离放大模块PCB焊接式 差分信号输入0-10mV/0-20mV/0-±10mV/0-±20mV转0-5V/0-10V/4-20mA

概述&#xff1a; IPO压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号混合集成厚模电路。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。该模块内部嵌入了一个高效微功率的电源&#xff0c;向输入端和输出端…

STM32CubeMX 安装教程

目录 总体讲解 1.0 java下载 1.1 CubeMx下载 2.0 java安装 2.1 CubMx安装 总体讲解 本次文章讲解CubMx的下载及安装&#xff0c;由于CubMx的运行环境需要java&#xff0c;所以我们需要先下载java的环境。 1.0 java下载 站内java8版本下载&#xff1a; https://download…

数字人源码部署该如何选对数字人源头工厂?

数字人作为AI产业的中流砥柱&#xff0c;其应用场景之广泛。从数字人口播、到直播到数字人克隆、到声音克隆、再至AI复活、数字人名片、数字人员工、数字人客服、3D息影舱智能交互、要知道这一切仅仅只是用了两年的时间&#xff0c;可见我国的AI技术取得突破性发展. 如果把时间…

Matlab绘制三维图像(论文插图)

Matlab绘制三维图像 hfigure; % 创建 surf surf(PHDeformed_1Unwrap); shading interp;lightangle(45,75); % 创建 zlabel zlabel(Z(phase/rad),FontWeight,bold,FontName,Times New Roman); % 创建 ylabel ylabel(Y(pixel),FontWeight,bold,FontName,Times New Roman); % 创建…