初学rt thread, 目标STM32F103C8T6最小系统板通过I2C读取MPU6050的数据,查找了很多文档都没成功。经过摸索需要在系统中增加I2C外设,本文主要描述如何在STM32F103C8T6最小系统BSP的基础上增加I2C外设,实现读取MPU6050的数据。
自己设计的两轮平衡车主板(大都用现成模块,就是把模块组合起来而已)。采用常见的STM32F103C8T6最小系统板 + MPU6050模块(如下图):
硬件连线如下,使用STM32F103C8T6最小系统的I2C1(PB8,PB9)分别连接MPU6050模块的SCL,SDA引脚。
事实上已经基于这套硬件,采用HAL实现了MPU6050数据的读取,硬件工作正常的。本节先验证rt thread的STM32F103C8T6最小系统BSP能否正常跑起来。后续增加I2C的工作都是以这个为基础。
请参考rt thread文档,不赘述。此处下载的rt thread版本是4.0.2
上一步骤下载rt thread版本是master版本的源码,个人不习惯直接进入源码目录做改动,因此先生成一个发布工程,搭建好项目框架,生成项目开发目录结构(RT-Thread 源码位于项目文件夹内,而不是 BSP 的上两级),此时生成的发布工程,可以随意拷贝到任何目录下运行,它是包含rt thread及选定BSP底层驱动包的一个完整包。
进入bsp\stm32\stm32f103-mini-system目录,在env下执行:
$ scons --dist
命令执行后,在当前目录下会创建一个名为dist的目录,dist目录中有一个压缩文件和一个文件夹,他们的内容是完全一样的。
将stm32f103-mini-system文件夹COPY到其他地方,比如直接COPY到F:\下。后续操作均在F:\ stm32f103-mini-system文件夹下操作。Rt thread源码目录不做其它任何改动。
进入F:\ stm32f103-mini-system文件夹,双击project.uvprojx打开项目。进入魔术棒 Debug选项,选择ST-Link Debugger
进入setting 设置 Flash Download 选中 Reset and Run
编译下载,正常的话STM32F103C8T6最小系统绿色的灯(连接在PC13)会闪烁(见1.1节图)。
该BSP默认将调试信息通过USART1输出:
至此,rt thread的STM32F103C8T6最小系统BSP能正常跑起来,工作正常。从设备使用看,该BSP使用了UART1,PIN两种设备
stm32f103-mini-system这个版本的BSP所支持的外设如下图所示,并不支持I2C,而MPU6050需要使用I2C。因此首先需要在BSP中增加I2C外设。
增加I2C外设,可参考下面这个官方文档:https://github.com/RT-Thread/rt-thread/blob/master/bsp/stm32/docs/STM32%E7%B3%BB%E5%88%97%E5%A4%96%E8%AE%BE%E9%A9%B1%E5%8A%A8%E6%B7%BB%E5%8A%A0%E6%8C%87%E5%8D%97.md
这个文档的范例是基于CubeMX增加外设的,在文档5.2节有如下描述:
由于I2C采用的是端口模拟的方式,并未采用硬件I2C,因此增加I2C外设不必按指导文档中说明的采用CubeMX方式配置。上表中“依赖PIN驱动,无需任何操作” 是指无需CubeMX中任何操作。其实要增加I2C还是要一系列操作的(千万别被“无需任何操作”误导!!!):
打开F:\stm32f103-mini-system\board目录下的Kconfig 文件,在其中增加如下红色框中的代码。
这段代码中的参数说明如下:
1)BSP_USING_I2C1 --- 其中的I2C1根据硬件连接决定,硬件连接到I2CX,则此处写I2CX。根据1.2节设计,我们采用的是I2C1
2)comment "Notice: PB8 --> 24; PB9 --> 25" --- 此处根据 1)中选择的I2CX设置其对应引脚。比如此处我的板子使用I2C1,采用的是PB8, PB9(不是默认的PB6, PB7)。对应的24,25 序号是rt thread对芯片引脚的一种编码方式,可在drv_gpio.c中查找,如下图显示PB8(I2C1_SCL),PB9(I2C1_SDA)分别对应引脚编号为24,25
修改完成后保存Kconfig文件。查看一下现在项目中的文档,如下图红框内,可发现没任何有关I2C的文件。继续后面的操作,会发现一些变化。
上一步我们修改了F:\stm32f103-mini-system\board\Kconfig文件,接下来要使能I2C外设
On-Chip Peripheral Drivers中使能I2C1
进入F:\stm32f103-mini-system目录,在env中打开menuconfig,可以发现在
Hardware Drivers Config --->On-Chip Peripheral Drivers 下新增了I2C1 BUS选项,如下图
选中Enable I2C1 BUS(software simulation), 按回车会出现下图的详细说明(其实就是在Kconfig中配置的哦)
RT Thread Components--->Device Drivers 中选中Using I2C device drivers, 同时 选中 Use GPIO to simulate I2C
menuconfig修改后注意save,然后重新生成工程,执行如下两个命令
再次打开工程项目,进入bsp\stm32\stm32f103-mini-system目录,打开project.uvprojx 文件。可以发现已经新增了如下红框中与I2C相关的文件
编译一下项目,此时在Applications下会出现很多.h文件,如下图
打开rtconfig.h文件,检查是否已经包含红框中I2C相关的代码
进入魔术棒 Debug选项,选择ST-Link Debugger,再次编译下载。查看串口输出,可以欣喜的发现I2C1 已经成功加入到device列表中。
读取MPU6050数据部分的程序,直接参考《应用笔记:RT-Thread I2C设备应用指南》,
链接https://www.rt-thread.org/qa/thread-6982-1-1.html
将链接中的drv_mpu6050.h, drv_mpu6050.c两个文件添加进项目,如下图:
在drv_mpu6050.c 中修改如下两处:
其中 #define MPU6050_ADDR 0X68 需要根据硬件设计来确定地址,按1.2节硬件连线,地址为0X68
#define MPU6050_I2CBUS_NAME "i2c1" 其中的I2C1就是我们在BSP中增加的I2C设备,特别注意名称与BSP中增加的一致.
然后将main.c改为如下代码:
#include
#include
#include "drv_mpu6050.h"
void mpu6050_thread_entry(void *parameter)
{
rt_int16_t temp; //温度
rt_int16_t gx,gy,gz; //三轴加速度
rt_int16_t ax,ay,az; //三轴角速度
rt_err_t ret;
while(1)
{
ret = mpu6050_temperature_get(&temp);
if (ret != RT_EOK)
{
rt_kprintf("mpu6050 : get temperature error\r\n");
}
ret = mpu6050_accelerometer_get(&ax, &ay, &az);
if (ret != RT_EOK)
{
rt_kprintf("mpu6050 : get acc error\r\n");
}
ret = mpu6050_gyroscope_get(&gx, &gy, &gz);
if (ret != RT_EOK)
{
rt_kprintf("mpu6050 : get gyro error\r\n");
}
if (ret == RT_EOK)
{
rt_kprintf("mpu6050: temperature=%-6d gx=%-6d gy=%-6d gz=%-6d ax=%-6d ay=%-6d az=%-6d\r\n",temp/100,gx,gy,gz,ax,ay,az);
}
rt_thread_delay(rt_tick_from_millisecond(1000));
}
}
int main(void)
{
rt_thread_t tid;
tid = rt_thread_create("mpu6050",
mpu6050_thread_entry,
RT_NULL,
1024,
24,
20);
if (tid == RT_NULL)
{
return -RT_ERROR;
}
rt_thread_startup(tid);
return RT_EOK;
}
重新编译,下载。程序可正常运行,可以读出MPU6050数据。倾斜电路板,数据有变化。