[已解决]气压传感器MS5611使用SPI接口的程序

2019-07-26 15:18发布

本帖最后由 忘川 于 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却不会出现。请问有人了解过该问题吗?如何解决?还是说只是楼主的芯片有问题?






友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。