基于STM32F103的“口袋”控制平台的水平仪
制作一个能够测量角度的水平仪,通过“水银柱”的方式在屏幕上显示,并显示板子倾斜的角度.
标签
STM32
MPU
寒假在家一起练
void
更新2021-03-02
1137

此次开发的是硬禾学堂为高校学生设计的嵌入式系统学习平台, 使用USB-C给这个板子供电,调试,烧录, 核心基于STM32F103R8T6, 搭配了一个240 * 240的LCD彩屏,MPU6050,和一颗环境光传感器.我完成了任务3: 制作一个能够测量角度的水平仪,通过“水银柱”的方式在屏幕上显示,并显示板子倾斜的角度

欲完成此项任务, 从开发环境开始, 使用STM32CubeIDE建立工程, 参考原理图设置部分模块初始化后,如图

Fr9CvmPSKsjpOgdpl6vpfsRrbLuO

核心没有独立配套晶振, 而是使用了调试器上的主振荡器输出8MHz的信号, 基于此修改时钟树配置如下

FiPNDIgCixe9zYL5-xkY3xIbHzwn

 

在lcd_init.h中,根据原理图修改端口

#define LCD_SCLK_Clr() HAL_GPIO_WritePin(LCD_SCL_GPIO_Port,LCD_SCL_Pin,GPIO_PIN_RESET)//SCL=SCLK
#define LCD_SCLK_Set() HAL_GPIO_WritePin(LCD_SCL_GPIO_Port,LCD_SCL_Pin,GPIO_PIN_SET)

#define LCD_MOSI_Clr() HAL_GPIO_WritePin(LCD_SDA_GPIO_Port,LCD_SDA_Pin,GPIO_PIN_RESET)//SDA=MOSI
#define LCD_MOSI_Set() HAL_GPIO_WritePin(LCD_SDA_GPIO_Port,LCD_SDA_Pin,GPIO_PIN_SET)

#define LCD_RES_Clr()  HAL_GPIO_WritePin(LCD_RST_GPIO_Port,LCD_RST_Pin,GPIO_PIN_RESET)//RES
#define LCD_RES_Set()  HAL_GPIO_WritePin(LCD_RST_GPIO_Port,LCD_RST_Pin,GPIO_PIN_SET)

#define LCD_DC_Clr()   HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_RESET)//DC
#define LCD_DC_Set()   HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_SET)
 		     
#define LCD_CS_Clr()   HAL_GPIO_WritePin(LCD_CS_GPIO_Port,LCD_CS_Pin,GPIO_PIN_RESET)//CS
#define LCD_CS_Set()   HAL_GPIO_WritePin(LCD_CS_GPIO_Port,LCD_CS_Pin,GPIO_PIN_SET)

#define LCD_BLK_Clr()  HAL_GPIO_WritePin(LCD_BL_GPIO_Port,LCD_BL_Pin,GPIO_PIN_RESET)//BLK
#define LCD_BLK_Set()  HAL_GPIO_WritePin(LCD_BL_GPIO_Port,LCD_BL_Pin,GPIO_PIN_SET)

对于I2C端口虽然连接了硬件端口,但是对于饱受诟病的硬件通信成功率,我选择了使用IO模拟

修改代码如下

#define MPU_SDA_IN()  {I2C2_SDA_GPIO_Port->CRH&=0XFFFF0FFF;I2C2_SDA_GPIO_Port->CRH|=8<<12;}//清除配置,设置为拉动输入模式
#define MPU_SDA_OUT() {I2C2_SDA_GPIO_Port->CRH&=0XFFFF0FFF;I2C2_SDA_GPIO_Port->CRH|=3<<12;}//清除配置,设置为推挽高速输出

#define MPU_IIC_SCL_Clr()   HAL_GPIO_WritePin(I2C2_SCL_GPIO_Port,I2C2_SCL_Pin,GPIO_PIN_RESET)
#define MPU_IIC_SCL_Set()   HAL_GPIO_WritePin(I2C2_SCL_GPIO_Port,I2C2_SCL_Pin,GPIO_PIN_SET)  
#define MPU_IIC_SDA_Clr()   HAL_GPIO_WritePin(I2C2_SDA_GPIO_Port,I2C2_SDA_Pin,GPIO_PIN_RESET)
#define MPU_IIC_SDA_Set()   HAL_GPIO_WritePin(I2C2_SDA_GPIO_Port,I2C2_SDA_Pin,GPIO_PIN_SET)  
#define MPU_IIC_SDA_Get()   HAL_GPIO_ReadPin( I2C2_SDA_GPIO_Port,I2C2_SDA_Pin)

其中,加快通信速率,我将翻转输入输出代码,结合寄存器配置的方法,端口是B11,

FuNJhuZxQxLnwGV3dWuJJQRDd8rR

配置GPIO引脚模式的一共有两个寄存器,CRH是高寄存器,用来配置高8位引脚:pin8~pin15;另一个是CRL寄存器,负责配置低8位引脚:pin0~pin7.

FtsDH9jv8JfP4e3iJZKsz6pF3DYN

改用寄存器配置后, 通信速率接近硬件速率.

 

解决了数据收发, 使用板载mpu6050读取xyz三轴的重力分量, 存入acc[0], acc[1], acc[2]

使用atan2, 分别计算xy轴合力与z轴方向的夹角,并转化为角度值:

sum_angle = sqrtf(acc[0]*acc[0]+acc[1]*acc[1]);
sum_angle = atan2(sum_angle,-acc[2])*180/PI;

判断是否水平,使用简单的计算xy平方和开根号:

sum_angle = sqrtf(acc[0]*acc[0]+acc[1]*acc[1]);
balance_state = sum_angle<2?1:0;

当数值小于2时,认为接近水平, 使画面的外圈变为青色; 否则, 外圈变为红棕色.

FsPqBKeAxKrE1ZYT3kmmbzRn3Fix

优化刷屏逻辑, 将刷新频率提高至4次/秒.

FimZHz-OKMxk1ffTFUkUC9qEx9Kf

总结:

   这次的stm32平台开发用到了熟悉的CubeIDE, 省去了很多寄存器的配置, 但寄存器仍也是嵌入式学习中不可缺少的重点

   单纯的使用寄存器虽然可以让代码体积减小,运行速度加快, 配置的过程也就非常头疼,便有了HAL库的出现.结合寄存器和HAL, 就可以将重点优化的部分独立配置,其余部分使用开发环境加速开发.

   感谢硬禾的策划的活动, 既能获得平台练手, 又能与小伙伴们交流学习进度.

 

附件下载
STM32_Pocket.rar
项目工程使用CubeIDE搭建, elf和bin在debug目录下
团队介绍
安徽师范大学
团队成员
Chou Ds
通信工程菜鸡一枚
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号