1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
实验目的
通过上一张的学习,我们知道知道STM32的通用定时器和高级定时器拥有PWM输出功能,本章我们将利用TIM3的CH3通道输出波形,数据手册请参看第14章中的相关内容。 实验简介 脉宽调制器(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。 STM32的定时器除了TIM6和TIM7,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出,这样,STM32最多可以同时产生30路PWM输出。这里我们仅利用TIM3的CH3产生一路PWM输出。 PWM原理 上图就是一个简单的 PWM 原理示意图。图中,我们假定定时器工作在向上计数 PWM 模式,且当 CNT 电路设计 TIM3的CH3通道映射到PB0上,外接了红色LED灯D4,PWM输出波形可以控制LED的亮度,改变占空比,可以改变LED亮度,电路图如下图。 有关寄存器 捕获/比较模式寄存器 1(TIMx_CCMR1) 这里我们主要了解 110和111这两种相反的模式 ** 捕获/比较使能寄存器(TIMx_CCER) ** 因为TIM3的CH3通道映射到PB0上 捕获/比较寄存器 1(TIMx_CCR1) 小、中和大容量产品的寄存器映像和位定义 寄存器代码 test.c #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "timer.h" int main(void) { u16 led0pwmval = 0; u8 dir = 1; Stm32_Clock_Init(9); uart_init(72,115200); delay_init(72); LED_Init(); TIM3_PWM_Init(899,0); //频率= 72000/(899+1)=80khz while(1) { delay_ms(10); if(dir) led0pwmval++; else led0pwmval--; if(led0pwmval > 300) dir = 0; if(led0pwmval == 0) dir = 1; LED3_PWM_VAL = led0pwmval; //捕捉/比较 寄存器3 使用的TIM3_CH3 } } timer.h #ifndef __TIMER_H #define __TIMER_H #include "sys.h" #define LED3_PWM_VAL TIM3->CCR3 void TIM3_Int_Init(u16 arr,u16 psc); void TIM3_PWM_Init(u16 arr,u16 psc); #endif timer.c #include "timer.h" #include "led.h" void TIM3_IRQHandler(void) { if(TIM3->SR & 0x0001) //溢出中断 { LED2 = !LED2; } TIM3->SR &= ~(1<<0); //清除中断标志位 } void TIM3_Int_Init(u16 arr,u16 psc) { RCC->APB1ENR |= 1<<1; //TIM3使能 TIM3->ARR = arr; //设置计数器自动重装值 TIM3->PSC = psc; //预分频器 TIM3->DIER |= 1<<0; //允许中断更新 TIM3->CR1 |= 0x01; //使能定时器3 MY_NVIC_Init(1,3,TIM3_IRQn,2); //抢占1 子优先级3 组 2 } void TIM3_PWM_Init(u16 arr,u16 psc) //PWM初始(自动重装值,时钟预分频数) { RCC->APB1ENR |= 1<<1; //TIM3时钟使能 RCC->APB2ENR |= 1<<3; //使能PORTB时钟 GPIOB->CRL &= 0xFFFFFFF0; GPIOB->CRL |= 0x0000000B; //复用推挽输出 RCC->APB2ENR |= 1<<0; //辅助时钟 //在配置AFIO,相关寄存器的时候,必须开启辅助 //功能 AFIO->MAPR &= 0xFFFFF3FF; //清除MAPR的【11:10】; AFIO->MAPR |= 1<<11; //部分重映射 TIM3_CH3->PB0 TIM3->ARR = arr; //设定计数器自动重装值 TIM3->PSC = psc; //预分频器不分频 TIM3->CCMR2 |= 7<<4; //CH3 PWM模式 TIM3->CCMR2 |= 1<<3; //CH3 预装载使能 TIM3->CCER |= 1<<8; //OC3输出使能 TIM3->CR1 = 0x0080; //ARPE使能 TIM3->CR1 |= 0x01; //使能定时器3 } HAL库代码 main.c #include "MyIncludes.h" int main() { u8 dir = 0; u16 duty = 1; System_Init(); SysTick_Init(NULL); PWM_Init(1000,duty); while(1) { delay_ms(10); if(dir == 0) { if(duty < 100) duty++; else dir = 1; } else if(dir == 1) { if(duty > 1) duty -- ; else dir = 0; } PWM_Init(10000,duty); } } pwm.h #ifndef __PWM_H_ #define __PWM_H_ #include "stm32f1xx.h" #include "stm32_types.h" #include "stm32f1xx_hal.h" void PWM_Init(u32 Freq, u32 Duty_Cycle); //PWM脉冲调制初始化(PWM频率,占空比) #endif pwm.c #include "pwm.h" TIM_HandleTypeDef PWMHandle; //TIM句柄结构变量声明 TIM_OC_InitTypeDef sConfig; //TIM输出比较配置结构变量声明 uint32_t uwPeriodValue = 0; //定时器ARR自动重装寄存器值 void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) //在HAL_TIM_PWM_Init中调用 { GPIO_InitTypeDef GPIO_InitStruct; __GPIOB_CLK_ENABLE(); __TIM3_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOB,&GPIO_InitStruct); } void PWM_Init(u32 Freq,u32 Duty_Cycle) //PWM(脉冲调制)初始化(PWM频率,占空比) { uwPeriodValue = (uint32_t)((SystemCoreClock/2/Freq) - 1); //uwPeriodValue = (72000000/2/1000)-1 // = 3599 PWMHandle.Instance = TIM3; //TIM3_CH3产生PWM PWMHandle.Init.Prescaler = 0; //设置计数频率为 0 PWMHandle.Init.Period = uwPeriodValue; //设置自动重装值 PWMHandle.Init.ClockDivision = 0; //时钟不分频,来自RCC PWMHandle.Init.CounterMode = TIM_COUNTERMODE_UP; //递增计数 PWMHandle.Init.RepetitionCounter = 0; //指定重复计数器值 为 0 if(HAL_TIM_PWM_Init(&PWMHandle) != HAL_OK) { while(1); } //如果初始化未完成将一直循环 sConfig.OCMode = TIM_OCMODE_PWM1; //PWM1模式 sConfig.OCPolarity = TIM_OCPOLARITY_LOW; //输出极性低电平 sConfig.OCFastMode = TIM_OCFAST_DISABLE; //输出比较快速使能禁止 sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; // 指定互补输出极性 sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET; //指定空闲状态期间的TIM输出比较管脚状态。 sConfig.OCIdleState = TIM_OCIDLESTATE_SET; //指定空闲状态期间的TIM输出比较管脚状态。 sConfig.Pulse = (Duty_Cycle *(uwPeriodValue - 1))/100; //设置占空比 //占空比是指高电平的时间占整个周期的比例。 //pulse = Duty_Cycle*(3599-1)/100 = 34.98Duty_Cycle; if(HAL_TIM_PWM_ConfigChannel(&PWMHandle,&sConfig,TIM_CHANNEL_3) != HAL_OK ) { while(1); } if(HAL_TIM_PWM_Start(&PWMHandle,TIM_CHANNEL_3) != HAL_OK) //PWM启动 { while(1); } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1767 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1069 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
592浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 23:37 , Processed in 0.850484 second(s), Total 76, Slave 60 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号