STM32 使用HAL库写Max31855的驱动,并优化了负温度的计算公式

01/17 11:36
阅读数 660

     芯片:STM32F030CC

    外设:SPI2,软件控制CS位,

注意:

  1. SPI的速率不要超过5MHz
  2. 如果用SPI的DMA来接收数据,则DMA的TX和RX一定要,一定要,一定要同时打开,仅打开RX是不行滴。

        

Max31855.h文件

/**
  ******************************************************************************
  * @file           : max31855.h
  * @brief          : header for max31855.c file.
  *                  此文件包含max31855的公共定义。
  ******************************************************************************
  *
  * 
  * 
  *
  ******************************************************************************
  */

/* 定义以防止递归包含 -------------------------------------*/
#ifndef __MAX31855_H__
#define __MAX31855_H__

/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal.h"
#include "stdbool.h"
#include "spi.h"
#include "stdio.h"
/* Private define ------------------------------------------------------------*/
/* SPI Simulator define for MAX31855, 0: use SPI2, 1: use simulator */   
#define SPI_SIM 0 //SPI选择模拟还是硬件,默认是使用SPI硬件。

//#define MAX_SPI_GPIO_Port		GPIOA
//#define MAX_SPI_CS_Pin			GPIO_PIN_4
//#define MAX_SPI_SCK_Pin			GPIO_PIN_5
//#define MAX_SPI_MISO_Pin		GPIO_PIN_6
//#define MAX_SPI_MOSI_Pin		GPIO_PIN_7

#define SPI2_CS_L	HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_RESET)	//CS置低
#define SPI2_CS_H	HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_SET)		//CS置高

/* Exported macro ------------------------------------------------------------*/

/* Exported types ------------------------------------------------------------*/

/* Exported variables --------------------------------------------------------*/

/* Exported functions ------------------------------------------------------- */
void Max31855GetTemp(void);
//float Max31855TCTemp(void);
//float Max31855CJTemp(void);

#endif /* __MAX31855_H__ */

/*********END OF FILE****/

max31855.c


/**
  ******************************************************************************
  * @file           : max31855.c
  * @brief          :MAX31855冷端补偿热电偶到数字转换器程序。
  ******************************************************************************
  *日期:2021.1.14
  *作者:
  * 
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "max31855.h"

/* 私有变量 ---------------------------------------------------------*/
float TCTemp = 0, CJTemp = 0; //热电偶变量 参考端变量
bool TCErrorFlag = false;		//热电偶故障标志位,置0                       

/* MAX31855 functions */
/*热电偶端采样计算*/
static float ThermalCoupleTemp(uint16_t data)
{
  float fraction = 0.0;	//小数部分
//  float temp = 0.0;
  uint16_t intpart = 0;	//整数部分

  
  /* 热电偶小数部分位: D19 D18 */
//  if(data&0x0008)    fraction += 0.5;
//  if(data&0x0004)    fraction += 0.25;

	/*先算小数部分*/
	fraction = ((data&0x000F) >> 2)*0.25;	//小数部分
	intpart = (data>>4)&0x7FFF;		//先将D16到D19位移掉,去符号,取整数部分。
  /*判断正负温度并计算 */
	  if(data&0x8000)	//如果D31位为1,则表示是负温度
	  {
		TCTemp=((2047-intpart)+(1-fraction));
		printf("热电偶端温度:-%0.2f℃\r\n",TCTemp);
	  }
	  else //否则为正温度,直接取数据计算
	  {
		TCTemp=intpart+fraction; //先将D31符号位去掉,再将D16 D17位去掉,保留热电偶温度数据。
		printf("热电偶端温度:%0.2f℃\r\n",TCTemp);
	  }
	return TCTemp;
}

/*参考端采样计算*/
static float ColdJunctionTemp(uint16_t data)
{
  float fraction = 0.0;
//  float temp = 0.0;
  uint16_t intpart = 0;
  
  /*内部温度小数部分: D7 D6 D5 D4*/
//  if(data&0x0080)        fraction += 0.5;
//  if(data&0x0040)        fraction += 0.25;
//  if(data&0x0020)        fraction += 0.125;
//  if(data&0x0010)        fraction += 0.0625;
	
  fraction = ((data&0x00FF) >> 4)*0.0625;  //小数部分
  intpart = (data>>8)&0X7F;	//先将D0到D7位移掉,去符号,取整数部分 
  /*判断正负温度并计算 */	
  if(data&0x8000)	//D15位为符号位,为1表示负温度
  {
	CJTemp=(127-intpart)+(1-fraction);
	printf("参考端:-%0.2f℃\r\n",CJTemp);	  
  }
  else	//否则为正温度
  {
	CJTemp=intpart+fraction;
	printf("参考端:%0.2f℃\r\n",CJTemp);
  }
  return CJTemp;
}

