此次开发的是硬禾学堂为高校学生设计的嵌入式系统学习平台, 使用USB-C给这个板子供电,调试,烧录, 核心基于STM32F103R8T6, 搭配了一个240 * 240的LCD彩屏,MPU6050,和一颗环境光传感器.我完成了任务3: 制作一个能够测量角度的水平仪,通过“水银柱”的方式在屏幕上显示,并显示板子倾斜的角度
欲完成此项任务, 从开发环境开始, 使用STM32CubeIDE建立工程, 参考原理图设置部分模块初始化后,如图
核心没有独立配套晶振, 而是使用了调试器上的主振荡器输出8MHz的信号, 基于此修改时钟树配置如下
在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,
配置GPIO引脚模式的一共有两个寄存器,CRH是高寄存器,用来配置高8位引脚:pin8~pin15;另一个是CRL寄存器,负责配置低8位引脚:pin0~pin7.
改用寄存器配置后, 通信速率接近硬件速率.
解决了数据收发, 使用板载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时,认为接近水平, 使画面的外圈变为青色; 否则, 外圈变为红棕色.
优化刷屏逻辑, 将刷新频率提高至4次/秒.
总结:
这次的stm32平台开发用到了熟悉的CubeIDE, 省去了很多寄存器的配置, 但寄存器仍也是嵌入式学习中不可缺少的重点
单纯的使用寄存器虽然可以让代码体积减小,运行速度加快, 配置的过程也就非常头疼,便有了HAL库的出现.结合寄存器和HAL, 就可以将重点优化的部分独立配置,其余部分使用开发环境加速开发.
感谢硬禾的策划的活动, 既能获得平台练手, 又能与小伙伴们交流学习进度.