打印
[研电赛技术支持]

【GD32H757Z海棠派使用手册】第六讲 TIMER_3路PWM输出实验

[复制链接]
3455|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

6.1 实验内容
通过本实验主要学习以下内容:
• TIMER PWM输出原理
• TIMER 定时中断
6.2 实验原理
6.2.1 IO口设置
本例程中,使用TIMER0输出前三个通道的占空比,这三个通道分别为PA8PA9PA10,从datasheet中我们可以看到这三个引脚的定义:
所以需要将这三个引脚配置为AF模式并选择正确的AF号:
6.2.2 TIMER输出PWM原理
TIMER计数方式有两种:边沿计数和中央计数,其中边沿计数分为向上计数和向下计数。
在向上计数模式下,需要配置TIMER的重载值,当TIMER开始工作后,计数值从0开始递增,当达到重载值后计数值变为0重新开始计数;
向下计数模式和向上模式类似,只是计数值是递减的,减到0后从重载数重新计数;
中央对齐模式的计数模式为从0开始计递增到重载值,再从重载值递减到0,从“00”为一次计数周期。
0和重载值之间,用户还可以设置一个比较值,PWM就是通过这个比较值来发出的,当计数值小于比较值时,IO口将会为高或者低,当计数值大于比较值时,IO将为输出为另一个电平,即低或高,当TIMER连续计数时,就呈现出PWM波形。比较值的大小将决定PWM的占空比。以下为TIMER输出PWM的示意图:
图中的OxCPRE输出极性,为高时为有效电平,为低时是无效电平,用户可以设置通道口为有效电平时输出高电平或者输出低电平。比如,将PA8设置为高电平有效,那么当OxCPRE输出为高时,PA8输出高电平;如果设置PA8为低电平有效,那么当OxCPRE输出为高时,则PA8输出低电平。
本实验采用TIMER5进行定时中断,在中断中改变TIMER0前三个通道的占空比,使用示波器或逻辑分析仪,可以测量TIMER0前三个通道PA8PA9PA10的波形。也可以通过飞线的方式将三个IO口分别接到红绿蓝三种不同颜色灯珠上,实现RGB彩灯的效果。
6.3 硬件设计
TIMER0的前三个通道分别为PA8PA9PA10,读者直接对开发板上引出的排针进行测试即可。
6.4 代码解析
本例程使用了两个TIMER,其中TIMER5用来产生30ms的周期性中断,在TIMER5的中断中,对TIMER0的三个通道占空比进行调整,从而实现占空比可变的效果。
6.4.1 主函数代码解析
主函数代码如下所示,主要包括串口初始化、LED初始化、RGB灯珠初始化(即timer0的三个通道初始化)、timer驱动初始化(该timer用于调整RGB灯珠PWM驱动时间)。
C++
int main(void)
{
    //延时和公共驱动部分初始化
    driver_init();
    //打印串口初始化   
    bsp_uart_init(&BOARD_UART);   
    //初始化LED组   
    bsp_led_group_init();  
    bsp_led_on(&LED2);
    bsp_led_off(&LED1);   
    bsp_rgb_init(1000000,10);//   
    //注册rgb_switch函数到timer定时中断的回调函数   
    TIMER_INT.timer_updata_callback=rgb_switch;   
    //初始化定时器,默认计数器频率100K,周期值3000,中断频率100K/3000= 33HZ(30ms)   
    bsp_timer_init(1000000,100);//     
    printf_log("\r\n RGB breathing lamp\r\n");   
    while(1)
    {
   
    }
}
6.4.2 RGB灯珠初始化函数解析
RGB灯珠初始化函数如下,在此定义了RGB_TIMER_RRGB_TIMER_GRGB_TIMER_B三个灯的控制结构体,并通过timer驱动进行配置。
C++
/* 定义注册RGB对应PWM通道 */
TIMER_CH_DEF(RGB_TIMER_R,TIMER0,0,TIMER_CH_PWM_LOW,A,8,AF_PP,GPIO_AF_1);
TIMER_CH_DEF(RGB_TIMER_G,TIMER0,1,TIMER_CH_PWM_LOW,A,9,AF_PP,GPIO_AF_1);
TIMER_CH_DEF(RGB_TIMER_B,TIMER0,2,TIMER_CH_PWM_LOW,A,10,AF_PP,GPIO_AF_1);

/*!
* 说明     RGB初始化
* 输入[1]  counter_frequency 计数器频率
* 输入[2]  period 周期值
* 返回值   无
*/
void bsp_rgb_init(uint32_t counter_frequency,uint16_t period)
{
    driver_timer_multi_channel_init(&RGB_TIMER_R,&RGB_TIMER_G,&RGB_TIMER_B,NULL,counter_frequency,period);
    driver_timer_pwm_on(&RGB_TIMER_R);
    driver_timer_pwm_on(&RGB_TIMER_G);
6.4.3 基础定时器初始化及中断处理函数
基础定时器初始化配置代码如下,在此用一个定时器TIMER5,并使能了其溢出中断。该定时器用于控制RGB PWM输出时间。
C
/* 注册定义定时器中断使用的timer */
TIMER_BASE_DEF(TIMER_INT,TIMER5);
/*!
* 说明     定时器中断初始化
* 输入[1]  counter_frequency:计数器频率值
* 输入[2]  period:周期值
* 返回值   无
*/
void bsp_timer_init(uint32_t counter_frequency,uint16_t period)
{
    driver_timer_base_int_init(&TIMER_INT,counter_frequency,period);
    nvic_irq_enable(TIMER5_DAC_UDR_IRQn,0,0);
}
其中断回调函数如下,通过该函数定时调整RGB三路PWM的占空比。
C
/*!
* 说明     定时器中断服务函数
* 输入[1]  无
* 返回值   无
*/
void TIMER5_DAC_UDR_IRQHandler(void)
{
    driver_timer_updata_int_handler(&TIMER_INT);                     
}

/*!
* 说明     RGB占空比切换函数(TIMER定时中断回调)
* 输入     无
* 输出     无
* 返回值   无
*/
void rgb_switch(void)
{   
    static  uint8_t r_duty=0,g_duty=0,b_duty=0;   
    //每轮中断依次调整rgb占空比,将全部组合遍历   
    bsp_rgb_duty_set(r_duty,g_duty,b_duty);      
    b_duty+=5;
    if(b_duty>100)
    {
        b_duty=0;
        g_duty+=5;
        if(g_duty>100)
        {
            g_duty=0;
            r_duty+=5;            
            if(r_duty>100)
            {
                r_duty=0;
                bsp_led_toggle(&LED2);
                bsp_led_toggle(&LED1);                  
            }
        }            
    }   
}
6.5 实验结果
将本例程代码下载到海棠派开发板中,使用示波器测量PA8PA9PA10上,可以看到三个通道输出PWM波,且占空比会周期性的变化。

本教程由GD32 MCU方案商聚沃科技原创发布,了解更多GD32 MCU教程,关注聚沃科技官网,GD32MCU技术交流群:859440462



使用特权

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

本版积分规则

170

主题

190

帖子

9

粉丝