糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > STM32CubeIDE HAL OLED MPU6050学习笔记

STM32CubeIDE HAL OLED MPU6050学习笔记

时间:2019-10-18 00:43:51

相关推荐

STM32CubeIDE HAL OLED MPU6050学习笔记

器件:1.STM32F103C8T6 (¥17.3)

2.中景园0.96寸OLED显示屏 (¥9)

3.MPU6050 (¥6.4)信泰微电子购买

4.ST-LINK V2(进口芯片版本,¥19.8),一定要买固件可升级版本,减少很多麻烦。

注意:程序可能出现在STM32CubeIDE下正常运行,单独上电没反应问题。单独上电后按一下板上的复位键能正常运行。

链接:/s/1cY1azrTi9-uVb5Oh9iWdEg?pwd=8888

提取码:8888

一、STM32CubeIDE配置

实际PA15未用

PA1、PA2用于OLED的IIC通信

PA10、PA11用于MPU6050的IIC通信

使用外部时钟,用内部时钟也可以,速度慢点,准确度低点。

调试端口设置

如何接线:②④⑥⑧接线对应STM32F103C8T6最小系统的对应端口。

点击Run会将固件写入STM32,期间可能会提示升级ST-LINK,升,不升用不了。有了ST-LINK还是很方便的可以debug,一步一步执行。

如何添加外部库

右键工程

添加includes文件夹,确认后退出。右键工程,刷新一下。

工程刷新后,添加source location,添加文件夹。

二、OLED使用

(天下文章一大抄,网上的驱动程序基本都一样,只是很难找到用HAL库的,我们只需要把标准库的程序改为HAL库就行了,建议搞清楚IIC基本原理。)

源码在百度链接里,这里写一下我修改的地方,源码内原始的只注释掉了,并没有删除,很容易识别。

olediic.h,尽可能保持原函数不变,程序修改的地方最少。

#ifndef __IIC_H

#define __IIC_H

//#include "sys.h"

#include "stm32f1xx_hal.h"

#define u8 uint8_t

#define u32 uint32_t

#define u16 uint16_t

/****************

注意:模拟IIC时,任意IO口(除JTAG口外,都可以做SDA和SCL)

****************/

//#define OLED_SCL_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_1)//SCL

#define OLED_SCL_Clr() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET)

//#define OLED_SCL_Set() GPIO_SetBits(GPIOA,GPIO_Pin_1)

#define OLED_SCL_Set() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET)

//#define OLED_SDA_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_2)//AIN

#define OLED_SDA_Clr() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET)

//#define OLED_SDA_Set() GPIO_SetBits(GPIOA,GPIO_Pin_2)

#define OLED_SDA_Set() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET)

void IIC_delay(void);

void I2C_Start(void);

void I2C_Stop(void);

void I2C_WaitAck(void);

void Send_Byte(u8 dat);

#endif

olediic.c 如下:

//#include "delay.h"

#include "olediic.h"

void IIC_delay(void)

{

u8 t=2;// 原數據 t=3

while(t--);

}

//起始信号

void I2C_Start(void)

{

OLED_SDA_Set();

OLED_SCL_Set();

IIC_delay();

OLED_SDA_Clr();

IIC_delay();

OLED_SCL_Clr();

IIC_delay();

}

//结束信号

void I2C_Stop(void)

{

OLED_SDA_Clr();

OLED_SCL_Set();

IIC_delay();

OLED_SDA_Set();

}

//等待信号响应

void I2C_WaitAck(void) //测数据信号的电平

{

OLED_SDA_Set();

IIC_delay();

OLED_SCL_Set();

IIC_delay();

OLED_SCL_Clr();

IIC_delay();

}

//写入一个字节

void Send_Byte(u8 dat)

{

u8 i;

for(i=0;i<8;i++)

{

if(dat&0x80)//将dat的8位从最高位依次写入

{

OLED_SDA_Set();

}

else

{

OLED_SDA_Clr();

}

IIC_delay();

OLED_SCL_Set();

IIC_delay();

OLED_SCL_Clr();//将时钟信号设置为低电平

dat<<=1;

}

}

oled.h 如下:

#ifndef __OLED_H

#define __OLED_H

//#include "sys.h"

//#include "stm32f10x.h"

#include "stm32f1xx_hal.h"

//#include "delay.h"

#include "stdlib.h"

#include "olediic.h"

#define OLED_CMD 0 //写命令

#define OLED_DATA 1 //写数据

void OLED_WR_Byte(u8 dat,u8 mode); //发送一个字节

void OLED_ColorTurn(u8 i);//反转颜色

void OLED_DisplayTurn(u8 i); //屏幕旋转180°

void OLED_DisPlay_On(void);//开启oled显示屏

void OLED_DisPlay_Off(void); //关闭oled显示屏

