基于STM32F103的USART的原理及应用(一)(实现手机BLE和MCU进行通信)

一,查阅数据手册,找到对应的IO口和外设总线并配置好外设源文件

想了解USART的具体原理的小伙伴请进传送门:(总结)STM32中USART原理及应用(PC、BLE、ESP8266通信实现)-CSDN博客

二,打开外设时钟

三,配置GPIO引脚为复用模式

四,重映射IO引脚为串口功能(不是必须的,像我用的是PA9 和 PA10,就可以不用,因为默认有串口功能)

五,配置UART1参数(波特率,数据位,停止位,校验位,设置无流控,设置全双工)(跟STM32F407代码一样)

六,配置USART的中断(选择中断通道,抢占优先级,响应优先级,打开中断通道)(跟STM32F407代码一样)

七,选择USART1的中断源,即当接收到数据时触发中断

八,打开串口

九,编写USART中断服务函数

十,完整代码展示

/******************************************************************************** @file    main.c * @author  * @version V1.0* @date    2024/12/30* @brief   本代码配置USART实现BLE和MCU进行串口通信,实现通过手机蓝牙来控制小灯的开关******************************************************************************
*/#include "stm32f10x.h"
#include "delay_us.h"
#include "delay_ms.h"
#include "string.h"/* Private typedef   用于记录用户自定义的一些数据类型的别名-------------------*//* Private define    用于记录用户自定义的类型,比如结构体、共用体、枚举-------*//* Private macro     用于记录用户自定义的宏定义-------------------------------*//* Private variables 用于记录用户自定义的全局变量-----------------------------*/
uint8_t  u1_rxbuf[512] = {0}; //作为UART1的接收缓冲区
uint32_t u1_rxcnt = 0;        //作为UART1的接收计数器/* Private function prototypes 用于记录用户自定义的函数声明-------------------*//* Private functions 用于记录用户自定义的函数原型-----------------------------*//*** @brief  该函数初始化IO引脚,用于LED的点亮* @param  None* @retval None*/
void LED_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;//打开时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//配置引脚参数GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOC, &GPIO_InitStructure);//输出高电平(点亮小灯)GPIO_SetBits(GPIOC, GPIO_Pin_14);
}/*** @brief  该函数初始化USART1,用于BLE通信* @param  None* @retval None*/
void USART1_Config(u32 baud)
{USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef  NVIC_InitStructure;GPIO_InitTypeDef  GPIO_InitStructure;//打开GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开USART2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//重映射IO引脚为串口功能GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);//配置GPIO的引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);//配置UART1的参数    最常用的格式: 1bit停止位  8bit数据位  No校验位  9600bpsUSART_InitStructure.USART_BaudRate = baud;											//波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;							//数据位USART_InitStructure.USART_StopBits = USART_StopBits_1;								//停止位USART_InitStructure.USART_Parity = USART_Parity_No;									//校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 	//无流控USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;     				//全双工USART_Init(USART1, &USART_InitStructure);//配置USART的中断NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);//选择UART1的中断源   接收到数据则触发中断请求USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//打开UART1串口USART_Cmd(USART1, ENABLE);}/*** @brief  程序的入口* @param  None* @retval None*/
int main(void)
{LED_Config();USART1_Config(9600);while (1){//判断UART2是否接收到数据  假设接收到 "led_on",则让LED点亮if( u1_rxcnt > 0 && strstr((char *)u1_rxbuf,"led_on")){GPIO_SetBits(GPIOC,GPIO_Pin_14); //输出高电平	u1_rxcnt = 0; //计数器复位memset((char *)u1_rxbuf,0,512); //清空数组}//判断UART2是否接收到数据  假设接收到 "led_off",则让LED熄灭if( u1_rxcnt > 0 && strstr((char *)u1_rxbuf,"led_off")){GPIO_ResetBits(GPIOC,GPIO_Pin_14); //输出低电平	u1_rxcnt = 0; //计数器复位memset((char *)u1_rxbuf,0,512); //清空数组}}
}/**
* @brief  This function handles USRAT1 interrupt request.
* @param  None
* @retval None
*/
void USART1_IRQHandler(void)
{//判断是否接收到数据if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET){   //把串口收到的字节存储到变量data中u1_rxbuf[u1_rxcnt++] = USART_ReceiveData(USART1); if( u1_rxcnt >= 512 ){u1_rxcnt = 0;}}
}/********************** (C) COPYRIGHT Your Name xxxx@126.com***END OF FILE****/

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

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

相关文章

如何在Java开发中选择适合的高性能工具库?

如何在Java开发中选择适合的高性能工具库? 在 Java 开发中选择适合的高性能工具库需要综合考虑多个因素,以下是详细的步骤和要点: 一、明确项目需求 功能需求 首先要确定项目需要的功能。例如,如果主要是进行 JSON 数据处理&a…

2025 小模型技术:驱动低代码与物联网融合发展新引擎

在科技的前沿赛道上,我们满怀期待地迈向 2025 年。这一年,小模型技术宛如一颗璀璨的新星,将在低代码与物联网的浩瀚星空中闪耀出独特光芒,成为引领二者融合发展的强劲引擎,为各行业的数字化变革带来澎湃动力与无限可能…

业务模型与UI设计

业务数据模型的设计、UI设计这应该是程序设计中不可缺少的部分。做程序设计的前提应该先把这两块设计好,那么,来一个实际案例,看看这2块的内容。 汽车保养记录业务模型与UI设计: 一、【车辆清单】 记录车辆相关的数据&#xff0…

微服务保护—Sentinel快速入门+微服务整合 示例: 黑马商城

1.微服务保护 微服务保护是确保微服务架构可靠、稳定和安全的策略与技术。 在可靠性上,限流是控制进入微服务的请求数量,防止流量过大导致服务崩溃。比如电商促销时对商品详情服务进行流量限制。熔断是当被调用的微服务故障过多或响应过慢时,…

unity学习4:git和SVN的使用差别

目录 1 svn 1.1 操作逻辑 1.2 对应工具 1.3 SVN避免冲突的好习惯 2 git 2.1 git的基础操作逻辑 2.1.1 commit时,提交文件之外的其他文件需要pull 2.1.2 commit时,发现要提交的本地文件和服务器的文件冲突了 2.1.3 pull 时 2.2 对应工具 2.3 …

Docker新手:在tencent云上实现Python服务打包到容器

1 使用docker的原因 一致性和可移植性:Docker 容器可以在任何支持 Docker 的环境中运行,无论是开发者的笔记本电脑、测试服务器还是生产环境。这确保了应用在不同环境中的行为一致,减少了“在我的机器上可以运行”的问题。 隔离性&#xff…

阻抗(Impedance)、容抗(Capacitive Reactance)、感抗(Inductive Reactance)

阻抗(Impedance)、容抗(Capacitive Reactance)、感抗(Inductive Reactance) 都是交流电路中描述电流和电压之间关系的参数,但它们的含义、单位和作用不同。下面是它们的定义和区别: …

Ruby 数据类型

Ruby 数据类型 Ruby,作为一种动态、开放源代码的编程语言,以其简洁明了的语法和强大的功能而闻名。在Ruby中,数据类型是编程的核心组成部分,它们决定了变量可以存储的信息种类以及可以对这些信息执行的操作。Ruby是一种类型安全的…

入门网络安全工程师要学习哪些内容【2025年寒假最新学习计划】

🤟 基于入门网络安全/黑客打造的:👉黑客&网络安全入门&进阶学习资源包 大家都知道网络安全行业很火,这个行业因为国家政策趋势正在大力发展,大有可为!但很多人对网络安全工程师还是不了解,不知道网…

【2024年-5月-14日-开源社区openEuler实践记录】深度剖析 Cantian-Connector-Mysql:开源连接方案新势力

引言 在数据驱动的时代,数据库连接组件是众多应用程序与数据存储之间的关键桥梁。Cantian-Connector-Mysql 作为一款开源项目,正逐渐受到开发者群体的关注,下面我们将从技术亮点、应用场景、部署实操以及代码示例等维度对它展开全面解读。 …

智联视频超融合平台:电力行业的智能守护者

文章目录 一、远程实时监控与设备状态监测二、提高应急响应能力三、实现无人值守与减员增效四、保障电力设施安全与防范外部破坏五、提升电网运行管理效率与决策科学性六、助力电力企业数字化转型与智能化发展七、智联视频超融合平台 在当今数字化浪潮下,视频联网平…

vue面试题|[2025-1-3]

1.v-if和v-show的区别? 都是可以控制元素的显示和隐藏 1.v-show是控制元素的display值来让元素显示和隐藏;v-if显示(隐藏)时会把整个DOM元素添加(删除) 2.v-show只是简单的css切换;v-if有一个局…

大型模型运行过程概述

整体过程 大模型,如大型语言模型(LLM),其生命周期主要分为两个阶段:训练和推理。这两个过程有着不同的目标、资源需求和技术挑战。 大模型的训练是一个复杂且资源密集的过程,它首先需要收集和准备大量的高…

PostgreSQL 表达式

PostgreSQL中的表达式是一种强大的工具,用于在数据库查询中处理和计算数据。它们由一个或多个值、运算符和PostgreSQL函数组合而成,类似于公式,并用于求值【1†source】。 在PostgreSQL中,表达式可以分为不同类型,如布…

带虚继承的类对象模型

文章目录 1、代码2、 单个虚继承3、vbptr是什么4、虚继承的多继承 1、代码 #include<iostream> using namespace std;class Base { public:int ma; };class Derive1 :virtual public Base { public:int mb; };class Derive2 :public Base { public:int mc; };class Deri…

责任链模式应用

牢记于心 职责单一: 责任链模式可以将每个验证逻辑封装到一个独立的处理器中&#xff0c;每个处理器负责单一的验证职责&#xff0c;符合单一职责原则。 可扩展性: 增加新的验证逻辑时&#xff0c;只需添加新的处理器&#xff0c;而不需要修改现有的代码。 清晰的流程: 将所…

信号的产生、处理

一、信号的概念 信号是linux系统提供的一种&#xff0c;向指定进程发送特定事件的方式。收到信号的进程&#xff0c;要对信号做识别和处理。信号的产生是异步的&#xff0c;进程在工作过程中随时可能收到信号。 信号的种类分为以下这么多种&#xff08;用指令kill -l查看&…

如何在 Windows 10/11 上录制带有音频的屏幕 [3 种简单方法]

无论您是在上在线课程还是参加在线会议&#xff0c;您都可能需要在 Windows 10/11 上录制带有音频的屏幕。互联网上提供了多种可选方法。在这里&#xff0c;本博客收集了 3 种最简单的方法来指导您如何在 Windows 10/11 上使用音频进行屏幕录制。请继续阅读以探索&#xff01; …

卸载干净 IDEA(图文讲解)

目录 1、卸载 IDEA 程序 2、注册表清理 3、残留清理 1、卸载 IDEA 程序 点击屏幕左下角 Windows 图标 -> 设置-控制面板->intellij idea 勾选第一栏 Delete IntelliJ IDEA 2022.2 caches and local history&#xff0c;表示同时删除 IDEA 本地缓存以及历史。 Delete I…

若依使用 Undertow 替代 Tomcat 容器

文章目录 需求提出应用场景解决思路注意事项完整代码第一步&#xff1a;在 ruoyi-framework/pom.xml 文件中进行依赖配置第二步&#xff1a;修改 application.yml 配置文件第三步&#xff1a;修改文件上传工具类 FileUploadUtils.java 运行结果 需求提出 在开发若依框架的前后…