stm32输出pwm 崩溃问题CmBacktrace开源工具

news/2024/10/17 18:20:04/

概述:stm32的每个引脚都有其自带的特殊功能,有定时器输出功能的引脚可以输出pwm。如果没有的也可以io口模拟输出,如果非要较真的话,理论上可以算是每个引脚都能输出PWM,但一般我们都使用带定时器输出功能的io。此文章来详述使用stm32F051R8T6型号单片机,带有定时器输出功能的引脚来输出pwm波形,同理其他型号的单片机也可实现。并同时来控制直流电机转速,本文以adda公司生产的AD0212DB-G50直流风扇为例讲述。

1.硬件条件

保证单片机输出IO可以支持定时器功能。我板子上连接风扇的引脚为PC9,根据单片机手册PC9引脚带有定时器功能

同理如下图的几个引脚都可以

再次就不一一列举了,在是用不同型号的单片机时,参考单片机手册。

2.stm32固件库

上图分别是stm32定时器相关的库函数,和相关调用的定时器驱动子函数,用户自己定义。

软硬件条件都准备好了,接下来就是pwm所需的相关配置。

1.首先是输出管脚的IO口设置,PWM输出,自然会采用到IO口作为输出端口,在STM32F051系列中,IO端口可以复用为TIM定时器输出通道。

采用PC9的复用功能AF1作为TIM3定时器的第4通道输出。

2.设置定时器的参数,配置出频率为17.57 KHz的PWM波

考虑time定时器的时钟频率。如果我们设置分频数为0,也就是说time定时器等于系统时钟,system_stm32f0xx.c中已经把系统频率设置在48MHZ,在startup_stm32f0xx.s中,首先运行了systemInit函数,因此可以确定time定时器运行在48MHZ。
定时器产生的PWM的频率可以按照下面的公式进行计算:
预定标的值TIM1_Period = (time定时器频率 / pwm的频率) - 1
预定标的值实际上就是定时器运行多少次算一个PWM周期,这个在设置pwm频率中重要的参数。

配置完整代码如下:

/*==============================================================================函数名      : Fan_PWMConfigInit功能        : 风扇控制引脚输出pwm控制风扇转速输入参数说明: 无返回值说明  : 无
------------------------------------------------------------------------------*/
void Fan_PWMConfigInit(void)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;s32 TimerPeriod, Channel1Pulse;/* 使能GPIO时钟 */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);/* 配置GPIO管脚参数设置*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC, &GPIO_InitStructure);/* GPIO管脚复用设置*/ GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_1); /*计算预定标 的值,也就是多少个时钟计数为一个周期*/TimerPeriod = (SystemCoreClock / 17570 ) - 1;/*计算CCR1 跳转值 在占空比为50%时*/Channel1Pulse = (u16)(((u32)5 * (TimerPeriod - 1)) / 10);/* TIM3 时钟使能 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);/* Time 定时基础设置*/TIM_TimeBaseStructure.TIM_Prescaler = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /* Time 定时设置为上升沿计算模式*/TIM_TimeBaseStructure.TIM_Period = TimerPeriod;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);/* 频道1的PWM 模式设置 */TIM_OCInitStructure.TIM_OCMode          = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState     = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_OutputNState    = TIM_OutputNState_Enable;TIM_OCInitStructure.TIM_OCPolarity      = TIM_OCPolarity_Low;TIM_OCInitStructure.TIM_OCNPolarity     = TIM_OCNPolarity_High;TIM_OCInitStructure.TIM_OCIdleState     = TIM_OCIdleState_Set;TIM_OCInitStructure.TIM_OCNIdleState    = TIM_OCIdleState_Reset;TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;      TIM_OC4Init(TIM3, &TIM_OCInitStructure);/* TIM3 计算器使能*/TIM_Cmd(TIM3, ENABLE);/* TIM3 主输出使能 */TIM_CtrlPWMOutputs(TIM3, ENABLE);}

在需要改变风扇转速时,只需要改变占空比即可。

