STM32F03C8T6 MPU6050 标准库
STM32 读取 MPU-6050 参数
1、摘要
整体代码是建立在野火的MPU-6050 的代码之上,原版是使用hal 库做的
原版的地址:
https://doc.embedfire.com/module/module_tutorial/zh/latest/Module_Manual/iic_class/mpu6050.html
我将代码移植到STM32F103C8T6 上, 上层应用完全照搬, 只是重写了
下面这两个函数, 使用标准库完成。
u8 Sensors_I2C_WriteRegister(unsigned char slave_addr,unsigned char reg_addr,unsigned short len,const unsigned char *data_ptr)u8 Sensors_I2C_ReadRegister(unsigned char slave_addr,unsigned char reg_addr,unsigned short len,unsigned char *data_ptr)
代码实现 就在下面的 iic.c 中。
2、移植过程中的问题
1、 是因为没有在接收倒数第二个字节是取消ACK, 就是这一句, 导致总线一致处于Busy 状态, 复位也不能解决, 只能断电。
if (i == len - 2) {I2C_AcknowledgeConfig(I2Cx, DISABLE);
}
2、 在第一个问题上,忽略了发送一个字节的情况, 导致发送一个字节还是会卡住, 因为总线处于Busy 状态。 所以加了这一句。
if (len == 1) {I2C_AcknowledgeConfig(I2Cx, DISABLE);}
注意EV7_1, NA 是通过 I2C_AcknowledgeConfig 实现, 取消后, 在程序最后还要使能,避免后续程序出问题。
3、主函数:
if (MPU6050ReadID() == 1) { // 读取一个字节的情况, 问题2解决的while (1) {delay_s(1);printf("1\r\n");MPU6050ReadAcc(Acel); // 读取多个字节情况, 问题1 解决的printf("1\r\n");printf("加速度: %8d %8d %8d\r\n",Acel[0],Acel[1],Acel[2]);MPU6050ReadGyro(Gyro); // 读取多个字节情况, 问题1 解决的printf("陀螺仪: %8d %8d %8d\r\n",Gyro[0],Gyro[1],Gyro[2]);MPU6050_ReturnTemp(&Temp); // 读取多个字节情况, 问题1 解决的printf("温度: %8.2f\r\n",Temp);}} else {printf("\r\n没有检测到MPU6050传感器!\r\n");while (1);}
4、我的主要代码如下
// iic.c
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"
#include "iic.h"#define I2C_PIN_SCL GPIO_Pin_6
#define I2C_PIN_SDA GPIO_Pin_7
#define I2C_PIN_MODE GPIO_Mode_AF_OD
#define I2C_PIN_PORT GPIOB
#define I2C_PIN_CLOCK RCC_APB2Periph_GPIOB
#define I2C_PIN_CLOCK_CMD RCC_APB2PeriphClockCmd#define I2Cx I2C1
#define I2C_CLOCK_CMD RCC_APB1PeriphClockCmd
#define I2C_CLOCK RCC_APB1Periph_I2C1
#define I2C_ADDRESS 0x30#define SLAVE_ADDRESS 0x78void I2C_Configuration(void)
{I2C_InitTypeDef I2C_InitStructure;GPIO_InitTypeDef GPIO_InitStructure; I2C_PIN_CLOCK_CMD(I2C_PIN_CLOCK,ENABLE);GPIO_InitStructure.GPIO_Pin = I2C_PIN_SCL | I2C_PIN_SDA;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = I2C_PIN_MODE;GPIO_Init(I2C_PIN_PORT, &GPIO_InitStructure);I2C_CLOCK_CMD(I2C_CLOCK,ENABLE);I2C_DeInit(I2Cx);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_16_9;I2C_InitStructure.I2C_OwnAddress1 = I2C_ADDRESS;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 400000;//400KI2C_Cmd(I2Cx, ENABLE);I2C_Init(I2Cx, &I2C_InitStructure);
}
u8 Sensors_I2C_WriteRegister(unsigned char slave_addr,unsigned char reg_addr,unsigned short len,const unsigned char *data_ptr)
{u8 i = 0;while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));I2C_GenerateSTART(I2Cx, ENABLE);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2Cx, slave_addr, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2Cx, reg_addr);while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING));for (i = 0; i < len; i++) {I2C_SendData(I2Cx, data_ptr[i]);while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING));}I2C_GenerateSTOP(I2Cx, ENABLE);return 0;
}u8 Sensors_I2C_ReadRegister(unsigned char slave_addr,unsigned char reg_addr,unsigned short len,unsigned char *data_ptr)
{u8 i = 0;while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));I2C_GenerateSTART(I2Cx, ENABLE);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2Cx, slave_addr, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2Cx, reg_addr);while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING));I2C_GenerateSTART(I2Cx, ENABLE);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2Cx, slave_addr, I2C_Direction_Receiver);while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));if (len == 1) {I2C_AcknowledgeConfig(I2Cx, DISABLE);}for (i = 0; i < len; i++) {while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));data_ptr[i] = I2C_ReceiveData(I2Cx);if (i == len - 2) {I2C_AcknowledgeConfig(I2Cx, DISABLE);}}I2C_GenerateSTOP(I2Cx, ENABLE);I2C_AcknowledgeConfig(I2Cx, ENABLE);return 0;
}
5、mpu部分
mpu6050.h 和mpu6050.c 是野火的原版程序, 我就不贴了。 参考最开始的野火链接即可。
STM32F03C8T6 MPU6050 标准库相关推荐
- Go 学习笔记(78)— Go 标准库 net/http 创建服务端(接收 GET、POST 请求)
使用 net/http 标准库创建一个 http 的 restful api 的服务端,用来处理 GET.POST 等请求. 源代码如下: package mainimport ("enco ...
- GCC 连接器、链接标准库 gcc -l、链接手动创建库(指定目录的库 gcc -L)
1. 链接器 链接器把多个二进制的目标文件(object file)链接成一个单独的可执行文件. 在链接过程中,它必须把符号(变量名.函数名等一些列标识符)用对应的数据的内存地址(变量地址.函数地址等 ...
- Go 学习笔记(55)— Go 标准库 sql (初始化数据库、插入、更新、删除数据库表、单行查询、多行查询、事务处理)
1. 标准库说明 Go 的标准库中是没有数据库驱动,只提供了驱动接口,有很多第三方实现了驱动,我们这里选择 go-sql-driver 这个实现是目前使用最多的.github 地址是:https:// ...
- Python 标准库之 subprocesss
Python 目前已经废弃了 os.system.os.spawn*.os.popen*.popen2.*.commands.* 来执行其他语言的命令,取而代之的是 subprocess 模块. 运行 ...
- Python 标准库之 xml.etree.ElementTree xml解析
Python 标准库之 xml.etree.ElementTree Python中有多种xml处理API,常用的有xml.dom.*模块.xml.sax.*模块.xml.parser.expat模块和 ...
- Go 学习笔记(21)— 标准库 os 操作文件(新建、打开、写入、读取、删除、关闭文件)
Go 操作文本文件时,与其它语言一样也有新建文件.打开文件.写文件.读文件.删除文件等操作.主要有两个标准库来提供这些操作,分别为 os 和 ioutil .在该文中我们介绍 os 模块. 1. 新建 ...
- bitset类型, 标准库类型
C++ primer 17.2 bitset类型, 标准库类型 1 使得位运算更容易实现, 并且能够处理超过最长整型大小的位集合. bitset定义在bitset中 定义和初始化bitset 1 bi ...
- c++标准库 及 命名空间std
1.命名空间std C++标准中引入命名空间的概念,是为了解决不同模块或者函数库中相同标识符冲突的问题.有了命名空间的概念,标识符就被限制在特定的范围(函数)内,不会引起命名冲突.最典型的例子就是st ...
- C++标准库简介(转)
C++标准库的所有头文件都没有扩展名.C++标准库的内容总共在50个标准头文件中定义,其中18个提供了C库的功能. <cname>形式的标准头文件[ <complex>例外]其 ...
最新文章
- 关于前后端配合开发的一点想法
- SUN PORTAL 7.2安装在windows 的问题解决办法!
- 关于页面加载的方法收集
- ME22N PO删除控制
- boost::describe模块宏BOOST_DESCRIBE_PP_NAME的测试程序
- Fragment Summary 2/2
- Gensee SDK RoleType详解
- 晶体封装越小esr越大_晶振
- 我38岁,从外企技术高管到失业在家,只因为做错了这件事
- php设计模式总结-单件模式
- 三元操作符(即条件表达式)
- 为什么编译个开源就觉得自己功劳巨大(对前研发总监李某功劳的分析)
- tomcat乱码问题解决
- 传智播客黑马程序员28期JavaEE基础及就业班视频教程
- testbed笔记:头文件里的函数
- 服务器防御DDoS的方法,一文解决DDoS攻击
- AliOS-Things--ESP8266-linkkitapp-配网(一)
- Lottie动画(二)Lottie动画制作
- 一款超好用的开源密码管理器?
- 为什么SEO效果不明显