NXP文档AN13000解读-基于S32K116的无感BLDC六步换相控制策略(预定位/开环启动/反电动势过零点检测)

目录

六步换相控制

单极性PWM

反电动势过零点检测技术

反电动势的测量

总线电流的测量

电机状态切换

Alignment

Start-up

Run

算法用到的各模块

各模块间的连接

ADC触发顺序

芯片的初始化

时钟配置与电源管理

FTM

Trigger MUX Control (TRGMUX)

PDB

ADC

LPSPI

LPUART

LPIT

引脚分配

软件架构

电机三状态

状态机

定时器与中断

过零点检测算法

转速估计、电流PI限制


针对三相无位置传感器BLDC控制

可实现:

  • 六步换相
  • 反电动势过零点检测或者霍尔传感器获取转子位置
  • 总线电压、电流、BEMF传感器
  • 通过霍尔或者BEMF获取转子速度
  • 直流母线过压、欠压、过流、过载、启动故障保护

无感电机控制获取转子位置常用方法有哪些:

  • 反电动势过零点检测技术
  • Flux level detection method我理解着时磁链的意思
  • 各种类型的观测器技术(滑膜、卡尔曼、龙博格……)
  • 信号注入

从控制角度来看:

  • 换向控制,即根据转子位置给各相通电,并采用 准方形的电流波形
  • 速度/转矩控制,即控制应用于各相的准方形电流波形的振幅,以实现所需的速度/转矩性能。

六步换相控制

又称为方波控制,某一时刻任意两相打开,另一相产生反电动势。

单极性PWM

该技术包括了换相控制与扭矩控制。

MOS管的开关状态决定换相占空比决定扭矩

具体模式:一相互补PWM输出,一相接地,一相断电

反电动势过零点检测技术

从图里面可以看出来,在反电动势过零点之后,延迟30°电角度,进行换相。

断电那一相的相电压为:

我们要找出的就是uc为0的时候,因此比较ec一半总线电压值,既可得到过零点时刻。

在速度不变的情况下,两个过零点之间的时间就是换相周期(60°)。

反电动势的测量

BEMF的测量应在(使用PWM互补输出)某相上桥臂 高电平时刻:如下图绿色部分

需要注意的是,根据电机和功率级参数的不同,电压振铃的振幅、周期和阻尼都会发生变化。因此,建议在靠近窗口的末端测量BEMF电压。这个样本点的时间也需要存储,因为它被用来增强过零检测。

如果出现了下面这个情况怎么办?

过零点出现在了 ADC相邻两个采样点之间,此时将无法准确获取过零点时刻,怎么办?

使用方法:近似插值法

总线电流的测量

为了直接获得直流母线电流的平均值,则必须在PWM中间来测量。

电机状态切换

Alignment

预定位,把转子拉到指定位置上。

方式:C上桥臂打开,A、B下桥臂打开。

Start-up

强制换相,换向周期由一个开环启动曲线控制

转速达到额定转速5%时,产生可识别的BEMF电压时,进行切换。

Run

算法用到的各模块

电控算法会用到的芯片外设:

  • 定时器FlexTimer Module (FTM)
  • 复用触发器Trigger MUX Control (TRGMUX)
  • 可编程延迟模块Programmable delay block (PDB)
  • 采样Analogue-to-Digital Converter (ADC)

各模块间的连接

从上往下看上图:蓝色部分属于无感

  • FTM1用于换相,被配置成计时器,对BEMF进行过零点检测
  • 使用FTM0 PWM初始化触发器init_trig或者外部触发器ext_trig
  • FTM0触发信号通过TRGMUX触发PDB0模块,PDB0模块又与ADC0模块配合工作

S32K116与预驱芯片MC34GD3000之间的配合部分有四个:

  • 两者之间通过低功耗的SPI LPSPI0通信
  • PWM信号
  • PTA11对GD3000故障检测信号
  • 总线电流的采样

ADC触发顺序