/* 风扇控制 */
static s32 CmdFanCtrl (TCmdTbl *cmdtp, s32 argc, s8 *argv[])
{u8 byCmd;s32 Channel1Pulse;if (argc < 2)return -1;byCmd = strtoul(argv[1], NULL, 0);switch(byCmd){case 1:Channel1Pulse = (u16)(((u32)875 * 2730) / 1000);break;case 2:Channel1Pulse = (u16)(((u32)75 * 2730) / 100);break;case 3:Channel1Pulse = (u16)(((u32)625 * 2730) / 1000);break;case 4:Channel1Pulse = (u16)(((u32)5 * 2730) / 10);break;case 5:Channel1Pulse = (u16)(((u32)375 * 2730) / 1000);break;case 6:Channel1Pulse = (u16)(((u32)25 * 2730) / 100);break;case 7:Channel1Pulse = (u16)(((u32)125 * 2730) / 1000);break;case 8:Channel1Pulse = (u16)(((u32)1 * 2730) / 100);break;}TIM_SetCompare4(TIM3, Channel1Pulse);return 0;
}

TIM_SetCompare4(TIM3, Channel1Pulse);该函数是改变对应TIM定时器对应通道占空比的函数,其中的2370是根据系统时间计算出来。使用不同的定时器和通道,可在stm32f0xx_tim.c中查找不同的库函数。

下面是输出的pwm波形

 崩溃问题CmBacktrace开源工具

CmBacktrace/README_ZH.md at master · armink/CmBacktrace · GitHub


http://www.ppmy.cn/news/248361.html

相关文章

AWS RDS 默认最大连接数

1GB 1,07,37,41,824 字节(1024 x 1024 x1024) {DBInstanceClassMemory/12582880} 默认的最大连接数 通过连接数据库&#xff0c;运行 show variables like %max_connections%;实际得出的 max_connections < {DBInstanceClassMemory/12582880} 由于为操作系统和 RDS 管…

QuestaSim问题

001 问题描述&#xff1a; QuestaSim-64 vlog 10.6c Compiler 2017.07 Jul 26 2017 ** Error: (vlog-13069) D:\1_projects\Questasim_prj\AHP2APB\apb_slv_trans.sv(6): near “uvm_sequence_item”: syntax error, unexpected IDENTIFIER. ** Error: D:\1_projects\Questasim…

RNA-seq 详细教程:实验设计(2)

学习目标 了解设置重复对于 RNA-seq 分析的重要性 了解生物重复次数、测序深度和鉴定到的差异表达基因之间的关系 了解如何设计 RNA-seq 实验&#xff0c;以避免批次效应 1. 注意事项 了解 RNA 提取和 RNA-seq 文库制备实验过程中的步骤&#xff0c;有助于设计 RNA-seq 实验&am…

BZOJ 2730 HNOI2012 矿场搭建 Tarjan

题目大意&#xff1a;给定一个无向图&#xff0c;要求将一些点设为出口 要求图中删掉任意一个点后剩余的任意一个点都与至少一个出口相连 求最少建多少个出口以及建最少出口的方案数 首先看到割点就是Tarjan搞 但是怎么搞 首先假设我们把所有的点双都缩点 那么我们一定可以得…

leetcode 165. 比较版本号-java实现

题目所属分类 模拟就可以了 原题链接 给你两个版本号 version1 和 version2 &#xff0c;请你比较它们。 版本号由一个或多个修订号组成&#xff0c;各修订号由一个 ‘.’ 连接。每个修订号由 多位数字 组成&#xff0c;可能包含 前导零 。每个版本号至少包含一个字符。修订…

基于HAL库的STM32的单定时器的多路输入捕获测量脉冲频率(外部时钟实现)

目录 写在前面 一般的做法&#xff08;定时器单通道输入捕获) 以外部时钟的方式(高低频都适用) 测试效果 写在前面 STM32的定时器本身有输入捕获的功能。可选择双端捕获&#xff0c;上升沿捕获或者是下降沿捕获。对应捕获频率来说,连续捕获上升沿或下降沿的时间间隔就是其脉…

编译LineageOS-20并输入Pixel 2XL

编译LineageOS-20并输入Pixel 2XL 2023-6-6 hongxi.zhu 目录 编译LineageOS-20并输入Pixel 2XL一、编译LineageOS-201. 准备工作1.1 安装platform-tools1.2 安装必要的依赖1.3 创建相关目录1.4 下载repo可执行文件1.5 配置 2. 拉取源码2.1 初始化仓库2.2 同步源码 3. 编译源码3…

【算法】--- 几分钟了解直接选择排序(排序中最简单的排序)+快排(解决一切的优质算法)(中)

文章目录 前言&#x1f31f;一、常见的排序算法&#xff1a;&#x1f31f;二、选择排序---直接选择排序&#xff1a;&#x1f30f;2.1.1 基本思想&#xff1a;&#x1f30f;2.1.2 直接选择排序:&#x1f30f;2.1.3 直接选择排序的特性总结&#xff1a;&#x1f30f;2.1.4 思路&…