我遇到的问题:
1. 因为读出的AD值都是0,转换过来的温度和的压力都是固定值 24.38℃,1017 mbar。
2. 读PROM时,我看网上 for (i=0;i<=6;i++),第一次循环,i = 0时,读校验值的高、低字节时收不到ack,其他的应有的ack都有收到,唯独这两次没有收到。不知道这个有没有影响,因为我看到网上有些读PROM是i=1开始的 for (i=1;i<=6;i++) ,也有从for (i=0;i<=6;i++)这样的,而且后面的校验方法都一样。不知道那个是对的?我读出的校验值是这样的。
Cal_C[0] = 65535
Cal_C[1] = 49510
Cal_C[2] = 50850
Cal_C[3] = 30456
Cal_C[4] = 27979
Cal_C[5] = 32325
Cal_C[6] = 27582
[mw_shl_code=applescript,true]#include"MS5611.h"
#include "BspUsart.h"
/*
C1 压力灵敏度 SENS|T1
C2 压力补偿 OFF|T1
C3 温度压力灵敏度系数 TCS
C4 温度系数的压力补偿 TCO
C5 参考温度 T|REF
C6 温度系数的温度 TEMPSENS
*/
uint16_t Cal_C[7]; //用于存放PROM中的6组数据1-6
double OFF_;
float Aux;
/*
dT 实际和参考温度之间的差异
TEMP 实际温度
*/
uint32_t dT,TEMP;
/*
OFF 实际温度补偿
SENS 实际温度灵敏度
*/
uint64_t OFf,SENS;
uint32_t D1_Pres,D2_Temp; // 数字压力值,数字温度值
uint32_t Pressure,Pressure_old,qqp; //大气压
uint32_t TEMP2,T2,OFF2,SENS2; //温度校验值
static void MS561101BA_EN(void)
{
//配置LED灯
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //LED
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_1);
}
/*******************************************************************************
* @函数名称 MS561101BA_RESET
* @函数说明 使能MS5611模块
* @输入参数 无
* @输出参数 无
* @返回参数 无
*******************************************************************************/
void MS561101BA_RESET(void)
{
I2C_Start();
I2C_Send_Byte(0xEE);//CSB接地,主机地址:0XEE,否则 0X77
I2C_Wait_Ack();
I2C_Send_Byte(0x1E);//发送复位命令
I2C_Wait_Ack();
I2C_Stop();
}
/*******************************************************************************
* @函数名称 MS5611_init
* @函数说明 初始化5611
* @输入参数 无
* @输出参数 无
* @返回参数 无
*******************************************************************************/
u8 MS5611_init(void)
{
u8 inth,intl;
int i;
MS561101BA_EN();
delay_ms(100);
I2C_Init();
delay_ms(100);
MS561101BA_RESET();
delay_ms(100);
for (i=0;i<=6;i++)
{
I2C_Start();
I2C_Send_Byte(0xEE);
I2C_Wait_Ack();
I2C_Send_Byte(0xA0 + (i*2));
I2C_Wait_Ack();
I2C_Stop();
delay_us(5);
I2C_Start();
I2C_Send_Byte(0xEE+0x01); //进入接收模式
delay_us(1);
I2C_Wait_Ack();
inth = I2C_Read_Byte(1); //带ACK的读数据
delay_us(1);
intl = I2C_Read_Byte(0); //最后一个字节NACK
I2C_Stop();
Cal_C = (((uint16_t)inth << 8) | intl);
printf("Cal_C[%d] = %d
",i,Cal_C);
}
return !Cal_C[0];
}
/**************************实现函数********************************************
*函数原型:unsigned long MS561101BA_getConversion(void)
*功 能: 读取 MS561101B 的转换结果
*******************************************************************************/
unsigned long MS561101BA_getConversion(uint8_t command)
{
unsigned long conversion = 0;
volatile u8 temp[3];
I2C_Start();
I2C_Send_Byte(0xEE); //写地址
I2C_Wait_Ack();
I2C_Send_Byte(command); //写转换命令
I2C_Wait_Ack();
I2C_Stop();
delay_ms(100);
I2C_Start();
I2C_Send_Byte(0xEE); //写地址
I2C_Wait_Ack();
I2C_Send_Byte(0); // start read sequence
I2C_Wait_Ack();
I2C_Stop();
delay_ms(100);
I2C_Start();
I2C_Send_Byte(0xEE+0x01); //进入接收模式
I2C_Wait_Ack();
temp[0] = I2C_Read_Byte(1); //带ACK的读数据 bit 23-16
temp[1] = I2C_Read_Byte(1); //带ACK的读数据 bit 8-15
temp[2] = I2C_Read_Byte(0); //带NACK的读数据 bit 0-7
I2C_Stop();
conversion = (unsigned long)temp[0] * 65536 + (unsigned long)temp[1] * 256 + (unsigned long)temp[2];
return conversion;
}
/**************************实现函数********************************************
*函数原型:void MS561101BA_GetTemperature(void)
*功 能: 读取 温度转换结果
*******************************************************************************/
void MS561101BA_GetTemperature(void)
{
D2_Temp = MS561101BA_getConversion(0x58);
delay_ms(20);
dT=D2_Temp - (((uint32_t)Cal_C[5])<<8);
TEMP=2000+dT*((uint32_t)Cal_C[6])/8388608;
}
///***********************************************
// * @brief 读取气压
// * @param NoneDDDDDD30
// * @retval None
//************************************************/
void MS561101BA_getPressure(void)
{
D1_Pres= MS561101BA_getConversion(0x48);
delay_ms(20);
OFF_=(uint32_t)Cal_C[2]*65536+((uint32_t)Cal_C[4]*dT)/128;
SENS=(uint32_t)Cal_C[1]*32768+((uint32_t)Cal_C[3]*dT)/256;
if(TEMP<2000)
{
Aux = (2000-TEMP)*(2000-TEMP);
T2 = (dT*dT) / 0x80000000;
OFF2 = 2.5f*Aux;
SENS2 = 1.25f*Aux;
TEMP = TEMP - T2;
OFF_ = OFF_ - OFF2;
SENS = SENS - SENS2;
}
Pressure= (D1_Pres*SENS/2097152-OFF_)/32768;
}
#include "I2C.h"
#include "timer.h"
void I2C_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOA时钟
//GPIOA11,A12初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
I2C_SDA_H;
I2C_SCL_H;
}
//void I2C_SDA_Out(void)
//{
// GPIO_InitTypeDef GPIO_InitStructure;
//
// GPIO_InitStructure.GPIO_Pin = I2C_SDA;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//
// GPIO_Init(GPIOB,&GPIO_InitStructure);
//}
//void I2C_SDA_IN(void)
//{
// GPIO_InitTypeDef GPIO_InitStructure;
//
// GPIO_InitStructure.GPIO_Pin = I2C_SDA;
//
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//
// GPIO_Init(GPIOB,&GPIO_InitStructure);
//}
void I2C_Start(void)
{
I2C_SDA_Out();
I2C_SDA_H;
I2C_SCL_H;
delay_us(5);
I2C_SDA_L;
delay_us(6);
I2C_SCL_L;
}
void I2C_Stop(void)
{
I2C_SDA_Out();
I2C_SCL_L;
I2C_SDA_L;
I2C_SCL_H;
delay_us(6);
I2C_SDA_H;
delay_us(6);
}
void I2C_Ack(void)
{
I2C_SCL_L;
I2C_SDA_Out();
I2C_SDA_L;
delay_us(2);
I2C_SCL_H;
delay_us(5);
I2C_SCL_L;
}
//主机不产生应答信号NACK
void I2C_NAck(void)
{
I2C_SCL_L;
I2C_SDA_Out();
I2C_SDA_H;
delay_us(2);
I2C_SCL_H;
delay_us(5);
I2C_SCL_L;
}
//等待从机应答信号
//返回值:1 接收应答失败
// 0 接收应答成功
u8 I2C_Wait_Ack(void)
{
u8 tempTime=0;
I2C_SDA_IN();
I2C_SDA_H;
delay_us(1);
I2C_SCL_H;
delay_us(1);
while(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA))
{
tempTime++;
if(tempTime>250)
{
I2C_Stop();
return 1;
}
}
I2C_SCL_L;
return 0;
}
//I2C 发送一个字节
void I2C_Send_Byte(u8 txd)
{
u8 i=0;
I2C_SDA_Out();
I2C_SCL_L;//拉低时钟开始数据传输
for(i=0;i<8;i++)
{
if((txd&0x80)>0) //0x80 1000 0000
I2C_SDA_H;
else
I2C_SDA_L;
txd<<=1;
I2C_SCL_H;
delay_us(2); //发送数据
I2C_SCL_L;
delay_us(2);
}
}
//I2C 读取一个字节
u8 I2C_Read_Byte(u8 ack)
{
u8 i=0,receive=0;
I2C_SDA_IN();
for(i=0;i<8;i++)
{
I2C_SCL_L;
delay_us(2);
I2C_SCL_H;
receive<<=1;
if(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA))
receive++;
delay_us(1);
}
if(ack==0)
I2C_NAck();
else
I2C_Ack();
return receive;
}
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2、for (i=0;i<=6;i++)只能得到Cal_C[0]-Cal_C[5]。你应该循环8次,得到Cal_C[0]-Cal_C[7],从而得到Cal_C[1]-Cal_C[6]。
3、u8 I2C_Wait_Ack(void)这个函数中
if(tempTime>250)
{
I2C_Stop();
return 1;
}
直接跳出,会不会少一个时钟?或者I2C_Stop()结束了,后面的数据都无效了?
我把OSR改成256,读出的AD值终于不是0,改成1024的话有时是0。OSR是 采样精度的意思吗?为何有这种情况的出现。
一周热门 更多>