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