STM32——串口实践

STM32——串口实践

1.蓝牙控制点灯

项目需求

通过蓝牙模块,实现手机控制蓝牙插座/风扇/灯。

本质:

  1. 采用蓝牙的透传功能;

  2. 控制 IO 口的输出。

硬件清单

HC01蓝牙模块

CH340

杜邦线

项目设计

HC01_TX – RX1

HC01_RX – TX1

项目实现

串口非中断法

HAL_UART_Receive(&huart1, ch, 19, 100);
//HAL_UART_Transmit(&huart1, ch, strlen(ch), 100);
//printf((char *)ch);
printf("%s", ch);
if (!strcmp((const char *)ch, "open")) {HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_RESET)printf("LED1已打开\n");
}else if(!strcmp((const char *)ch, "close")) {HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_SET)printf("LED1已关闭\n");
} else {if(ch[0] != '\0')printf("指令发送错误:%s", ch);
}

串口中断法

printf("收到数据:");
if (!strcmp((const char *)UART1_RX_Buffer, "open")) {HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_RESET)printf("LED1已打开\n");
}else if(!strcmp((const char *)UART1_RX_Buffer, "close")) {HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_SET)printf("LED1已关闭\n");
} else {if(UART1_RX_Buffer[0] != '\0')printf("指令发送错误:%s", UART1_RX_Buffer);
}

2.WI_FI点灯

项目需求

通过ESP8266模块,实现手机控制wifi插座/风扇/灯。

硬件清单

ESP8266模块

CH340

杜邦线

项目实现

注意:

  1. 工作中一般不直接在中断服务函数里处理数据,而是在收到数据后直接丢给队列,再处理数据;

  2. 在中断服务函数里尽量减少使用延时函数及打印函数。

AP模式

#define SIZE 12char buffer[SIZE];
char LJWL[] = "AT+CWJAP=\"TP-LINK_3E30\",\"18650711783\"\r\n"; //入网指令
char LJFWQ[] = "AT+CIPSTART=\"TCP\",\"192.168.0.130\",8880\r\n"; //连接服务器指令
char TCMS[] = "AT+CIPMODE=1\r\n"; //透传指令
char SJCS[] = "AT+CIPSEND\r\n"; //数据传输开始指令
char CQMK[] = "AT+RST\r\n"; //重启模块指令
char AT_OK_Flag = 0; //OK返回值的标志位
char AT_Connect_Net_Flag = 0; //WIFI GOT IP返回值的标志位
// 接收完成回调函数,收到一个数据后,在这里处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{// 判断中断是由哪个串口触发的if(huart->Instance == USART1){// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)if((UART1_RX_STA & 0x8000) == 0){// 如果已经收到了 0x0d (回车),if(UART1_RX_STA & 0x4000){// 则接着判断是否收到 0x0a (换行)if(buf == 0x0a){// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1UART1_RX_STA |= 0x8000;// 查看是否收到 WIFI GOT IPif(!strcmp((uint8_t *)UART1_RX_Buffer, "WIFI GOT IP"))AT_Connect_Net_Flag = 1;// 查看是否收到 OKif(!strcmp((uint8_t *)UART1_RX_Buffer, "OK"))AT_OK_Flag = 1;// 查看是否收到 FAILif(!strcmp((uint8_t *)UART1_RX_Buffer, "FAIL")){int i = 0;for(i = 0; i < 5; i++){HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);HAL_Delay(1000);}HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);printf(CQMK);}// 灯控指令if(!strcmp((uint8_t *)UART1_RX_Buffer, "L-1"))HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);if(!strcmp((uint8_t *)UART1_RX_Buffer, "L-0"))HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);memset(UART1_RX_Buffer, 0, UART1_REC_LEN);UART1_RX_STA = 0;}else// 否则认为接收错误,重新开始UART1_RX_STA = 0;}else // 如果没有收到了 0x0d (回车){//则先判断收到的这个字符是否是 0x0d (回车)if(buf == 0x0d){// 是的话则将 bit14 位置为1UART1_RX_STA |= 0x4000;}else{// 否则将接收到的数据保存在缓存数组里UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;UART1_RX_STA++;// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收if(UART1_RX_STA > UART1_REC_LEN - 1)UART1_RX_STA = 0;}}}// 重新开启中断HAL_UART_Receive_IT(&huart1, &buf, 1);}
}
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_NVIC_SetPriority(SysTick_IRQn,0,0);// 开启接收中断HAL_UART_Receive_IT(&huart1, &buf, 1);HAL_UART_Transmit(&huart2, "let's go!!\r\n", strlen("let's go!!\r\n"), 100);//发送联网AT指令并等待成功printf(LJWL);//while(!AT_Connect_Net_Flag);while(!AT_OK_Flag) HAL_Delay(50);AT_OK_Flag = 0;//发送连服务器指令并等待成功printf(LJFWQ);while(!AT_OK_Flag) HAL_Delay(50);AT_OK_Flag = 0;//发送透传模式指令并等待成功printf(TCMS);while(!AT_OK_Flag) HAL_Delay(50);AT_OK_Flag = 0;//发送数据传输指令并等待成功printf(SJCS);while(!AT_OK_Flag) HAL_Delay(50);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */printf("liangxu shuai\r\n");HAL_UART_Transmit(&huart2, "hello liangxu\r\n", strlen("hello liangxu\r\n"),100);HAL_Delay(3000);}/* USER CODE END 3 */
}

