GD32F450高级定时器六步换相测试
GD32F450的高级定时器很适合用来驱动电机,比如直流无刷和永磁同步。六步换相在直流无刷驱动里运用广泛。定时器设置函数:
#include "six_step.h"
vu32 step = 1;
void six_step_init(void)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
timer_break_parameter_struct timer_breakpara;
rcu_periph_clock_enable(RCU_GPIOE);
rcu_periph_clock_enable(RCU_TIMER0);
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_8);
gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_8);
gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_8);
gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_9);
gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_9);
gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_9);
gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_10);
gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_10);
gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_10);
gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_11);
gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_11);
gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_11);
gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_12);
gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_12);
gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_12);
gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_13);
gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_13);
gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_13);
gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_14);
gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_14);
gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_14);
gpio_mode_set(GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_15);
gpio_output_options_set(GPIOE,GPIO_OTYPE_PP,GPIO_OSPEED_MAX,GPIO_PIN_15);
gpio_af_set(GPIOE,GPIO_AF_1,GPIO_PIN_15);
timer_initpara.alignedmode=TIMER_COUNTER_EDGE;
timer_initpara.clockdivision=TIMER_CKDIV_DIV1;
timer_initpara.counterdirection=TIMER_COUNTER_UP;
timer_initpara.period=599;
timer_initpara.prescaler=199;
timer_initpara.repetitioncounter=0;
timer_init(TIMER0,&timer_initpara);
timer_ocintpara.ocidlestate=TIMER_OC_IDLE_STATE_HIGH;
timer_ocintpara.ocnidlestate=TIMER_OCN_IDLE_STATE_HIGH;
timer_ocintpara.ocpolarity=TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity=TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.outputstate=TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate=TIMER_CCXN_ENABLE;
timer_channel_output_config(TIMER0,TIMER_CH_0,&timer_ocintpara);
timer_channel_output_config(TIMER0,TIMER_CH_1,&timer_ocintpara);
timer_channel_output_config(TIMER0,TIMER_CH_2,&timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,299);
timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_TIMING);
timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);
timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1,299);
timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_TIMING);
timer_channel_output_shadow_config(TIMER0,TIMER_CH_1,TIMER_OC_SHADOW_ENABLE);
timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2,299);
timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_TIMING);
timer_channel_output_shadow_config(TIMER0,TIMER_CH_2,TIMER_OC_SHADOW_ENABLE);
timer_breakpara.runoffstate= TIMER_ROS_STATE_ENABLE;
timer_breakpara.ideloffstate= TIMER_IOS_STATE_ENABLE ;
timer_breakpara.deadtime= 164;
timer_breakpara.breakpolarity= TIMER_BREAK_POLARITY_LOW;
timer_breakpara.outputautostate= TIMER_OUTAUTO_ENABLE;
timer_breakpara.protectmode= TIMER_CCHP_PROT_OFF;
timer_breakpara.breakstate= TIMER_BREAK_ENABLE;
timer_break_config(TIMER0,&timer_breakpara);
timer_primary_output_config(TIMER0,ENABLE);
timer_interrupt_enable(TIMER0,TIMER_INT_CMT);
timer_interrupt_disable(TIMER0,TIMER_INT_BRK);
nvic_irq_enable(TIMER0_TRG_CMT_TIMER10_IRQn,1,1);
timer_enable(TIMER0);
}
void TIMER0_TRG_CMT_TIMER10_IRQHandler(void)
{
/* clear TIMER interrupt flag */
timer_interrupt_flag_clear(TIMER0,TIMER_INT_CMT);
switch(step){
/* next step: step 2 configuration .A-C` breakover---------------------------- */
case 1:
/*channel0 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);
/*channel1 configuration */
timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);
/*channel2 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);
step++;
break;
/* next step: step 3 configuration .B-C` breakover---------------------------- */
case 2:
/*channel0 configuration */
timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);
/*channel1 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);
/*channel2 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE);
step++;
break;
/* next step: step 4 configuration .B-A` breakover---------------------------- */
case 3:
/*channel0 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE);
/*channel1 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);
/*channel2 configuration */
timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE);
step++;
break;
/* next step: step 5 configuration .C-A` breakover---------------------------- */
case 4:
/*channel0 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE);
/*channel1 configuration */
timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE);
/*channel2 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_ENABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE);
step++;
break;
/* next step: step 6 configuration .C-B` breakover---------------------------- */
case 5:
/*channel0 configuration */
timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);
/*channel1 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE);
/*channel2 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_ENABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE);
step++;
break;
/* next step: step 1 configuration .A-B` breakover---------------------------- */
case 6:
/*channel0 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE);
/*channel1 configuration */
timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0);
timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE);
/*channel2 configuration */
timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE);
timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE);
step = 1;
break;
}
}
static u32 delay;
void systick_config(void)
{
/* setup systick timer for 1000Hz interrupts */
if (SysTick_Config(SystemCoreClock / 100U)){
/* capture error */
while (1){
}
}
/* configure the systick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x00U);
}
/*!
\brief delay a time in milliseconds
\paramcount: count in milliseconds
\param none
\retval none
*/
void delay_1ms(uint32_t count)
{
delay = count;
while(0U != delay){
}
}
/*!
\brief delay decrement
\paramnone
\param none
\retval none
*/
void delay_decrement(void)
{
if (0U != delay){
delay--;
}
}
void SysTick_Handler(void)
{
timer_event_software_generate(TIMER0,TIMER_EVENT_SRC_CMTG);
}
主函数:
#include "bitband.h"
#include "usart.h"
#include "systick.h"
#include "led.h"
#include "six_step.h"
/*!
\brief main function
\paramnone
\param none
\retval none
*/
int main(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
// systick_set(200);
// usart_init(9600);
// led_init();
// printf("hello c language...\r\n");
systick_config();
six_step_init();
while(1)
{
// printf("hello gd32...\r\n");
// led_toggle();
// delay_ms(750);
}
}
结果:
这个高级定时器挺厉害的 豌豆爹 发表于 2022-11-15 13:31
这个高级定时器挺厉害的
可以的{:biggrin:} 这个效果看起来不错啊 实际测试效果如何,稳不稳? chenqianqian 发表于 2022-11-19 11:18
这个效果看起来不错啊
是的 daichaodai 发表于 2022-11-19 17:37
实际测试效果如何,稳不稳?
还没正式测试,, 这个高级定时器效果非常好,各个波形也稳定 OKAKAKO 发表于 2022-11-24 21:35
这个高级定时器效果非常好,各个波形也稳定
你们也在测试吗 zeshoufx 发表于 2022-11-25 16:57
你们也在测试吗
看你的波形输出确实挺稳定,以前做过类似的 OKAKAKO 发表于 2022-11-25 21:19
看你的波形输出确实挺稳定,以前做过类似的
哦哦,,你们主要是做电机控制这块吗 zeshoufx 发表于 2022-11-26 19:58
哦哦,,你们主要是做电机控制这块吗
我不是这个方向的,参与过类似的项目而已 请问六步换相是一种什么方式呢 适用于什么种类的电机呢 tpgf 发表于 2022-12-5 09:56
请问六步换相是一种什么方式呢 适用于什么种类的电机呢
电子换相无刷电机要对转子永磁体位置进行精确检测,并用电子开关切换不同绕组通电以获得持续向前的动力,在目前的绝大多数电动车三相无刷电机中均使用三个开关式的霍尔传感器检测永磁体相对于定子线圈的位置,控制器跟据三个霍尔传感器输出的六种不同信号输出相应的控制信号驱动电子开关向马达供电。这就是所谓六步换相法 从电机原理可以看出,换相必须及时,否则会导致电机失步,从而使电机噪音增大,效率降低 为什么只有高级定时器适合呢 需要特殊的控制吗 coshi 发表于 2022-12-5 13:05
为什么只有高级定时器适合呢 需要特殊的控制吗
普通的定时器应该不能输出pwm波 OKAKAKO 发表于 2022-11-24 21:35
这个高级定时器效果非常好,各个波形也稳定
有没有测试过抗干扰能力呢另外和频率挂钩吗 coshi 发表于 2022-12-5 13:05
为什么只有高级定时器适合呢 需要特殊的控制吗
高级定时器可以输出互补的PWM,方便设置死区,刹车 drer 发表于 2022-12-5 12:03
从电机原理可以看出,换相必须及时,否则会导致电机失步,从而使电机噪音增大,效率降低 ...
是的,,,
页:
[1]
2