[MM32硬件] 【灵动微电子MM32F0121测评】3.PWM呼吸灯

[复制链接]
 楼主| 阿源玩电子 发表于 2025-6-24 21:26 | 显示全部楼层 |阅读模式
本帖最后由 阿源玩电子 于 2025-6-24 21:44 编辑

PWM呼吸灯

  • 原理图部分

LED原理图

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

  • pwm_dsp.c
  1. #include "pwm_dsp.h"
  2. void TIM1_PWM_Configure(void)
  3. {
  4.     RCC_ClocksTypeDef       RCC_Clocks;
  5.     GPIO_InitTypeDef        GPIO_InitStruct;
  6.     TIM_OCInitTypeDef       TIM_OCInitStruct;
  7.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  8.     uint32_t                TIM_ClockFrequency = 0;
  9.     uint32_t                HPRE = 0, PPRE2 = 0;

  10.     // PWM参数配置
  11.     uint32_t PWM_Frequency = 1000;    // 1kHz PWM频率
  12.     uint16_t PWM_Period = 1000;       // 周期值(ARR),占空比范围0-1000
  13.     uint16_t PrescalerValue = 0;      // 预分频值

  14.     // 1. 获取时钟频率
  15.     HPRE  = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE)  >> RCC_CFGR_HPRE_Pos;
  16.     PPRE2 = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos;
  17.     RCC_GetClocksFreq(&RCC_Clocks);

  18.     // 计算TIM1时钟频率
  19.     if (HPRE < 8) {
  20.         TIM_ClockFrequency = (PPRE2 < 4) ? RCC_Clocks.PCLK2_Frequency : RCC_Clocks.PCLK2_Frequency * 2;
  21.     } else {
  22.         TIM_ClockFrequency = (PPRE2 < 4) ? RCC_Clocks.PCLK2_Frequency * 2 : RCC_Clocks.PCLK2_Frequency * 4;
  23.     }

  24.     // 2. 计算预分频值 (目标计数器时钟 = 1MHz)
  25.     PrescalerValue = (uint16_t)(TIM_ClockFrequency / 1000000) - 1;

  26.     // 3. 初始化TIM1定时器
  27.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

  28.     TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
  29.     TIM_TimeBaseInitStruct.TIM_Prescaler = PrescalerValue;  // 设置预分频
  30.     TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
  31.     TIM_TimeBaseInitStruct.TIM_Period = PWM_Period - 1;     // ARR值 (1000-1)
  32.     TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1;
  33.     TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
  34.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);

  35.     // 4. 配置PWM模式 (初始占空比0%)
  36.     TIM_OCStructInit(&TIM_OCInitStruct);
  37.     TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
  38.     TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
  39.     TIM_OCInitStruct.TIM_Pulse = 0;               // 初始CCR值(占空比)
  40.     TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
  41.     TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Set;

  42.     TIM_OC1Init(TIM1, &TIM_OCInitStruct);  // 配置通道1
  43.     TIM_OC2Init(TIM1, &TIM_OCInitStruct);  // 配置通道2

  44.     // 启用预装载寄存器
  45.     TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
  46.     TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
  47.     TIM_ARRPreloadConfig(TIM1, ENABLE);

  48.     // 5. 配置GPIO为PWM输出
  49.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  50.     GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_7);  // TIM1_CH1
  51.     GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_7);  // TIM1_CH2

  52.     GPIO_StructInit(&GPIO_InitStruct);
  53.     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
  54.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
  55.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  56.     GPIO_Init(GPIOB, &GPIO_InitStruct);

  57.     // 6. 使能TIM1和PWM输出
  58.     TIM_Cmd(TIM1, ENABLE);
  59.     TIM_CtrlPWMOutputs(TIM1, ENABLE);
  60. }
  • pwm_dsp.h
    1. #include "hal_conf.h"
    2. void TIM1_PWM_Configure(void);

4.试验现象
PB14(TIM1_CH1)PB15(TIM1_CH2)将输出1kHz 的 PWM 信号,并可动态调整占空比(0%~100%),将占空比由0变化到1000,再由1000变换到0,由此作为呼吸效果

呼吸灯

呼吸灯







MM32F0121C6PV_03PWM.zip

5.63 MB, 下载次数: 1

工程

loutin 发表于 2025-7-2 12:43 | 显示全部楼层
从硬件配置到软件编程,每个步骤都有详细的说明,这对于初学者来说非常有帮助。
ccook11 发表于 2025-7-2 13:34 | 显示全部楼层
可以学习如何配置MCU的定时器和GPIO
sanfuzi 发表于 2025-7-3 21:50 | 显示全部楼层
灵动微电子MM32F0121是一款基于ARM Cortex-M0内核的32位微控制器(MCU),具有高集成度和便捷开发体验的特点。
pentruman 发表于 2025-7-4 21:46 | 显示全部楼层
PWM呼吸灯实验是一个实用的项目
sanfuzi 发表于 2025-7-5 22:27 | 显示全部楼层
频率和占空比的调节方法。              
mnynt121 发表于 2025-7-6 15:36 | 显示全部楼层
深入浅出地解释了PWM的工作原理以及如何通过调整占空比来实现亮度变化。
wilhelmina2 发表于 2025-7-7 14:10 | 显示全部楼层
定时器的初始化、GPIO的配置、PWM输出的设置
kmzuaz 发表于 2025-7-10 11:50 | 显示全部楼层
一篇非常有价值的测评文章,适合对灵动微电子MM32F0121微控制器和PWM技术
mikewalpole 发表于 2025-7-10 14:52 | 显示全部楼层
动态占空比调整的代码片段直接可行,降低了学习门槛。
rosemoore 发表于 2025-7-11 13:31 | 显示全部楼层
对PWM原理、定时器工作模式等理论部分描述较少,可能对完全零基础的读者不够友好
pentruman 发表于 2025-7-12 13:11 | 显示全部楼层
步骤描述是否详尽,对于初学者来说是否足够友好。
mickit 发表于 2025-7-12 16:53 | 显示全部楼层
除了呼吸灯外是否还能启发其他创意项目
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

33

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部