GD32F303的PWM实现LED呼吸灯的方法

GD32F303的PWM实现LED呼吸灯的方法

  1. 首先配置TIMER1,定义初始化结构体变量
static void ConfigTIMER1ForPWMPB10(unsigned short arr, unsigned short psc)
{
  //定义初始化结构体变量
  timer_oc_parameter_struct timer_ocinitpara;
  timer_parameter_struct timer_initpara;
  
  rcu_periph_clock_enable(RCU_GPIOB);    //使能GPIOB时钟
  rcu_periph_clock_enable(RCU_TIMER1);   //使能TIMER1时钟
  rcu_periph_clock_enable(RCU_AF);       //使能TIMER1时钟
  
  gpio_pin_remap_config(GPIO_TIMER1_PARTIAL_REMAP1, ENABLE);  //TIMER1部分重映射TIMER1_CH2->PB10
  gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);  //设置GPIO输出模式及速度

  timer_deinit(TIMER1);                                  //将TIMER1配置为默认值
  timer_struct_para_init(&timer_initpara);               //timer_initpara配置为默认值
    
  timer_initpara.prescaler         = psc;                //设置预分频值
  timer_initpara.alignedmode       = TIMER_COUNTER_EDGE; //设置对齐模式
  timer_initpara.counterdirection  = TIMER_COUNTER_UP;   //设置向上计数
  timer_initpara.period            = arr;                //设置重装载值
  timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;   //设置时钟分频因子
  timer_initpara.repetitioncounter = 0;                  //设置重复计数值
  timer_init(TIMER1, &timer_initpara);                   //初始化定时器
    
  //将结构体参数初始化为默认值
  timer_channel_output_struct_para_init(&timer_ocinitpara);  
    
  timer_ocinitpara.outputstate  = TIMER_CCX_ENABLE;                    //设置通道输出状态
  timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;                  //设置互补通道输出状态
  timer_ocinitpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;              //设置通道输出极性
  timer_ocinitpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;             //设置互补通道输出极性
  timer_ocinitpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;             //设置空闲状态下通道输出极性
  timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;            //设置空闲状态下互补通道输出极性
  timer_channel_output_config(TIMER1, TIMER_CH_2, &timer_ocinitpara);  //初始化结构体
     
  timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_2, 0);                   //设置占空比
  timer_channel_output_mode_config(TIMER1, TIMER_CH_2, TIMER_OC_MODE_PWM0);         //设置通道比较模式
  timer_channel_output_shadow_config(TIMER1, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);  //失能比较影子寄存器
  timer_auto_reload_shadow_enable(TIMER1);                                          //自动重载影子使能 

  timer_enable(TIMER1);  //使能定时器
}

2. 设置占空比的函数

void SetPWM(signed short val)
{
  s_iDutyCycle = val;                   //获取占空比的值
  
  timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_2, s_iDutyCycle);  //设置占空比
}

3. 实现占空比循环的函数,每50ms被调用1次

void CirclePWM(void)
{
  static signed short val=600;       //占空比
  static unsigned char flag=0;       //0:由亮到暗       1:由暗到亮
  
  SetPWM(val);         //设置PWM值
  
  if(flag==0)    //由亮到暗
  {
    if(val==0)
      flag=1;
    else
      val-=50;
  }
  if(flag==1)    //由暗到亮
  {
    if(val==600)
      flag=0;
    else
      val+=50;
  }
}

4. 配置LED的GPIO

static  void  ConfigLEDGPIO(void)
{
  //使能RCU相关时钟
  rcu_periph_clock_enable(RCU_GPIOA);                                 //使能GPIOA的时钟
  //这里将PA8由推挽输出改为浮空输入
  gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_8);  //设置GPIO输出模式及速度
                                 
}

5. 在2ms的任务里面定义呼吸灯的周期,这里设置的是50ms,可以根据实际需求任意更改效果

static  void  Proc2msTask(void)
{  
  static signed short s_iCnt25=0;
  
  if(Get2msFlag())  //判断2ms标志状态
  { 

    if(s_iCnt25>=49)
    {
      CirclePWM();    //实现PWMV循环
      
      s_iCnt25=0;
    }
    else
    {
      s_iCnt25++;
    }
       
    Clr2msFlag();   //清除2ms标志
  }
}

代码结束了,关于PWM和GPIO的配置,根据实际使用来更改即可。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
GPIO模拟PWM(脉冲宽度调制)是一种通过在GPIO引脚上快速切换电平来模拟PWM信号的方法。在某些单片机或嵌入式系统中,可能没有硬件支持的PWM功能,但可以使用GPIO来实现类似的效果。 要在GPIO上模拟PWM,你可以按照以下步骤进行操作: 1. 选择一个合适的GPIO引脚作为输出引脚。 2. 使用编程语言(如Python或C)来控制GPIO引脚的电平。 3. 通过控制GPIO引脚的电平持续时间来模拟PWM信号的占空比。 4. 使用一个循环或定时器来控制PWM信号的频率。 下面是一个使用Python进行GPIO模拟PWM的示例代码: ```python import time import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(18, GPIO.OUT) pwm = GPIO.PWM(18, 100) # 设置频率为100Hz pwm.start(50) # 设置初始占空比为50% try: while True: # 改变占空比 for duty_cycle in range(0, 101, 5): pwm.ChangeDutyCycle(duty_cycle) time.sleep(0.1) for duty_cycle in range(100, -1, -5): pwm.ChangeDutyCycle(duty_cycle) time.sleep(0.1) except KeyboardInterrupt: pass pwm.stop() GPIO.cleanup() ``` 以上代码使用RPi.GPIO库来控制树莓派的GPIO引脚。通过改变`ChangeDutyCycle()`函数的参数,可以改变PWM信号的占空比。循环部分可以让PWM信号在0%到100%之间循环变化。 请注意,GPIO模拟PWM的精度可能不如硬件PWM,并且频率也会受到系统性能的限制。因此,对于需要高精度和稳定性的应用,建议使用支持硬件PWM的设备或模块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JIM_ICE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值