还是从上往下,从左往右看这个图:

  • FTM1 init_trig信号触发换相事件;同时通过TRGMUX触发FTM0,使其计数器清零;同时FTM0 PWM初始化触发PDB0计数器,PDB0达到自己第一个预触发延迟值时,启动第一个ADC0采样,这里第一个采样的是总线电流
  • 总线电压与反电动势的采样在PWM高电平快结束时进行连续采样
  • ADC0转换完成中断通知CPU后,进行过零点检测

芯片的初始化

打开示例代码,找到main.c文件main()函数,首先看到就是芯片的初始化函数:

/* MCU peripherals initialization */
McuClockConfig();
McuPowerConfig();
McuIntConfig();
McuTrigmuxConfig();
McuPinsConfig();
McuLpuartConfig();
McuLpitConfig();
McuAdcConfig();
McuPdbConfig();
McuFtmConfig();

时钟配置与电源管理

RUN模式下的时钟频率:Fast Internal Reference Clock (FIRC)

配置如下:

/*******************************************************************************
*
* Function: 	void McuClockConfig(void)
*
* Description:  This function installs the pre-defined clock configuration table
* 				to the clock manager. For details see clockMan1 configuration
* 				in Processor Expert.
*
*******************************************************************************/
void McuClockConfig(void)
{/* Clock configuration for MCU and MCU's peripherals */CLOCK_SYS_Init(g_clockManConfigsArr,CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr,CLOCK_MANAGER_CALLBACK_CNT);/* Clock configuration update */CLOCK_SYS_UpdateConfiguration(0, CLOCK_MANAGER_POLICY_FORCIBLE);
}

电源配置:

代码:

/*******************************************************************************
*
* Function: 	void McuPowerConfig(void)
*
* Description:  This function configures the Power manager for operation.
* 				For details see pwrMan1 configuration in Processor Expert.
*
*******************************************************************************/
void McuPowerConfig(void)
{/* Power mode configuration for RUN mode */POWER_SYS_Init(&powerConfigsArr, 0, &powerStaticCallbacksConfigsArr, 0);/* Power mode configuration update */POWER_SYS_SetMode(0, POWER_MANAGER_POLICY_AGREEMENT);
}
/* ************************************************************************** Configuration structure for Power Manager Configuration 0* ************************************************************************* */
/*! @brief User Configuration structure power_managerCfg_0 */
power_manager_user_config_t pwrMan1_InitConfig0 = {.powerMode = POWER_MANAGER_RUN,                                  /*!< Power manager mode  */.sleepOnExitValue = false,                                       /*!< Sleep on exit value */
};        /*! @brief Array of pointers to User configuration structures */
power_manager_user_config_t * powerConfigsArr[] = {&pwrMan1_InitConfig0
};
/*! @brief Array of pointers to User defined Callbacks configuration structures */
power_manager_callback_user_config_t * powerStaticCallbacksConfigsArr[] = {(void *)0};

FTM

FlexTimer module (FTM) 16为计数器,功能强大:向上计数模式、死区插入、故障注入……

中心对齐模式,6个互补的通道生成中心对齐PWM

换相用的FTM1配置如下:

代码:

void McuFtmConfig(void)
{/* FTM1 initialized as a simple up-counting timer */FTM_DRV_Init(INST_FLEXTIMER_MC0, &flexTimer_mc0_InitConfig, &stateMc0);/* init FTM1 counter */FTM_DRV_InitCounter(INST_FLEXTIMER_MC0, &flexTimer_mc0_TimerConfig);/* FTM0 module initialized as PWM signals generator */FTM_DRV_Init(INST_FLEXTIMER_PWM0, &flexTimer_pwm0_InitConfig, &statePwm0);/* FTM0 module PWM initialization */FTM_DRV_InitPwm(INST_FLEXTIMER_PWM0, &flexTimer_pwm0_PwmConfig);/* Mask all FTM0 channels to disable PWM output */FTM_DRV_MaskOutputChannels(INST_FLEXTIMER_PWM0, PWM_CHANNEL_GROUP, false);/* Set FTM0SYNCBIT to trigger and update FTM0 registers */SIM->FTMOPT1 |= SIM_FTMOPT1_FTM0SYNCBIT_MASK;
}

