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呢,个 ...
随机推荐
- 浅读-《深入浅出Nodejs》
原书作者:朴灵 https://book.douban.com/subject/25768396/ 这次算是重读 深入浅出Nodejs,了解到很多之前忽略的细节,收获蛮多,这次顺便将其记录分享,对学习 ...
- odoo 开发入门教程系列-计算的字段和变更(Computed Fields And Onchanges)
计算的字段和变更(Computed Fields And Onchanges) 模型之间的关系是任何Odoo模块的关键组成部分.它们对于任何业务案例的建模都是必要的.然而,我们可能需要给定模型中字段之 ...
- kubernetes 安装cilium
kubernetes 安装cilium Cilium介绍 Cilium是一个开源软件,用于透明地提供和保护使用Kubernetes,Docker和Mesos等Linux容器管理平台部署的应用程序服务之 ...
- [大数据]Hadoop简述
1 Hadoop:发展沿革 摘要:1个人(Doug Cutting).2个公司(Google.Cloudera) 1.1 渊源 Hadoop项目 最初开发者/创始者: Doug Cutting(道格· ...
- [数据库/Java]数据库开发过程中产生的MySQL错误代码及其解决方案
前言 吐槽一下,均是这两天遇到的破烂事儿,搞定了也好,以后出现此类问题也就放心些了. 下列遇到的问题大都是因为MySQL从5.x版本升级到8.0.11(MySQL8.0涉及重大改版)后,跟着连带着出现 ...
- 前端里那些你不知道的事儿之 【window.onload】
作者:京东科技 孙凯 一.前言 相信很多前端开发者在做项目时同时也都做过页面性能优化,这不单是前端的必备职业技能,也是考验一个前端基础是否扎实的考点,而性能指标也通常是每一个开发者的绩效之一.尤其马上 ...
- 虚拟机安装linux操作系统中IP设置
问题描述:用虚拟机安装linux操作系统时,不选择分配IP,系统默认会分配动态IP,如果是临时搭建,就可以默认动态IP,也可以使用连接工具连接虚拟机.但如果是长期使用,选择使用固定的IP会更好,需要手 ...
- JAVASE和JAVAEE的区别
JAVASE和JAVAEE的区别 JavaEE: Java Enterprise Edition,Java企业版,多用于企业级开发,包括web开发等等.企业版本帮助开发和部署可移植.健壮.可伸缩切安全 ...
- 【迭代器设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
简介 迭代器模式(Iterator Pattern),是一种结构型设计模式.给数据对象构建一套按顺序访问集合对象元素的方式,而不需要知道数据对象的底层表示. 迭代器模式是与集合共存的,我们只要实现一个 ...
- [Wechat]概念辨析:微信的生态平台/运管平台
0 引言 微信的各类XX社区.XX文档.XX平台,实在是太多,让人眼花缭乱.必须得理一理了. 1 微信公众平台 https://mp.weixin.qq.com/ 即 微信公众号(小程序 / 订阅号 ...