前言
本人玩车的时候要用到陀螺仪
MPU6050容易卡死,然后还很漂,还是太难用了
68块钱的陀螺仪在上位机上的效果挺满意,于是打算用串口用到自己的模型上
本文教大家如何编写串口程序,通过串口获取角度
大家把本文的原理学会后,再去获取其他,比如角加速度,角速度都没问题了
官方参考文档
在官方文档中找到那篇通信协议的文档
在这个页面中我们可以获取的信息有
帧头都是0x55
根据第二帧来决定后面输入进来的是什么数据
串口助手查看数据
可以看到模块会把所有数据都传出来
所以我们只需要根据两个头帧,以及后面需要的数据长度来定义接受长度,最后再转化即可
STM32cubemx配置
我打算用串口1中断的方式来接收
然后OLED在屏幕中显示
OLED如何导入HAL库看我上一期文章
定义参数
uint8_t buffer[1];
float xyz[3];
定义两个全局变量
xyz主要用来传输角度,用作全局变量,到时候要传到主函数
buffer[1]主要是用来串口接收一个字符
然后在main.c里面也定义成全局变量
extern float xyz[3];
开启串口中断接收
HAL_UART_Receive_IT(&huart1, (uint8_t *)buffer, 1);
喜欢在初始化完后加,不加的话不会开启中断
因为加了之后是告诉程序
你要开始接受一个字符了,然后要把接受的存到buffer里面
串口中断回调函数编写(重点!)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static uint8_t i = 0;
static int16_t buff[8];
if(huart->Instance == USART1)
{
buff[i++] = buffer[0];
if((i == 1) && (buff[0] != 0x55))
{
i = 0;
}
if((i == 2) && (buff[1] != 0x53))
{
i = 0;
}
if(i == 8)
{
int16_t value_x = (buff[3] << 8) | buff[2];
int16_t value_y = (buff[5] << 8) | buff[4];
int16_t value_z = (buff[7] << 8) | buff[6];
xyz[0] = (float)value_x / 32768* 180 ;
xyz[1] = (float)value_y/ 32768* 180;
xyz[2] = (float)value_z / 32768* 180;
for(int j = 0; j < 8; j++)
{
buff[j] = 0;
}
i = 0;
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)buffer, 1);
}
}
首先让第一个字符接收,接收完i就等于1了
判断buff[0]是不是接收到0x55头帧了
如果没有接收到那么i等于0从新开始接收
因为我们要获取的是角度,所以第二帧是0x53
第二帧是数据类型判断帧
如果不是0x53,也就代表后面的高八位和第八位都不是我们要的角度数据
所以就重置
然后我们确定接下来的数据无误后,分别获取后面的六位数据
根据这张表格
所以我们只需要获取到YawH后就可以计算了
16位数据是大小为65536,但是如果是有符号,那么就会/2,-32767到32768之间,然后除于32768再乘180度就可以获取角度了
获取完后重新归零数据
主函数显示
sprintf(out,"%.1f ",xyz[0]);
OLED_ShowString(1, 1, out);
sprintf(out,"%.1f ",xyz[1]);
OLED_ShowString(2, 1, out);
sprintf(out,"%.1f ",xyz[2]);
OLED_ShowString(3, 1, out);
HAL_Delay(200);
基本OLED显示了
效果展示
0度到90度的变化