STA模式:

#include <stdio.h>
#include <string.h>
char buffer[SIZE];
//1 工作在路由模式
char LYMO[] = "AT+CWMODE=2\r\n";
//2 使能多链接
char DLJ[] = "AT+CIPMUX=1\r\n";
//3 建立TCPServer
char JLFW[] = "AT+CIPSERVER=1\r\n"; // default port = 333
//发送数据
char FSSJ[] = "AT+CIPSEND=0,5\r\n";
char AT_OK_Flag = 0; //OK返回值的标志位
char AT_Connect_Net_Flag = 0; //WIFI GOT IP返回值的标志位
char Client_Connect_Flag = 0;
// 接收完成回调函数,收到一个数据后,在这里处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{// 判断中断是由哪个串口触发的if(huart->Instance == USART1){// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)if((UART1_RX_STA & 0x8000) == 0){// 如果已经收到了 0x0d (回车),if(UART1_RX_STA & 0x4000){// 则接着判断是否收到 0x0a (换行)if(buf == 0x0a){// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1UART1_RX_STA |= 0x8000;// 查看是否收到 WIFI GOT IPif(!strcmp(UART1_RX_Buffer, "WIFI GOT IP"))AT_Connect_Net_Flag = 1;// 查看是否收到 OKif(!strcmp(UART1_RX_Buffer, "OK"))AT_OK_Flag = 1;// 查看是否收到 FAILif(!strcmp(UART1_RX_Buffer, "0,CONNECT"))Client_Connect_Flag = 1;// 灯控指令if(!strcmp(UART1_RX_Buffer, "L-1"))HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);if(!strcmp(UART1_RX_Buffer, "L-0"))HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);memset(UART1_RX_Buffer, 0, UART1_REC_LEN);UART1_RX_STA = 0;}else// 否则认为接收错误,重新开始UART1_RX_STA = 0;}else // 如果没有收到了 0x0d (回车){//则先判断收到的这个字符是否是 0x0d (回车)if(buf == 0x0d){// 是的话则将 bit14 位置为1UART1_RX_STA |= 0x4000;}else{// 否则将接收到的数据保存在缓存数组里UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;UART1_RX_STA++;// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收if(UART1_RX_STA > UART1_REC_LEN - 1)UART1_RX_STA = 0;}}}// 重新开启中断HAL_UART_Receive_IT(&huart1, &buf, 1);}
}
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_NVIC_SetPriority(SysTick_IRQn,0,0);// 开启接收中断HAL_UART_Receive_IT(&huart1, &buf, 1);HAL_UART_Transmit(&huart2, "let's go\r\n", strlen("let's go\r\n"), 100);printf(LYMO);while(!AT_OK_Flag) HAL_Delay(50);AT_OK_Flag = 0;printf(DLJ);while(!AT_OK_Flag) HAL_Delay(50);AT_OK_Flag = 0;printf(JLFW);while(!Client_Connect_Flag) HAL_Delay(50);AT_OK_Flag = 0;if(Client_Connect_Flag){HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);}/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 *///4 发送数据printf(FSSJ);HAL_Delay(2000);printf("Hello");HAL_Delay(2000);}/* USER CODE END 3 */
}

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

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

