6.1 实验内容
通过本实验主要学习以下内容:
• TIMER PWM输出原理
• TIMER 定时中断
6.2 实验原理
本例程中,采用TIMER5进行定时中断,在中断中改变TIMER0前三个通道的占空比,使用示波器或逻辑分析仪,可以测量TIMER0前三个通道PA8、PA9和PA10的波形。也可以通过飞线的方式将三个IO口分别接到红绿蓝三种不同颜色灯珠上,实现RGB彩灯的效果。
6.3 硬件设计
TIMER0的前三个通道分别为PA8、PA9和PA10,读者直接对开发板上引出的排针进行测试即可。
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);
//TIMER0设置1M频率,重载值设置100,PWM频率为10K
bsp_rgb_init(1000000,100);//
//注册rgb_switch函数到timer定时中断的回调函数
TIMER_INT.timer_updata_callback=rgb_switch;
//初始化定时器,默认计数器频率100K,周期值3000,中断频率100K/3000= 33HZ(30ms)
bsp_timer_init(100000,3000);
printf_log("\r\n RGB breathing lamp\r\n");
while(1)
{
}
}
6.4.2 RGB灯珠初始化函数解析
RGB灯珠初始化函数如下,在此定义了RGB_TIMER_R、RGB_TIMER_G、RGB_TIMER_B三个灯的控制结构体,并通过timer驱动进行配置。
C++
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);
driver_timer_pwm_on(&RGB_TIMER_B);
}
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);
6.4.3 基础定时器初始化及中断处理函数
基础定时器初始化配置代码如下,在此用一个定时器TIMER5,并使能了其溢出中断。该定时器用于控制RGB PWM输出时间。
C
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_IRQn,0,0);
}
其中断回调函数如下,通过该函数定时调整RGB三路PWM的占空比。
C
void TIMER5_IRQHandler(void)
{
driver_timer_updata_int_handler(&TIMER_INT);
}
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 实验结果
将本例程代码下载到紫藤派开发板中,使用示波器测量PA8、PA9、PA10上,可以看大三个通道占空比的变化。
更多GD32F470紫藤派资料下载:https://www.gd32bbs.com/cms/kaifaban/391.html