发布时间:2026/8/21 22:23:40
STM32 学习日志:PWM 驱动直流电机、DWT 精确延时、DHT11 单总线通信与 Keil 工程模板 STM32 学习日志PWM 驱动直流电机、DWT 精确延时、DHT11 单总线通信与 Keil 工程模板学习日期2026 年 8 月 19 日今天主要学习了 PWM 控制 TB6612FNG 有刷直流电机、DWT 微秒延时、DHT11 温湿度传感器的单总线通信以及手动建立 Keil 工程模板的方法。一、PWM 基础知识PWM 即脉宽调制通过控制一个方波中“高电平持续时间”的比例来控制平均输出效果。对于 STM32 定时器PWM 频率 定时器计数时钟 / [(PSC 1) × (ARR 1)] 占空比 CCR / (ARR 1) 占空比分辨率 1 / (ARR 1)其中PSC预分频器决定定时器计数速度。 ARR自动重装载值决定一个 PWM 周期需要计多少次。 CCR比较寄存器决定高电平持续到第几次计数。 CNT定时器当前正在计数的值。可以简单记忆PSC 控制计数速度。 ARR 决定 PWM 周期。 CCR 决定高电平时间也就是占空比。例如PSC 71 ARR 99 定时器时钟 72MHz则PWM 频率 72MHz / 72 / 100 10kHz如果CCR 20占空比约为20 / 100 20%如果CCR 80占空比约为80 / 100 80%注意代码中直接写20、80作为 PWM 速度值的前提是ARR 99。如果 ARR 不是 99CCR 的范围也必须跟着改变。二、TB6612FNG 电机驱动模块STM32 的 GPIO 引脚只能输出很小的电流不能直接驱动直流电机。因此需要 TB6612FNG 这种电机驱动模块。TB6612FNG 可以理解为电机的“功率放大器”STM32 负责发出控制命令。 TB6612FNG 负责使用 VM 电源给电机提供实际电流。本次电机 1 使用的核心连接如下STM32 引脚TB6612FNG 引脚作用PB0PWMAPWM 调速信号PA4AIN1电机方向控制PA5AIN2电机方向控制PA7STBY驱动芯片使能KEY1用户按键切换快慢KEY2用户按键切换正反转需要重点记住PWMA控制电机速度。 AIN1、AIN2控制电机方向。 STBY控制驱动芯片是否工作。 AO1、AO2连接电机两根线。 VM电机电源。 VCC驱动芯片逻辑电源。 GNDSTM32、模块、电机电源必须共地。三、为什么 PWM 极性通常设置为 HighTB6612FNG 的 PWMA/PWMB 是高电平有效。CubeMX 中设置CH Polarity High表示PWM 高电平驱动器允许输出。 PWM 低电平驱动器停止输出或进入制动状态。这样逻辑最直观CCR 越大 → 高电平时间越长 → 电机获得驱动的时间越长 → 电机转速越快注意PWM 极性不决定电机正反转。PWM控制速度。 AIN1/AIN2控制方向。四、TB6612FNG 电机控制程序1. 先启动 PWM再使能电机驱动芯片在/* USER CODE BEGIN 2 */中加入HAL_TIM_PWM_Start(htim3,TIM_CHANNEL_3);HAL_GPIO_WritePin(STBY_GPIO_Port,STBY_Pin,GPIO_PIN_SET);含义第一句让 TIM3_CH3 开始从 PB0 输出 PWM。 第二句把 STBY 拉高让 TB6612FNG 退出待机并开始工作。如果 STBY 没有拉高即使 PWM 和方向引脚都正确电机也不会转动。2. 编写电机方向与速度控制函数voidMotor_Set(uint8_tdir,uint16_tspeed){__HAL_TIM_SET_COMPARE(htim3,TIM_CHANNEL_3,speed);if(dir0){HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_RESET);HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_SET);}}这个函数有两个参数dir方向。 speedPWM 比较值也就是 CCR 值。方向逻辑AIN1AIN2电机状态高低正转低高反转如果实际电机方向和程序描述相反通常只是电机两根线接反了。可以交换 AO1/AO2 的电机接线或者交换程序中正反转逻辑。3. 定义速度和状态变量#defineSPEED_LOW20#defineSPEED_HIGH80uint8_tspeed_mode0;uint8_tdir_mode0;含义SPEED_LOW低速 PWM 值。 SPEED_HIGH高速 PWM 值。 speed_mode 0低速。 speed_mode 1高速。 dir_mode 0正转。 dir_mode 1反转。4. 按键控制速度和方向if(HAL_GPIO_ReadPin(GPIOA,KEY1_Pin)GPIO_PIN_SET){speed_mode!speed_mode;uint16_tspeed(speed_mode0)?SPEED_LOW:SPEED_HIGH;Motor_Set(dir_mode,speed);while(HAL_GPIO_ReadPin(GPIOA,KEY1_Pin)GPIO_PIN_SET);}!speed_mode的作用是切换 0 和 10 变 1。 1 变 0。三目运算符(speed_mode0)?SPEED_LOW:SPEED_HIGH;意思是如果当前是低速模式speed 取 SPEED_LOW。 否则 speed 取 SPEED_HIGH。while等待松手的作用是防止按住按键时不断切换状态。实际使用时还应加入约 10ms 到 20ms 的消抖延时否则机械按键可能一次按下被识别多次。五、DWT 精确延时DWT 是 Cortex-M 内核自带的高速计数器全称为Data Watchpoint and Trace 数据观察点与跟踪单元初学阶段最常用的是DWT_CYCCNTCPU 周期计数器。STM32F103 常用主频为 72MHz1 秒 72,000,000 个时钟周期。 1 微秒 72 个时钟周期。因此 DWT 可以实现微秒级延时DWT_DelayUs(10);DWT_DelayMs(100);DWT_DelayS(1);DWT 初始化的核心逻辑DEMCR|(uint32_t)DEMCR_TRCENA;DWT_CYCCNT0;DWT_CTRL|(uint32_t)DWT_CTRL_CYCCNTENA;含义DEMCR_TRCENA打开内核调试与跟踪功能。 DWT_CYCCNT 0先将周期计数器清零。 DWT_CTRL_CYCCNTENA让周期计数器开始计数。DWT 适合DHT11 单总线时序。 超声波模块微秒延时。 测量一段程序的运行时间。 精确软件延时。注意DWT 延时属于忙等待延时期间 CPU 一直在循环等待不适合长时间延时。短延时DWT_DelayUs()。 较长延时HAL_Delay()、定时器中断或非阻塞计时。六、DHT11 单总线通信流程DHT11 使用一根 DATA 数据线进行双向通信。空闲状态下DATA 由上拉电阻保持高电平。完整流程1. DHT11 上电后等待至少 1 秒。 2. STM32 将 DATA 配置为输出。 3. STM32 拉低 DATA 至少 18ms。 4. STM32 释放 DATA并改为输入。 5. DHT11 拉低约 83us表示收到请求。 6. DHT11 拉高约 87us表示准备发送数据。 7. DHT11 发送 40 位数据。 8. STM32 读取数据并校验。DHT11 一次发送 5 个字节湿度整数 湿度小数 温度整数 温度小数 校验和校验和计算校验和 湿度整数 湿度小数 温度整数 温度小数如果计算结果和接收到的第五个字节相同说明数据正确。DHT11 每一位数据的判断方式先低电平约 50us。 高电平约 26us表示 0。 高电平约 70us表示 1。所以程序会在高电平开始后约 40us 判断40us 后仍是高电平这一位是 1。 40us 后已经变低这一位是 0。读取 DHT11 时等待电平变化必须加入超时判断。否则 DHT11 未接好或没有供电时程序可能永久卡在while循环中。七、GPIO 配置结构体的理解DHT11 中经常需要让一个 GPIO 在输出和输入之间切换GPIO_InitTypeDef GPIO_InitStruct{0};这句含义是创建一个 GPIO 配置变量。 并把结构体中所有成员先初始化为 0。后续填写GPIO_InitStruct.PinDHT11_DATA_Pin;GPIO_InitStruct.Modemode;GPIO_InitStruct.Pullpull;GPIO_InitStruct.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(DHT11_DATA_GPIO_Port,GPIO_InitStruct);可以理解为先准备一张 GPIO 配置表。 填写要配置哪个引脚、输入还是输出、是否上拉、输出速度。 最后调用 HAL_GPIO_Init()将配置真正写入 STM32。八、Keil 工程目录作用手动创建 STM32 工程时常见目录如下文件夹作用Doc项目文档、接线图、模块说明、readme 等LibrariesCMSIS 核心库和 HAL 驱动库ProjectKeil 工程文件、编译输出文件等User用户编写的 main.c、外设驱动、BSP 文件等常见 User 文件作用文件作用main.c主函数入口主要应用逻辑main.hmain.c 对应头文件放函数声明和全局定义stm32f1xx_hal_conf.hHAL 外设模块开关配置stm32f1xx_it.c中断服务函数实现stm32f1xx_it.h中断函数声明system_stm32f1xx.c系统初始化、时钟变量更新九、手动建立 Keil 工程模板步骤第一步建立 Doc、Libraries、Project、User 四个文件夹。 第二步复制 CMSIS、STM32F1xx_HAL_Driver 到 Libraries。 第三步复制 main.c、main.h、stm32f1xx_hal_conf.h、 stm32f1xx_it.c、stm32f1xx_it.h、system_stm32f1xx.c 到 User。 第四步在 Keil 中新建工程选择正确的 STM32 芯片。 第五步建立分组 STARTUP、CMSIS、STM32F1xx_HAL_Driver、USER、DOC。 第六步分别把启动文件、system 文件、HAL 源文件、 User 源文件和文档添加到对应分组。 第七步在魔术棒中设置芯片、时钟、输出 HEX、 宏定义、头文件路径和下载调试器。 第八步编写 main.c编译验证。常用宏定义USE_HAL_DRIVER STM32F103xB十、新增模块文件时的注意事项在已有工程中加入一个新模块例如 DHT11、OLED、DWT 或电机模块时1. 在 User 文件夹建立模块目录例如 dht11。 2. 放入该模块的 .c 和 .h 文件。 3. 在 Keil 的 USER 分组中添加对应的 .c 文件。 4. 在使用该模块的源文件中包含对应 .h 文件。 5. 确认 HAL 配置文件已打开所需外设模块。 6. 重新编译查看错误和警告。今天还遇到了一个典型问题MX_USART1_UART_Init();函数虽然已经在串口源文件中实现但main.c没有包含串口头文件导致编译器提示function MX_USART1_UART_Init declared implicitly解决方法是在main.c加入#includeusart/bsp_usart.h这说明.c文件负责实现函数.h文件负责声明函数。使用某模块时不能只把.c文件加入 Keil还要在需要调用的位置包含对应的.h文件。十一、今日总结今天学习的内容可以概括为PWM 中ARR 决定周期CCR 决定占空比。 TB6612FNG 中PWMA 控制速度 AIN1/AIN2 控制方向 STBY 必须拉高才能工作。 DWT 是内核自带的高速周期计数器 适合微秒延时和程序运行时间测量。 DHT11 使用单总线通信 主机低电平至少 18ms 发起请求 传感器回应后发送 40 位温湿度数据。 Keil 工程中 模块的 .c 文件要加入工程 模块的 .h 文件要在使用处包含。

