IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> mpu9250芯片内置磁力计灵敏度工厂校正值参数读取 stm32 arduino -> 正文阅读

[嵌入式]mpu9250芯片内置磁力计灵敏度工厂校正值参数读取 stm32 arduino

mpu9250芯片内置磁力计灵敏度工厂校正值参数读取 stm32 arduino

一般情况下读到的?ASAX,ASAY,ASAZ 为163,167,153 这样的固定值,每一片9250芯片都不同,处理工厂校正值后然后再进行地磁椭球校正(见我以前的文章)

通过这两步校正后,航向角yaw的误差在1度内,基本能满足各类应用。

#include "i2c.h" ? //i2c通讯部分

#define AK8963_I2C_ADDR ? ? 0x18 ? //0x0C ? ? //地磁仪地址为0x18

/* Read-only Reg ( ROM ) */ //芯片内置地磁仪校正值
#define AK8963_ASAX ? ? ? ? ? ? ? 0x10
#define AK8963_ASAY ? ? ? ? ? ? ? 0x11
#define AK8963_ASAZ ? ? ? ? ? ? ? 0x12

#define AK8963_CNTL1 ? ? ? ? ? ? 0x0A
#define AK8963_CNTL2 ? ? ? ? ? ? 0x0B

float ?mag_sensadj[3] = {1, 1, 1};
float ?AK8963_ASA[3] = {0};

uint8_t asa[3] = {0};
?
void MPU92_AUX_AK8963_Init( void );

//读取厂家芯片内地磁校正值
void MPU92_AUX_AK8963_Init( void )
{
? uint8_t res;

? Delayms(1);
? Single_Write(AK8963_I2C_ADDR, AK8963_CNTL2, 0x01); ? ?// Reset Device
? Delayms(10);
? Single_Write(AK8963_I2C_ADDR, AK8963_CNTL1, 0x00); ? ?// Power-down mode
? Delayms(1);
? Single_Write(AK8963_I2C_ADDR, AK8963_CNTL1, 0x1F); ? ?// Fuse ROM access mode, Read sensitivity adjustment
? Delayms(10);
? asa[0] = Single_Read(AK8963_I2C_ADDR, AK8963_ASAX);
? Delayms(1);
? asa[1] = Single_Read(AK8963_I2C_ADDR, AK8963_ASAY);
? Delayms(1);
? asa[2] = Single_Read(AK8963_I2C_ADDR, AK8963_ASAZ);
? Delayms(1);
#if ENABLE_DEBUG_LOG
? printf(" >>> AK8963 ASA ? : %02X %02X %02X\r\n", asa[0], asa[1], asa[2]);
#endif
? Single_Write(AK8963_I2C_ADDR, AK8963_CNTL1, 0x00); ? ?// Power-down mode
? Delayms(10);
? Single_Write(AK8963_I2C_ADDR, AK8963_CNTL1, 0x16); ? ?// Continuous measurement mode 2 & 16-bit
? Delayms(10);

? AK8963_ASA[0] = (asa[0] - 128) * 0.5 / 128 + 1;
? AK8963_ASA[1] = (asa[1] - 128) * 0.5 / 128 + 1;
? AK8963_ASA[2] = (asa[2] - 128) * 0.5 / 128 + 1;


? res = Single_Read(AK8963_I2C_ADDR, AK8963_CNTL1) & 0x10;
? switch (res) {
? ? case 0x00: ?mag_sensadj[0] = mag_sensadj[1] = mag_sensadj[2] = 0.6; ? break;
? ? case 0x10: ?mag_sensadj[0] = mag_sensadj[1] = mag_sensadj[2] = 0.15; ?break;
? }


? mag_sensadj[0] *= AK8963_ASA[0];
? mag_sensadj[1] *= AK8963_ASA[1];
? mag_sensadj[2] *= AK8963_ASA[2];

}
/

代码中引用为?

mx=mx*mag_sensadj[0];

my=my*mag_sensadj[1];

mz=mz*mag_sensadj[2];

一般情况下读到的?ASAX,ASAY,ASAZ 为163,167,153 这样的固定值,每一片9250芯片都不同,处理工厂校正值后然后再进行地磁椭球校正(见我以前的文章)

通过这两步校正后,航向角yaw的误差在1度内,基本能满足各类应用。

附件?

i2c.h

#ifndef _I2C_H
#define _I2C_H

typedef enum {FALSE=0,TRUE=1} bool;
void I2C_GPIO_Config(void); ?//mpu9250 输入定义
void I2C_delay(void);?? ?
void delay5ms(void);
bool I2C_Start(void);
void I2C_Stop(void);
void I2C_Ack(void);
void I2C_NoAck(void);
bool I2C_WaitAck(void);
void I2C_SendByte(u8 SendByte); //数据从高位到低位//
unsigned char I2C_RadeByte(void); ?//数据从高位到低位//
bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data);
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address);
void WWDG_Configuration(void);
void WWDG_IRQHandler(void);

#endif
//

i2c.c

#include "stm32f10x.h"
#include "i2c.h"


