STM32 HAL库基于DRV8301的FOC开环速度控制

这篇具有很好参考价值的文章主要介绍了STM32 HAL库基于DRV8301的FOC开环速度控制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

CubeMX基本配置

drv8301控制模式(3pwm?6pwm?死区时间设置?)

SVPWM理论推导

HALL接口设置以及旋转速度获取原理


FOC开环控制主要分为三步:第一,角度自增;第二,Park逆变换;第三,SVPWM计算出下个周期要写入的占空比Ta,Tb,Tc

验证SVPWM模块也非常简单,串口打印出来应该是个比较标准的马鞍波(我是20k频率,可供参考) 

drv8301中文资料,stm32,单片机,嵌入式硬件

如果角度改变太快会造成波形有不同程度的失真,不过是正常现象,角度变化改小点就可以了

CubeMX基本配置

使用STM32外设情况如下:

TIM1高级定时器CH1-CH3输出三路互补的PWM信号,设置为中央对齐模式,同时CH4配置为PWM generation no output用于触发ADC采样,具体原因可以看这篇博客:foc配置篇——ADC注入组使用定时器触发采样的配置_定时器触发adc采样_jdhfusk的博客-CSDN博客

据我测试Center Align Mode1和Center Align Mode2没啥很大的区别,定时器Update中断触发位置都是在中间的时刻,但最后我采用的是在ADC采集完成的回调函数中进行FOC运算,所以配置成什么模式就更无所谓了。

这里就提一句比较推荐使用高级定时器TIM1和TIM8来做PWM输出,因为只有他俩是挂在168M下的,而且具有互补输出功能,在频率比较高的情况下,占空比不至于过小。

drv8301中文资料,stm32,单片机,嵌入式硬件

 ADC配置如下,随意看看就行,没啥很特别的

drv8301中文资料,stm32,单片机,嵌入式硬件

 初始化代码如下:

void MOTOR1_PWM_Init(void)
{
	//PWM初始化
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
	HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
	HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
	HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1,0);
	__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2,0);
	__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3,0);
	//通道4触发ADC采样
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);
	__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4,3900);
	//开启ADC注入转换
	HAL_ADCEx_InjectedStart_IT(&hadc1);
}

drv8301控制模式(3pwm?6pwm?死区时间设置?)

一开始采样3PWM控制,但是这个模式不灵活的地方在于,DRV8301是通过DTC引脚到地的电阻值设置死区时间的,而怨种队友一开始坚定认为用了很好的MOS管,就只接了0欧电阻(相当于50ns死区时间)。推荐6PWM模式,配置简单,死区时间设置很方便,而且DRV8301默认就是6PWM控制,省了一步寄存器更改配置

死区时间计算理论上为 MOS管关断时间(看芯片手册) + 单片机IO口翻转时间(对于F4来说10ns左右)当然,理论计算出来后最好还要留一点裕量

我一开始没怎么考虑死区时间问题,于是电机转起来的声音非常惨绝人寰。排查了很久代码的问题,最后锁定了死区时间问题

实际调试时发现,死区时间过小,电机会有尖锐的噪声,死区时间过大,采样电流会隐隐看到有些不连续,严重时就像这样(神似马鞍波)

drv8301中文资料,stm32,单片机,嵌入式硬件

 这个时候我们就可以考虑适当调小死区时间,效果好的时候就是这样啦

drv8301中文资料,stm32,单片机,嵌入式硬件

SVPWM理论推导

彻底吃透SVPWM如此简单 - 知乎 (zhihu.com)

这里推荐直接看这篇文章,至于代码网上有很多,但关键在于理解以下几个问题:

为什么要选择中心对其模式?

Uq的实际含义是什么?

以及采集总线电压到底有什么作用?

我一开始配置单片机外设的时候也没考虑过总线电压采集,其实如果电压比较稳定没有波动的话给个定值完全ok

HALL接口设置以及旋转速度获取原理

drv8301中文资料,stm32,单片机,嵌入式硬件

 首先选择HALL接口模式,选择时钟源及合适的分频系数,以得到最大计数器周期,该周期长于传感器上两次变化的间隔时间

Input Filter 其实是为了抗干扰,因为会有电磁干扰进入引脚,就相当于按键的多次计数软件滤波

drv8301中文资料,stm32,单片机,嵌入式硬件

 三个引脚二配置为内部上拉模式,当然在硬件电路上加上拉电阻也可以的。如果不上拉是无法获取到稳定的电平信号的(本人惨痛教训,曾经直接把三根信号线接到示波器上看,只有几十mV的电平,当时还以为是电机坏了)

