STM32软硬件SPI读取MAX31865 PT100温度支持shell功能
生活随笔
收集整理的這篇文章主要介紹了
STM32软硬件SPI读取MAX31865 PT100温度支持shell功能
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
? ? ? ? PT100的溫度讀取硬件是利用TB的MAX31865現成模塊,也可以自己做相應的PCB。原理圖可以查看美信官方文檔作為參考。傳送門:https://www.maximintegrated.com/en/products/interface/sensor-interface/MAX31865.html
????????STM32的SPI功能就不多贅述,可以利用軟件模擬SPI或使用STM32的硬件SPI。相應的優缺點個人使用總結單個SPI通訊用軟硬件都行,多機通訊使用STM32的硬件SPI較好。
????????下面將展示STM32軟硬件SPI讀取MAX31865,獲得電阻值計算溫度的模塊代碼。
????????百度云鏈接:https://pan.baidu.com/s/1B8qxTVGqyX6V1TCjKcCfrQ?
????????提取碼:fq7g
????????CSDN連接:max31865軟硬件讀寫.rar-互聯網文檔類資源-CSDN下載
顯示效果如下:
軟件模擬SPI讀取MAX31865,轉換為溫度輸出。
#include "max31865.h"/*********************************************** 調用方式:MAX31865_Init() 返回值: SDO ---> PC10 CS ---> PC12 SCLK ---> PC9 SDI ---> PC11 DRDY ---> PC13 函數說明:MAX31865 初始化,軟件模擬 ************************************************/ void MAX31865_Init(void) {GPIO_InitTypeDef GPIO_InitStructure ;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin = MAX31865_CS|MAX31865_SCLK|MAX31865_SDI;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(MAX31865_CONTROL_PORT,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = MAX31865_SDO|MAX31865_DRDY;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(MAX31865_CONTROL_PORT,&GPIO_InitStructure);MAX31865_CS_SET;MAX31865_SCLK_SET; }/*********************************************** 調用方式:MAX31865_Write() 返回值: 函數說明:MAX31865 寫寄存器,addr:寄存器地址,data:數據 ************************************************/ void MAX31865_Write(unsigned char addr, unsigned char data) {unsigned char i;MAX31865_CS_CLR;for(i=0;i<8;i++) //寫地址{MAX31865_SCLK_CLR;if(addr&0x80) MAX31865_SDI_SET;else MAX31865_SDI_CLR;MAX31865_SCLK_SET;addr<<=1;}for(i=0;i<8;i++) //寫數據{MAX31865_SCLK_CLR;if(data&0x80) MAX31865_SDI_SET;else MAX31865_SDI_CLR;MAX31865_SCLK_SET;data<<=1;}MAX31865_CS_SET; } /*********************************************** 調用方式:MAX31865_Read() 返回值: data 函數說明:MAX31865 讀寄存器 ,addr:寄存器地址 ************************************************/ unsigned char MAX31865_Read(unsigned char addr) {unsigned char i;unsigned char data=0;MAX31865_CS_CLR;for(i=0;i<8;i++) //寫地址{MAX31865_SCLK_CLR;if(addr&0x80) MAX31865_SDI_SET;else MAX31865_SDI_CLR;MAX31865_SCLK_SET;addr<<=1;}for(i=0;i<8;i++) //讀數據{MAX31865_SCLK_CLR;data<<=1; MAX31865_SCLK_SET; if(MAX31865_SDO_READ) data|=0x01;else data|=0x00;}MAX31865_CS_SET;return data; } /*********************************************** 調用方式:MAX31865_Cfg() 返回值: 函數說明:MAX31865 配置 ************************************************/ void MAX31865_Cfg(void) {//BIAS ON,自動,4線,50HZ 根據文件修改四線還是三線MAX31865_Write(0x80, 0xC3); } /*********************************************** 調用方式:MAX31865_GetTemp() 返回值: 函數說明:MAX31865 獲取溫度 ************************************************/ float MAX31865_GetTemp(void) { unsigned int data;float Rt;float Rt0 = 100; //PT100 float Z1,Z2,Z3,Z4,temp;float a = 3.9083e-3;float b = -5.775e-7;float rpoly; // MAX31865_Write(0x80, 0xD3);data=MAX31865_Read(0x01)<<8;data|=MAX31865_Read(0x02);data>>=1; //去掉Fault位Rt=(float)data/32768.0*RREF;Z1 = -a;Z2 = a*a-4*b;Z3 = 4*b/Rt0;Z4 = 2*b;temp = Z2+Z3*Rt;temp = (sqrt(temp)+Z1)/Z4;if(temp>=0){return temp;}rpoly = Rt;temp = -242.02;temp += 2.2228 * rpoly;rpoly *= Rt; // squaretemp += 2.5859e-3 * rpoly;rpoly *= Rt; // ^3temp -= 4.8260e-6 * rpoly;rpoly *= Rt; // ^4temp -= 2.8183e-8 * rpoly;rpoly *= Rt; // ^5temp += 1.5243e-10 * rpoly;return temp; } #ifndef __MAX31865_H #define __MAX31865_H#include "stm32f10x.h" #include "math.h" #include "usart_arb.h" #include "delay.h"/* MAX31865參考電阻 */ #define RREF (430) //400Ω/* MAX31865控制口 */ #define MAX31865_CONTROL_PORT GPIOC #define MAX31865_SDO GPIO_Pin_10 #define MAX31865_CS GPIO_Pin_12 #define MAX31865_SCLK GPIO_Pin_9 #define MAX31865_SDI GPIO_Pin_11 #define MAX31865_DRDY GPIO_Pin_13 #define MAX31865_CS_SET GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_CS,Bit_SET) #define MAX31865_CS_CLR GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_CS,Bit_RESET) #define MAX31865_SCLK_SET GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_SCLK,Bit_SET) #define MAX31865_SCLK_CLR GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_SCLK,Bit_RESET) #define MAX31865_SDI_SET GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_SDI,Bit_SET) #define MAX31865_SDI_CLR GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_SDI,Bit_RESET)#define MAX31865_SDO_READ GPIO_ReadInputDataBit(MAX31865_CONTROL_PORT,MAX31865_SDO) #define MAX31865_DRDY_READ GPIO_ReadInputDataBit(MAX31865_CONTROL_PORT,MAX31865_DRDY)void MAX31865_Init(void); //MAX31865 初始化,軟件模擬 void MAX31865_Cfg(void); //MAX31865 配置 float MAX31865_GetTemp(void);//MAX31865 獲取溫度#endif硬件SPI讀取MAX31865,轉換為溫度輸出。?
#include "stm32_spi.h"__IO uint32_t TIMEOUT=LONG_TIMEOUT; /*********************************************** 調用方式: SPI_Inital() SDO ---> PA5 CS ---> PB6 SCLK ---> PA5 SDI ---> PA7 DRDY ---> PB6 返回值: 函數說明:MAX31865 硬件spi初始化 ************************************************/ void SPI_Inital(void) {SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure; // GPIORCC_APB2PeriphClockCmd(SPI_GPIO_CLK, ENABLE);RCC_APB2PeriphClockCmd(SPI_CS_GPIO_CLK, ENABLE);/*!< SPI Periph clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);/*!< GPIO configuration */ /*!< Configure SPI pins */GPIO_InitStructure.GPIO_Pin = SPI_SCK|SPI_MOSI|SPI_MISO;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(MAX31865_SPI_PORT, &GPIO_InitStructure);/*!< Configure SPI pin: CS */GPIO_InitStructure.GPIO_Pin = SPI_CS;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(MAX31865_IO_PORT, &GPIO_InitStructure); //set CS highGPIO_SetBits(MAX31865_IO_PORT, SPI_CS); /*!< SPI configuration */SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize =SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;/* SPI Peripheral Enable */SPI_Cmd(SPI1, ENABLE);/* Apply SPI configuration after enabling it */SPI_Init(SPI1, &SPI_InitStructure); } /*********************************************** 調用方式: SPI_Write() 返回值: 函數說明:SPI寫數據 ************************************************/ uint8_t SPI_Write(uint8_t *buffer, uint8_t nBytes) {uint8_t i;for(i=0;i<nBytes;i++){TIMEOUT = LONG_TIMEOUT;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){ //not emptyif((TIMEOUT--) == 0) return (1);}SPI_I2S_SendData(SPI1,buffer[i]);TIMEOUT = LONG_TIMEOUT;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){ if((TIMEOUT--) == 0) return (1);}SPI_I2S_ReceiveData(SPI1); }return(0); } /*********************************************** 調用方式: SPI_Read() 返回值: 函數說明:SPI讀數據 ************************************************/ uint8_t SPI_Read(uint8_t *buffer, uint8_t nBytes) {uint8_t i;SPI_I2S_ReceiveData(SPI1);for(i=0;i<nBytes;i++){TIMEOUT = LONG_TIMEOUT;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){ //not emptyif((TIMEOUT--) == 0) return (1);}SPI_I2S_SendData(SPI1,0x00);TIMEOUT = LONG_TIMEOUT;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){if((TIMEOUT--) == 0) return (1);}buffer[i]= SPI_I2S_ReceiveData(SPI1);}return(0); } /*********************************************** 調用方式: SPI_WriteByte() 返回值: 函數說明:SPI字節寫數據 ************************************************/ uint8_t SPI_WriteByte(uint8_t data) {TIMEOUT = LONG_TIMEOUT;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){ //not emptyif((TIMEOUT--) == 0) return (1);}SPI_I2S_SendData(SPI1,data);TIMEOUT = LONG_TIMEOUT;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){if((TIMEOUT--) == 0) return (1);}SPI_I2S_ReceiveData(SPI1);SPI_I2S_ReceiveData(SPI1);return(0); } /*********************************************** 調用方式: SPI_WriteByte() 返回值: 函數說明:SPI字節讀數據 ************************************************/ uint8_t SPI_ReadByte(void) {SPI_I2S_ReceiveData(SPI1);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //not empty SPI_I2S_SendData(SPI1,0xff);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return (SPI_I2S_ReceiveData(SPI1)); } /*********************************************** 調用方式: Set_DRDY_Pin_INPUT() 返回值: 函數說明:MAX31865 DRDY輸入IO配置 ************************************************/ void Set_DRDY_Pin_INPUT(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(DRDY_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = DRDY_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(MAX31865_IO_PORT, &GPIO_InitStructure); } /*********************************************** 調用方式: DRDY_Pin_Value() 返回值: 函數說明: 讀MAX31865 DRDY_Pin_Value高低電平 ************************************************/ uint8_t DRDY_Pin_Value(void) {return(GPIO_ReadOutputDataBit(MAX31865_IO_PORT, DRDY_PIN)); } #ifndef __STM32_SPI_H #define __STM32_SPI_H#ifdef __cplusplusextern "C" { #endif/* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h"#define FLAG_TIMEOUT ((uint32_t)0x1000) #define LONG_TIMEOUT ((uint32_t)(10 *FLAG_TIMEOUT))#define MAX31865_SPI_PORT GPIOA #define MAX31865_IO_PORT GPIOB// define SPI pins #define SPI_SCK GPIO_Pin_5 /* GPIOA.5*/ #define SPI_MISO GPIO_Pin_6 /*GPIOA.6*/ #define SPI_MOSI GPIO_Pin_7 /*GPIOA.7*/ #define SPI_CS GPIO_Pin_6 /*GPIOB.6*/ #define DRDY_PIN GPIO_Pin_5 /*GPIOB.5*/#define SPI_GPIO_CLK RCC_APB2Periph_GPIOA #define SPI_CS_GPIO_CLK RCC_APB2Periph_GPIOB #define DRDY_GPIO_CLK RCC_APB2Periph_GPIOB#define SPI_CS_HIGH GPIO_SetBits(MAX31865_IO_PORT, SPI_CS) #define SPI_CS_LOW GPIO_ResetBits(MAX31865_IO_PORT, SPI_CS)void SPI_Inital(void);//MAX31865 硬件spi初始化 uint8_t SPI_Write(uint8_t *buffer, uint8_t nBytes);//SPI寫數據 uint8_t SPI_Read(uint8_t *buffer, uint8_t nBytes); //SPI讀數據 uint8_t SPI_WriteByte(uint8_t data);//SPI字節寫數據 uint8_t SPI_ReadByte(void); //SPI字節讀數據 void Set_DRDY_Pin_INPUT(void);//MAX31865 DRDY輸入IO配置 uint8_t DRDY_Pin_Value(void);//讀MAX31865 DRDY_Pin_Value高低電平#ifdef __cplusplus } #endif#endif #include "max31865.h"/*********************************************** 調用方式:MAX31865_Init() 返回值: SDO ---> PC10 CS ---> PC12 SCLK ---> PC9 SDI ---> PC11 DRDY ---> PC13 函數說明:MAX31865 初始化,軟件模擬 ************************************************/ void MAX31865_Init(void) {GPIO_InitTypeDef GPIO_InitStructure ;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin = MAX31865_CS|MAX31865_SCLK|MAX31865_SDI;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(MAX31865_CONTROL_PORT,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = MAX31865_SDO|MAX31865_DRDY;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(MAX31865_CONTROL_PORT,&GPIO_InitStructure);MAX31865_CS_SET;MAX31865_SCLK_SET; }/*********************************************** 調用方式:MAX31865_Write() 返回值: 函數說明:MAX31865 寫寄存器,addr:寄存器地址,data:數據 ************************************************/ void MAX31865_Write(unsigned char addr, unsigned char data) {unsigned char i;MAX31865_CS_CLR;for(i=0;i<8;i++) //寫地址{MAX31865_SCLK_CLR;if(addr&0x80) MAX31865_SDI_SET;else MAX31865_SDI_CLR;MAX31865_SCLK_SET;addr<<=1;}for(i=0;i<8;i++) //寫數據{MAX31865_SCLK_CLR;if(data&0x80) MAX31865_SDI_SET;else MAX31865_SDI_CLR;MAX31865_SCLK_SET;data<<=1;}MAX31865_CS_SET; } /*********************************************** 調用方式:MAX31865_Read() 返回值: data 函數說明:MAX31865 讀寄存器 ,addr:寄存器地址 ************************************************/ unsigned char MAX31865_Read(unsigned char addr) {unsigned char i;unsigned char data=0;MAX31865_CS_CLR;for(i=0;i<8;i++) //寫地址{MAX31865_SCLK_CLR;if(addr&0x80) MAX31865_SDI_SET;else MAX31865_SDI_CLR;MAX31865_SCLK_SET;addr<<=1;}for(i=0;i<8;i++) //讀數據{MAX31865_SCLK_CLR;data<<=1; MAX31865_SCLK_SET; if(MAX31865_SDO_READ) data|=0x01;else data|=0x00;}MAX31865_CS_SET;return data; } /*********************************************** 調用方式:MAX31865_Cfg() 返回值: 函數說明:MAX31865 配置 ************************************************/ void MAX31865_Cfg(void) {//BIAS ON,自動,4線,50HZ 根據文件修改四線還是三線MAX31865_Write(0x80, 0xC3); } /*********************************************** 調用方式:MAX31865_GetTemp() 返回值: 函數說明:MAX31865 獲取溫度 ************************************************/ float MAX31865_GetTemp(void) { unsigned int data;float Rt;float Rt0 = 100; //PT100 float Z1,Z2,Z3,Z4,temp;float a = 3.9083e-3;float b = -5.775e-7;float rpoly; // MAX31865_Write(0x80, 0xD3);data=MAX31865_Read(0x01)<<8;data|=MAX31865_Read(0x02);data>>=1; //去掉Fault位Rt=(float)data/32768.0*RREF;Z1 = -a;Z2 = a*a-4*b;Z3 = 4*b/Rt0;Z4 = 2*b;temp = Z2+Z3*Rt;temp = (sqrt(temp)+Z1)/Z4;if(temp>=0){return temp;}rpoly = Rt;temp = -242.02;temp += 2.2228 * rpoly;rpoly *= Rt; // squaretemp += 2.5859e-3 * rpoly;rpoly *= Rt; // ^3temp -= 4.8260e-6 * rpoly;rpoly *= Rt; // ^4temp -= 2.8183e-8 * rpoly;rpoly *= Rt; // ^5temp += 1.5243e-10 * rpoly;return temp; } #ifndef __MAX31865_H #define __MAX31865_H#include "stm32f10x.h" #include "math.h" #include "usart_arb.h" #include "delay.h"/* MAX31865參考電阻 */ #define RREF (430) //400Ω/* MAX31865控制口 */ #define MAX31865_CONTROL_PORT GPIOC #define MAX31865_SDO GPIO_Pin_10 #define MAX31865_CS GPIO_Pin_12 #define MAX31865_SCLK GPIO_Pin_9 #define MAX31865_SDI GPIO_Pin_11 #define MAX31865_DRDY GPIO_Pin_13 #define MAX31865_CS_SET GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_CS,Bit_SET) #define MAX31865_CS_CLR GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_CS,Bit_RESET) #define MAX31865_SCLK_SET GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_SCLK,Bit_SET) #define MAX31865_SCLK_CLR GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_SCLK,Bit_RESET) #define MAX31865_SDI_SET GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_SDI,Bit_SET) #define MAX31865_SDI_CLR GPIO_WriteBit(MAX31865_CONTROL_PORT,MAX31865_SDI,Bit_RESET)#define MAX31865_SDO_READ GPIO_ReadInputDataBit(MAX31865_CONTROL_PORT,MAX31865_SDO) #define MAX31865_DRDY_READ GPIO_ReadInputDataBit(MAX31865_CONTROL_PORT,MAX31865_DRDY)void MAX31865_Init(void); //MAX31865 初始化,軟件模擬 void MAX31865_Cfg(void); //MAX31865 配置 float MAX31865_GetTemp(void);//MAX31865 獲取溫度#endif主函數顯示?
/*********************************************** 調用方式:無 返回值: 函數說明:主函數 ************************************************/ int main(void) {Bsp_init();//初始化板載程序while(1){ Get_RTCSencod();//float temp = MAX31865_GetTemp();//軟件模擬spi讀取max31865合成溫度float temp = Get_Hardware_SPI_Temp();//硬件spi讀取max31865合成溫度if(isReadTemp == 1 && isShowShell == 1){#if 0if(SysRTC_Secondflag == 1){SysRTC_Secondflag = 0;printf("%02d:%02d:%02d",THH, TMM, TSS); printf("temp=%.2f\r\n",temp);LED_Light();#endif#if 1if(SysRTC_Secondflag == 1){SysRTC_Secondflag = 0;printf("%02d:%02d:%02d",THH, TMM, TSS);printf("temp=%.2f\r\n",temp);LED_Light();//delay_ms(100);}#endif}}}硬件模塊連接示意圖:?
總結
以上是生活随笔為你收集整理的STM32软硬件SPI读取MAX31865 PT100温度支持shell功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android备份手机号码,简单四步 完
- 下一篇: 2022年湖北省大学生电子设计竞赛A题(