打印

GD32E230G8定时器+PWM

[复制链接]
1328|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2024-11-13 10:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
定时器:

         频率f=主频/(arr+1)(psc+1)

        其中,arr——自动重装值——>Period

                  psc——预分频值(0-65535)——>Prescaler

        例如f=72000000/(99+1)(719+1)=1000Hz,则周期T=1/1000=0.001s,即1ms

初始化:

//定时器14初始化
void TIM14_Counter_Init(u16 arr,u16 psc)
{
               
                /* 定义一个定时器初始化结构体 */
    timer_parameter_struct timer_init_struct;
   
        //Enable TIMER14 clock开启 TIMER14的时钟
                rcu_periph_clock_enable(RCU_TIMER14);
       
                /* TIMER5 初始化配置 */
                timer_deinit(TIMER14);
       
       
                /* 初始化TIMER相关结构体默认值参数 */
    timer_struct_para_init(&timer_init_struct);
       
       
                timer_init_struct.prescaler         = psc;/* 时钟预分频系数 */
                timer_init_struct.period            = arr;/* 自动重装载值 */
                timer_init_struct.counterdirection  = TIMER_COUNTER_UP;
                timer_init_struct.clockdivision     = TIMER_CKDIV_DIV1;
                timer_init(TIMER14, &timer_init_struct);
       
       
                nvic_irq_enable(TIMER14_IRQn, 1);                                /* TIMER14中断设置,抢占优先级1 */
               
               
                timer_flag_clear(TIMER14,TIMER_FLAG_UP); //清除TIMx更新中断标志
                timer_interrupt_enable(TIMER14,TIMER_INT_UP);        /* 使能更新中断 */
       
       
                timer_enable(TIMER14);
       
}

中断服务函数

//TIM14定时器中断服务函数
void TIMER14_IRQHandler(void)
{
                if(timer_flag_get(TIMER14, TIMER_FLAG_UP)!=RESET)//检查TIM14更新中断发生与否
                {
                                timer_flag_clear(TIMER14,TIMER_FLAG_UP);                /* 定时器更新中断的标识位需要手动清除 */
               
                                tim4_count++;
               
                                if(tim4_count>=100)
                                {       
                                        tim4_count=0;
                                        nowTime++;//100ms更新一次计时器
                                        sleepCount++;
                                        shutCount++;
                                        sleepCheck();//检测振动开关
                                }
                }
}

PWM:

//pwm初始化
void PWM_Init(void)
{
       
                /* enable the GPIOB clock */
                rcu_periph_clock_enable(RCU_GPIOB);
                //Enable TIMER2 clock开启 TIMER2的时钟
                rcu_periph_clock_enable(RCU_TIMER2);
       
                gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0);
        gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_0);
        gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_0);
       
  
       /* 定义一个定时器初始化结构体 */
       timer_parameter_struct timer_init_struct;
       /* 定义一个定时器输出比较参数结构体*/
      timer_oc_parameter_struct timer_oc_init_struct;

       
                        //复位外设TIMERx
                 timer_deinit(TIMER2);
       
       
                /* TIMER2 configuration */
                timer_init_struct.prescaler         = 719;
                timer_init_struct.alignedmode       = TIMER_COUNTER_EDGE;
                timer_init_struct.counterdirection  = TIMER_COUNTER_UP;
                timer_init_struct.period            = PWM_T-1;;
                timer_init_struct.clockdivision     = TIMER_CKDIV_DIV1;
                timer_init_struct.repetitioncounter = 0;
                timer_init(TIMER2, &timer_init_struct);

                /* PWM初始化 */
    timer_oc_init_struct.outputstate  = TIMER_CCX_ENABLE;                /* 通道使能 */
    timer_oc_init_struct.outputnstate = TIMER_CCXN_DISABLE;                /* 通道互补输出使能(定时器2无效) */
    timer_oc_init_struct.ocpolarity   = TIMER_OC_POLARITY_HIGH;        /* 通道极性 */
    timer_oc_init_struct.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;/* 互补通道极性(定时器2无效)*/
    timer_oc_init_struct.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;/* 通道空闲状态输出(定时器2无效)*/
    timer_oc_init_struct.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;/*互补通道空闲状态输出(定时器2无效) */

                /* PWM Mode configuration: Channel2 */
                timer_channel_output_config(TIMER2, TIMER_CH_2, &timer_oc_init_struct);
                 
    /* PWM模式0 */
    timer_channel_output_mode_config(TIMER2,TIMER_CH_2,TIMER_OC_MODE_PWM0);
               
                /* 不使用输出比较影子寄存器 */
    timer_channel_output_shadow_config(TIMER2,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);       
               
                //所有的通道输出使能
//                timer_primary_output_config(TIMER0,ENABLE);
       
                /* 自动重装载影子比较器使能   TIMERx自动重载影子使能  使能定时器自动重装载值*/
    timer_auto_reload_shadow_enable(TIMER2);       
       
                /* TIMER2 enable使能外设TIMERx */
    timer_enable(TIMER2);
}

pwm输出函数,改变uk值改变占空比

        //参数1:定时器名称
    //参数2:定时器通道,根据输出引脚与定时器通道映射关系,看手册
    //参数3:占空比设置 ,改变uk值即改变pwm输出占空比
    //占空比d=uk/arr
    timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_2, uk);

使用特权

评论回复
沙发
g0d5xs| | 2024-12-17 21:25 | 只看该作者
这种还比较简单的,我觉得PWM还是可玩性比较高,可以点灯和电机控制

使用特权

评论回复
板凳
cen9ce| | 2024-12-17 23:15 | 只看该作者
这种PWM不就是直接控制的了吗

使用特权

评论回复
地板
d1ng2x| | 2024-12-18 15:45 | 只看该作者
你可以看看例程,例子直接干就好了

使用特权

评论回复
5
ex7s4| | 2024-12-18 17:19 | 只看该作者
根据需求选择一个可用的定时器(如TIM1, TIM2等)。配置定时器模式:选择定时器的工作模式(如向上计数、向下计数等)。

使用特权

评论回复
6
lamanius| | 2024-12-18 20:33 | 只看该作者
其实,如果需要使用中断或DMA来更新PWM的占空比,需要配置相应的中断和DMA设置

使用特权

评论回复
7
kaif2n9j| | 2024-12-18 21:01 | 只看该作者
这个其实可以多讲讲,主要是有一些定时器的配置还是有讲究的

使用特权

评论回复
8
lix1yr| | 2024-12-19 07:11 | 只看该作者
这个+1是必须要重视的,有些时候容易被忽略的

使用特权

评论回复
9
liu96jp| | 2024-12-19 08:21 | 只看该作者
定时器配置成PWM不就可以了吗

使用特权

评论回复
10
t1ngus4| | 2024-12-19 09:09 | 只看该作者
PWM其实要是直接控制电机之类的更有意义一些

使用特权

评论回复
11
zhizia4f| | 2024-12-19 10:11 | 只看该作者
这种PWM控制还可以的,而且官方的例程写的还是比较细致的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2055

主题

7455

帖子

10

粉丝