相关新闻

2026/8/21 22:23:40

OSP和沉金哪个好怎么选?OSP和沉金避坑要点

在产品立项阶段,表面处理工艺直接影响 PCB 物料成本。很多项目简单全部选用沉金,造成不必要成本浪费;也有部分项目一味追求低成本选用 OSP,后期 SMT 良率低,返工成本远大于板材节省的费用。想要做好成本管控&#xff0…

2026/8/21 22:23:40

Python教程(16)——lambda表达式详解

函数介绍 我们平常常常能够于代码里见到一种起始的此类表达式, 要是未曾学习过相关知识, 或许会一脸茫然 , 不明白究竟这个关键字是用来做什么的 , 用以表示什么。 实际上这个就是函数。 函数是一种特殊的匿名函数, 它并非仅存在这种情况, 它能够让我们迅速定义简单的函数, …

2026/8/21 22:23:40

DM管理对象依赖性:提升数据库系统稳定性的关键技术

一、DM管理对象依赖性基础 1.1 对象依赖性的定义与重要性 对象依赖性是指数据库中各种对象(如表、视图、存储过程、函数等)之间存在的引用关系。在DM数据库中,当一个对象引用了另一个对象时,它们之间就建立了依赖关系。这种依赖关…

2026/8/21 23:44:43

