完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
添加了对于PWM中arr,psc以及division的说明,还有PWM的频率和占空比的改变问题
使用STM32F103ZET6 定时器4 CH2通道产生PWM波,在GPIOD,GPIO_PIN13引脚LED1产生呼吸灯效果。 实验工具:MDK5,STM32F103ZET6开发板 使用固件库编程 实验效果:LED灯亮——逐渐变暗——全灭——逐渐变亮——亮 相关程序已在最下方给出; 工程 pwm.c文件 #include "pwm.h" //简单进行定时器初始化,设置 预装载值 和 分频系数 void Tim_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; // 初始化结构体 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//分配时钟 //相关配置 TIM_TimeBaseInitStruct.TIM_Prescaler = psc; //a number between 0x0000 and 0xFFFF TIM_TimeBaseInitStruct.TIM_Period = arr; //a number between 0x0000 and 0xFFFF TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数 TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //分频因子 TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct); //打开定时器 TIM_Cmd(TIM4,ENABLE); } //初始化GPIO口 void Tim_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; //GPIO初始化结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟,进行重映射 GPIO_PinRemapConfig(GPIO_Remap_TIM4 ,ENABLE); //重映射开启 //初始化GPIOD组时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); //初始化引脚 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13; //引脚 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //速度 GPIO_Init(GPIOD,&GPIO_InitStruct); } //pwm初始化 void Pwm_Init(u16 arr,u16 psc) { TIM_OCInitTypeDef TIM_OCInitStruct; // PWM模式,输出等设置 //初始化定时器和IO口 Tim_GPIO_Init(); Tim_Init(arr,psc); //初始化PWM模式 TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; //PWM1模式 TIM_OCInitStruct.TIM_OutputState= TIM_OutputState_Enable;//输出使能 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //高电平有效 TIM_OC2Init(TIM4,&TIM_OCInitStruct); //设置利用通道2输出 //这里只初始化通道1,我们可以根据自己需求初始化其它通道 // TIM_OC2Init(TIM3,&TIM_OCInitstrcuture); // TIM_OC3Init(TIM3,&TIM_OCInitstrcuture); // TIM_OC4Init(TIM3,&TIM_OCInitstrcuture); //使能预装载寄存器: TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable); //使能自动重装载的预装载寄存器允许位 //TIM_ARRPreloadConfig(TIM4,ENABLE); } pwm.h文件 #ifndef __PWM_H_ #define __PWM_H_ #include "stm32f10x.h" void Pwm_Init(u16 arr,u16 psc); void Tim_Init(u16 arr,u16 psc); void Tim_GPIO_Init(void); #endif /*重装载时间 Tout = (arr+1)*(psc+1)/Tclk 系统时钟Tclk=72MHz 比如我们设置arr=7199,psc=9999 定时器更新(7199+1)*(1/7200)=1s,也就是1s进入一次更新Update */ 由数据手册可以看出上电后默认功能并非定时器,想要使用定时器4必须对其进行功能复用,如何进行复用请参考 林一捆 的博客 在进行重映射时应参考数据手册,根据手册进行相关配置。 其中关于定时器的使用及设置问题请参考 private_void_main 的博客 有关通道CH2,CH1等的选择问题已经在程序中做了说明。 对于PWM中arr,psc以及division的说明; arr是自动重装值,比如arr=300且无中断时,CNT从0加到300,再从0加到300一直循环。从图一可以看出在PWM中arr控制的是其周期 psc是预分频器,它可以改变来自APB1的时钟。 division控制APB1的分频 TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //分频因子 #define TIM_CKD_DIV1 ((uint16_t)0x0000) #define TIM_CKD_DIV2 ((uint16_t)0x0100) #define TIM_CKD_DIV4 ((uint16_t)0x0200) PWM的频率计算方法 溢出时间(相当于pwm的周期) Tout = (arr+1)(psc+1)/Tclk 系统时钟Tclk=72MHz 比如我们设置arr=7199,psc=9999 定时器更新(7199+1)(1/7200)=1s,也就是周期为1s 频率=1/tout PWM的占空比调节 比如我初始化为Pwm_Init(199,0);即 arr = 199,psc = 0;此时根据公式能够算出来pwm的频率和周期。但是要改变pwm的占空比则是靠TIM_SetCompare2(TIM4,i);函数 (实际上是改变CCRX的值) 例如令 i = 100,则占空比为100/199,如果我们写一个循环让 i 在0–199之间循环,那么我们就可以随意调节pwm的占空比了。 程序链接:https://pan.baidu.com/s/1ekL2o2xJtL32Wod_Gih1EQ 提取码:1fql |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1877 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1661 浏览 1 评论
1145 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
760 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1720 浏览 2 评论
1963浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
789浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
612浏览 3评论
629浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
590浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-11 23:28 , Processed in 0.772225 second(s), Total 76, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号