完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
什么是PWM信号?
官方解释:PWM信号一般指脉冲宽度调制。脉冲宽度调制是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。 相信大家都会很努力的看完它吧。作为一个学习糟糕的大学生,我一般都不看这种官方的解释,我认为的PWM信号就是一种占空比可调的方波,什么又是占空比呢?不知道就去百度吧。懒得百度我也可以告诉你,占空比就是在一个脉冲周期内,高电平持续的时间占总时间的比例。嗯,这下应该知道PWM是什么了吧。 STM32输出PWM信号 STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定 时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4 路的 PWM 输出,这样,STM32 最多可以同时产生 30 路 PWM 输出!(cope过来的)由于资源和时间有限,所以我这里拿STM32F103来做这个信号的输出。emmmm,这边我用TM3的CH2输出一路PWM。 首先说的是控制寄存器 1(TIMx_CR1),它的样子大概是这样的: 位15:10:是6个保留位,始终读为0。 CKD[1:0]:定时器时钟频率在数字滤波器使用的采样频率之间的分频比例。(总的来说就是分频系数)。 ARPE:自动重装载预装载的允许位。 CMS:选择中央对齐模式。 DIR:控制计数器的计算方向。 OPM:单脉冲模式。 URS:更新请求源位。 UDIS:禁止(允许)更新位。 CEN:禁止(使能)计数器。 接着是第二个寄存器:状态寄存器(TIMx_SR),该寄存器用来标记当前与定时 器相关的各种事件/中断是否发生。 CC4OF:捕获/比较4重复捕获标记。 CC3OF:捕获/比较3重复捕获标记。 CC2OF:捕获/比较2重复捕获标记。 CC1OF:捕获/比较1重复捕获标记,仅当相应的通道被配置为输入捕获时,该标记可由硬件置’1’。写’0’可清除该位。 TIF:触发器中断标记,当发生触发事件(当从模式控制器处于除门控模式外的其它模式时,在TRGI输入端检测到有效边沿,或门控模式下的任一边沿)时由硬件对该位置’1’。它由软件清’0’。 CC4IF:捕获/比较4 中断标记。 CC3IF:捕获/比较3 中断标记。 CC2IF:捕获/比较2 中断标记。 CC1IF:捕获/比较1 中断标记。 UIF:更新中断标记。 这个寄存器前面那些什么标记啊什么都不用管,这里主要是了解UIF这一位,当产生更新事件时该位由硬件置’1’。它由软件清’0’。也就是说它为0时是无中断产生的。 了解了上面寄存器的配置就可以对定时器进行配置了,但要想实现PWM的输出,还有另外几个寄存器需要配置。 第一个是是捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器总共有 2 个,TIMx _CCMR1 和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 CH2 ,而 TIMx_CCMR2 控制 CH3 和 CH4 。 他有两个模式,所以在不同模式下同一个位可能会有不同的作用。这里我们只需要配置OCxM(至于是1还是2就要看你使用的PWM模式是1还2了)。我们使用的是 PWM 模式,所以这 3 位必须设置为 110/111。这两种主要就是输出极性相反。 接着是捕获/比较使能寄存器(TIMx_CCER),该寄存器控制着各个输入输出通道的开关。 这里我们只用到了 CC2E 位,该位是输入/捕获 2 输出使能位,要想PWM 从 IO 口输出,这个位必须设置为 1,所以我们需要设置该位为 1。 最后是捕获/比较寄存器(TIMx_CCR1~4),该寄存器总共有 4 个,对应 4 个 输通道 CH1~4。我这里只有TIMx_CCR1的图,其实它里面都是一样的: 在输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽了。 如果要用到重映射的功能还需要配置复用重映射和调试 IO 配置寄存器(AFIO_MAPR) 因为我不用这个功能,所以我就不配置了。 代码实现 接下来就是代码实现了,首先呢,是开启TIM3的时钟和PA7的时钟: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 因为TIM3是在APB1总线上,所以TIM3的时钟初始化要使用RCC_APB1PeriphClockCmd()函数,PA7是在APB2总线上的。接着是对PA7的配置: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); 对TIM3的配置: TIM_TimeBaseStructure.TIM_Period = arr; TIM_TimeBaseStructure.TIM_Prescaler =psc; TIM_TimeBaseStructure.TIM_ClockDivision = 0; //不分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出比较使能 TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性高 TIM_OC1Init(TIM3, &TIM_OCInitStructure); 使能输出: TIM_CtrlPWMOutputs(TIM3,ENABLE); //MOE 主输出使能 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //CH2预装载使能 TIM_ARRPreloadConfig(TIM3, ENABLE); //TIM3使能 TIM_Cmd(TIM3, ENABLE); 以上就配置完了PWM的输出,至于占空比的设置,这里有一个函数可以调节占空比: void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)这个函数在stm32f10x_tim.c文件中,如果设置成这样TIM_SetCompare2(TIM3, 0)则会输出3.3V,好了PWM的输出就到这里了。谢谢大家的观看。 下面是完整的代码: void TIM3_CH2_PWM_Init(u16 arr,u16 psc){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = arr; TIM_TimeBaseStructure.TIM_Prescaler =psc; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_CtrlPWMOutputs(TIM3,ENABLE); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); TIM_Cmd(TIM3, ENABLE); } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
556浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 04:26 , Processed in 0.597109 second(s), Total 48, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号