TIM-BLDC六步换相-串口中断模拟检测霍尔信号换相-软件COM事件解析
一、COM事件解析
COM事件简介:COM事件即换相事件只用于高级定时器当中,其主要目的是用在BLDC方波的控制中,用于同时更新6路PWM的状态,即同时更新占空比的目的,从而达到3相同时换相;如果不使用COM事件,由于代码是按顺序执行,程序中会按代码顺序更新6路PWM的状态,会造成通道之间存在延迟。
COM事件产生有两种方式,本文介绍直接通过软件产生COM事件
即:TIM_GenerateEvent(TIM1,TIM_EventSource_COM);
COM事件使能
TIM_CCPreloadControl(TIM1,ENABLE);
COM事件使能后,操作CCxE、CCxNE、OCxM位时,只有当COM事件发生后,功能才会生效。
COM事件验证
case 6://W+U-(由W+V-换相到此状态)
TIM1->CH3CVR=10;
TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Enable);
TIM1->CH1CVR=100;
TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Enable);//U-
TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Disable);//V相由高电平变为低电平
//程序中使能COM事件
TIM_CCPreloadControl(TIM1,ENABLE);
TIM_GenerateEvent(TIM1,TIM_EventSource_COM);
可以看出在由W+V-换相到W+U-的过程中,U-由低电平变为高电平/V-由高电平变为低电平,这两个事件是同时发生的。
//程序中失能COM事件
TIM_CCPreloadControl(TIM1,DISABLE);
可以看出在由W+V-换相到W+U-的过程中,事件1:U-由低电平变为高电平/事件2:V-由高电平变为低电平,这两个事件是按照程序当中先执行事件1再执行事件2的顺序进行的,二者之间存在4.88us的延时
二、串口中断模拟检测霍尔信号换相
在120°导通区间,上桥臂开关管采用PWM调制,下桥臂恒通
串口接收5/4/6/2/3/1数据完成从U+V-→W+V-→W+U-→V+U-→V+W-→U+ W-的六步换相
程序实际运行波形图如下:
三、完整程序代码如下:
#include "debug.h"
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART2_Printf_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}
void USART2_CFG( void )
{
NVIC_InitTypeDef NVIC_InitStructure= {0};
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM1_CH1_( u16 arr, u16 psc, u16 ccp)//TIM1_CH1 从定时器 输出波形
{
GPIO_InitTypeDef GPIO_InitStructure={0};
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
TIM_OCInitTypeDef TIM_OCInitStructure={0};
TIM_BDTRInitTypeDef TIM_BDTRInitStructure={0};
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure); //TIM1_CH1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure); //TIM1_CH2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure); //TIM1_CH3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_InitStructure); //TIM1_CH1N
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_InitStructure); //TIM1_CH2N
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_InitStructure); //TIM1_CH3N
TIM_TimeBaseInitStructure.TIM_Period =arr;
TIM_TimeBaseInitStructure.TIM_Prescaler =psc;
TIM_TimeBaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OCInitStructure.TIM_Pulse = ccp;
TIM_OC1Init( TIM1, &TIM_OCInitStructure );
TIM_OCInitStructure.TIM_Pulse = ccp;
TIM_OC2Init( TIM1, &TIM_OCInitStructure );
TIM_OCInitStructure.TIM_Pulse = ccp;
TIM_OC3Init( TIM1, &TIM_OCInitStructure );
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 132;//
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
// TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
// TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
// TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Disable);
TIM_CCPreloadControl(TIM1,ENABLE);
// TIM_CCPreloadControl(TIM1,DISABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_Cmd(TIM1,ENABLE);
TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);
TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Disable);
}
void USART2_IRQHandler( void )//串口2中断
{
__IO u8 CHannel = 0;
if( USART_GetITStatus( USART2, USART_IT_RXNE ) != RESET )
{
CHannel = USART_ReceiveData( USART2 );
}
switch(CHannel)
{
case 1://U+ W-
TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Disable);
TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
TIM1->CH1CVR=60;
TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Enable);
TIM1->CH3CVR=100;
TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Enable);
break;
case 2://V+U-
TIM1->CH2CVR=50;
TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Enable);
TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Disable);
TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
TIM1->CH1CVR=100;
TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Enable);
break;
case 3://V+W-
TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Disable);
TIM1->CH2CVR=40;
TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Enable);
TIM1->CH3CVR=100;
TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Enable);
break;
case 4://W+V-
TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Disable);
TIM1->CH2CVR=100;
TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Enable);
TIM1->CH3CVR=30;
TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Enable);
break;
case 5://U+V-
TIM1->CH1CVR=20;
TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Enable);
TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Disable);
TIM1->CH2CVR=100;
TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Enable);
break;
case 6://W+U-
TIM1->CH3CVR=10;
TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Enable);
TIM1->CH1CVR=100;
TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Enable);
TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Disable);
break;
default:
TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);
TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Disable);
TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Disable);
break;
}
TIM_GenerateEvent(TIM1,TIM_EventSource_COM);//产生COM事件
}
int main(void)
{
Delay_Init();
USART2_Printf_Init(115200);
USART2_CFG();
TIM1_CH1_(100-1,8-1,0);
while(1);
}