[单片机芯片] 【CH32X035评估板测评】+ PWM 呼吸灯实验

[复制链接]
 楼主| xiaoqi976633690 发表于 2023-9-16 20:13 | 显示全部楼层 |阅读模式
本帖最后由 xiaoqi976633690 于 2023-9-16 20:18 编辑

1、开发环境
开发板:CH32X035C-R0-1V2
IDE:MounRiver Studio
仿真器:WCHLINKE
例程参考自官方example TIM-> PWM_Output:PWM输出例程

2、硬件配置
PB9----LED1
pb8.bmp
3、代码实现

PWM 频率和脉宽关系
a.ARR(TIM_Period) 是计数值;
b.PSC(TIM_Prescaler) 是预分频值。
计算公式:Fpwm = 主频 / ((ARR+1)*(PSC+1))(单位:Hz)
/*********************************************************************
* @fn      TIM1_OutCompare_Init
*
* @brief   Initializes TIM1 output compare.
*
* @param   arr - the period value.
*          psc - the prescaler value.
*          ccp - the pulse value.
*
* @return  none
*/
void TIM1_PWMOut_Init(u16 arr, u16 psc, u16 ccp)
{
        GPIO_InitTypeDef GPIO_InitStructure={0};
        TIM_OCInitTypeDef TIM_OCInitStructure={0};
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};

        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_TIM1, ENABLE );

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init( GPIOB, &GPIO_InitStructure );

        TIM_TimeBaseInitStructure.TIM_Period = arr;//ARR 自动重装器的值
        TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
        TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
#if (PWM_MODE == PWM_MODE1)
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

#elif (PWM_MODE == PWM_MODE2)
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;

#endif

        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = ccp;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OC1Init( TIM1, &TIM_OCInitStructure );

#if (PWM_SPE_MODE == PWM_SPE_MODE_ENABLE)
        TIM_OC12_SupersedeModeCmd( TIM1, TIM_Supersede_Mode_OC1_H, TIM_Supersede_Mode_OC2_H, ENABLE);
#endif

        TIM_CtrlPWMOutputs(TIM1, ENABLE );
        TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );
        TIM_ARRPreloadConfig( TIM1, ENABLE );
        TIM_Cmd( TIM1, ENABLE );
}

pwm init.bmp
pwm脉宽-计算公式:duty circle = TIMx->CH1CVR / ARR(单位:%)
若是我传入的 pwm_pulse= 20,则duty circle = 20 / 100 = 20%
  1. /*********************************************************************
  2. * @fn      TIM_SetCompare1
  3. *
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]   Sets the TIMx Capture Compare1 Register value.
  5. *
  6. * @param   TIMx - where x can be 1 to 3 select the TIM peripheral.
  7. *          Compare1 - specifies the Capture Compare1 register new value.
  8. *
  9. * [url=home.php?mod=space&uid=266161]@return[/url]  none
  10. */
  11. void TIM_SetCompare1(TIM_TypeDef *TIMx, uint16_t Compare1)
  12. {
  13.     TIMx->CH1CVR = Compare1;
  14. }
复制代码

  1. void PWM_Change(u8 pwm_pulse,u_int32_t arr)
  2. {
  3.     TIM_SetCompare1(TIM1,pwm_pulse);
  4.     TIM_SetAutoreload(TIM1,arr);
  5. }
复制代码
main函数
int main(void)
{
    u8 i=0,stat=0;
        SystemCoreClockUpdate();
        Delay_Init();
        USART_Printf_Init(115200);
        printf("SystemClk:%d\r\n",SystemCoreClock);
        printf("ChipID:%08x\r\n", DBGMCU_GetCHIPID());
        TIM1_PWMOut_Init( 99, 99, 99);

        while(1)
        {

            switch(stat)
            {
                             case 0:
                             i+=2;
                            if(i>100) stat=1;
                            PWM_Change(i,99);
                            break;
                                case 1:
                            i-=2;
                            if(i<1) stat=0;
                            PWM_Change(i,99);
                            break;
            }
        if(i>75) Delay_Ms(50);
        if(i>50&&i<75) Delay_Ms(30);
        if(i<20) Delay_Ms(10);
        if(i>20&&i<50) Delay_Ms(20);
        }
}
main.bmp
4、实验现象

1694865691578.gif
1694866324483.gif