下面来到本篇重点了,就是到底如何根据霍尔信号推算当前的电角度?

霍尔传感器分为60°安装方式和120°安装方式,但是仔细观察下面这张图就会发现,本质的区别不大。对于HALL接口模式下,三个信号异或,只要有一路信号发生跳变单片机就会进入输入捕获中断,也就是每隔60电角度就可以在触发中断里得到准确的电角度值

对于120°安装时,信号在0-2PI内变换6次,顺序是5-4-6-2-3-1

而60°安装时,信号改变顺序是4-6-7-3-1-0

drv8301中文资料,stm32,单片机,嵌入式硬件

但这里存在一个问题,就是我们需要根据TIM2->CCR1捕获值来计算角速度吗?

由于我把FOC的运算放在ADC注入组的中断里,所有如果把角速度计算放在霍尔中断,但是在adc中断里算电角度会有严重的延迟误差,每次校准时会有一个很明显的突变发生 

drv8301中文资料,stm32,单片机,嵌入式硬件

如果把计算角速度的公式放在adc中断里就能得到一个很平滑的曲线

 drv8301中文资料,stm32,单片机,嵌入式硬件

 话不多说直接上代码文章来源地址https://www.toymoban.com/news/detail-607961.html

/**
  * 函数功能: 霍尔传感器回调函数
  * 输入参数: @htim,霍尔传感器接口定时器
  * 返 回 值: 无
  * 说    明:霍尔信号发生跳变后进入这个中断,只做角度矫正
  */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	uint8_t hall_read_temp;
	if(htim == &htim2)
	{
		hall_read_temp = HALL_GetPhase();
		if(hall_read_temp==0x05)
    {
      hall_angle = 0.0f+PHASE_SHIFT_ANGLE;
    }
    else if(hall_read_temp==0x04)
    {
      hall_angle = (PI/3.0f)+PHASE_SHIFT_ANGLE;
    }
    else if(hall_read_temp==0x06)
    {
      hall_angle = (PI*2.0f/3.0f)+PHASE_SHIFT_ANGLE;
    }
    else if(hall_read_temp==0x02)
    {
      hall_angle = PI+PHASE_SHIFT_ANGLE;
    }
    else if(hall_read_temp==0x03)
    {
      hall_angle = (PI*4.0f/3.0f)+PHASE_SHIFT_ANGLE;
    }
    else if(hall_read_temp==0x01)
    {
      hall_angle = (PI*5.0f/3.0f)+PHASE_SHIFT_ANGLE;
    }
    if(hall_angle<0.0f)
    {
      hall_angle += 2.0f*PI;
    }
    else if(hall_angle>(2.0f*PI))
    {
      hall_angle -= 2.0f*PI;
    }
    
	}
}


void FOC_ControllerTask(void)
{
		//最先计算霍尔角度,其次电流,然后送入SVPWM计算
		static uint8_t hall_phase,hall_phase_last;
		static uint16_t hall_count;
		hall_phase = HALL_GetPhase();
		if(hall_phase == hall_phase_last)
		{
			hall_count++;
			if(hall_count > 2000)
			{
				hall_count = 0;
				hall_angle_add = 0;
			}
		}
		else
		{
			hall_angle_add = (float)PI/3.0f/hall_count;
			hall_count = 0;
			hall_phase_last = hall_phase;
		}
		hall_angle = _normalizeAngle(hall_angle + hall_angle_add);
}