void OLED_Refresh(void);

void OLED_Clear(void);

void OLED_DrawPoint(u8 x,u8 y,u8 t);

void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2,u8 mode);

void OLED_DrawCircle(u8 x,u8 y,u8 r);

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode);

void OLED_ShowChar6x8(u8 x,u8 y,u8 chr,u8 mode);

void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode);

void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode);

void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1,u8 mode);

void OLED_ScrollDisplay(u8 num,u8 space,u8 mode);

void OLED_ShowPicture(u8 x,u8 y,u8 sizex,u8 sizey,u8 BMP[],u8 mode);

void OLED_Init(void);

void OLED_ShowFloat(u8 x,u8 y,float num,u8 len,u8 size,u8 mode);

float My_abs(float a);

#endif

oled.c部分

void OLED_Init(void)

{

/*

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能A端口时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1; //PA1->IIC_SCL PA2->IIC_SDA

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz

GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA1,PA2

GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2); //PA1,PA2置高

*/

GPIO_InitTypeDef GPIO_InitStructure={0};

GPIO_InitStructure.Pin=GPIO_PIN_2|GPIO_PIN_1;

GPIO_InitStructure.Pull=GPIO_PULLUP;

GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP;

GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);

OLED_WR_Byte(0xAE,OLED_CMD);//---关闭OLED面板

OLED_WR_Byte(0x00,OLED_CMD);//---设置列低地址

OLED_WR_Byte(0x10,OLED_CMD);//---设置列高地址

OLED_WR_Byte(0x40,OLED_CMD);//---设置起始行地址设置映射RAM显示起始行(0x00~0x3F)

OLED_WR_Byte(0x81,OLED_CMD);//---设置对比控制寄存器

OLED_WR_Byte(0xCF,OLED_CMD);//---设置亮度

OLED_WR_Byte(0xA1,OLED_CMD);//---设置分段/列映射 0xa0左右反置 0xa1正常

OLED_WR_Byte(0xC8,OLED_CMD);//---设置COM列/行扫描方向 0xc0上下反置 0xc8正常

OLED_WR_Byte(0xA6,OLED_CMD);//---设置正常显示

OLED_WR_Byte(0xA8,OLED_CMD);//---设置复用比(1到64)

OLED_WR_Byte(0x3f,OLED_CMD);//---1/64负载

OLED_WR_Byte(0xD3,OLED_CMD);//---设置显示偏移映射RAM计数器(0x00~0x3F)

OLED_WR_Byte(0x00,OLED_CMD);//---不抵消

OLED_WR_Byte(0xd5,OLED_CMD);//---设置显示时钟分频比/振荡器频率

OLED_WR_Byte(0x80,OLED_CMD);//---s设置分频比,将时钟设置为100帧/秒

OLED_WR_Byte(0xD9,OLED_CMD);//---设置预充电时间

OLED_WR_Byte(0xF1,OLED_CMD);//---将预充电设置为15个时钟,放电设置为1个时钟

OLED_WR_Byte(0xDA,OLED_CMD);//---设置com引脚硬件配置

OLED_WR_Byte(0x12,OLED_CMD);//---

OLED_WR_Byte(0xDB,OLED_CMD);//---设置 vcomh

OLED_WR_Byte(0x30,OLED_CMD);//---设置VCOM取消选择级别

OLED_WR_Byte(0x20,OLED_CMD);//---设置页面寻址模式 (0x00/0x01/0x02)

OLED_WR_Byte(0x02,OLED_CMD);//---

OLED_WR_Byte(0x8D,OLED_CMD);//---设置电荷泵启用/禁用

OLED_WR_Byte(0x14,OLED_CMD);//---设置(0x10)禁用

OLED_Clear();

OLED_WR_Byte(0xAF,OLED_CMD);

}

修改的地方其实很少,如果用中景园提供的原程序修改,oled的功能还要强大一些。

三、MPU6050使用

MPU6050要完全搞懂,很难,购买硬件的时候商家要送一堆资料。于是改改改。

mpuiic.h如下:红色部分全部修改为同名函数见mpuiic.c

#ifndef __MPUIIC_H

#define __MPUIIC_H

//#include "sys.h"

#include "stm32f1xx_hal.h"

#define u8 uint8_t

#define u32 uint32_t

#define u16 uint16_t

//IO方向设置 ---PB11

//#define MPU_SDA_IN() {GPIOB->CRH &= 0XFFFF0FFF;GPIOB->CRH |= 8<<12;} //上拉/下拉 输入模式

//#define MPU_SDA_OUT() {GPIOB->CRH &= 0XFFFF0FFF;GPIOB->CRH |= 3<<12;} //推挽输出 输出模式

//IO操作函数

