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事件解析的更多相关文章

  1. 六步实现Spring.NET 与 NHibernate 的整合

    最近刚完成一个项目,其中对数据库的架构用到的是Spring.NET 与 NHibernate相结合的产物.对于这两项技术,我自己也不是太熟悉,不过好在网上有很多关于这方面的介绍文档,在这里就不多说了. ...

  2. 轻松六步教会你如何修改system.img.ext4文件

    http://bbs.xiaomi.cn/thread-2943923-1-1.html 希望更多的ROM作者,看了此教程后,学会ROM制作,给大家带来更多更好的ROM 首先下载如下包 Linux U ...

  3. 【Linux开发】linux设备驱动归纳总结(六):2.分享中断号

    linux设备驱动归纳总结(六):2.分享中断号 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  4. 古有七步成诗,今有六步完成DevOps上华为云DevCloud实践

    引言: 在“DevOps能力之屋(Capabilities House of DevOps)”中,华为云DevCloud提出(工程方法+最佳实践+生态)×工具平台=DevOps能力.华为云DevClo ...

  5. c# ado 连接数据库 六步曲

    建立连接分为六步:1.定义连接字符串,oracle 的连接字符串为: private static string connString = "Data Source=192.168.1.13 ...

  6. STM8S和STM8L调试串口中断的注意点

    1. STM8L串口中断注意点 在调试PM2.5传感器GP2Y1051的时候,发现在仿真的时候开始能够进行数据的接受,但是如果暂停之后就不能接受数据,其实只是接收了一次完整的数据. 问题程序 解决方法 ...

  7. Event Recommendation Engine Challenge分步解析第六步

    一.请知晓 本文是基于: Event Recommendation Engine Challenge分步解析第一步 Event Recommendation Engine Challenge分步解析第 ...

  8. Stm32L0串口中断接收使用

    最新在做LoRa的项目,使用的是STM32L072和SX1276,需要做一个串口透传模块,刚开始做demo的时候不考虑功耗,所以串口发送和接收直接使用下列函数执行: HAL_UART_Transmit ...

  9. STM32 串口中断总结

    原文:https://blog.csdn.net/weixin_42480952/article/details/82981409 最近在学习使用dma传输方式进行串口通讯,感觉这个很详细,存一下 . ...

  10. 【Vue实战之路】二、路由使用基础,六步搞定Vue-router

    vue-router的出现是为了解决路由与视图(实际项目中的单文件组件)的对应关系.若单单为了实现交互时对相应组件的渲染,则通过vue的基础操作完全可以实现,那么为什么要是用vue-router呢,个 ...

随机推荐

  1. 一遍博客带你上手Servlet

    概念 Servlet其实就是Java提供的一门动态web资源开发技术.本质就是一个接口. 快速入门 创建web项目,导入servlet依赖坐标(注意依赖范围scope,是provided,只在编译和测 ...

  2. 最强绘图AI:一文搞定Midjourney(附送咒语)

    最强绘图AI:一文搞定Midjourney(附送咒语) Midjourney官网:https://www.midjourney.com 简介 Midjourney是目前效果最棒的AI绘图工具.访问Mi ...

  3. Chrome浏览器插件 Undo Close Tab (恢复关掉的标签页)

    背景 如果您经常使用Chrome浏览器,也许有时候会意外关闭一个标签页,从而丢失您正在查看的内容.这时您可能会感到非常烦恼,并希望能够迅速找回这个标签页.当然,您可以通过点击浏览器历史记录中的条目来找 ...

  4. PVE Cloud-INIT 模板配置

    PVE Cloud-INIT 模板配置 Cloud-init是什么 Cloud-init是开源的云初始化程序,能够对新创建弹性云服务器中指定的自定义信息(主机名.密钥和用户数据等)进行初始化配置.通过 ...

  5. pandas之合并操作

    Pandas 提供的 merge() 函数能够进行高效的合并操作,这与 SQL 关系型数据库的 MERGE 用法非常相似.从字面意思上不难理解,merge 翻译为"合并",指的是将 ...

  6. Kubernetes客户端认证(二)—— 基于ServiceAccount的JWTToken认证

    1.概述 在 Kubernetes 官方手册中给出了 "用户" 的概念,Kubernetes 集群中存在的用户包括 "普通用户" 与 "Service ...

  7. IE盒模型和标准盒模型之间的差别

    1.W3C标准盒子模型 w3c盒子模型的范围包括margin.border.padding.content,并且content部分不包含其他部分 2.IE盒子模型 IE盒子模型的范围包括margin. ...

  8. Istio数据面新模式:Ambient Mesh技术解析

    摘要:Ambient Mesh以一种更符合大规模落地要求的形态出现,克服了大多数Sidecar模式的固有缺陷,让用户无需再感知网格相关组件,真正将网格下沉为基础设施. 本文分享自华为云社区<华为 ...

  9. Python_16 session、cookie 鉴权

    一.查缺补漏 1. pprint https://www.cnblogs.com/yjybupt/p/10669988.html https://www.cnblogs.com/wongbingmin ...

  10. Nginx Web快速入门

    Nginx Web快速入门 目录 Nginx Web快速入门 Nginx概述 为什么选择Nginx服务 Nginx的应用场景 源码安装nginx Yum安装nginx Nginx相关命令总结 Ngin ...