到了这里,关于STM32 HAL库基于DRV8301的FOC开环速度控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [FOC-Simulink]使用Simulink代码生成工具基于STM32开发板对永磁同步电机进行开环控制

    代码链接:【免费】使用Simulink代码生成工具对永磁同步电机进行开环控制资源-CSDN文库 本文介绍使用Simulink代码生成功能在STM32开发板平台上运行永磁同步电机。 硬件基础: Nucleo-G431RB开发板 X-NUCLEO-IHM07M1驱动扩展板 57BLDC-24V-210W时代超群直流电机 软件基础: MATLAB 2022b 安装

    2024年02月13日
    浏览(32)
  • 【STM32】BLDC驱动&控制开发笔记 | 07_SPI通信测试 - STM32F407用SPI配置DRV8323驱动芯片

    最近在埋头搞STM32 + 无刷直流电机控制,想实现用自己的STM32F407VGT6芯片板子,外加一块驱动板(目前选用到TI的DRV8302或者DRV8323驱动芯片),搞定电机驱动,最后实现比较好的控制效果。如果不是同一块芯片的同学也不用急着走,大体上都是可借鉴哒~ 本文主要实现使用SPI通信

    2024年02月08日
    浏览(43)
  • 【STM32篇】DRV8425驱动步进电机

    【STM32篇】4988驱动步进电机_hr4988-CSDN博客         在上篇文章中使用了HR4988实现了步进电机的驱动,在实际运用过程,HR4988或者A4988驱动步进电机会存在电机噪音太大的现象。本次将向各位友友介绍一个驱动简单且非常静音的一款步进电机驱动IC。         DRV8424/25 是适

    2024年04月11日
    浏览(44)
  • 【DRV8323】电机驱动芯片寄存器配置指南,通过STM32F407的SPI通信配置

    笔者计划使用一块使用到STM32F407控制芯片与DRV8323s驱动芯片的板子,驱动BLDC。了解到需要使用SPI通信来配置DRV8323s驱动芯片,配置过程中涉及DRV8323数据手册中提及的几个寄存器,故写此文做个记录。 另外,DRV8323芯片和DRV8302、DRV8303、DRV8353都有极大的相似之处,可以相互参考

    2024年02月02日
    浏览(52)
  • 【STM32】使用HAL库进行电机速度环PID控制,代码+调参

    主控:STM32F103C8T6 在进行速度控制之前,我们首先需要进行速度采样,这里参见这篇博文 ​ 这里不细说电机驱动模块的选型和使用,而是说一个常见的误区。我们驱动电机要使用两路PWM,一般是一路给PWM信号,一路是纯低电平。但这其实是不好的,正确的做法是一路给PWM,另

    2023年04月20日
    浏览(44)
  • STM32CubeMX 直流电机串级PID位置速度控制、HAL库、cubemx、PID、串级PID、位置控制、速度控制、双环控制

    提示:本文章的串级PID位置速度控制,是在前两篇文章速度控制,位置控制的基础上实现的,这一章节中不需要额外的cubemx的配置,只需要写简单的代码即可,复杂的地方在于串级pid的调试过程。 pid是我们在学习单片机中首先要学会的控制算法,而串级pid又是在单pid的基础上

    2024年02月14日
    浏览(41)
  • 使用Simulink代码生成工具基于STM32开发板对永磁同步电机进行开环控制

    代码链接:【免费】使用Simulink代码生成工具对永磁同步电机进行开环控制资源-CSDN文库 本文介绍使用Simulink代码生成功能在STM32开发板平台上运行永磁同步电机。 硬件基础: Nucleo-G431RB开发板 X-NUCLEO-IHM07M1驱动扩展板 57BLDC-24V-210W时代超群直流电机 软件基础: MATLAB 2022b 安装

    2023年04月14日
    浏览(51)
  • STM32基于HAL库的开发与应用(2)GPIO口控制

    一、GPIO口是在单片机开发应用中使用最频繁的一个控制。GPIO口可作为输出高低电平也可以作为输入检测输入电平的高低。 (1)通常GPIO口输出控制LED灯、有源蜂鸣器等一些只需要高低电平就可以触发的模块。 (2)通常GPIO口作为输入,用来检测输入电平的高低状态,常用于

    2024年02月11日
    浏览(28)
  • STM32机器人控制开发教程No.4 使用串口通信控制电机(基于HAL库)

    在机器人控制中,单片机(Arduino/STM32)与上位机(Raspberry Pi/NVIDIA Jetson nano)之间的通信经常采用串口通信的方式,那应该如何使用STM32的串口通信以及根据自己定义的协议来完成数据的接收与发送呢?在本篇文章中将给你演示如何通过自定协议来完成对电机的控制以及获取编码

    2023年04月25日
    浏览(43)
  • stm32 FOC系列 直流有刷控制原理

    1、直流有刷驱动板        使用三极管搭建的简易 H 桥电路,如图 5.3.1 所示:                  图 5.3.1 是使用三极管搭建的简易 H 桥电路,其中 MOTOR 表示直流有刷电机, Q1、 Q2、 Q3 和 Q4 为 4 个三极管,其中 Q1 和 Q3 接在了电源正极, Q2 和 Q4 接在了电源负极。 上

    2024年01月21日
    浏览(21)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包