static void Max31855ReadData(uint16_t *TC, uint16_t *CJ)
{
#if SPI_SIM
  uint32_t data = 0;
  
  HAL_GPIO_WritePin(MAX_SPI_GPIO_Port, MAX_SPI_CS_Pin|MAX_SPI_SCK_Pin, GPIO_PIN_RESET);
  SPI_Delay(100);        // Delay 1us
  
  for(int i=0; i<32; i++)
  {
    HAL_GPIO_WritePin(MAX_SPI_GPIO_Port, MAX_SPI_SCK_Pin, GPIO_PIN_SET);    
    /*串行时钟频率最大值 5MHz */
    SPI_Delay(100);        // Delay 1us

    data <<= 1;
    if(HAL_GPIO_ReadPin(MAX_SPI_GPIO_Port, MAX_SPI_MISO_Pin) == GPIO_PIN_SET)
    {
      data |= 1U;      // Bit set
    }
    else
    {
      //data &= ~1U;   // Bit clear
    }
    
    HAL_GPIO_WritePin(MAX_SPI_GPIO_Port, MAX_SPI_SCK_Pin, GPIO_PIN_RESET);    
    SPI_Delay(100);        // Delay 1us
  }
  
  HAL_GPIO_WritePin(MAX_SPI_GPIO_Port, MAX_SPI_CS_Pin, GPIO_PIN_SET);
  
  *TC = data >> 16;
  *CJ = data & 0x0000FFFF;
#else
  uint8_t TXData[4], RXData[4];//32位数据
  
//  HAL_GPIO_WritePin(TC_CS_GPIO_Port, TC_CS_Pin, GPIO_PIN_RESET);
	SPI2_CS_L;
//  SPI_Delay(100);        // Delay 1us 
	HAL_Delay(1);
	HAL_SPI_TransmitReceive(&hspi2, TXData, RXData, 4, 100);
	HAL_Delay(1);
//  SPI_Delay(100);        // Delay 1us 
	SPI2_CS_H;
//  HAL_GPIO_WritePin(TC_CS_GPIO_Port, TC_CS_Pin, GPIO_PIN_SET);
  

  *TC = RXData[0]<<8|RXData[1];	//数据整合起来
  *CJ = RXData[2]<<8|RXData[3];
  
//  printf("RXData[0]=%X\r\n",RXData[0]);
//  printf("RXData[1]=%X\r\n",RXData[1]);
//  printf("RXData[2]=%X\r\n",RXData[2]);
//  printf("RXData[3]=%X\r\n",RXData[3]);
#endif
}

/*得到热电偶和冷量温度。 */
void Max31855GetTemp(void)
{
  uint16_t TC = 0, CJ = 0;
  
  Max31855ReadData(&TC, &CJ);
  
  //当任何SCV(D2)、SCG(D1)或OC(D0)故障激活时,D16的读数为1
  if(TC&0x0001)	//判断是否故障
  {
	TCErrorFlag = true;
  }
  else 
  {
	TCErrorFlag = false;
  }
  
  if(TCErrorFlag==true)		//当出现故障则进行判断
  {
	printf("D16位为1,热电偶故障\r\n");
	if((CJ&0x0001)==0x0001)
	{
	printf("OC热电偶开路\r\n");
	}  
	if((CJ&0x0002)==0x0002)
	{
	printf("SCG热电偶短路到了GND\r\n");
	}
	if((CJ&0x0004)==0x0004)
	{
	printf("SCV热电偶短路到了VCC\r\n");
	}	  
  }
  else	//无故障,进行数据转换
  {
	printf("热电偶无故障\r\n");
	TCTemp = ThermalCoupleTemp(TC);
	CJTemp = ColdJunctionTemp(CJ);
//	printf("热电偶端:%0.2f℃,参考端:%0.2f℃\r\n",TCTemp,CJTemp);
  }
}

///* 获取热电偶温度。*/
//float Max31855TCTemp()
//{
//  return TCTemp;
//}

///*获取冷态温度。*/
//float Max31855_CJTemp()
//{
//  return CJTemp;
//}
/**********END OF FILE****/

main.c 中直接调用Max31855GetTemp();

#include "max31855.h"

//

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		HAL_Delay(1000);
		printf("测试中3!\r\n"); 
	  Max31855GetTemp();
		
  }

 MAX31855负温度的计算公式:

 

展开阅读全文
spi
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部