1. 程式人生 > >io口模擬spi,stm32f103與MS5611基於spi匯流排的溫度壓力高度資料讀取

io口模擬spi,stm32f103與MS5611基於spi匯流排的溫度壓力高度資料讀取

以下檔案為原始檔

/**

    -----------------------MS5611驅動 && IO口模擬SPI驅動-------------------------

  *****************************************************************************/

/* 包含的標頭檔案 --------------------------------------------------------------*/
#include "ms5611_spi.h"
#include "delay.h"
#include "math.h"
/***************************************************
函式名稱:MS_SPI_Delay
功    能:SPI延時
作    者:MANGO
****************************************************/
void MS_SPI_Delay(void)
{
  uint16_t cnt = 5;

  while(cnt--);
}
/***************************************************
函式名稱:MS_SPI_GPIO_Conf
功    能:SPI引腳配置
作    者:MANGO
****************************************************/
void MS_SPI_GPIO_Conf(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //推輓輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      //IO口速度設定為50MHz
    
    /* CS CLK MOSI */
    GPIO_InitStructure.GPIO_Pin = MS_PIN_SPI_CS|MS_PIN_SPI_CLK|MS_PIN_SPI_MOSI;
    GPIO_Init(GPIOB, &GPIO_InitStructure);                                // 三個IO均是PORT_B,配置引數相同,可以一起初始化
    
    /* MISO */
    GPIO_InitStructure.GPIO_Pin = MS_PIN_SPI_MISO;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //浮空輸入
    GPIO_Init(MS_PORT_SPI_MISO, &GPIO_InitStructure);
}   
 /***************************************************
函式名稱:MS_SPI_Init
功    能:SPI初始化
作    者:MMANGO
****************************************************/
void MS_SPI_Init(void)
{
    MS_SPI_GPIO_Conf();
    
    MS_SPI_CS_DISABLE;
    MS_SPI_CLK_HIGH;
    MS_SPI_MOSI_HIGH;
    
}
 /***************************************************
函式名稱:MS_SPI_WriteByte
功    能:SPI寫一位元組資料
參    數:TxData  傳送的位元組資料
作    者:MANGO
****************************************************/
void MS_SPI_WriteByte(uint8_t TxData)
{
  uint8_t cnt;

  for(cnt=0; cnt<8; cnt++)
  {
    MS_SPI_CLK_LOW;                                 //時鐘 - 低
    MS_SPI_Delay();

    if(TxData & 0x80)                            //傳送資料
      MS_SPI_MOSI_HIGH;
    else
      MS_SPI_MOSI_LOW;
    TxData <<= 1;

//    MS_SPI_Delay();
    MS_SPI_CLK_HIGH;                                //時鐘 - 高
    MS_SPI_Delay();
  }
}
 /***************************************************
函式名稱:MS_SPI_ReadByte
功    能:SPI讀一位元組資料
參    數:RxData  接收的位元組資料
作    者:MANGO
****************************************************/
uint8_t MS_SPI_ReadByte(void)
{
  uint8_t cnt;
  uint8_t RxData = 0;

  for(cnt=0; cnt<8; cnt++)
  {
    MS_SPI_CLK_LOW;                                 //時鐘 - 低
    MS_SPI_Delay();

    RxData <<= 1;
    if(MS_SPI_MISO_READ)                            //讀取資料
    {
      RxData |= 0x01;
    }

    MS_SPI_CLK_HIGH;                                //時鐘 - 高
    MS_SPI_Delay();
  }

  return RxData;
}
 /***************************************************
函式名稱:MS_Init
功    能:MS5611初始化
參    數:coef 地址1-6位校準係數,0為出產資料和設定,7為序列程式碼和CRC
作    者:MANGO
****************************************************/
void MS_Init(uint16_t coef[8])
{
    uint16_t i;
    uint8_t data[16]={0};

    
    MS_SPI_CS_ENABLE;
    MS_SPI_WriteByte(0x1E);     //Reset 5611
    delay_us(2800);
    MS_SPI_CS_DISABLE;    
/*********向MS5611寫指令返回係數************/
    for(i=0;i<8;i++)
    {
        MS_SPI_Delay();
        MS_SPI_CS_ENABLE;
        MS_SPI_WriteByte(0xa0+2*i);    
        data[2*i]=MS_SPI_ReadByte();
        data[2*i+1]=MS_SPI_ReadByte();
        MS_SPI_CS_DISABLE;
        coef[i]=data[2*i]*256+data[2*i+1];
    }    
}
 /***************************************************
函式名稱:MS_Read_Temperature
功    能:MS5611溫度讀取
參    數:ms_data 地址0為溫度,1為壓力,2為高度;coef見上面函式
作    者:MANGO
****************************************************/
void MS_Read_Data(uint16_t coef[8] , float ms_data[3])
{
    uint32_t D1,D2;
    int      dT,T2,TEMP;
    int64_t  OFF,SENS,OFF2,SENS2;
    
    MS_SPI_CS_ENABLE;
    MS_SPI_WriteByte(0x58);
    MS_SPI_CS_DISABLE;
    delay_us(8220);
    MS_SPI_CS_ENABLE;
    MS_SPI_WriteByte(0x00);
    D2=MS_SPI_ReadByte()*65536+MS_SPI_ReadByte()*256+MS_SPI_ReadByte();
    MS_SPI_CS_DISABLE;
    dT = D2 - ((uint32_t)coef[5])*256;
    TEMP = 2000 + dT*((float)coef[6])/8388608;
    
    MS_SPI_CS_ENABLE;
    MS_SPI_WriteByte(0x48);
    MS_SPI_CS_DISABLE;
    delay_us(8220);
    MS_SPI_CS_ENABLE;
    MS_SPI_WriteByte(0x00);
    D1=MS_SPI_ReadByte()*65536+MS_SPI_ReadByte()*256+MS_SPI_ReadByte();
    MS_SPI_CS_DISABLE;
    
    //二階溫度補償
    if(TEMP<2000)
    {
        T2 = (float)(dT*dT)/2147483648;
        OFF2 = 2.5f*(TEMP-2000)*(TEMP-2000);
        SENS2 = 1.25f*(TEMP-2000)*(TEMP-2000);        
        if(TEMP<-1500)
        {
            OFF2 = OFF2 +7*(TEMP+1500)*(TEMP+1500);
            SENS2 = SENS2 +5.5f*(TEMP+1500)*(TEMP+1500);
        }
            
    }
    else
    {
        T2 = 0;
        OFF2 = 0;
        SENS2 = 0;
    }
    
    ms_data[0]=(TEMP-T2)/100.0;            //溫度
    
    OFF = ((int64_t)coef[2])*65536 + (((int64_t)coef[4])*dT)/128 - OFF2;
    SENS = ((int64_t)coef[1])*32768 + (((int64_t)coef[3])*dT)/256 - SENS2;
    
    ms_data[1] = ((D1*SENS/2097152 - OFF)/32768);           
    ms_data[2] = (44330.0f*(1.0f - pow((float)ms_data[1]/101325.0f, 0.190295f)));      //氣壓高度轉換公式   高度單位 m
    ms_data[1] = ms_data[1]/100.0;                   //壓強    mbar

}

