打印

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

[复制链接]
11551|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
忘川|  楼主 | 2013-9-15 12:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 忘川 于 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却不会出现。请问有人了解过该问题吗?如何解决?还是说只是楼主的芯片有问题?






相关帖子

沙发
dirtwillfly| | 2013-9-15 16:16 | 只看该作者
没用过。SPI接口都是一样的

使用特权

评论回复
板凳
mmbs| | 2013-9-15 23:26 | 只看该作者
程序差不多的吧。

使用特权

评论回复
地板
mmbs| | 2013-9-15 23:26 | 只看该作者
楼主可以使用模拟IIC读写的。

使用特权

评论回复
5
忘川|  楼主 | 2013-9-18 14:13 | 只看该作者
mmbs 发表于 2013-9-15 23:26
楼主可以使用模拟IIC读写的。

请问有MS5611在MSP430上的例程吗?翻了很多都是在STM32上的……

使用特权

评论回复
6
comeon201208| | 2013-9-20 20:02 | 只看该作者
长须的差不多的啦,SPi总线程序的可以借助存储的SPI总线的介绍的

使用特权

评论回复
7
mmbs| | 2013-9-29 20:27 | 只看该作者
忘川 发表于 2013-9-18 14:13
请问有MS5611在MSP430上的例程吗?翻了很多都是在STM32上的……

stm32一般使用的宏定义,你可以自己写个参考函数的。

使用特权

评论回复
8
曦水长流| | 2014-3-30 20:25 | 只看该作者
楼主,您好!我也在调试MS5611模块,不知您的程序可否参考一下?IIC或者SPI的都可以,不胜感激!!pcq4292669@126.com

使用特权

评论回复
9
taihezhibanh| | 2014-3-30 22:34 | 只看该作者
没用过 不太懂

使用特权

评论回复
10
忘川|  楼主 | 2014-5-2 15:36 | 只看该作者
曦水长流 发表于 2014-3-30 20:25
楼主,您好!我也在调试MS5611模块,不知您的程序可否参考一下?IIC或者SPI的都可以,不胜感激!!pcq42926 ...

其实上面的程序就是可以使用的了,你复制一下。

使用特权

评论回复
11
huaqping| | 2014-12-30 11:15 | 只看该作者
很好,学习了,这个测量是有点偏差,可以用加权平均

使用特权

评论回复
12
littlelincoln| | 2015-3-6 15:40 | 只看该作者
请问你是如何解决的读出数据为00或者ff的?我现在也遇到了这个问题,不知问题出在哪儿,偶尔正常,大多都是00或者ff。被调戏的心力憔悴

使用特权

评论回复
13
vivilzb1985| | 2015-3-7 18:45 | 只看该作者
看来这个主要是基于SPI总线通讯的啊。

使用特权

评论回复
14
shenmu2012| | 2015-3-8 15:46 | 只看该作者
自己写SPI总线程序的话,注意那个SPCLK的信号的啊。

使用特权

评论回复
15
firstblood| | 2015-3-9 20:04 | 只看该作者
做模拟的SPI总线的,需要注意SCLK信号的。

使用特权

评论回复
16
bkbxbsyjh| | 2015-7-29 16:54 | 只看该作者

        MS561101BA_GetTemperature(MS561101BA_D2_OSR_4096);
        MS561101BA_GetPressure(MS561101BA_D1_OSR_4096);
MS5611读D1 D2 读出来的数值为0xff
这是怎么回事呢?

使用特权

评论回复
17
云妹y| | 2015-8-5 23:52 | 只看该作者
请问楼主,如何用串口查看气压值?需要用ADC采集吗

使用特权

评论回复
18
云妹y| | 2015-8-5 23:56 | 只看该作者
mmbs 发表于 2013-9-15 23:26
楼主可以使用模拟IIC读写的。

请问用iic写的话,模块对应的IO口要怎么配置呢?要有就是如何用串口看当前的气压值,用adc采集然后串口发送吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

13

帖子

0

粉丝