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事件解析的更多相关文章
- 六步实现Spring.NET 与 NHibernate 的整合
最近刚完成一个项目,其中对数据库的架构用到的是Spring.NET 与 NHibernate相结合的产物.对于这两项技术,我自己也不是太熟悉,不过好在网上有很多关于这方面的介绍文档,在这里就不多说了. ...
- 轻松六步教会你如何修改system.img.ext4文件
http://bbs.xiaomi.cn/thread-2943923-1-1.html 希望更多的ROM作者,看了此教程后,学会ROM制作,给大家带来更多更好的ROM 首先下载如下包 Linux U ...
- 【Linux开发】linux设备驱动归纳总结(六):2.分享中断号
linux设备驱动归纳总结(六):2.分享中断号 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- 古有七步成诗,今有六步完成DevOps上华为云DevCloud实践
引言: 在“DevOps能力之屋(Capabilities House of DevOps)”中,华为云DevCloud提出(工程方法+最佳实践+生态)×工具平台=DevOps能力.华为云DevClo ...
- c# ado 连接数据库 六步曲
建立连接分为六步:1.定义连接字符串,oracle 的连接字符串为: private static string connString = "Data Source=192.168.1.13 ...
- STM8S和STM8L调试串口中断的注意点
1. STM8L串口中断注意点 在调试PM2.5传感器GP2Y1051的时候,发现在仿真的时候开始能够进行数据的接受,但是如果暂停之后就不能接受数据,其实只是接收了一次完整的数据. 问题程序 解决方法 ...
- Event Recommendation Engine Challenge分步解析第六步
一.请知晓 本文是基于: Event Recommendation Engine Challenge分步解析第一步 Event Recommendation Engine Challenge分步解析第 ...
- Stm32L0串口中断接收使用
最新在做LoRa的项目,使用的是STM32L072和SX1276,需要做一个串口透传模块,刚开始做demo的时候不考虑功耗,所以串口发送和接收直接使用下列函数执行: HAL_UART_Transmit ...
- STM32 串口中断总结
原文:https://blog.csdn.net/weixin_42480952/article/details/82981409 最近在学习使用dma传输方式进行串口通讯,感觉这个很详细,存一下 . ...
- 【Vue实战之路】二、路由使用基础,六步搞定Vue-router
vue-router的出现是为了解决路由与视图(实际项目中的单文件组件)的对应关系.若单单为了实现交互时对相应组件的渲染,则通过vue的基础操作完全可以实现,那么为什么要是用vue-router呢,个 ...
随机推荐
- vue中使用vue.extend在dom挂载vue实例
const CounterComponent = Vue.extend(Counter); this.vm = new CounterComponent({}).$mount('#container' ...
- python入门教程之七流程控制
条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if age >= ...
- ORA-12154: TNS:could not resolve the connect identifier specified--sys密码包含@符号
问题描述:在操作系统登录数据库时,由于忘记了sys密码,重新修改的sys密码包含@符号,登录时报错, ORA-12154: TNS:could not resolve the connect iden ...
- zookeeper重启,线上微服务全部掉线,怎么回事?
注册中心zookeeper被重启,线上微服务全部掉线,怎么回事?! 最近因为一次错误的运维操作,导致线上注册中心zk被重启.而zk重启后发现所有线上微服务开始不断掉线,造成了持续30分钟的P0故障. ...
- laravel 中使用的 PDF 扩展包 laravel-dompdf 和 laravel-snappy
这两天项目中需要将HTML页面转换为PDF文件方便打印,我在网上搜了很多资料.先后尝试了laravel-dompdf和laravel-snappy两种扩展包,个人感觉laravel-snappy比较好 ...
- win10环境下 VMware Workstation Pro 安装centos7无法上网
一.安装centos7 网上类似的教程太多了,我就不一一写了,提供两个网址,先按照教程安装 VMware Workstation Pro ,秘钥在第二个链接里面(亲测可用), 安装完VMware在根据 ...
- DevOps、SRE、平台工程的区别
DevOps.SRE和平台工程的概念在不同时期出现,并由不同的个人和组织开发. DevOps作为一个概念是由Patrick Debois和Andrew Shafer在2009年的敏捷会议上提出的.他们 ...
- springboot注解@PostContruct以及@Cacheable
1.@PostContruct @PostConstruct和@PreDestroy两个注解被用来修饰一个非静态的void()方法. @PostConstruct 加该注解会在项目启动的时候执行该方法 ...
- 使用js截取路径参数方法
1.根据传入的路径和参数名称截取 export function getUrlParams(href,name) { var reg = new RegExp("(^|\\?|&)& ...
- 一文讲透产品经理如何用好ChatGPT
作者:京东零售 何雨航 "4.0版本的ChatGPT可以有效提升产品经理工作效率,但并无法替代产品经理的角色." 一.引言 3月15日,OpenAI发布了最新的基于GPT-4的Ch ...