Trigger MUX Control (TRGMUX)

FTM0初始化触发信号init_trig触发PDB0模块,必须指定TRGMUX_PDB0寄存器的选择位字段SEL0来定义触发源。

在后面找到了:

PDB

无感六步换相中需要配置的PDB:

表中,第二行 总线电流采样,在PWM高电平正中间(50%)

第三行,第四行总线电压与反电动势,都尽量在PWM高电平后期(80%处进行采样),可使用背对背模式,在采集完总线电压后,直接采集反电动势。

PDB预触发器也可以配置为背靠背模式工作,当ADC转换完成时触发下一个PDB通道预触发器和触发输出。

pdb_delay0是一个静态值,在初始化的时候就可定义。

pdb_delay1则需要计算:

[100,1200]的限制,100主要防止在占空比比较小的时候,与 pdb0_ch0_pretrig1发成碰撞;同样考虑到ADC的转换时间1.1us左右。

配置如下:

代码:

pre-trigger0直接设置为0,在PWM高电平开始时,就直接采样总线电流.

pre-trigger1设置应该是实时的,根据占空比的变化而变化,80%,但在初始化的时候应该设置一个最小值100。

pre-trigger2设置成背靠背模式,只要pre-trigger1转换完成,就直接进行反电动势的采样。

void McuPdbConfig(void)
{/* PDB0 module initialization */PDB_DRV_Init(INST_PDB0, &pdb0_InitConfig0);/* PDB0 CH0 pre-trigger0 initialization */PDB_DRV_ConfigAdcPreTrigger(INST_PDB0, 0, &pdb0_AdcTrigInitConfig0);/* PDB0 CH0 pre-trigger1 initialization */PDB_DRV_ConfigAdcPreTrigger(INST_PDB0, 0, &pdb0_AdcTrigInitConfig1);/* PDB0 CH0 pre-trigger1 initialization */PDB_DRV_ConfigAdcPreTrigger(INST_PDB0, 0, &pdb0_AdcTrigInitConfig2);/* Set PDB0 modulus value set to half of the PWM cycle */PDB_DRV_SetTimerModulusValue(INST_PDB0, HALF_PWM_MODULO);/* PDB0 CH0 pre-trigger0 delay set to sense DC bus current in the middle of the PWM cycle */PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB0, 0, 0, 0);/* PDB0 CH0 pre-trigger1 delay set to sense DC bus voltage towards the end of the active PWM pulse *//* BEMF voltage will be automatically triggered after DC bus voltage conversion is completed */PDB_DRV_SetAdcPreTriggerDelayValue(INST_PDB0, 0, 1, PDB_DELAY_MIN);/* Enable PDB0 prior to PDB0 load */PDB_DRV_Enable(INST_PDB0);/* Load PDB0 configuration */PDB_DRV_LoadValuesCmd(INST_PDB0);
}

ADC

在不同的扇区对不同的相进行反电动势采样。

配置

代码:

基本参数配置

/*! adConv0 configuration structure */
const adc_converter_config_t adConv0_ConvConfig0 = {.clockDivide = ADC_CLK_DIVIDE_1,.sampleTime = 12U,.resolution = ADC_RESOLUTION_12BIT,.inputClock = ADC_CLK_ALT_1,.trigger = ADC_TRIGGER_HARDWARE,.pretriggerSel = ADC_PRETRIGGER_SEL_PDB,.triggerSel = ADC_TRIGGER_SEL_PDB,.dmaEnable = false,.voltageRef = ADC_VOLTAGEREF_VREF,.continuousConvEnable = false,.supplyMonitoringEnable = false,
};const adc_chan_config_t adConv0_ChnConfig0 = {.interruptEnable = false,.channel = ADC_INPUTCHAN_EXT3,
};const adc_chan_config_t adConv0_ChnConfig1 = {.interruptEnable = false,.channel = ADC_INPUTCHAN_EXT12,
};const adc_chan_config_t adConv0_ChnConfig2 = {.interruptEnable = true,.channel = ADC_INPUTCHAN_EXT13,
};

