当前位置: 首页 > news >正文

stm32F407 实现有感BLDC 六步换相 cubemx配置及源代码(二)

接上节stm32F407 实现有感BLDC 六步换相 cubemx配置及源代码(一)-CSDN博客

基本配置设置完成之后,本文代码采用KEIL5软件进行编写及实现。

首先新建一个HALL.c文件与HALL.h文件,HALL.c文件包括霍尔状态真值判断、六步换相函数、以及霍尔传感器的初始化。

霍尔状态真值判断的目的是为了获取当前电机旋转到的位置,对UVW三相霍尔值进行读取最直接的方法就是通过读取stm32的IO电平来实现。

以下为对应的霍尔状态真值判断函数:

uint8_t HALL_Value(void)
{
//HALL_Ustate --- PD12
//HALL_Vstate --- PD13
//HALL_Wstate --- PB8uint8_t State = 0;/* 读取霍尔位置传感器 U 的状态 */if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12) != GPIO_PIN_RESET){State |= 0x01U << 2;}/* 读取霍尔位置传感器 V 的状态 */if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_13) != GPIO_PIN_RESET){State |= 0x01U << 1;}/* 读取霍尔位置传感器 W 的状态 */if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) != GPIO_PIN_RESET){State |= 0x01U << 0;}return State;
}

这个时候,会想到一个问题,就是这个函数既然是获取电机位置,那么我具体在哪些场景下会调用这些函数呢?

其实我们在刚拿到BLDC电机的时候,就会用这个函数来调试查看电机正转与反转时霍尔真值的变化情况,当然了,要调试查看的话,可以采用串口来看。

另外一个场景就是六步换相时,需要获取霍尔真值。

下面则是六步换相程序和霍尔传感器初始化,我的BLDC电机在正转时,真值2对应A相桥臂的上桥臂导通,B相桥臂的下桥臂导通,C相桥臂悬空,不做动作。真值3对应A相桥臂的上桥臂导通,B相桥臂悬空,C相桥臂的下桥臂导通。其余真值也是根据我实际电机的霍尔状态与相序导通关系来做发波处理的。

void SIX_STEP(uint8_t hallState) 
{switch(hallState) {case 2: // A+ B-    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 200);      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 0); HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);            //使得对应所用驱动板上的下管一直导通HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 200);HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);            break;case 3: // A+ C-__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 200);      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 200); HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 0);HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);  break;case 1: // B+ C-__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 200);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 200); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 0);HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);  break;case 5: // B+ A-__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 200); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 200);HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);  break;case 4: // C+ A-__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 200); HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 200);HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);  break;case 6: // C+ B-__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 200);      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 0); HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 200);HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);   break;default: // 错误处理break;}
}/*霍尔传感器初始化*/
void HALL_Init(void)
{/* 启动霍尔传感器接口 */HAL_TIMEx_HallSensor_Start_IT(&htim4);	}

200是PWM波的占空比,占空比改变能够改变电机的速度 。

下面是主程序和中断程序:

int main(void)
{SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();MX_TIM1_Init();MX_TIM4_Init();         HALL_Init();            //霍尔传感器初始化HALL_State = HALL_Value();SIX_STEP(HALL_State);  while (1){}}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM4){HALL_State = HALL_Value();SIX_STEP(HALL_State);HAL_GPIO_WritePin(GPIOH,GPIO_PIN_9,GPIO_PIN_SET);__HAL_TIM_CLEAR_FLAG(&htim4,TIM_FLAG_CC1);}
}

看到这里,肯定有人会疑问,为什么中断中放了六步换相和霍尔真值判断的程序,还要在主程序里面加两行一模一样的程序呢?

这是因为刚开始电机在没有六步换相转动之前,电机是处于静止的,因为霍尔信号没有变化,所以这个时候是触发不了霍尔中断的。因此先在主程序里面判断一下静止时候的霍尔值,然后根据这个霍尔值发波,来让电机转动一下,从而产生变化的一个霍尔信号,这个时候产生霍尔中断,然后执行六步换相程序,最后循环往复的触发中断,不断地进行换相。

根据以上程序,电机能够正常转动,采用六步换相的电机噪声较大是正常的。

http://www.lryc.cn/news/608370.html

相关文章:

  • sqli-labs:Less-20关卡详细解析
  • 沿街晾晒识别准确率↑32%:陌讯多模态融合算法实战解析
  • Linux网络-------4.传输层协议UDP/TCP-----原理
  • QUdpSocket 详解:从协议基础、通信模式、数据传输特点、应用场景、调用方式到实战应用全面解析
  • kong网关集成Safeline WAF 插件
  • 力扣刷题日常(11-12)
  • [硬件电路-122]:模拟电路 - 信号处理电路 - 模拟电路与数字电路、各自的面临的难题对比?
  • 面试实战,问题二十二,Java JDK 17 有哪些新特性,怎么回答
  • 【0基础PS】PS工具详解--图案图章工具
  • 二叉树算法之【Z字型层序遍历】
  • ctfshow_源码压缩包泄露
  • AIGC系列:本地部署大模型
  • Rust进阶-part2-泛型
  • Flutter基础知识
  • 在线问诊系统源码解析:图文+视频双模式架构开发全攻略
  • CH32V单片机启用 FPU 速度测试
  • 江协科技STM32 13-1 PWR电源控制
  • 从零打造大语言模型--处理文本数据
  • FFmpeg+javacpp中纯音频播放
  • 互联网医院系统,互联网医院好处有哪些?
  • 音视频学习(四十八):PCM和WAV
  • CatBoost 完整解析:类别特征友好的梯度提升框架
  • 基于单片机智能雨刷器/汽车刮水器设计
  • zset 中特殊的操作
  • nodejs读写文件
  • 【redis】基于工业界技术分享的内容总结
  • C++ 模板初阶
  • 阿里云:Ubuntu系统部署宝塔
  • 回归预测 | Matlab实现CNN-LSTM-self-Attention多变量回归预测
  • ventoy 是一个非常棒的开源工具,可以制作多系统的usb启动盘