本帖最后由 忘川 于 2013-9-21 23:56 编辑
请问有人使用过气压传感器MS5611吗?最近从BMP085转去做分辨率高一点的MS5611,但是手头上只有MS5611的I2C参考程序。
请问有大侠可以分享一下MS5611在MSP430系列上使用SPI接口的程序供参考一下吗?无比感谢!!!
/----------------------------------------------------------------------------------------------------------------------------------------------------/
更新帖子:我写了一下SPI接口的程序,然后发现读出PROM的数据要不都是0要不都是0xff,求大侠现身赐教……T-T
程序如下:
#include <msp430x54x.H>
#include <math.h> //Keil library
#include <stdio.h>
#include <stdlib.h> //Keil library
#include "MS5611.h"
#include "CC1101.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define SPI_B0_MO BIT1
#define SPI_B0_MI BIT2
#define MS_B0_CLK BIT3
#define SPI_B0_CS BIT0
#define MS5611_PS BIT7
#define MS5611_SPI P2DIR |= MS5611_PS; P2OUT &= ~MS5611_PS
#define MS5611_Enable P3OUT &= ~SPI_B0_CS
#define MS5611_Disable P3OUT |= SPI_B0_CS
void Init_SPI_B0(void);
void Wait_MS();
unsigned char SPI_B0_Send_byte(unsigned char byte);
unsigned char SPI_B0_Receive_byte(void);
void SPI_B0_Strobe(unsigned char strobe);
unsigned char SPI_B0_Read(unsigned char addr);
unsigned char SPI_B0_Read_16bits(unsigned char addr);
void MS5611_RESET();
void MS5611_Init();
void MS5611_PROM_READ();
unsigned long MS5611_CONVERSION(unsigned char command);
void MS5611_getTemperature(unsigned char OSR_Temp);
void MS5611_getPressure(unsigned char OSR_Pres);
float get_altitude();
#define MS5611_ADC 0x00
#define CMD_MS5611_RESET 0x1E
#define CMD_MS5611_PROM_Setup 0xA0
#define CMD_MS5611_PROM_C1 0xA2
#define CMD_MS5611_PROM_C2 0xA4
#define CMD_MS5611_PROM_C3 0xA6
#define CMD_MS5611_PROM_C4 0xA8
#define CMD_MS5611_PROM_C5 0xAA
#define CMD_MS5611_PROM_C6 0xAC
#define CMD_MS5611_PROM_CRC 0xAE
#define CMD_CONVERT_D1_OSR4096 0x48 // Maximun resolution
#define CMD_CONVERT_D2_OSR4096 0x58 // Maximun resolution
unsigned long setup,C1,C2,C3,C4,C5,C6,CRC; //用于存放PROM中的8组数据
unsigned long D1_Pres,D2_Temp; // 存放压力和温度
float dT,Temperature,Pressure;
double OFF,SENS;
float TEMP2,Aux,OFF2,SENS2; //温度校验值
/*-------------------------SPI_B0-----------------------------*/
void Init_SPI_B0(void)
{
P3SEL |= 0x0E; // P9.1-3 SPI option select
UCB0CTL1 |= UCSWRST; // 复位SPI状态机
UCB0CTL1 |= UCSSEL__SMCLK; // 选择SCK参考源为SMCLK
UCB0CTL0 |= UCMST+UCSYNC+UCCKPH+UCMSB; // 3-pin, 8-bit SPI master, Clock polarity high, MSB
UCB0CTL0 &= ~UCCKPL;
UCB0BR0 = 0x02;
UCB0BR1 = 0x00;
UCB0CTL1 &= ~UCSWRST;
}
void Wait_MS()
{
while(P3IN&SPI_B0_MI);
}
unsigned char SPI_B0_Send_byte(unsigned char byte)
{
while((UCB0IFG&UCTXIFG)==0);
UCB0TXBUF=byte;
while((UCB0IFG&UCRXIFG)==0);
return(UCB0RXBUF);
}
unsigned char SPI_B0_Receive_byte(void)
{
return SPI_B0_Send_byte(0);
}
unsigned char SPI_B0_Read(unsigned char addr)
{
unsigned char rTemp;
MS5611_Enable; // CS=0 CS enabl
Wait_MS();
SPI_B0_Send_byte(addr); // Send address
rTemp = SPI_B0_Receive_byte();
MS5611_Disable; // CS=1 CS disable
return ( rTemp );
}
unsigned char SPI_B0_Read_16bits(unsigned char addr)
{
unsigned char byteH,byteL;
unsigned int return_value;
MS5611_Enable;
SPI_B0_Send_byte(addr);
byteH = SPI_B0_Receive_byte();
byteL = SPI_B0_Receive_byte();
MS5611_Disable;
return_value = ((unsigned int)byteH<<8) | (byteL);
return(return_value);
}
void SPI_B0_Strobe(unsigned char strobe)
{
MS5611_Enable; //CS=0 CS enable
Wait_MS(); // Wait for CCxxxx ready
SPI_B0_Send_byte(strobe); // Send strobe
MS5611_Disable;
}
/*-------------------------MS5611-----------------------------*/
void MS5611_RESET()
{
SPI_B0_Strobe(CMD_MS5611_RESET);
}
void MS5611_PROM_READ()
{
//MS5611_Enable;
//Wait_MS();
C1 = SPI_B0_Read_16bits(CMD_MS5611_PROM_C1);
C2 = SPI_B0_Read_16bits(CMD_MS5611_PROM_C2);
C3 = SPI_B0_Read_16bits(CMD_MS5611_PROM_C3);
C4 = SPI_B0_Read_16bits(CMD_MS5611_PROM_C4);
C5 = SPI_B0_Read_16bits(CMD_MS5611_PROM_C5);
C6 = SPI_B0_Read_16bits(CMD_MS5611_PROM_C6);
setup = SPI_B0_Read_16bits(CMD_MS5611_RESET);
CRC = SPI_B0_Read_16bits(CMD_MS5611_PROM_CRC);
//MS5611_Disable;
}
void MS5611_Init()
{
Init_SPI_B0();
MS5611_SPI;
P3DIR |= BIT0; P3OUT |= BIT0;
MS5611_RESET();
delay_ms(10);
MS5611_PROM_READ();
delay_ms(10);
}
long MS5611_SPI_read_ADC()
{
unsigned char byteH,byteM,byteL;
long return_value;
MS5611_Enable;
SPI_B0_Send_byte(MS5611_ADC);
byteH = SPI_B0_Receive_byte();
byteM = SPI_B0_Receive_byte();
byteL = SPI_B0_Receive_byte();
MS5611_Disable;
return_value = (((long)byteH)<<16) | (((long)byteM)<<8) | (byteL);
return(return_value);
}
void MS5611_getPressure(unsigned char OSR_Pres)
{
SPI_B0_Strobe(CMD_CONVERT_D1_OSR4096);
D1_Pres=MS5611_SPI_read_ADC();
delay_ms(10);
OFF=(ulong)C2*65536+((ulong)C4*dT)/128;
SENS=(ulong)C1*32768+((ulong)C3*dT)/256;
if(Temperature<2000)
{
// second order temperature compensation when under 20 degrees C
TEMP2 = (dT*dT) / 0x80000000;
Aux = Temperature*Temperature;
OFF2 = 2.5*Aux;
SENS2 = 1.25*Aux;
Temperature = Temperature - TEMP2;
OFF = OFF - OFF2;
SENS = SENS - SENS2;
}
Pressure=(D1_Pres*SENS/2097152-OFF)/32768;
}
void MS5611_getTemperature(unsigned char OSR_Temp)
{
SPI_B0_Strobe(CMD_CONVERT_D2_OSR4096);
D2_Temp=MS5611_SPI_read_ADC();
delay_ms(10);
dT=D2_Temp - (((ulong)C5)<<8);
Temperature=2000+dT*((ulong)C6)/8388608;
}
float get_altitude()
{
float tmp_float,Altitude;
tmp_float = (Pressure / 101325.0);
tmp_float = pow(tmp_float, 0.190295);
Altitude = 44330 * (1.0 - tmp_float);
return (Altitude);
}
void main(void)
{
int i=0;
float altitude[10];
Init_CLK();
//Init_1101();
MS5611_Init();
while(1)
{
MS5611_getTemperature(CMD_CONVERT_D2_OSR4096);
MS5611_getPressure(CMD_CONVERT_D1_OSR4096);
altitude[i++]=get_altitude();
}
_EINT();
LPM4;
}
/*-------------------------------------9月21日更新--------------------------------------*/
楼主已经解决了MS5611的通信问题,上述程序是可用的,没有错误,时序以及端口引脚设置均正确。
另外请问各位大侠是否有人使用过MS5611该款气压传感器?楼主意图使用差分来确定两个物体之间的高度差,但是发现即便是两个芯片放在同一水平面依旧恒久地存在着1米~两米的差别(随时间而有所改变),而该问题在BMP085却不会出现。请问有人了解过该问题吗?如何解决?还是说只是楼主的芯片有问题?
|