sector 0,3 -> ADC0_SE13 -> Phase C voltage measurement

sector 1,4 -> ADC0_SE14 -> Phase B voltage measurement

sector 2,5 -> ADC0_SE9 -> Phase A voltage measurement

ADC0_SE3 -> DC bus current measurement

ADC0_SE12 -> DC bus voltage measurement

void McuAdcConfig(void)
{/* ADC0 module initialization */ADC_DRV_ConfigConverter(INST_ADCONV0, &adConv0_ConvConfig0);ADC_DRV_AutoCalibration(INST_ADCONV0);/* ADC0_SE3 input channel is used for DC bus current sensing */ADC_DRV_ConfigChan(INST_ADCONV0, 0, &adConv0_ChnConfig0);/* ADC0_SE12 input channel is used for DC bus voltage sensing */ADC_DRV_ConfigChan(INST_ADCONV0, 1, &adConv0_ChnConfig1);/* ADC0_SE9, ADC0_14, ADC0_13 input channel is used for BEMF voltage sensing */ADC_DRV_ConfigChan(INST_ADCONV0, 2, &adConv0_ChnConfig2);
}

LPSPI

TPP配置并控制GPIO引脚,以启用/禁用或重置应用程序中的MC34GD3000。

void GD3000_Init(void)
{/* GD3000 pin configuration - EN1:PTA3 EN2:PTA3 & RST:PTA2 */tppDrvConfig.en1PinIndex 	= 3U;tppDrvConfig.en1PinInstance = instanceA;tppDrvConfig.en2PinIndex 	= 3U;tppDrvConfig.en2PinInstance = instanceA;tppDrvConfig.rstPinIndex 	= 2U;tppDrvConfig.rstPinInstance = instanceA;/* GD3000 device configuration */tppDrvConfig.deviceConfig.deadtime = 	INIT_DEADTIME;tppDrvConfig.deviceConfig.intMask0 = 	INIT_INTERRUPTS0;tppDrvConfig.deviceConfig.intMask1 = 	INIT_INTERRUPTS1;tppDrvConfig.deviceConfig.modeMask = 	INIT_MODE;tppDrvConfig.deviceConfig.statusRegister[0U] = 0U;tppDrvConfig.deviceConfig.statusRegister[1U] = 0U;tppDrvConfig.deviceConfig.statusRegister[2U] = 0U;tppDrvConfig.deviceConfig.statusRegister[3U] = 0U;tppDrvConfig.csPinIndex = 5U;tppDrvConfig.csPinInstance = instanceB;tppDrvConfig.spiInstance = 0;tppDrvConfig.spiTppConfig.baudRateHz = 	  LPSPI_FREQ;tppDrvConfig.spiTppConfig.sourceClockHz = 48000000U;TPP_ConfigureGpio(&tppDrvConfig);TPP_ConfigureSpi(&tppDrvConfig, NULL);TPP_Init(&tppDrvConfig, tppModeEnable);//TPP_Deinit(&tppDrvConfig);
}

LPUART

UART作为FreeMASTER运行时调试和可视化工具之间的通信接口,也需要配置一下

配置的时候注意这几个参数就可以:

代码 波特率38400,8位,1个停止位

void McuLpuartConfig(void)
{/* LPUART module initialization */LPUART_DRV_Init(INST_LPUART0, &lpuart0_State, &lpuart0_InitConfig0);
}
const lpuart_user_config_t lpuart0_InitConfig0 = {.transferType = LPUART_USING_INTERRUPTS,.baudRate = 38400U,.parityMode = LPUART_PARITY_DISABLED,.stopBitCount = LPUART_ONE_STOP_BIT,.bitCountPerChar = LPUART_8_BITS_PER_CHAR,.rxDMAChannel = 0U,.txDMAChannel = 0U,
};