源码附件
PWM_Output.zip (386.66 KB, 下载次数: 21) https://bbs.21ic.com/forum.php?mod=attachment&aid=MjE2MDA1MHwwYWM4YTU0ZnwxNzU2Mjk4NTI2fDB8




loutin 发表于 2023-10-5 18:57 | 显示全部楼层
根据CH32X035的具体规格和文档,查找并了解PWM模块的相关寄存器和配置选项。配置PWM的频率、占空比和计数器等参数,以满足你的呼吸灯效果需求。
yorkbarney 发表于 2023-10-5 19:02 | 显示全部楼层
为了实现呼吸灯的平滑过渡效果,你可以使用渐变算法或缓慢变化的逻辑来调整PWM的占空比。通过逐步增加或减小占空比的值,可以实现呼吸灯的渐亮和渐暗效果。
jkl21 发表于 2023-10-5 19:28 | 显示全部楼层
通过调整PWM的占空比,可以控制呼吸灯的亮度。占空比越大,亮度越高。
averyleigh 发表于 2023-10-5 19:40 | 显示全部楼层
可以通过调整定时器的计数频率和PWM周期来调整呼吸灯的速度,使其更加柔和和自然。
mickit 发表于 2023-10-5 19:46 | 显示全部楼层
根据呼吸灯的需求,需要设置不同的PWM占空比,通常可以通过调整定时器的计数周期来实现。
pixhw 发表于 2023-10-5 20:00 | 显示全部楼层
保为LED提供足够的电源电压和电流,以确保LED正常工作并防止损坏。
adolphcocker 发表于 2023-10-5 20:06 | 显示全部楼层
需要选择一个适合的PWM模块来生成PWM信号。
mattlincoln 发表于 2023-10-5 20:12 | 显示全部楼层
根据需要调整PWM的频率,可以通过设置定时器周期来实现。
jkl21 发表于 2023-10-5 20:17 | 显示全部楼层
在切换PWM信号的高电平和低电平时,可能会出现延时。你需要考虑这个延时对呼吸灯效果的影响,并在程序中进行适当的处理。
dspmana 发表于 2023-10-5 20:49 | 显示全部楼层
选择一个合适的GPIO引脚作为PWM输出引脚,连接到呼吸灯的控制电路。确保选择的引脚支持PWM功能,并在配置时将其设置为PWM输出模式。
zerorobert 发表于 2023-10-5 21:19 | 显示全部楼层
要生成PWM信号,通常需要配置一个定时器来产生PWM的时钟。你需要设置定时器的时钟源、分频因子和周期等参数。
cashrwood 发表于 2023-10-5 21:50 | 显示全部楼层
定时器有多种对齐方式,需要根据实际情况选择对齐方式以实现正确的PWM输出。
janewood 发表于 2023-10-5 22:20 | 显示全部楼层
在设置PWM占空比时,需要注意PWM的分辨率,确保设置的占空比可以在实际的PWM信号中表示出来。
10299823 发表于 2023-10-6 23:00 | 显示全部楼层
PWM频率越高,呼吸灯的亮度就越高,但也会影响呼吸灯的频率。
pmp 发表于 2023-10-8 13:28 | 显示全部楼层
CH32X035 单片机集成了 PWM 模块,可以通过配置相应的寄存器来实现 PWM 输出。首先,需要启用 PWM 模块,然后配置 PWM 信号的频率、占空比等参数。具体配置方法请参考 CH32X035 数据手册。
tabmone 发表于 2023-10-8 13:36 | 显示全部楼层
为了让呼吸灯的亮度变化更为平滑,需要添加适当的延时,即在一个PWM周期内,控制亮灭时间的比例。
linfelix 发表于 2023-10-8 13:59 | 显示全部楼层
要实现呼吸灯效果,需要控制 LED 的亮度。可以通过改变 PWM 信号的占空比来实现 LED 亮度的变化。占空比越小,LED 亮度越低;占空比越大,LED 亮度越高。
wwppd 发表于 2023-10-8 14:19 | 显示全部楼层
在实现PWM呼吸灯时,需要考虑单片机的资源使用情况,例如内存、时钟等
cashrwood 发表于 2023-10-8 14:26 | 显示全部楼层
CH32X035单片机有多个PWM通道
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

204

帖子

2

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