标题 STM32 模拟IIC驱动MS5607调试记录
因项目需求,需使用MS5607的作为检测气压,再此写下自己遇见的问题以及调试记录。
硬件原理图如下:
IIC接口总线使用了气压传感器,SHT35温度传感器,调试MS5607硬件的7位地址是0X76。所以写的地址是0xEC,读操作的地址是0XED.
在第一次写数据的时候MCU无法得到ACK回应,最后查到的问题是地址错误导致的无回馈信号,在发送正确的时序图如下:
MS5607操作指令:
复位指令:
void MS5607BA_Reset(void)
{
u8 err=0;
IIC_Start();
IIC_Send_Byte(MS5607BA_ADR_Write);
err = IIC_Wait_Ack();
IIC_Send_Byte(MS5607BA_RESET);
err = IIC_Wait_Ack();
IIC_Stop();
delay_ms(200);
}
获得ADC读取的数字的值
void MS5607_Send_CMD(u8 command)
{
u8 err=0;
IIC_Start();
IIC_Send_Byte(MS5607BA_ADR_Write);
err = IIC_Wait_Ack();
IIC_Send_Byte(command);
err = IIC_Wait_Ack();
IIC_Stop();
}
void MS5607_ADC_Answer(u8 *Data)
{
u8 err=0;
IIC_Start();
IIC_Send_Byte(MS5607BA_ADR_Read);
err = IIC_Wait_Ack();
*Data++=IIC_Read_Byte(1);
*Data++=IIC_Read_Byte(1);
*Data=IIC_Read_Byte(0);
IIC_Stop();
}
读取PRPM 0xa0 —0xae
void MS5607BA_readPROM(void)
{
uint16_t value=0;u8 Promdata[2]={0};
u8 i;
u8 err=0;
u8 Read_CMD=Prom_Read_CMD;
for(i=0;i<8;i++)
{
IIC_Start();
IIC_Send_Byte(MS5607BA_ADR_Write);
err = IIC_Wait_Ack();
IIC_Send_Byte(Read_CMD);
err = IIC_Wait_Ack();
IIC_Stop();
IIC_Start();
IIC_Send_Byte(MS5607BA_ADR_Read);
err = IIC_Wait_Ack();
Promdata[0] = IIC_Read_Byte(1);
Promdata[1] = IIC_Read_Byte(0);
IIC_Stop();
Cal_C[i]=Promdata[0]<<8|Promdata[1];
Read_CMD+=2;
}
printf("\n The MS561101BA is reading PROM : \r\n");
}
读取D1值
u32 MS5607BA_Conversion_GetPressure(void)
{
u8 Press_Temp[3]={0};
u32 D1_PessTmp=0;
MS5607_Send_CMD(MS5607BA_D1_OSR_4096);
delay_ms(50);
MS5607_Send_CMD(MS5607BA_ADC_READ);
delay_ms(50);
MS5607_ADC_Answer(Press_Temp);
delay_ms(50);
D1_PessTmp= Press_Temp[0]<<16| Press_Temp[1]<<8|Press_Temp[2];
return D1_PessTmp;
}
读取D2 温度的数字值
u32 MS5607BA_Conversion_Temp(void)
{
u8 Tempbuf[3]={0};
u32 D2_Data;
MS5607_Send_CMD(MS5607BA_D2_OSR_4096);
delay_ms(50);
MS5607_Send_CMD(MS5607BA_ADC_READ);
delay_ms(50);
MS5607_ADC_Answer(Tempbuf);
delay_ms(50);
D2_Data= Tempbuf[0]<<16| Tempbuf[1]<<8|Tempbuf[2];
return D2_Data;
}
计算温度
char MS5607_GetTemperature (void)
{
D2_Temp = MS5607BA_Conversion_Temp();
if(D2_Temp == 0)
return 0;
delay_ms ( 20 );
if(D2_Temp > ( ( uint32_t ) Cal_C[5] * (0x00000001 << 8) ))
dT = D2_Temp - ( ( uint32_t ) Cal_C[5] * (0x00000001 << 8) );
else
{
dT = ( ( uint32_t ) Cal_C[5] * (0x00000001 << 8) ) - D2_Temp;
dT *= -1;
}
Temperature = 2000 + (( dT * Cal_C[6] ) / (0x00000001 << 23));
if(Temperature<-4000) Temperature=-4000;
if(Temperature>8500) Temperature=8500;
return 1;
}
计算温度补偿压力
char MS5607_GetPressure (void)
{
D1_Pess = MS5607BA_Conversion_GetPressure();
if(D1_Pess == 0)
return 0;
delay_ms ( 20 );
OFF = ( ( float)Cal_C[2] * (0x00000001 << 17) ) + ( ( float ) Cal_C[4] * dT ) / 64.0;
SENS = ( ( float ) Cal_C[1] * (0x00000001 << 16) ) + ( ( float ) Cal_C[3] * dT ) / 128.0;
if ( Temperature < 2000 )
{
T2 = ( dT * dT ) / (( u32 )0x0000000001 << 31);
OFF2 = 61 * (( Temperature - 2000 ) * ( Temperature - 2000 )) / 16;
SENS2 = 2 * (( Temperature - 2000 ) * ( Temperature - 2000 )) ;
if ( Temperature < -1500 )
{
OFF2 = OFF2 + 15 * (( Temperature + 1500 ) * ( Temperature + 1500 )) ;
SENS2 = SENS2 + 8 * (( Temperature + 1500 ) * ( Temperature + 1500 )) ;
}
}
else
{
T2 = 0;
OFF2 = 0;
SENS2 = 0;
}
Temperature = Temperature - T2;
OFF = OFF - OFF2;
SENS = SENS - SENS2;
Press = ( D1_Pess * SENS / (0x00000001 << 21) - OFF ) / (0x00000001 << 15);
MS5607TempPress.Pressure=(float)Press/100;
MS5607TempPress.Temperature=(float)Temperature/100;
if(MS5607TempPress.Temperature<-40)MS5607TempPress.Temperature=-40;
if(MS5607TempPress.Temperature>85) MS5607TempPress.Temperature=85;
if(MS5607TempPress.Pressure<10) MS5607TempPress.Pressure=10;
if(MS5607TempPress.Pressure>1200) MS5607TempPress.Pressure=1200;
return 1;
}
开始的时候全速运行的时候读数有问题,最后发现两个命令之间时间太短没有延迟时间,单步调试时好的。在进行修改了延迟时间后全速运行是可行的,在折腾了一天后终于可以检测到温度压力以及湿度的值。
温湿度以及气压的值如下变量的所示:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)