1、创建仿真模型的基础配置

1.1打开matlab,先把当前工作目录设置为模型所在文件夹;

1.2打开simulink,创建一个空白工程;创建后在空白画布上点击右键,对模型的参数进行配置;

1.3求解器配置,仿真时间默认为10秒,可根据情况自行选择;求解器类型为定步长,离散型;求解器固定步长(基础采样时间)应与高频任务的采样周期保持一致,那么10K赫兹对应的时间就是0.0001s,在数据字典中定义个参数T_HF_TASK表示该时间;勾选将每个离散速率视为单独任务;勾选自动处理数据传输的速率转换;确定性数据传输选择从不(最小延迟);

速率转换模块的两个作用

1.4创建数据字典

点击建模下的模型资源管理器

点击文件,选择新建,选择数据字典,新建数据字典,为该数据字典命名,例如my123

点击design data,再点击添加,可以添加任意数据类型

设置高频任务时间,点击添加simulink参数快捷方式,把该参数命名为T_HF_TASK,值设为0.0001,点击应用;

1.5数据字典与模型关联

点击模型资源管理器,点击模型文件,点击模型文件的外部数据,点击浏览,在文件夹中找到刚才新建的数据字典.sldd格式,选择该数据字典进行应用;

现在数据字典就已经与模型关联起来了

1.6求解器测试

点击仿真下的库浏览器,进入untitled模型

从库里面选择一个阶跃信号

再选择一个输出信号和示波器

最终组成如下框图

点击仿真下的运行

可以点击示波器观测阶跃的输出信号

2、基于模型模版搭建自己的模型框架

2.1删除刚才的求解器测试模型,把模版模型复制到自己的模型画板上;

2.2把模版模型的数据字典叶复制到自己的模型上,点击外部数据

2.3点击浏览,把原来的数据字典替换为复制模型的数据字典,点击应用即可

2.4此时新的数据字典已经加入,旧的数据字典已经别替换,此时可以通过筛选框查找数据信号;

2.5配置好数据字典后,点击更新图,更新整个复制过来的模型

2.6svpwm和sin,cos函数的这些文件是C语言,通过脚本把它反编译为模型文件(mexw64),把这些文件复制到模型文件夹下(数据字典所在的文件夹下),更新图

2.7点击示波器观测波形,再点击运行,输出为仿真的相电流与机械速度;

3、代码生成的配置

3.1右键点击模型画布空白处,选择模型配置参数

3.2选择代码生成,系统的目标文件是嵌入式系统的要选择ert.tlc文件,工具链选择GUN TOOLS FOR ARM这是MATLAB自带的工具链,也可以选择Min GW64,效果是一样的;

3.3硬件实现,选择ARM的Cortex-M的通用内核

3.4优化等级选择最小值,不优化

3.5报告

3.6接口

代码替换库默认是没有的,可以选择cortex-m作为代码替换库,它生成的代码运行速度更快,

3.7点击代码生成

点击APP下的embedded coder

点击生成代码generate code

4、cube mx配置

4.1MCU资源分配

4.2PWM实现

arr决定了pwm的频率设置,ccr决定了占空比

rcr是重复计数寄存器,如果设置为0的时候,在一个PWM周期结束触发一次更细事件,同时触发更新中断;

电机绕组可以等效为一个电阻和一个电感,电感的特性是两端电压可以突变,电流不能突变;

在SVPWM的U0时刻进行采样,此时三相均有电流流过,且电流大小和方向不变;

虽然不能准确的指导U1是在哪个时刻切换成U0,但是整个扇区的总时间不变,可以确定U0的结束时刻,在U0的结束时刻采样;

4.3新建工程

点击file,选择新建工程

输入MCU型号

勾选内核与封装,选择芯片,点击开始工程

4.4时钟配置

在时钟配置前,先启用HSE和ADC

配置HSE为晶体或陶瓷振荡器,本开发板设置了一颗8M的外部晶振

打开ADC1和ADC2的0,1,2通道;

此时外部HSE和ADC已经不是灰色,可以进行配置了

从外部输入8M时钟,采用PLL经过9倍频,就得到了72M的PLL时钟,选择系统时钟为PLL时钟,HCLK就是APB高级外围总线的时钟,PCLK1的时钟最大36M,对APB1进行2分频,PCLK1就变成了36M,对ADC时钟进行6分频,就得到了12M的ADC时钟;

4.5System的配置

配置调试模式为SWD模式,系统的基准时钟设置为Systick

配置TIM1,也就是PWM输出,设置时钟源为内部时钟通道;

通道1和3设置为PWM互补输出,通道4设置为PWM不输出