相关文章

SouthLeetCode-打卡24年01月第2周

SouthLeetCode-打卡24年01月第2周 // Date : 2024/01/08 ~ 2024/01/14 001.数组中第三大的数 (1) 题目描述 001#2023机试T1#北岸计划2024/01/08 给定一个nums[]数组&#xff0c;求出数组中第三大的数&#xff0c;注意数组中可能包含重复的元素&#xff0c;保证一定有第三大…

【Python实战】Python多线程批量采集图片

前言 本文来介绍如何多线程采集图片&#xff0c;多线程效率更快&#xff0c;但是&#xff0c;我们单一IP请求过于频繁&#xff0c;可能会被反爬&#xff0c;被封IP&#xff0c;所以&#xff0c;我们就要用到IP代理池&#xff0c;这里&#xff0c;我给大家推荐一个&#xff0c;可…

5.10 动态优先级模式

动态优先级模式与静态优先级模式类似&#xff0c;但动态优先级模式会随着任务运行时条件的改变自动调整任务优先级。调整任务优先级的策略有很多种&#xff0c;最常见的是“最早截止期优先”(Earliest Deadline First)&#xff0c;即优先级最高的任务是离截止时间最近的任务。动…

11个技巧让你的Python性能起飞

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python 是一门非常强大且易于学习的编程语言&#xff0c;但在处理大规模数据或复杂任务时&#xff0c;可能会遇到性能瓶颈。为了让你的 Python 代码运行更快&#xff0c;本文将介绍一些提高 Python 性能的技巧和…

uniapp如何添加多个表单数组?

目录 一、实现思路 二、实现步骤 ①view部分展示 ②JavaScript 内容 ③css中样式展示 三、效果展示 四、小结 注意事项 总结模板&#xff1a; 一、实现思路 1.在 data 中定义一个数组&#xff0c;用于存储表单项的数据 2.在模板中使用 v-for 指令渲染表单项 3.在 methods 中…

低代码

腾讯云微搭低代码 WeDa _低代码开发平台_可视化开发平台-腾讯云 首页 - 钉钉宜搭 快速上手多维表格 爱速搭 - 企业应用智能设计平台 | 低代码平台 - 百度智能云 Astro轻应用 Astro Zero_低代码开发平台_软件开发工具_应用开发工具_华为云 低代码是一种软件开发方法&#x…

如何快速搭建个人博客

说明&#xff1a;本文介绍如何使用Halo框架快速搭建个人博客&#xff0c;我用的是阿里云的云服务器&#xff0c;操作系统是CentOS 7.0。 安装Docker&DockerCompose &#xff08;1&#xff09;Docker安装 Docker的安装参考&#xff0c;Docker安装&卸载&#xff1b; …

springboot修改orm事务

在Spring Boot结合MyBatis的应用中&#xff0c;如果你需要在服务层为某个特定方法单独修改MySQL的提交事务行为&#xff0c;你可以通过使用Transactional注解并指定相关的属性来实现。这个注解不仅允许你控制事务的开启和关闭&#xff0c;还可以设置事务的一些特定属性&#xf…

AI算力专题:算力系列之四-各省算力规划建设梳理-绿色低碳高质量发展-部署算力建设AI产业研究

今天分享的是AI算力系列深度研究报告&#xff1a;《AI算力专题&#xff1a;算力系列之四-各省算力规划建设梳理-绿色低碳高质量发展-部署算力建设AI产业研究》。 &#xff08;报告出品方&#xff1a;中泰证券&#xff09; 报告共计&#xff1a;40页 数据中心能耗情况 随着越…