以下檔案為標頭檔案

/**
    -----------------------MS5611驅動 && IO口模擬SPI驅動-------------------------

  *****************************************************************************/

/* 定義防止遞迴包含 ----------------------------------------------------------*/
#ifndef __MS_SPI_H
#define __MS_SPI_H

/* 包含的標頭檔案 --------------------------------------------------------------*/
#include "stm32f10x.h"


/* 巨集定義 --------------------------------------------------------------------*/
#define MS_PORT_SPI_CS                                    GPIOB
#define MS_PORT_SPI_CLK                                    GPIOB
#define MS_PORT_SPI_MISO                                GPIOB
#define MS_PORT_SPI_MOSI                                GPIOB

#define MS_PIN_SPI_CS                                        GPIO_Pin_3
#define MS_PIN_SPI_CLK                                    GPIO_Pin_6
#define MS_PIN_SPI_MISO                                    GPIO_Pin_4
#define MS_PIN_SPI_MOSI                                    GPIO_Pin_5

#define MS_SPI_CS_ENABLE                                (MS_PORT_SPI_CS->BRR  = MS_PIN_SPI_CS)            //置0
#define MS_SPI_CS_DISABLE                                (MS_PORT_SPI_CS->BSRR = MS_PIN_SPI_CS)          //置1
#define MS_SPI_CLK_LOW                                    (MS_PORT_SPI_CLK->BRR      = MS_PIN_SPI_CLK)  //置0
#define MS_SPI_CLK_HIGH                                    (MS_PORT_SPI_CLK->BSRR  = MS_PIN_SPI_CLK)   //置1
#define MS_SPI_MOSI_LOW                                 (MS_PORT_SPI_MOSI->BRR = MS_PIN_SPI_MOSI) //置0
#define MS_SPI_MOSI_HIGH                                (MS_PORT_SPI_MOSI->BSRR = MS_PIN_SPI_MOSI) //置1

#define MS_SPI_MISO_READ                                (MS_PORT_SPI_MISO->IDR & MS_PIN_SPI_MISO)     //檢測輸入

/* 函式申明 ------------------------------------------------------------------*/
void MS_SPI_GPIO_Conf(void);    //初始化IO口
void MS_SPI_Init(void);             //初始化SPI口
void MS_SPI_WriteByte(uint8_t TxData);    
uint8_t MS_SPI_ReadByte(void);
void MS_Init(uint16_t coef[8]);
void MS_Read_Data(uint16_t coef[8] , float ms_data[2]);

#endif