STM32笔记之PWM输出,调节频率及占空比
创作时间:
作者:
@小白创作中心
STM32笔记之PWM输出,调节频率及占空比
引用
1
来源
1.
https://chandianzi.cn/stm32-bi-ji-zhi-pwm-shu-chu-tiao-jie-pin-lyu-ji-zhan-kong-bi-2.html
本文将详细介绍如何使用STM32F103C8T6微控制器的TIM1定时器输出两路PWM信号。通过配置定时器和GPIO,可以实现频率和占空比的调节,适用于各种需要PWM输出的场景。
以STM32F103C8T6使用TIM1的CH1,CH4同时输出两路PWM为例:
引脚 | 定时器 | 通道 |
|---|---|---|
PA8 | TIM1 | CH1 |
PA11 | TIM1 | CH4 |
步骤:
GPIO_InitTypeDef GPIO_InitStruct; //GPIO初始化结构体
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //定时器初始化结构体
TIM_OCInitTypeDef TIM_OCInitStruct; //定时器通道初始化结构体
1. 开启时钟:同时打开GPIOA,TIM1,复用时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO,ENABLE);//开启时钟
2. 初始化GPIOA:
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; // 初始化GPIO--PA8、PA11为复用推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8 | GPIO_Pin_11;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct); //GPIO初始化
3. 初始化定时器:
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); //用其默认值填充每个TIM_TimeBaseInitStruct成员
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //分频因子
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStruct.TIM_Period=Per; //自动重装载值
TIM_TimeBaseInitStruct.TIM_Prescaler=Psc; //预分频值
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct); //完成定时器初始化
4. 初始化定时器通道:
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; //初始化输出比较
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse=0;
TIM_OC1Init(TIM1,&TIM_OCInitStruct); //定时器通道1初始化
TIM_OC4Init(TIM1,&TIM_OCInitStruct); //定时器通道4初始化
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC1预装载寄存器使能//CH1 TIM1
TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC4预装载寄存器使能//CH4 TIM1
5. 完成初始化:
TIM_ARRPreloadConfig(TIM1,ENABLE); //允许或禁止在定时器工作时向ARR(自动重装载值)的缓冲器中写入新值,以便在更新事件发生时载入覆盖以前的值,此处为允许
TIM_CtrlPWMOutputs(TIM1,ENABLE); // 高级定时器专属!!!(通用定时器不用此函数)--MOE主输出使能 //高级定时器TIM1:必须有这个函数才能输出PWM: TIM_CtrlPWMOutputs(TIM1,ENABLE);
TIM_Cmd(TIM1,ENABLE); //定时器使能
完整的PWM初始化函数:
/**********************************************************
** 函数名:PWM_Init_TIM1
** 功能描述: 定时器初始化函数
** 入口参数:预分频值,自动重装载值
** 输入参数: Psc(预分频值),Arr(自动重装载值)
** 输出参数: 无
***********************************************************/
void PWM_Init_TIM1(u16 Psc,u16 Arr)
{
GPIO_InitTypeDef GPIO_InitStruct; //GPIO初始化
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //定时器初始化
TIM_OCInitTypeDef TIM_OCInitStruct; //定时器通道初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO,ENABLE);//开启时钟
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; // 初始化GPIO--PA8、PA11为复用推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8 | GPIO_Pin_11;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct); //GPIO初始化
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); //用其默认值填充每个TIM_TimeBaseInitStruct成员
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //分频因子
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStruct.TIM_Period=Arr; //自动重装载值
TIM_TimeBaseInitStruct.TIM_Prescaler=Psc; //预分频值
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct); //完成定时器初始化
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; // 初始化输出比较
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse=0;
TIM_OC1Init(TIM1,&TIM_OCInitStruct); //定时器通道1初始化
TIM_OC4Init(TIM1,&TIM_OCInitStruct); //定时器通道4初始化
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC1预装载寄存器使能//CH1 TIM1
TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);// OC4预装载寄存器使能//CH4 TIM1
TIM_ARRPreloadConfig(TIM1,ENABLE); //允许或禁止在定时器工作时向ARR(自动重装载值)的缓冲器中写入新值,以便在更新事件发生时载入覆盖以前的值,此处为允许
TIM_CtrlPWMOutputs(TIM1,ENABLE); //高级定时器专属!!!--MOE主输出使能 //高级定时器TIM1:必须有这个函数才能输出PWM: TIM_CtrlPWMOutputs(TIM1,ENABL);
TIM_Cmd(TIM1,ENABLE); //定时器使能
//TIM_SetCompare1(TIM1,500);//设置TIMx捕获比较1寄存器值 此处为TIM1通道1
//TIM_SetCompare4(TIM1,500);//设置TIMx捕获比较4寄存器值 此处为TIM1通道4
}
修改输出PWM的频率和占空比
1. 频率:
PWM的频率 = 时钟频率 / (自动重装载值 + 1) * (预分频值 + 1)
STM32F103C8T6最大时钟频率为72MHZ = 72 000 000 HZ
通过修改Psc和Arr可以输出不同频率的PWM输出
PWM_Init_TIM1(0,7199); // PWM频率 f = 72000000/(7199+1)*(0+1) = 10KHZ
// PWM周期 T = 1/f = 1/10000 = 0.0001S = 0.1ms
2. 占空比:
使用函数
TIM_SetComparex(TIM_TypeDef* TIMx, uint16_t Comparex)
/**
* @brief Sets the TIMx Capture Compare1 Register value
* @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
* @param Compare1: specifies the Capture Compare1 register new value.
* @retval None
*/
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)
{
/* Check the parameters */
assert_param(IS_TIM_LIST8_PERIPH(TIMx));
/* Set the Capture Compare1 Register value */
TIMx->CCR1 = Compare1;
}
Compare1(CH1)是用于与TIMx比较的数,相当于用TIMx的一个周期的时间减去这个Compare1,使得TIMx的周期从后面开始的Compare1的时间为TIMx的前部分时间的反向。即若前部分时间为高电平,则Compare1段所在时间为低电平。若前部分时间为低电平,则Compare1段所在时间为高电平。(可通过配置PWM模式及CCER修改,参考正点原子PWM输出实验)
图片源自正点原子
PWM占空比 = CCRx/ARR 或 PWM占空比 =( ARR-CCRx)/ARR
PWM_Init_TIM1(0,7199); // PWM频率 f = 72000000/(7199+1)*(0+1) = 10KHZ
// PWM周期 T = 1/f = 1/10000 = 0.0001S = 0.1ms
TIM_SetCompare1(TIM1,3599);//设置TIMx捕获比较1寄存器值 此处为TIM1通道1 占空比为50%
TIM_SetCompare4(TIM1,3599);//设置TIMx捕获比较4寄存器值 此处为TIM1通道4 占空比为50%
热门推荐
【NLP自然语言处理】探索注意力机制:解锁深度学习的语言理解新篇章
物联网,跨行业革新的神奇力量
Android Jetpack四大组件详解
老枞水仙茶品鉴指南:从外观到内质的全方位解析
华为哈勃增资至94.8亿,半导体产业投资“多点开花”
部落冲突雷龙流派战术攻略:数量配置、辅助兵种选择与实战技巧详解
我国氯化钾行业发展现状:产能稳定且集中 总进口量突破千万吨
武汉美食指南:一份详尽的美食推荐清单英文双语对照
Excel批量生成条码的完整指南
蓝莓奶油蛋糕食谱
英特尔核显性能天梯图:一览酷睿处理器集成显卡差异
你不能错过的4K高清壁纸美图网站收藏
发票的重要性与作用:从交易凭证到诚信体系
芯见小科普 | 不用电也能显示,墨水屏是什么原理?
Excel表格内容自动调整全攻略:列宽、行高、换行和格式设置
梭子蟹哪些部位不能吃?处理方法详解
今年已发生12起化工事故!24死9伤
4 种最健康的食用油(以及 4 种要避免的食用油)
普吉岛旅游攻略,探索泰南明珠的全方位指南
C语言调试错误指南:从基础到高级调试技巧
计算机二级C语言零基础备考指南
医生,我家孩子“散瞳”,该选【快散】还是【慢散】?
16款必玩游戏推荐:如果你喜欢《Clash Royale》
如何准确分析上证指数的趋势?这种趋势分析的依据是什么?
《苏园六纪》:邂逅园林风雅
如何表扬团队协作能力差
给孩子“立规矩”的6个小技巧,让孩子舒舒服服地听话!
纳他霉素在眼科感染中的应用:案例分享与效果分析
推荐算法和机器学习算法之间是什么关系
YOLOv12论文详解:以注意力机制为核心的实时目标检测