当前位置: 首页 > 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.dtcms.com/a/311582.html

相关文章:

  • JavaScript将String转为base64 笔记250802
  • 人工智能篇之计算机视觉
  • golang——viper库学习记录
  • 牛客 - 旋转数组的最小数字
  • 题单【模拟与高精度】
  • 先学Python还是c++?
  • 工具自动生成Makefile
  • 机器学习——K 折交叉验证(K-Fold Cross Validation),实战案例:寻找逻辑回归最佳惩罚因子C
  • 深入理解C++中的vector容器
  • VS2019安装HoloLens 没有设备选项
  • 大模型(五)MOSS-TTSD学习
  • 二叉树的层次遍历 II
  • 算法: 字符串part02: 151.翻转字符串里的单词 + 右旋字符串 + KMP算法28. 实现 strStr()
  • Redis数据库存储键值对的底层原理
  • 信创应用服务器TongWeb安装教程、前后端分离应用部署全流程
  • Web API安全防护全攻略:防刷、防爬与防泄漏实战方案
  • Dispersive Loss:为生成模型引入表示学习 | 如何分析kaiming新提出的dispersive loss,对扩散模型和aigc会带来什么影响?
  • 二、无摩擦刚体捉取——抗力旋量捉取
  • uniapp 数组的用法
  • 【c#窗体荔枝计算乘法,两数相乘】2022-10-6
  • Python Pandas.from_dummies函数解析与实战教程
  • 【语音技术】什么是动态实体
  • 【解决错误】IDEA启动SpringBoot项目 出现:Command line is too long
  • 5734 孤星
  • process_vm_readv/process_vm_writev 接口详解
  • 如何在 Ubuntu 24.04 或 22.04 LTS Linux 上安装 Guake 终端应用程序
  • Next.js 怎么使用 Chakra UI
  • LINUX82 shell脚本变量分类;系统变量;变量赋值;四则运算;shell
  • 落霞归雁·思维框架
  • 队列的使用【C++】