//#define MPU_IIC_SCL PBout(10) //SCL

//#define MPU_IIC_SDA PBout(11) //SDA

//#define MPU_READ_SDA PBin(11) //输入SDA

//IIC所有操作函数

void MPU_IIC_Delay(void); //IIC延时2ms函数

void MPU_IIC_Init(void); //初始化IIC的IO口

void MPU_IIC_Start(void); //发送IIC开始信号

void MPU_IIC_Stop(void); //发送IIC停止信号

void MPU_IIC_Send_Byte(u8 txd);//IIC发送一个字节

u8 MPU_IIC_Read_Byte(unsigned char ack);//IIC读取一个字节

u8 MPU_IIC_Wait_Ack(void); //IIC等待ACK信号

void MPU_IIC_Ack(void); //IIC发送ACK信号

void MPU_IIC_NAck(void); //IIC不发送ACK信号

void IMPU_IC_Write_One_Byte(u8 daddr,u8 addr,u8 data);

u8 MPU_IIC_Read_One_Byte(u8 daddr,u8 addr);

#endif

mupiic.c部分如下:

#include "mpuiic.h"

//#include "delay.h"

//#define MPU_SDA_IN() {GPIOB->CRH &= 0XFFFF0FFF;GPIOB->CRH |= 8<<12;} //上拉/下拉 输入模式

//#define MPU_SDA_OUT() {GPIOB->CRH &= 0XFFFF0FFF;GPIOB->CRH |= 3<<12;} //推挽输出 输出模式

void MPU_SDA_IN()

{

GPIO_InitTypeDef GPIO_InitStruct={0};

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);

GPIO_InitStruct.Pin=GPIO_PIN_11;

GPIO_InitStruct.Pull=GPIO_PULLUP;

GPIO_InitStruct.Mode=GPIO_MODE_INPUT;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

void MPU_SDA_OUT()

{

GPIO_InitTypeDef GPIO_InitStruct={0};

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);

GPIO_InitStruct.Pin=GPIO_PIN_11;

GPIO_InitStruct.Pull=GPIO_PULLUP;

GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

//#define MPU_IIC_SCL PBout(10) //SCL

//#define MPU_IIC_SDA PBout(11) //SDA

//#define MPU_READ_SDA PBin(11) //输入SDA

void MPU_IIC_SCL(uint8_t dat)

{

switch(dat)

{

case 0:HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);break;

default:HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);

}

}

void MPU_IIC_SDA(uint8_t dat)

{

switch(dat)

{

case 0:HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);break;

default:HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);

}

}

uint8_t MPU_READ_SDA()

{

GPIO_PinState PinState;

uint8_t rt;

PinState=HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11);

switch(PinState)

{

case GPIO_PIN_RESET:rt=0;break;

default:rt=1;

}

return rt;

}

void delay_us(uint16_t n)

{

uint16_t i=n*8;

while(i--);

}

/**********************************************

函数名称:MPU_IIC_Delay

函数功能:MPU IIC延时函数,延时2ms

函数参数:无

函数返回值:无

**********************************************/

void MPU_IIC_Delay(void)

{

delay_us(2);

}

/**********************************************

函数名称:MPU_IIC_Init

函数功能:MPU IIC初始化

函数参数:无

函数返回值:无

**********************************************/

void MPU_IIC_Init(void)

{

/*

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //先使能外设IO PORTB时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11; //端口配置

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHz

GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIO

GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11); //PB10,PB11 输出高

*/

GPIO_InitTypeDef GPIO_InitStructure={0};

GPIO_InitStructure.Pin=GPIO_PIN_10|GPIO_PIN_11;

GPIO_InitStructure.Pull=GPIO_PULLUP;

GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP;

GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);

}

mpu6050.h 和 mpu6050.c 基本没修改

用以上程序只能得到, aacx,aacy,aacz(三轴加速度传感器原始数),gyrox,gyroy,gyroz(三轴陀螺仪原始数据),没什么用。

通常用数字运动处理(DMP)引擎处理,就是厂家提供的eMPL文件夹下面的程序处理为pitch,roll,yaw(俯仰角度绕X轴旋转、横滚角度绕Z轴旋转、航向角度绕Y轴旋转)。当然程序还是要改改改。

inv_mpu.h部分如下:

#ifndef _INV_MPU_H_

#define _INV_MPU_H_

//#include "stm32f10x.h"

#include "stm32f1xx_hal.h"

#define u8 uint8_t

#define u32 uint32_t

#define u16 uint16_t

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

其他程序就把

//#include "usart.h"

//#include "delay.h"

注释掉就行了。

感觉好简单,还是卖家给力,给的程序都是标准库的成熟程序,简单改改就是HAL库程序了。

如果觉得《STM32CubeIDE HAL OLED MPU6050学习笔记》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。