最近收到了极术社区的GD32F303苹果派开发板,开箱如图
“苹果派”这块板子的官方例程很多,仅仅是出版书籍就有三本,涵括了初级、进阶和微机原理等不同领域,据官方说后续还会出版freeRTOS相关的书籍。综合看来很适合小白学习单片机。
上电会有一个精美的GUI例程,涵括了该板子的所有功能:
心血来潮买了几个BLDC电机,准备这次就使用苹果派这块板子试一下BLDC电机的控制。
苹果派这块板子的书籍和例程很多,要驱动电机首先要配置定时器,产生可控的PWM脉冲。
趁快递还没到,先学习一下PWM的生成方式:
按照例程和书籍配置寄存器TIMER2:
static void ConfigTimer2(unsigned short arr, unsigned short psc)
{
timer_parameter_struct timer_initpara; //timer_initpara用于存放定时器的参数
//使能RCU相关时钟
rcu_periph_clock_enable(RCU_TIMER2); //使能TIMER2的时钟
timer_deinit(TIMER2); //设置TIMER2参数恢复默认值
timer_struct_para_init(&timer_initpara); //初始化timer_initpara
//配置TIMER2
timer_initpara.prescaler = psc; //设置预分频器值
timer_initpara.counterdirection = TIMER_COUNTER_UP; //设置向上计数模式
timer_initpara.period = arr; //设置自动重装载值
timer_initpara.clockdivision = TIMER_CKDIV_DIV1; //设置时钟分割
timer_init(TIMER2, &timer_initpara); //根据参数初始化定时器
timer_interrupt_enable(TIMER2, TIMER_INT_UP); //使能定时器的更新中断
nvic_irq_enable(TIMER2_IRQn, 1, 0); //配置NVIC设置优先级
timer_enable(TIMER2); //使能定时器
}
配置PWM输出模式:
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); //使能定时器
}
void InitPWM(void)
{
ConfigTIMER1ForPWMPB10(599, 999); //配置TIMER1,120000000/(999+1)/(599+1)=200Hz
}
void SetPWM(signed short val)
{
s_iDutyCycle = val; //获取占空比的值
timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_2, s_iDutyCycle); //设置占空比
}
设置主函数:
#include "Main.h"
#include "gd32f30x_conf.h"
#include "SysTick.h"
#include "RCU.h"
#include "NVIC.h"
#include "Timer.h"
#include "PWM.h"
int main(void)
{
SystemInit();
InitRCU();
InitNVIC();
InitTimer();
InitSysTick();
InitPWM();
SetPWM(100);
while(1)
{
}
}
在KEIL中编写好代码后,连接板子上的GD-LINK接口
由于使用GDlink烧录,故在"Target"标签页选择"DEBUG"为“CMSIS-DAP Debugger”
经实测GDLINK的烧录速度较慢,这里可以把时钟频率调整为10MHZ以增快烧录速度
烧录完成后用示波器的探头连接PB10引脚,如图,可以看到清晰的PWM波型
有了PWM之后,控制电机就显得极其简单了