char ?test=0; ?? ??? ??? ??? ? //IIC

//************************************
/*模拟IIC端口输出输入定义*/
#define SCL_H ? ? ? ? GPIOB->BSRR = GPIO_Pin_6
#define SCL_L ? ? ? ? GPIOB->BRR ?= GPIO_Pin_6?
? ?
#define SDA_H ? ? ? ? GPIOB->BSRR = GPIO_Pin_7
#define SDA_L ? ? ? ? GPIOB->BRR ?= GPIO_Pin_7

#define SCL_read ? ? ?GPIOB->IDR ?& GPIO_Pin_6
#define SDA_read ? ? ?GPIOB->IDR ?& GPIO_Pin_7


/*******************************************************************************
* Function Name ?: I2C_GPIO_Config
* Description ? ?: Configration Simulation IIC GPIO
* Input ? ? ? ? ?: None?
* Output ? ? ? ? : None
* Return ? ? ? ? : None
****************************************************************************** */
void I2C_GPIO_Config(void) ?//mpu9250 输入定义
{
? GPIO_InitTypeDef ?GPIO_InitStructure;?
?
? GPIO_InitStructure.GPIO_Pin = ?GPIO_Pin_6;
? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; ?
? GPIO_Init(GPIOB, &GPIO_InitStructure);

? GPIO_InitStructure.GPIO_Pin = ?GPIO_Pin_7;
? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
? GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/*******************************************************************************
* Function Name ?: I2C_delay
* Description ? ?: Simulation IIC Timing series delay
* Input ? ? ? ? ?: None
* Output ? ? ? ? : None
* Return ? ? ? ? : None
****************************************************************************** */
void I2C_delay(void)
{
?? ??? ?
? ?u8 i=10; ?// 30 这里可以优化速度?? ?,经测试最低到5还能写入
? ?while(i)?
? ?{?
? ? ?i--;?
? ?} ?
}

void delay5ms(void)
{
?? ??? ?
? ?int i=1000; ?
? ?while(i)?
? ?{?
? ? ?i--;?
? ?} ?
}
/*******************************************************************************
* Function Name ?: I2C_Start
* Description ? ?: Master Start Simulation IIC Communication
* Input ? ? ? ? ?: None
* Output ? ? ? ? : None
* Return ? ? ? ? : Wheather?? ? Start
****************************************************************************** */
bool I2C_Start(void)
{
?? ?SDA_H;
?? ?SCL_H;
?? ?I2C_delay();
?? ?if(!SDA_read)return FALSE;?? ?//SDA线为低电平则总线忙,退出
?? ?SDA_L;
?? ?I2C_delay();
?? ?if(SDA_read) return FALSE;?? ?//SDA线为高电平则总线出错,退出
?? ?SDA_L;
?? ?I2C_delay();
?? ?return TRUE;
}
/*******************************************************************************
* Function Name ?: I2C_Stop
* Description ? ?: Master Stop Simulation IIC Communication
* Input ? ? ? ? ?: None
* Output ? ? ? ? : None
* Return ? ? ? ? : None
****************************************************************************** */
void I2C_Stop(void)
{
?? ?SCL_L;
?? ?I2C_delay();
?? ?SDA_L;
?? ?I2C_delay();
?? ?SCL_H;
?? ?I2C_delay();
?? ?SDA_H;
?? ?I2C_delay();
}?
/*******************************************************************************
* Function Name ?: I2C_Ack
* Description ? ?: Master Send Acknowledge Single
* Input ? ? ? ? ?: None
* Output ? ? ? ? : None
* Return ? ? ? ? : None
****************************************************************************** */
void I2C_Ack(void)
{?? ?
?? ?SCL_L;
?? ?I2C_delay();
?? ?SDA_L;
?? ?I2C_delay();
?? ?SCL_H;
?? ?I2C_delay();
?? ?SCL_L;
?? ?I2C_delay();
} ??
/*******************************************************************************
* Function Name ?: I2C_NoAck
* Description ? ?: Master Send No Acknowledge Single
* Input ? ? ? ? ?: None
* Output ? ? ? ? : None
* Return ? ? ? ? : None
****************************************************************************** */
void I2C_NoAck(void)
{?? ?
?? ?SCL_L;
?? ?I2C_delay();
?? ?SDA_H;
?? ?I2C_delay();
?? ?SCL_H;
?? ?I2C_delay();
?? ?SCL_L;
?? ?I2C_delay();
}?
/*******************************************************************************
* Function Name ?: I2C_WaitAck
* Description ? ?: Master Reserive Slave Acknowledge Single
* Input ? ? ? ? ?: None
* Output ? ? ? ? : None
* Return ? ? ? ? : Wheather?? ? Reserive Slave Acknowledge Single
****************************************************************************** */
bool I2C_WaitAck(void) ?? ? ?//返回为:=1有ACK,=0无ACK
{
?? ?SCL_L;
?? ?I2C_delay();
?? ?SDA_H;?? ??? ??? ?
?? ?I2C_delay();
?? ?SCL_H;
?? ?I2C_delay();
?? ?if(SDA_read)
?? ?{
? ? ? SCL_L;
?? ? ?I2C_delay();
? ? ? return FALSE;
?? ?}
?? ?SCL_L;
?? ?I2C_delay();
?? ?return TRUE;
}
/*******************************************************************************
* Function Name ?: I2C_SendByte
* Description ? ?: Master Send a Byte to Slave
* Input ? ? ? ? ?: Will Send Date
* Output ? ? ? ? : None
* Return ? ? ? ? : None
****************************************************************************** */
void I2C_SendByte(u8 SendByte) //数据从高位到低位//
{
? ? u8 i=8;
? ? while(i--)
? ? {
? ? ? ? SCL_L;
? ? ? ? I2C_delay();
? ? ? if(SendByte&0x80)
? ? ? ? SDA_H; ?
? ? ? else?
? ? ? ? SDA_L; ??
? ? ? ? SendByte<<=1;
? ? ? ? I2C_delay();
?? ??? ?SCL_H;
? ? ? ? I2C_delay();
? ? }
? ? SCL_L;
} ?
/*******************************************************************************
* Function Name ?: I2C_RadeByte
* Description ? ?: Master Reserive a Byte From Slave
* Input ? ? ? ? ?: None
* Output ? ? ? ? : None
* Return ? ? ? ? : Date From Slave?
****************************************************************************** */
unsigned char I2C_RadeByte(void) ?//数据从高位到低位//
{?
? ? u8 i=8;
? ? u8 ReceiveByte=0;

? ? SDA_H;?? ??? ??? ??? ?
? ? while(i--)
? ? {
? ? ? ReceiveByte<<=1; ? ? ?
? ? ? SCL_L;
? ? ? I2C_delay();
?? ? ?SCL_H;
? ? ? I2C_delay();?? ?
? ? ? if(SDA_read)
? ? ? {
? ? ? ? ReceiveByte|=0x01;
? ? ? }
? ? }
? ? SCL_L;
? ? return ReceiveByte;
}?
//ZRX ? ? ? ? ?
//?????*******************************************

bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)?? ??? ? ? ? //void
{
? ?? ?if(!I2C_Start())return FALSE;
? ? I2C_SendByte(SlaveAddress); ? //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址?
? ? if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
? ? I2C_SendByte(REG_Address ); ? //设置低起始地址 ? ? ?
? ? I2C_WaitAck();?? ?
? ? I2C_SendByte(REG_data);
? ? I2C_WaitAck(); ??
? ? I2C_Stop();?
? ? delay5ms();
? ? return TRUE;
}