墨水屏阅读卡片:打造低功耗桌面信息看板的技术实践

大家好,我是CSDN的一名技术博主。今天想和大家聊聊一个我坚持使用了一年多的“生产力工具”——墨水屏阅读卡片。这并非一篇严格意义上的技术教程,更像是一次深度的使用复盘与经验分享。我会结合自己使用M5 Stack PaperS3等设备的真实体验,拆…

2026/8/21 23:44:43

PDAGENT-BENCH:AI智能体如何革新VLSI物理设计流程

1. 项目缘起:当VLSI物理设计遇上AI智能体 最近几年,AI领域最让人兴奋的进展之一,无疑是大型语言模型(LLM)和视觉语言模型(VLM)的爆发式增长。从ChatGPT到GPT-4V,再到层出不穷的开源模…

2026/8/21 23:44:43

本地AI翻唱部署指南:Soulx_Singer V10从零到一实战

想用AI翻唱自己喜欢的歌曲,但总是被在线服务的限制、隐私顾虑和付费门槛劝退?或者你尝试过一些开源方案,却发现效果生硬、操作复杂,最终只能放弃? 今天要介绍的 Soulx_Singer V10,可能是目前对个人开发者和…

2026/8/21 23:44:43

混压PCB成本解析与设计实战:从高速信号到射频应用的全链路指南

