上一章讲了啥是有限状态机模型和LSM6DSOX的FSM的特点。
本章我将从FSM的编程模块到Unico FSM编程界面,分别介绍各个模块、
区域、变量的意义,为编写自己FSM状态机程序打个基础,下面我们开始吧。
上一帖中介绍了LSM6DSOX的FSM中一共有16个完全独立并资源相同的状态机程序块,
那么每个程序块长什么样子呢?
一个状态机程序块中包含了输入选择器和状态机代码块两部分。
输入选择器能够将传感器信号或者内部计算的数据信号中选择输入信号源,
所支持的信号如下:
- LSM6DSOX加速度计数据、加速度和 矢量的模。
- LSM6DSOX陀螺仪角速度数据、角速度和 矢量的模。
- 外部传感器(比如磁力计)数据,磁力和 矢量的模。
- 内部计算的角度、角度和 角度矢量和
- 正确配置的机器学习模块的输出。
其中,上述空间物理量和 矢量的模计算方法如公式:
怎么选择输入FSM信号源呢?这里就涉及到了一个命令“SINMUX”,用这个命令
就可以配置不同的数据到FSM的数据源端了,具体用法参考末尾的指令说明。
状态机代码块就是我们实现自己状态机的功能模块了,如下图所示,状态机代码块
由固定变量、可变变量、指令程序组成:
固定变量区位于程序块的最前端,长度固定6字节,一共6个变量,根据配置系统
自动更新,无需自己更改。
可变变量区位于固定变量区之后,长度随使用而改变,最长36字节,一共24个变量,
随用随设置。
指令程序区位于可变变量区之后,由条件和命令组成,控制输入选择器的命令
“SINMUX”就在这个区域内设置。
状态机代码块中的上述三个区域总长度最多256字节。每次上电时,
需要重新配置FSM代码块内容。
每个状态机代码块都可以根据输入的信号采样集数据,产生一个中断信号,
并且修改相应的FSM_OUTS寄存器状态。
指令代码保存在LSM6DSOX状态机程序块的可变变量区之后,由一系列实现
算法逻辑的状态组成。
每个指令都有一个8位的操作码,每个操作码可以实现一个命令指令(CMD)
或者条件指令(RESET/NEXT,RNC),它们被称为程序状态,多个指令在
一起组成FSM整体逻辑,其中:
- 命令指令(CMD),用于执行流控制、输出和同步等特殊任务,有的命令
会需要参数,参数会作为一个单独的指令来执行,后面详细讲。
- 条件指令(RESET/NEXT,RNC),由两个条件组合在一起(4位的RESET
条件和4位的NEXT条件),用来复位或者继续执行程序流。
指令代码对LSM6DSOX寄存器和状态机内部参数偶直接影响,有些指令
还可以产生额外的功能,比如更新状态信息等,下面分别介绍下命令指令和
条件指令的特点和使用方法。
命令指令(CMD)
命令指令是修改状态机行为中的流控制、输出、和同步的行为。
当一个命令被执行时,会立即执行(不需要更新输入采样集),程序指针(PP)
被设置为下一行,将执行如下动作:
- 如果新的一行是一个命令指令,则立即执行此行命令。
- 如果新的一行是一个条件指令,则在下一个输入采样值到来之时,
- 处理此行条件判断指令。
有些命令指令可能会需要参数,需要的参数必须在命令指令下一行定义。
这里用"STHR1"命令来举例,该指令用来动态改变阈值1(THRESH1)的值,
在Unico中的配置方法如下:
当程序指针(PP)指向状态S0的0x0A地址时,设备识别出"0xAA"指令码为"STHR1"命令。
该指令需要两个参数,那么设备就不等待新的输入采样集,直接运行S0-S2三个状态,
执行后阈值1的值将被设置为“0x5640”即小数“100.0”
条件指令(RESET/NEXT,RNC)
条件指令用于重置或者继续程序流,条件指令在一个新的输入采样集准备好后,
在一个单一状态下执行。
条件指令中用于重置判断的RESET条件定义在操作码的高4位,而用于判断继续的
NEXT指令定义在操作码的低4位,条件指令的执行逻辑如下图所示:
当进入条件指令后,首先判断重置条件(RESET),只有在RESET条件不满足时,
才判断继续条件(NEXT)。
当两个条件均不满足时,状态机会等待一个新的采样集到来,然后重新开始判断。
当满足RESET条件时,就会发生向复位点切换的状态过渡,即PP=PR。
当RESET条件不满足,且NEXT条件满足时,就会向下一个状态过渡,即PP = PP+1;
默认情况下,复位点(RP)被设置为第一个状态,但可以通过"SRP/CRP"指令动态改变
复位点的位置。
值得注意的是,RESET和NEXT条件为同一个条件的情况是没有意义的。
条件指令能够判断的条件一共有三种:
- 超时:当设置了定时器,定时计数器TC的值达到零的时候,条件满足,成立。
- 阈值比较:当启动的输入值高于(或低于)设定的阈值时,条件满足,成立。
- 过零检测:当启动的输入越过零位时,条件满足,成立。
以上就是命令指令和条件指令的所有特点了。
FSM指令集中一共提供了16个条件指令和35个命令指令。
我已经将所有指令集使用说明翻译成了中文,并排版做成了一个速查PDF,共享给大家使用。
UnicoGUI
上面讲了FSM程序块的结构和变量区,那怎么去编程呢?ST很贴心的出了一款
上位机-UnicoGUI,可以配置LSM6DSOX里的所有寄存器,FSM甚至可以直接
显示状态机图,下面我将详细介绍下UnicoGUI的FSM编程部分。
关于如何连接开发板和启动UnicoGUI软件,如果有问题可以参考 LSM6DSOX开
箱与体验“Port not open & not supported ”问题解决。这里默认大家都能
正常打开UnicoGUI软件了哈。
在Unico的主界面左侧,点开FSM模块,可以看到界面中一共有三个标签栏,
Configuration,Interrupt,Debug
默认的界面就是状态机设置、编程的界面,如下图所示。
在这个界面中我们可以看到有很多的按键和输入框,参考Unico上FSM使用.pdf文件中,
我标注了8个红框区域,逐一来看:
1、StateMachine Selection,状态机选择,这个下拉菜单中一共有16个选项,对应
的就是前面讲的16个独立的状态机程序块。
2、FSM_ODR,FSM频率(Output Data Rate),这个值在限制了加速度/角速度数据
传输到代码块的最高频率,建议是将加速度/角速度的输出频率高于这个值,也就
是在Unico主界面的Opitions中Accelerater output data rate和
Gyrocope Output data rate值高于FSM ODR的值,避免欠采样问题发生。
3、Long_Counter,16位计数器,一个最大可以计数65535的全局计数器,也就是
所有状态机程序块公用。
Max Value是设置计数器的最大溢出值,16位数据形式标志(例如65525填写FFFF),
底下两个勾选可以设置计数器溢出时是否产生INT1/INT2外部中断。
计数器的值可以从程序中使用“INCR”来增加。
4、Converter,格式转换,由于FSM中用的都是半精度浮点数HFP,
所以在这给我们提供了32位浮点数转16位浮点数、16位转32位的小工具。
5、SMx status,状态机x状态设置,这个区域有三个选项,Enabled用于启动状态机x,
只有勾选Enabled该状态机程序块才会工作。INT1 INT2分别将状态机的中断路由
到INT1、INT2外部中断上,16个状态机可以独立设置启动与否,绑定外部中断。
6、SMx Fixed Data Section,状态机x固定变量区,显示了6个变量和2个开关:
- ConfigA和configB中储存了程序所使用的的资源量
- Size 显示的是状态机总的字节数,图中由于没有配置任何资源,
所以显示的6字节为固定变量区大小。
- Setting中保存了当前程序状态,选择的掩码,选择的阈值,输入
信号等等。
- Reset Pointer(RP)复位点,储存了条件指令中返回判断(RESET)
为真所跳转的地址。
- Program Pointer(PP)当前运行程序点,储存了当前采样时间内
正在执行的指令的地址。
- Hysteresis ,回滞变量开关,启动该选项后,下方的Hysteresis
回滞变量可以设置。
- Decimation,降频变量开关,启动该选项后,下方的dest降频变量
可以设置。
上面的固定变量,在用UnicoGUI的时候这六个变量都是跟随编程操作自动更改的,
无需自行更改。
当我们想要直接使用LSMC6DSOX在自己的项目中的时候,则需要考虑设置其中的值。
7、SMx Variable Data Section,状态机x可变变量区,其中显示了24个变量,
共计36个字节,当我们用不到某些变量的时候,Unico就不会配置该变量到
状态机程序块中,也就不占用内存。其中黑色字体的就是可以设置的变量,
- Thresh1-3,阈值,在条件指令中,用来比较输入信号对应轴的数据是
否到达阈值。
- Hysteresis,回滞参数,当设置了回滞参数后,在对某轴进行阈值比较时,
会将比较值增加回滞参数变成一个比较区间,如下图所示。
- MasksA-C,轴选择掩码,用于指定输入数据的哪个轴进行阈值条件或
过零条件判断。
- Timer1-3,定时器值,在条件指令中,设置的定时器比较的时间值。
- Dest,降频因子,用来降低状态机处理传感器数据的频率,
将该状态机处理数据的频率降为FSM ODR/Dest。
- Decision Tree,机器学习决策树接口,通过“CHKDT”命令检查
机器学习核心内部的决策树结果,当FSM和机器学习结合的时候
就需要用到这个参数。
灰色字体的是没法直接设置的变量,
- Temporary MaskA-C,临时掩码,用来保存MasksA-C的复制值。
- DX,DY,DZ,DV,三轴角度、角度和矢量的模,显示的是当前传感器
角速度积分得到的角度值。
- DeltaT,角速度积分参数,角速度会乘上该值后积分乘角度值。
- PAS,Previous axis sign,上一个轴号,储存前一个采样的轴号,在
零点交叉条件下使用。
- DESC,内部计数器,在降频时使用,由设备自动管理。
- TC,Timer Counter,内部临时定时计数器,用于检测定时器是否
过期。
8、SMx Instructions Section,程序指令区,上图中这个区域只有四个按键,
分别是Add State 增加状态指令,Import State Machine导入状态机指令,
Export State Machine导出状态机指令和Reset State Machine重置状态机指令。
当点击Add State按键后,就可以增加一条状态指令,如下图所示
图中红框内容从左至右分别是:
- S0 状态号,随着状态指令增加,状态号依次递增
- 0x06 状态地址,也是随着状态指令增加而增长,Reset Pointer(RP)
复位点和Program Pointer(PP)当前运行程序点中的数据就是指这个
地址,首状态地址随前面固定变量和可变变量总长度而定,图中由于
只有6个固定长度,因此状态S0地址为0x06。
- RNC,Reset/Next conditions,选择该条状态为条件指令
- CMD,Commands,选择该条状态为命令指令
- 指令选择框,选择需要的指令
- 16进制指令码,所选指令的16进制形式
- Add,增加状态按钮,在此状态前增加状态
- Remove,删除状态按钮,删除此条状态。
在FSM模块的Interrupt界面下,分成了两个区域,如图所示。
左侧为输入加速度、角速度、输出外部中断INT1/INT2的波形图。
右侧为16个状态机的输出寄存器OUT_Sx的数据,通过点击read,可以读取当前的值。
在FSM模块的Debug界面下,也是分成了两个区域,如下图所示。
左侧为我们写的状态机图,通过分析它可以很清楚的看到我们的状态机状态是如何
改变的。
右侧为调试区域,通过导入采集的输入数据集,可以对左边的状态机进行仿真调试,
这里就先不细说了。
以上就是对LSM6DSOX中FSM编程模块各个模块和参数的基础认识,对这些有了初步的
认识和了解之后,我们就可以着手看看示例状态机程序,分析下其工作流程和编写流程了~
以下是35个命令指令和16个条件指令的简介截图,翻译文档我放在文章末尾了~:
命令指令
条件指令
指令集详细介绍的翻译文件放在下方了,大家有什么问题直接下方留言交流呀~