参数设置,配置计数模式为中央对齐模式1,配置ARR等于3600(系统时钟72M,为了使PWM频率为10k),两个arr是一个PWM周期;

CKD配置为除以2,CKD表示死区时间的步长,

时钟周期是时钟频率的倒数。已知 TIMxCLK = 72MHz,则其时钟周期为:tCK_INT​=72 MHz1​=721000​ ns≈13.89 ns

而题目中 tDTS​=2×tCK_INT​,是因为定时器的 ** 死区时间时钟分频(CKD)** 配置为 2,即死区时间的时钟步长是内部时钟周期的 2 倍,因此:tDTS​=2×721000​ ns≈27.78 ns

RCR重复计数寄存器配置为1,这样每次上升溢出加上一次下降溢出产生一个更新事件;

OSSR表示当定时器不工作时,输出状态的选择,选择禁止的时候,输出将被禁止,当选择使能的时候输出处于关闭状态;本工程选择使能,它将具有更好的灵活性;

OSSI表示当定时器空闲时,输出状态的选择,配置为使能;

锁定等级配置为1;

死区时间配置为10,表示10乘以死区时间的步长;

TIM1配置总览

4.6PWM通道的配置

通道1和3采用默认配置,分别为PWM模式1;pulse就表示CCR,默认为0,运行过程中实时更新;

通道4设置为PWM模式2;CCR设置为3600-1,设置极性为高电平;

使能ADC1的更新中断

4.7ADC的配置

首先配置ADC1,选择独立模式,数据右对齐;使用注入转换,注入转换的优先级高于规则转换;

转换的数量配置为1,外部的触发源配置为TIM1的捕获比较4事件,转换模式设置为非连续模式;

转换通道配置为通道2(对应了A相电流采样),采样时间7.5个周期;

ADC2的配置,主要采样通道为1(B相电流的采样),其他的一致

“IN0、IN1、IN2 被勾选” 只是通道的 “硬件使能”,而 “Rank=1、Channel=1” 是注入转换模式下的 “逻辑采集配置”—— 只有被配置到 “转换序列(Rank)” 里的通道,才会真正被 ADC 采集。因此,虽然有 3 个通道被硬件使能,但由于注入转换只配置了 1 个采集通道(Rank=1、Channel=1),所以实际上只采集了 1 个通道。

如果需要同时采集 IN0、IN1、IN2,需将Number Of Conversions改为 3,并为每个通道分别配置Rank(如 Rank1=IN0、Rank2=IN1、Rank3=IN2)和对应的Channel

最后使能ADC的全局中断,ADC1和ADC2公用一个全局中断;

4.8TIM2的配置

将TIM2用作编码器的接口,时钟源选择内部时钟,组合通道选择编码器模式;

计数模式为向上计数,但实际上它是根据编码器的脉冲来向上计数或向下计数的;

计数周期也就是ARR设置为编码器一圈的总的脉冲数,因为我们用的编码器是用的2500,所以这里设置为10000-1;

设置计数模式为TI1和TI2同时计数;输入滤波为9;

开启TIM2的全局中断

4.9TIM3的配置

主要作为HALL传感器的接口,本工程暂时未用,仅做展示;

选择内部时钟,组合通道选择hall传感器模式;

计数模式为向上计数,计数周期65535,极性上升沿,输入滤波设置为11;

开启TIM3的全局中断

4.10USART1

串口1的配置,模式为异步通信,波特率为576000,8个数据位,1个停止位;

开启全局中断

4.11中断优先级配置管理

数字越小,优先级越高

配置system tick timer优先级为4;

配置tim1更新中断优先级最高为0;

配置ADC的全局中断优先级为2;

TIM2,TIM3,USART1优先级全部设置为3;

将TIM1更新中断设置为最高优先级,可以在它更新中断里使能ADC采样或者配置采样那几个ADC通道,

4.12工程配置及代码生成

保存工程

选择工具链IDE,这里选择MDK-ARM(也就是keil),选择固件库版本

勾选将所有的固件库复制到工程文件夹下;勾选为每个外设生成对应的.c或.h文件;勾选每次变更代码时保持用户代码不变;

最后点击生成代码

main.c文件展示

it.c展示

5、代码集成

将simulink模型代码和嵌入式框架代码接口放在一张图里面,方便直观理解集成过程

将高频任务放在ADC1_2的中断中(里面有电流环,进入ADC中断以为着采样完成,及时的获取反馈电流来调用电流环),将中频任务放在systick中进行周期调用;

手写代码的集成

集成后的工程框架

集成后的代码展示

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