【Docker】linux、nginx、容器镜像三者基本概念

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

PCB设计10条重要布线原则(学习笔记)

文章目录 一、连线精简二、避免走直角线三、差分走线四、蛇形走线五、圆滑走线六、数字与模拟分开七、3W原则八、20H原则九、铜箔承载电流十、过孔承载电流 一、连线精简 尽量用最短的路径去布线 1、可以省资源 2、信号差损少 3、线能不拐弯就不拐弯 4、能不换层就不换层 二…

SQL中实现行列转换

目录 方法一&#xff1a;sum case when 方法二&#xff1a;sum if 方法三&#xff1a;pivot 现在有一张表class_gender&#xff0c;内容如下&#xff1a; classgender一年级女一年级女一年级男一年级男二年级女二年级女二年级男 现在我们要根据上表&#xff0c;统计得到下…

初识attention

近年来&#xff0c;attention机制在机器视觉和机器翻译领域受到了广泛的关注&#xff0c;有很多文章都是融合attention来提高性能。attention受启发于人类的视觉系统&#xff0c;最先应用于序列化的机器翻译(NLP)后又推广到计算机视觉中&#xff0c;本篇文章就来简单学习一下at…

JS基础 - 遍历对象方法(6种)

初始值&#xff1a; var obj {a: 1,b: 2,c: 3,d: 4,e: 5,}; 第一种&#xff1a;for in for (let key in obj) {console.log(key ":" obj[key]);} 第二种&#xff1a;Object.keys 获取key Object.keys(obj).forEach((key) > {console.log(key ":" …

AI绘画:PhotoMaker Win11本地安装记录!

昨天介绍一个叫PhotoMaker的AI绘画开源项目。挺不错的&#xff01; 通过这个项目可以快速制作特定人脸的AI绘画作品&#xff0c;相比传统的技术效果会好很多&#xff0c;效率也高很多。 今天趁热打铁&#xff0c;本地电脑装装看&#xff0c;并且记录&#xff0c;分享一下&#…

js padEnd方法介绍笔记

padEnd() 是 JavaScript 字符串的方法之一&#xff0c;它用于在当前字符串的末尾添加指定数量的字符&#xff0c;直到字符串达到指定的长度。 padEnd() 方法接受两个参数&#xff1a; 目标长度和要添加的填充字符。 如果当前字符串的长度已经等于或超过目标长度&#xff0c;则不…

程序员怎么写简历_写简历软件

你们在制作简历时&#xff0c;是不是基本只关注两件事&#xff1a;简历模板&#xff0c;还有基本信息的填写。 当你再次坐下来更新你的简历时&#xff0c;可能会发现自己不自觉地选择了那个“看起来最好看的模板”&#xff0c;填写基本信息&#xff0c;却没有深入思考如何使简历…

vue预览pdf文件的几种方法

文章目录 vue预览pdf集中方法方法一&#xff1a;方法二&#xff1a;展示效果&#xff1a;需要包依赖&#xff1a;代码&#xff1a; 方法三&#xff1a;展示效果&#xff1a;需要包依赖&#xff1a;代码&#xff1a;自己调参数&#xff0c;选择符合自己的 vue预览pdf集中方法 我…

第 9 章:理解C++内存模型

本章是继[第8章]讨论的延续&#xff0c;我们在那里讨论了一些多进程和多线程技术&#xff1b;本章将增强它们的使用。我们将引导你了解各种技术&#xff0c;同时聚焦于本章的主要内容——C内存模型。但为了讨论这一点&#xff0c;你首先将简要检视通过智能指针和可选对象实现的…

ZK鉴权设计以及相关探讨

文章目录 1. zk的鉴权设计2. zk鉴权应用范围3. zk鉴权的常用方法4. 推荐配置5. 参考文档 鉴权&#xff0c;分别由鉴和权组成 鉴&#xff1a; 表示身份认证&#xff0c;认证相关用户是否存在以及相关的用户名和密码是否一致权&#xff1a; 完成身份的鉴后&#xff0c;还需要判断…