LPIT

中断主要用来控制电机速度,电流。

每1ms产生一个中断

配置

我理解这里的1ms中断进行速度控制,意思是说,速度的更新速度

/*******************************************************************************
*
* Function: 	void McuLpitConfig(void)
*
* Description:  This function configures LPIT module.
* 				For more details see configuration in Processor Expert.
*
* Note: 		Speed control of the BLDC motor is executed in LPIT interrupt
* 				routine every 1ms.
*
*******************************************************************************/
void McuLpitConfig(void)
{/* LPIT module initialization */LPIT_DRV_Init(INST_LPIT1, &lpit1_InitConfig);/* LPIT channel0 initialization */LPIT_DRV_InitChannel(INST_LPIT1, 0, &lpit1_ChnConfig0);}
/*! Global configuration of lpit1 */
const lpit_user_config_t lpit1_InitConfig =
{.enableRunInDebug = false,         /*!< true: LPIT run in debug mode; false: LPIT stop in debug mode */.enableRunInDoze = false           /*!< true: LPIT run in doze mode; false: LPIT stop in doze mode */
};/*! User channel configuration 0 */
lpit_user_channel_config_t lpit1_ChnConfig0 =
{.timerMode = LPIT_PERIODIC_COUNTER,.periodUnits = LPIT_PERIOD_UNITS_MICROSECONDS,.period = 1000U,.triggerSource = LPIT_TRIGGER_SOURCE_INTERNAL,.triggerSelect = 0U,.enableReloadOnTrigger = false,.enableStopOnInterrupt = false,.enableStartOnTrigger = false,.chainChannel = false,.isInterruptEnabled = true
};

引脚分配

配置

FTM0

ADC0

SPI

UART

TRGMUX

还有一些GPIO口的配置:复位、片选、按键……

软件架构

框图

两部分逻辑:

  • 换相控制,通过反电动势过零点检测确定换相事件,并为下一次换相做准备
  • 速度/扭矩控制,速度PI通过控制占空比控制速度

电机三状态

还是三个状态来启动:alignment state、 open-loop start state、 the run state。

  • 外设初始化完成,进入alignment state
  • alignment state状态下,转子会被稳定在一个已知的位置上(预定位),以便在两个旋转方向上产生相同的启动扭矩(实现方式:C相PWM信号,AB相占空比为0,也就是接到负极)
  • 当alignment时间到达后,进入open-loop start,这时候转速比较低,是没办法进行反电动势过零点检测的。
  • 当开环转速达到额定转速的5%时,进入闭环run state

状态机

INIT,PWM占空比和直流总线电流偏移校准的初始配置,之后状态机将转换到STOP状态。

STOP, appSwitchState variable = 1切换到CALIB

CALIB,提供直流总线电流校准,之后进入ALIGNMENT

ALIGNMENT,在BLDC appconfig.h可以查看具体的预定位占空比,和预定位持续时间

START,该状态下,属于强制换相,换相周期由STARTUP_CMT_PER控制;电机加速度由START_CMT_ACCELER控制;该状态下的换相次数由STARTUP_CMT_CNT控制

完成换相次数后,进入RUN

RUN,反电动势过零点检测,闭环

FAULT,故障检测,过压、欠压、过流、GD3000故障

定时器与中断

这部分有些不理解?

过零点检测算法

转速估计、电流PI限制

极对数:

电机每相可以有多个极对,每相的极对数定义了电旋转和机械旋转之间的比率

原文档下载地址

https://www.nxp.com.cn/docs/en/application-note/AN13000.pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/13043.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计团队管理秘籍:打造高效团队的必备技巧!

