C/C++教程

TIM-BLDC六步换相-串口中断模拟检测霍尔信号换相-软件COM事件解析

本文主要是介绍TIM-BLDC六步换相-串口中断模拟检测霍尔信号换相-软件COM事件解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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);

}

这篇关于TIM-BLDC六步换相-串口中断模拟检测霍尔信号换相-软件COM事件解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!