在硬件设计和PCB打样领域,混压PCB(混合介质层压板)因其独特的性能优势,正从高端通信、航空航天等特种领域,逐步走向对信号完整性、电源完整性和热管理有更高要求的消费电子、工控及汽车电子项目中。很多工程师听说过混…

2026/8/21 23:39:38

数学建模竞赛实战:从问题抽象到模型构建的完整思维路径

1. 项目概述:一次从“解题”到“建模”的思维跃迁去年美赛C题“股票投资策略”的题目一出来,我身边不少队伍就陷入了两个极端:要么是金融背景的同学狂喜,觉得终于能大展拳脚,开始疯狂调用各种复杂的金融模型&#xff1…

2026/8/21 13:13:49

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/21 20:14:07

工业传感器与变送器详解:序章 从物理世界到工业数据

序章 从物理世界到工业数据 ——重新认识工业传感器与变送器 工业自动化系统正变得日益复杂。今天的工业现场早已不是简单的控制回路,而是由多层技术共同构成的立体体系:PLC、DCS、SCADA、MES、工业互联网、边缘计算与人工智能。控制系统可以执行复杂算法,工业网络可以实现…

2026/8/21 0:03:13

Linux命令-uucico(UUCP传输程序)

Linux命令-uucico(UUCP传输程序) 🔰简介UUCP 体系简介 📖语法⚙️选项配置文件 💡示例示例 1:基本传输操作示例 2:主模式与从模式示例 3:调试与故障排查示例 4:UUCP 配置…

2026/8/21 0:03:13

Linux命令-uupick(UUCP文件接收工具)

Linux命令-uupick(UUCP文件接收工具)🔰简介uupick 在 UUCP 传输链中的位置📖语法⚙️选项交互命令💡示例示例 1:基本接收操作示例 2:仅处理来自特定系统的文件示例 3:完整 UUCP 文件…

2026/8/21 15:40:01

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/21 15:40:01

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/21 0:31:27

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…