//单字节读取*****************************************
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{ ? unsigned char REG_data; ? ? ?? ?
?? ?if(!I2C_Start())return FALSE;
? ? I2C_SendByte(SlaveAddress); ? //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址?
? ? if(!I2C_WaitAck()){I2C_Stop();test=1; return FALSE;}
? ? I2C_SendByte((u8) REG_Address); ? //设置高起始地址+器件地址?
? ? I2C_WaitAck();
? ? I2C_Start();
? ? I2C_SendByte(SlaveAddress+1);
? ? I2C_WaitAck();

?? ?REG_data= I2C_RadeByte();
? ? I2C_NoAck();
? ? I2C_Stop();
? ? //return TRUE;
?? ?return REG_data;

}?? ??? ??? ??? ??? ??? ? ? ??

?/*
********************************************************************************
** 函数名称 : WWDG_Configuration(void)
** 函数功能 : 看门狗初始化
** 输 ? ?入?? ?: 无
** 输 ? ?出?? ?: 无
** 返 ? ?回?? ?: 无
********************************************************************************
*/
void WWDG_Configuration(void)
{
? RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);?? ?
? WWDG_SetPrescaler(WWDG_Prescaler_8);?? ? ? ? ? ? ? ? ?// ?WWDG clock counter = (PCLK1/4096)/8 = 244 Hz (~4 ms) ?
? WWDG_SetWindowValue(0x41);?? ??? ? ? ? ? ? ? ? ? ? // Set Window value to 0x41
? WWDG_Enable(0x50);?? ??? ? ? ? ? // Enable WWDG and set counter value to 0x7F, WWDG timeout = ~4 ms * 64 = 262 ms?
? WWDG_ClearFlag();?? ??? ??? ? ? ? ? // Clear EWI flag
? WWDG_EnableIT();?? ??? ??? ? ? ? ? // Enable EW interrupt
}

/*
********************************************************************************
** 函数名称 : WWDG_IRQHandler(void)
** 函数功能 : 窗口提前唤醒中断
** 输 ? ?入?? ?: 无
** 输 ? ?出?? ?: 无
** 返 ? ?回?? ?: 无
********************************************************************************
*/?

void WWDG_IRQHandler(void)
{
? /* Update WWDG counter */
? WWDG_SetCounter(0x50);
?? ?
? /* Clear EWI flag */
? WWDG_ClearFlag();?
}
?//************************************************

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-25 12:22:20  更:2021-08-25 12:22:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 17:54:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计