GD32的中断、定时器与PWM综合使用
引言
GD32F4xx系列微控制器凭借其Cortex-M4内核和丰富外设资源,在工业控制、物联网等领域广泛应用。本文通过多个实战案例,深入解析中断处理机制、定时器应用及PWM波形生成的实现,并最终实现蜂鸣器音乐播放功能。
开发环境
- 硬件:GD32F450开发板
- 工具链:GCC + GD32 Firmware Library
- 关键外设:TIMER、USART、GPIO、SYSTICK
一、异常与中断处理机制
在gd32f4xx_it.c
中定义了ARM Cortex-M4的核心异常处理函数:
c
Copy
// 硬件异常处理(进入死循环)
void HardFault_Handler(void) {
while(1);
}
// 定时器5中断服务函数(示例)
void TIMER5_DAC_IRQHandler() {
if(timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP)) {
gpio_bit_toggle(GPIOC, GPIO_PIN_9); // LED翻转
timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_UP);
}
}
关键点:
- 异常处理函数命名需与向量表一致
- 清除中断标志避免重复触发
- 优先级通过
nvic_irq_enable()
配置
二、定时器基础应用
1. 定时器配置流程(以TIMER5为例)
c
Copy
void Timer_config() {
rcu_periph_clock_enable(RCU_TIMER5); // 使能时钟
timer_deinit(TIMER5); // 复位定时器
timer_parameter_struct tps = {
.prescaler = 10000 - 1, // 预分频
.period = SystemCoreClock/10000 -1 // 自动重装载值
};
timer_init(TIMER5, &tps);
timer_interrupt_enable(TIMER5, TIMER_INT_UP); // 使能更新中断
nvic_irq_enable(TIMER5_DAC_IRQn, 2, 2); // 设置中断优先级
timer_enable(TIMER5); // 启动定时器
}
参数计算:
- 定时频率 = 系统时钟 / (预分频+1) / (周期+1)
- 例:系统时钟120MHz,生成1Hz信号
三、PWM生成与多通道控制
1. PWM输出配置(TIMER1通道0)
c
Copy
void PWM_Config() {
// GPIO复用配置
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_5); // PA5复用为TIMER1_CH0
// 定时器基础配置
timer_parameter_struct tps = { ... };
timer_init(TIMER1, &tps);
// PWM通道配置
timer_oc_parameter_struct oc_param = {
.outputstate = TIMER_CCX_ENABLE,
.ocpolarity = TIMER_OC_POLARITY_HIGH
};
timer_channel_output_config(TIMER1, TIMER_CH_0, &oc_param);
timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_0, pulse); // 设置占空比
}
2. 多通道PWM控制(TIMER2三通道)
c
Copy
// 通过串口指令调整占空比示例
void Usart0_on_recv(uint8_t* data) {
switch(data[0]) {
case 0x00: Timer2_ch0_update(duty0++); break; // CH0占空比+
case 0x01: Timer2_ch0_update(duty0--); break; // CH0占空比-
// 其他通道类似
}
}
四、蜂鸣器音乐播放实战
1. 音符频率生成原理
c
Copy
// 根据音符值设置定时器周期
void Buzzer_beep(uint8_t note) {
uint32_t freq = note_table[note]; // 音符频率表
timer_autoreload_value_config(TIMERx, SystemCoreClock / freq);
}
2. 《两只老虎》乐谱实现
c
Copy
// 音符与节拍数据
uint8_t notes[] = {1,2,3,1, 1,2,3,1, 3,4,5, ...};
uint8_t durations[] = {4,4,4,4, 4,4,4,4, 4,4,8, ...};
// 播放逻辑
for(int i=0; i<len; i++) {
Buzzer_beep(notes[i]);
delay_1ms(durations[i] * 100); // 持续音符
Buzzer_stop();
delay_1ms(20); // 音符间隔
}
五、系统滴答定时器(SYSTICK)
1. 微秒级延时实现
c
Copy
volatile uint32_t tick = 0;
void SysTick_Handler(void) {
tick++;
}
uint32_t systick_tick_us() {
return tick;
}
void delay_1us(uint32_t us) {
uint32_t start = systick_tick_us();
while(systick_tick_us() - start < us);
}
总结
通过上述案例,我们实现了:
- 定时器中断控制LED闪烁
- 多通道PWM输出及串口控制
- 蜂鸣器音乐播放系统
- 高精度延时函数
GD32F4xx的定时器模块功能强大,可扩展至电机控制、电源管理等复杂应用。开发者应灵活运用预分频、自动重载等参数,结合中断机制实现精准定时控制。