SPI驱动6针OLED
SPI的配置方法
芯片的选择
配置RCC、SYS、时钟树
设置下载方式
设置系统主频
- 以上与之前的工程配置相同
- 可选SPI1或SPI2
Mode模式在此选择全双工主模式,OLED屏幕仅需要接受来自单片机的通信信号,也可选择“Transmit Only Master”
选择开启SPI后,对应的复用引脚会出现SCK、MISO、MOSI,其中SCK作为通信的时钟引脚连接屏幕的CLK,驱动OLED只用到MOSI(单片机输出、屏幕输入);
此外,可选用两个引脚作为屏幕的RES、DC,配置为IO口输出模式即可,为方便起见,可自定义名为RES、DC作为标注,若OLED带有CS片选引脚,可再设置1个输出引脚,标为CS,并且CS引脚的电平必须拉低
最后生成代码即可
代码移植
由于提供的代码使用库函数编写,故需修改部分代码使之符合hal库的编写方式
(1)eg:中景园的提供的驱动代码中有oled.c oled.h bmp.h oledfont.h
(2)在keil里添加文件,并注意在C/C++中添加路径
(3)修改oled.h
(4)修改oled.c
(5)修改main.c
(6)使用oled.c中的函数即可实现屏幕的通信显示,可显示字符字符串、数字、文字与图片,并作相应的处理
IIC驱动MPU6050
IIC的配置方法
芯片的选择
配置RCC、SYS、时钟树
设置下载方式
设置系统主频
- 以上与之前的工程配置相同
- 可选IIC1或IIC2
在一般的mpu6050中,我们仅需要通电后,连接上面的SDA数据引脚和CLK时钟引脚即可实现对角度的解算与原始数据的读取
首先添加mpu6050与dmp的相关程序文件,然后为符合hal库的编写方式,做出部分修改
(1)添加头文件
#include "oled.h"
#include "mpu6050.h"
#include "control.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
(2)添加变量
float pitch,roll,yaw; //欧拉角
short aacx,aacy,aacz; //加速度传感器原始数据
short gyrox,gyroy,gyroz; //陀螺仪原始数据
short temp; //温度
(3)在相关初始化函数定义之后添加以下代码
while(mpu_dmp_init())
{
HAL_Delay(200);
printf("%s\r\n","Mpu6050_DMP Init Wrong!");
printf(" %d",mpu_dmp_init());
}
printf("%s\r\n","DMP_Mpu6050 Init OK!");
while(1)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
{
// temp=MPU_Get_Temperature(); //得到温度值
// MPU_Get_Accelerometer(&aacx,&aacy,&aacz); //得到加速度传感器数据
// MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //得到陀螺仪数据
printf("三轴角度:%f-%f-%f\r\n",pitch,roll,yaw);
// printf("三轴加速度:%d-%d-%d\r\n",aacx,aacy,aacz);
// printf("三轴角角度:%d-%d-%d\r\n",gyrox,gyroy,gyroz);
}
delay_ms(100);
若需要串口输出打印,可以在usart.c中加入串口重定向代码
(4)修改inv_mpu.c
#define i2c_write MPU_Write_Len
#define i2c_read MPU_Read_Len
#define delay_ms HAL_Delay
#define get_ms mget_ms
这里DMP官方把这个函数封装起来了, MPU_Write_Len,MPU_Read_Len,HAL_Delay,mget_ms。我们需要在IIC中去定义这三个函数(换个说法就是给IIC读写函数换个皮)
/* USER CODE BEGIN 1 */
unsigned char MPU_Write_Len(unsigned char addr,unsigned char reg,unsigned char len,unsigned char *buf)
{
HAL_I2C_Mem_Write(&hi2c1, addr, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 0xfff);
return 0;
}
unsigned char MPU_Read_Len(unsigned char addr,unsigned char reg,unsigned char len,unsigned char buf)
{
HAL_I2C_Mem_Read(&hi2c1, addr, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 0xfff);
return 0;
}
/ USER CODE END 1 */
接下来我们只要更改 mpu_dmp_init函数即可,这个函数是DMP库对外的接口,这里我们把正点原子中的
MPU_IIC_Init(); //初始化IIC总线
改成
MX_I2C1_Init(); //初始化IIC总线
即可
unsigned char mpu_dmp_init(void)
{
unsigned char res=0;
MX_I2C1_Init(); //初始化IIC总线
if(mpu_init()==0) //初始化MPU6050
{
res=mpu_set_sensors(INV_XYZ_GYRO|INV_XYZ_ACCEL);//设置所需要的传感器
if(res)return 1;
res=mpu_configure_fifo(INV_XYZ_GYRO|INV_XYZ_ACCEL);//设置FIFO
if(res)return 2;
res=mpu_set_sample_rate(DEFAULT_MPU_HZ); //设置采样率
if(res)return 3;
res=dmp_load_motion_driver_firmware(); //加载dmp固件
if(res)return 4;
res=dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation));//设置陀螺仪方向
if(res)return 5;
res=dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT|DMP_FEATURE_TAP| //设置dmp功能
DMP_FEATURE_ANDROID_ORIENT|DMP_FEATURE_SEND_RAW_ACCEL|DMP_FEATURE_SEND_CAL_GYRO|
DMP_FEATURE_GYRO_CAL);
if(res)return 6;
res=dmp_set_fifo_rate(DEFAULT_MPU_HZ); //设置DMP输出速率(最大不超过200Hz)
if(res)return 7;
res=run_self_test(); //自检
if(res)return 8;
res=mpu_set_dmp_state(1); //使能DMP
if(res)return 9;
}else return 10;
return 0;
}
这时候我们移植的就差不多了,但是还要注意一些细节问题,比如IIC地址的位对齐问题,在HAL库中,是没有将IIC地址左移的,所以我们需要手动将我们的IIC地址左移一位,因为我的ADO给的低电平,所以地址就是0X68<<1了
const struct hw_s hw={
0x68<<1, //addr
1024, //max_fifo
118, //num_reg
340, //temp_sens
-521, //temp_offset
256 //bank_size
};
最后即可通过串口得取陀螺仪的数据