本期介绍的是六轴传感器6050,之前在网上CSDN上看了许多关于MPU6050的介绍,感觉许多都是空话,真正实用的东西并不多,下面该模块的程序我是先看的正点原子stm32单片机的例程之后一点一点移植到FPGA中的。这里只移植了初始化和读取陀螺仪原始数据部分的程序,关于DMP嘛,因为个人能力不够移植不了。
01六轴传感器
本期介绍的ATK-MPU6050是一款高性能三轴加速度加三轴陀螺仪的六轴传感器模块,该模块采用InvenSense公司的MPU6050芯片作为核心,该芯片内部整合了3轴陀螺仪和3轴加速度传感器,并可利用自带的数字运动处理器DMP硬件加速引擎,该模块与外界的通信方式为IIC协议,向应用后台输出姿态解算后的数据。
ATK-MPU6050模块自带DMP,通信协议为IIC、通信速率为400KHz、兼容3.3V和5V系统、陀螺仪和加速度测量维度均为3维。
02器件初始化
在使用MPU6050获取数据之前首先需要对MPU6050进行初始化。MPU6050与控制器之间的通信方式为IIC通信,所以也需要先例化IIC协议。
对于IIC协议的几个状态,此处我事先定义了几个参数,wr写状态,sta起始状态,rd读状态,sto停止状态,ack有应答,nack无应答。
然后便开始编写初始化MPU6050的时序,程序如下图所示,最上面那几行是复位后全部清零,en是一个计数器的使能端,en为0时停止计数,为1时开始计数。tx_data为IIC将要发送的数据寄存器。go为IIC通信的启动端。cmd为当前IIC状态的选择端,因为有时IIC通信中需要起始位或结束位有时不需要,这里的cmd便可以作为选择这些的端口。en_ms为毫秒计数的使能端。
首先要做的便是复位IIC,需要发送的数据有三部分,首先是发送器件ID和写命令,然后就是发送复位地址,最后便是发送复位数据。
下图为IIC写入第一个数据,器件ID和写命令,该模块的器件ID为0x68(在5V系统中),将其器件ID左移一位后与0进行按位与运算,0x68的二进制值为0110_1000,左移一位后便是1101_0000,与0进行按位与运算后还是自己本身,这便是IIC需要写入MPU6050的器件地址与写状态的值。
写入数据之前,首先设置状态cmd为起始信号sta和写状态wr,将sta与wr进行按位或便是选择执行这两项,sta与wr进行按位或后cmd的值便为6'b000_011。然后go赋值为1启动IIC,tx_data写入当前要传输的数据8'b1101_0000,然后跳转到下一个状态。
等tx_data寄存器内写入数据后便可以关闭go,将go端口置0。然后等待IIC一个字节发送成功的标志信号,当trans_done置1后表示IIC一个字节发送完成。
接着便开始发送下一个数据,写入复位地址,cmd选择写状态,此处不需要起始信号所以直接将wr的值赋给cmd,然后开启go将其置1,tx_data写入复位的地址,该地址为0x6B,在此处写为8'h6B,h表示十六进制,地址赋给tx_data寄存器成功后便可以关闭go将其置0,然后等待IIC一个字节发送成功,同样trans_done为1是IIC一个字节发送完成,这时便跳转置下一个状态。
复位地址发送完成之后便发送复位数据,同样的道理,先给cmd写入需要的状态,此处需要写状态wr和停止信号sto,将wr与sto进行按位或,cmd的值便为6'b001_001,复位数据为0x80,此处写为8'h80。
然后延时100ms。将en置1使能计数器,cnt_full为1时表示100ms计数值满,然后关闭en停止计数。
此部分便是100ms计数器的写法。
100ms延时之后复位MPU6050便结束了,然后便开始唤醒MPU6050。和上面一样,首先发送器件地址和写命令,即二进制的1101_0000。然后等待一次发送结束后便开始下一次发送,器件ID发送之后便是发送唤醒地址,该地址为8'h6B,唤醒地址发送完成之后便是发送唤醒数据0x00,这里我写的是8'h00。
详细步骤已经在第一部分详细阐述了,后面几乎都大同小异,首先是对cmd的状态进行选择,即有无起始信号或结束信号、是写命令还是读命令。然后便是需要写入的数据tx_data,一次数据写入完成之后标志信号trans_done置1后便可以跳转到下一次数据的发送或读取。
此处为陀螺仪量程设置,首先是发送器件地址和写命令,然后便是发送陀螺仪地址,该地址为8'h1B,然后设置的陀螺仪量程,这里量程设置为±2000dps所以需要发送的数据为八位的0001_1000。
接下来便是加速度计的量程设置,首先还是发送器件地址和写命令。然后便是发送加速度计的地址,该地址为8'h1C,地址数据发送完成之后便是发送设置加速度计量程的数据,这里加速度的量程设置为±2g,所以需要发送的数据为0x00。
然后便是配置数字低通滤波器的采样率,首先发送器件地址和写命令,然后写入采样频率分频器地址0x19。因为这里配置的是数字低通滤波器的采样率为50HZ,所以发送的数据便为1000/50-1=19,最后发送设置采样率的参数为十进制的19。
设置完采样率后还需配置数字低通滤波频率,此处我们设置为采样率的一半,即25HZ,首先还是先发送器件地址和写命令,然后发送配置寄存器地址0x1A,最后是配置数字低通滤波频率的数据即发送十进制数据4。
然后是关闭使能中断,首先还是发送器件地址和写命令,然后发送使能中断地址8'h38,最后发送关闭使能数据8'h00。
关闭使能中断后便是设置IIC主模式,首先发送器件地址和写命令,然后发送控制寄存器地址8'h6A,最后发送关闭IIC主模式命令8'h00。
关闭FIFO,首先也是发送器件地址和写命令,然后发送FIFO使能寄存器地址8'h23,最后发送关闭FIFO命令8'h00。
然后便是配置INT端口,此处INT需为低电平有效,首先还是先发送器件地址和写命令,然后写中断/旁路设置寄存器地址8'h37,最后发送数据8'h80对INT进行设置。
接下来便需要读取器件ID,用来检测上诉配置是否正确以及MPU6050是否初始化成功。首先还是先发送器件地址以及写命令二进制数据1101_0000,然后写入器件ID寄存器地址0x75,然后便需要配置读命令了,器件ID 0x68左移一位之后与1进行按位与运算,运算结果为8'h1101_0001,该值变为器件地址和读命令,然后cmd配置为rd | sto,读取状态与停止信号按位或运算,cmd的值为6'b001_100,IIC通信的SDA数据端便开始读取IIC传输过来的数据,读取结束之后IIC产生一个结束位,此次读取便结束了。然后便开始验证读取到的器件ID是否正确,若读取的器件ID正确则开始进行下一步。
读取的数据ID存储在rx_data这个8位的寄存器中,读取结束后便判断读取的对不对,若读取的ID正确便可以进行下一步配置,初始化即配置完成。
首先是设置CLKSEL、PLL的X轴为参考,先发送器件地址和写命令,然后便发送设置管理寄存器的地址8'h6B,最后便是发送配置的数据8'h01。
然后便是配置加速度与陀螺仪都工作,首先还是先发器件地址与写命令,然后发送管理地址8'h6C,最后发送配置数据8'h00。
这里需要再次设置一下数字低通滤波器的采样率与滤波频率。设置方式与参数和上面一模一样。采样率为50Hz,滤波频率为采样率的一半。
03数据的读取
然后便可以开始读数据了,这里我读的是三轴陀螺仪的数据,三轴加速度的数据读取和这个是一样的。
这里我在初始化成功后延时了400ms,然后发送了器件地址和写命令,然后写入读取陀螺仪值的地址8'h43,然后便是写入器件地址和读数据,即器件地址左移一位后与1进行按位或运算,运算得到的值为8'b1101_0001。接下来便可以开始读取数据了。
此处读取数据一共有6组,理论上三轴传感器即X轴Y轴Z轴的数据应该是3组数据,这里之所以是6组数据是因为这三组数据都是16位的,而IIC读取的数据都是8位的,所以相当于将这三组数据拆开读的,先读一组数据的前八位再读这组数据的后八位,所以才有6组数据,上图中程序的最后面便是将这6组数据重新组合成三组数据。