本帖最后由 阿源玩电子 于 2025-6-24 21:44 编辑
PWM呼吸灯
LED原理图
2.引脚复用,使用TIM1的1,2通道用于调光,PB14和PB15复用为AF7功能。
引脚复用
3.定时器配置 频率计算: - 预分频值计算为(TIM_ClockFrequency / 1000000) - 1,使计数器时钟为1MHz
- 设置ARR值为999(1000-1),得到精确的1kHz PWM频率
占空比范围:
- 通过设置ARR=999,CCR值范围0-999对应0%-100%占空比
- 使用TIM_SetCompare1(TIM1, value),TIM_SetCompare2(TIM1, value)设置占空比,value范围0-999
- #include "pwm_dsp.h"
- void TIM1_PWM_Configure(void)
- {
- RCC_ClocksTypeDef RCC_Clocks;
- GPIO_InitTypeDef GPIO_InitStruct;
- TIM_OCInitTypeDef TIM_OCInitStruct;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
- uint32_t TIM_ClockFrequency = 0;
- uint32_t HPRE = 0, PPRE2 = 0;
- // PWM参数配置
- uint32_t PWM_Frequency = 1000; // 1kHz PWM频率
- uint16_t PWM_Period = 1000; // 周期值(ARR),占空比范围0-1000
- uint16_t PrescalerValue = 0; // 预分频值
- // 1. 获取时钟频率
- HPRE = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos;
- PPRE2 = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos;
- RCC_GetClocksFreq(&RCC_Clocks);
- // 计算TIM1时钟频率
- if (HPRE < 8) {
- TIM_ClockFrequency = (PPRE2 < 4) ? RCC_Clocks.PCLK2_Frequency : RCC_Clocks.PCLK2_Frequency * 2;
- } else {
- TIM_ClockFrequency = (PPRE2 < 4) ? RCC_Clocks.PCLK2_Frequency * 2 : RCC_Clocks.PCLK2_Frequency * 4;
- }
- // 2. 计算预分频值 (目标计数器时钟 = 1MHz)
- PrescalerValue = (uint16_t)(TIM_ClockFrequency / 1000000) - 1;
- // 3. 初始化TIM1定时器
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
- TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
- TIM_TimeBaseInitStruct.TIM_Prescaler = PrescalerValue; // 设置预分频
- TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInitStruct.TIM_Period = PWM_Period - 1; // ARR值 (1000-1)
- TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1;
- TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
- TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);
- // 4. 配置PWM模式 (初始占空比0%)
- TIM_OCStructInit(&TIM_OCInitStruct);
- TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStruct.TIM_Pulse = 0; // 初始CCR值(占空比)
- TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
- TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Set;
- TIM_OC1Init(TIM1, &TIM_OCInitStruct); // 配置通道1
- TIM_OC2Init(TIM1, &TIM_OCInitStruct); // 配置通道2
- // 启用预装载寄存器
- TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
- TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
- TIM_ARRPreloadConfig(TIM1, ENABLE);
- // 5. 配置GPIO为PWM输出
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_7); // TIM1_CH1
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_7); // TIM1_CH2
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
- // 6. 使能TIM1和PWM输出
- TIM_Cmd(TIM1, ENABLE);
- TIM_CtrlPWMOutputs(TIM1, ENABLE);
- }
|
|