一个成功的设计团队取决于正确的人员、良好的沟通和高效的流程。作为设计团队的经理&#xff0c;你有责任确保团队的所有成员都能很好地合作&#xff0c;并有效地产生预期的结果。这里有一些关于如何管理好一个设计团队的技巧。 1、雇佣正确的人: 当你组建你的设计团队时&#…

依次判断数组中的各元素是否以指定后缀作为结尾numpy.char.endswith()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 依次判断数组中的各元素 是否以指定后缀作为结尾 numpy.char.endswith() [太阳]选择题 下列代码最后输出的结果是&#xff1f; import numpy as np s np.array([teacher, student]) print(&…

【雕爷学编程】Arduino动手做(154)---AFMotor电机扩展板模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

创建台虚拟机并安装上window10系统(NETBASE 第一课)

虚拟机&#xff08;Virtual Machine&#xff09;是一种基于软件的模拟技术&#xff0c;它可以将一台物理计算机模拟成多个虚拟计算机运行不同的操作系统和应用程序&#xff0c;从而实现资源的虚拟化和隔离。在虚拟机中&#xff0c;每个虚拟计算机都拥有自己的独立的操作系统和应…

aidl原理

aidl 流程 为了方便理解&#xff0c;先将binder看做是一个黑盒子 aidl的流程图如下 demo连接添加链接描述 Androidstudio 会帮我们生成emotionAidlService&#xff0c;具体目录在n\build\generated\aidl_source_output_dir\debug\out\com\example\emotion\emotionAidlServic…

web安全php基础_php之string对象详解

PHP 字符串 字符串变量用于包含有字符的值。 在创建字符串之后&#xff0c;我们就可以对它进行操作了。您可以直接在函数中使用字符串&#xff0c;或者把它存储在变量中。 在下面的实例中&#xff0c;我们创建一个名为 txt 的字符串变量&#xff0c;并赋值为 “Hello world!…

【数据仓库】Apache Doris介绍

Apache Doris介绍 Apache Doris应用场景 Apache Doris核心特性 Apache Doris架构 Doris数据模型三种 Aggregate模型介绍 Uniq模型介绍 在某些多维分析场景下,用户更关注的是如何保证Key的唯一性Key 唯一性约束。因此&#xff0c;我们引入了 Unig 的数据模型。该模型本质上是聚…

【Go】Go 语言教程--GO条件和循环语句(八)

往期教程&#xff1a; Go 语言教程–介绍&#xff08;一&#xff09;Go 语言教程–语言结构&#xff08;二&#xff09;Go 语言教程–语言结构&#xff08;三&#xff09;Go 语言教程–数据类型&#xff08;四&#xff09;Go 语言教程–语言变量&#xff08;五&#xff09;Go …

新版Grafana仪表盘

一 Grafana 是什么 Grafana 是一个开源的指标量监测和可视化工具&#xff0c;常用于展示基础设施的时序数据和应用 程序运行分析。 官网指路&#xff1a; https://grafana.com/ 与前文相关的两个概念&#xff1a; 1&#xff09;数据源&#xff08;Datasource&#xff09;&…

电池SOC和动力电池OCV功率联合估计研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

(Windows版)PostgreSQL - TimescaleDB插件的2种安装方法

一&#xff1a;下载pgsql相对应的timescaledb插件包 下载地址&#xff1a;https://github.com/timescale/timescaledb/releases/tag/2.10.1 二&#xff1a;开始安装 注意&#xff1a;在安装前&#xff0c;先关闭PostgreSQL 服务 方法一 1.【控制面板\系统和安全\管理工具\…

图像金字塔、滑动条、鼠标事件响应

1、拉普拉斯图像金字塔 1.1 原理 1.2 实现 //拉普拉斯图像金字塔 void test1() {//高斯图像金字塔构建Mat img imread("F:/testMap/lena.png");vector<Mat> Guass;int level 3;Guass.push_back(img);for (int i 0; i < level; i){Mat guass;pyrDown(Gua…