这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 热敏电阻至数字输出转换器MAX31865的驱动源码

共5条 1/1 1 跳转至

热敏电阻至数字输出转换器MAX31865的驱动源码

工程师
2021-05-08 22:48:25     打赏

MAX31865是简单易用的热敏电阻至数字输出转换器,优化用于铂电阻温度检测器(RTD)。外部电阻设置RTD灵敏度,高精度Δ- Σ ADC将RTD电阻与基准电阻之比转换为数字输出。MAX31865输入具有高达±45V的过压保护,提供可配置的RTD及电缆开路、短路条件检测。


驱动源码可参考如下:


/*********start********第一块max31865芯片相关************************/    

//硬件对应

#define T1_SCLK        PFout(8)   // 对应PG1 

#define T1_MISO        PFin(6)   // 对应PF15     

#define T1_MOSI        PFout(4)  // 对应PF13  

#define T1_CS          PFout(2)  // 对应PF11  

#define T1_RE          PFin(0)    // 对应PB1   

//信号描述定义    

#define SDI_H  T1_MOSI=1

#define SDI_L  T1_MOSI=0

#define SCLK_H T1_SCLK=1

#define SCLK_L T1_SCLK=0

#define NCS_H  T1_CS=1

#define NCS_L  T1_CS=0


#define SDO    T1_MISO    

#define DRDY   T1_RE    


//数据变量    

IO_EXT u8  Fault_Status; //出水max31865芯片错误标志   

IO_EXT float tempture;  //出水

IO_EXT u16   temp1_ad;  //出水的AD值


/*********end********第一块max31865芯片相关************************/   

//功能实现函数

IO_EXT void ConfigurePortPins(void); //初始化 引脚功能   

IO_EXT void Task_ReadIOInfo(void); //读取IO资源函数

IO_EXT void MAX31865_SB_Write(u8 addr,u8 wdata); //3线配置MAX31865

IO_EXT u8 MAX31865_SB_Read(u8 addr);


#define IO_GLOBAL


#include "io.h"

#include "main.h"

/**

* @brief        MAX31865芯片所用单片机引脚的初始化 

* @param        

* @param        

* @retval   

*/

static void MAX31865_Port_Init(void)

{  

    GPIO_InitTypeDef GPIO_InitStruct;

  /*##-1- Enable peripherals and GPIO Cloc #########################*/

  /* Enable GPIO TX/RX clock */

    __HAL_RCC_GPIOF_CLK_ENABLE();

  /* SPI SCK GPIO pin configuration********  PG1  */

  GPIO_InitStruct.Pin       = GPIO_PIN_8;      //哪个引脚

  GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;  //输出

  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH; //速度选最快的

  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  /* SPI MISO GPIO pin configuration****** PF15 */

  GPIO_InitStruct.Pin = GPIO_PIN_6;

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);


  /* SPI MOSI GPIO pin configuration**** PF13  */

  GPIO_InitStruct.Pin = GPIO_PIN_4;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);


  /* SPI cs GPIO pin configuration**** PF11  */  

  GPIO_InitStruct.Pin = GPIO_PIN_2;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

    /*  re GPIO pin configuration****** PB1 */

  GPIO_InitStruct.Pin = GPIO_PIN_0;

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); 

   NCS_H;

   SCLK_H;

}

/**

* @brief        IO资源引脚的初始化 

* @param        

* @param        

* @retval   

*/

void ConfigurePortPins(void)

{

    MAX31865_Port_Init();

}


#define  DT_NUM    0x30  //延时时间

/**

* @brief        简单粗暴的延时函数

* @param        

* @param        

* @retval   

*/

void Delay(u32 nCount) 

  for(; nCount != 0; nCount--); 

}


/**

* @brief        读max31865的寄存器

* @param        地址

* @param        

* @retval   

*/


u8 MAX31865_SB_Read(u8 addr)//SPI Single-Byte Read

{

  u8 i=0;

  u8 read = 0;

  

  NCS_L;

  Delay(DT_NUM);

  for(i = 0; i < 8; i++)

  {

    SCLK_L;

    if (addr & 0x80)

        {SDI_H;}

    else 

        {SDI_L;}

    Delay(DT_NUM);

    SCLK_H;

    addr <<= 1;

    Delay(DT_NUM);

  }

  Delay(DT_NUM);

  for (i = 0; i < 8; i++)

  {

    SCLK_L;

    read = read<<1;

    Delay(DT_NUM);

    if(SDO)

    {

      read++;

    }

    SCLK_H;

    Delay(DT_NUM);

  }

  NCS_H;

  return read;

}


/**

* @brief        写max31865的寄存器

* @param        地址

* @param        数据

* @retval   

*/

void MAX31865_SB_Write(u8 addr,u8 wdata)//SPI Single-Byte Write

{

  u8 i = 0;

  NCS_L;                          //拉低片选信号

  Delay(DT_NUM);          //粗暴延时

  //写地址

  for(i = 0; i < 8; i++)  //0-7

  {

    SCLK_L;                                  //时钟线拉高

    if (addr & 0x80)      // xxxx xxxx  & 1000 0000   addr最高位是否为1简单判断

        {SDI_H;}                  // 为1 发送高电平                        

    else 

        {SDI_L;}                          //为0 发送低电平

    Delay(DT_NUM);                   //粗暴延时

    SCLK_H;               //时钟线拉低

    addr <<= 1;           //数据左移 判断次高位

    Delay(DT_NUM);                  //粗暴延时

  }

  //写数据

  for(i = 0; i < 8; i++)

  {

    SCLK_L;

    if (wdata & 0x80)

        {SDI_H;}

    else {SDI_L;}

    Delay(DT_NUM);

    SCLK_H;

    wdata <<= 1;

    Delay(DT_NUM);

  }

  //操作完成拉高片选

  NCS_H;

}



/**

* @brief        简单滤波计算温度值

* @param        

* @param        

* @retval   扩大100倍的温度

*/

u8 temp1;

u8 temp2;

float Get_tempture(void)//PT100

{

  float temps;       

  

  u16 dtemp[2];

  u16 data_temp;

  u8 i;

  static u8 cnt_num =0;

  static u16 temp1_num[8];

  static u32 temp1_sum;

  static u16 temp1_min =0;

  static u16 temp1_max =0;

  dtemp[0]=MAX31865_SB_Read(0x01);//读RTD_MSB

  dtemp[1]=MAX31865_SB_Read(0x02);//读RTD_LSB  

  data_temp=(dtemp[0]<<7)+(dtemp[1]>>1);//Get 15Bit DATA;

    

  temp1=dtemp[0];

  temp2=dtemp[1];

  temp1_ad = data_temp;


    if(cnt_num<8)cnt_num++;

    else cnt_num=0;

    

    temp1_num[cnt_num] = data_temp;


        temp1_min = temp1_num[cnt_num];

          temp1_max = temp1_num[cnt_num];


          if(power_time < 10) return 0; 

  

          for (i=0,temp1_sum=0; i<8; i++)

          {

                 temp1_sum += temp1_num[i];

                 if (temp1_num[i]<=temp1_min) temp1_min = temp1_num[i];

                 if (temp1_num[i]>=temp1_max) temp1_max = temp1_num[i];

          }


          temp1_sum -= temp1_min;        

          temp1_sum -= temp1_max;

    temps = temp1_sum/6;

        

    temps=(temps*402)/32768;//Here is the rtd R value;

  

    temps=(temps-100)*100/0.385055;//A gruad 本身值经扩大100倍单位为1摄氏度

   

    return temps;

}


/**

* @brief        得到PT100温度值

* @param        

* @param        

* @retval 

*/


void  GetPT100_Temp(void) 


        u8 i;

        static u8 cnt_num =0;

        static float temp1_num[64];

        static float temp1_sum;

        static float temp1_min =0;

        static float temp1_max =0;

        

    if(cnt_num<64)cnt_num++;

    else cnt_num=0;

    

    temp1_num[cnt_num] = Get_tempture();


        temp1_min = temp1_num[cnt_num];

          temp1_max = temp1_num[cnt_num];


          if(power_time < 10) return; 

  

          for (i=0,temp1_sum=0; i<64; i++)

          {

                 temp1_sum += temp1_num[i];

                 if (temp1_num[i]<=temp1_min) temp1_min = temp1_num[i];

                 if (temp1_num[i]>=temp1_max) temp1_max = temp1_num[i];

          }

          

          temp1_sum -= temp1_min;        

          temp1_sum -= temp1_max;

    tempture = temp1_sum/62;

    Fault_Status=MAX31865_SB_Read(0x07);//Get Fault_Status


/**

* @brief        读取IO资源

* @param        

* @param        

* @retval 

*/





关键词: MAX31865     热敏电阻     DAC    

工程师
2021-05-08 22:55:01     打赏
2楼

美信这个芯片的功能很少见啊,应该不错!


工程师
2021-05-08 23:00:04     打赏
3楼

有没有碰到用带接地屏蔽网的热电偶,有些天,会一直读不出实际温度,读出温度为0,工业现场,原来用玻璃纤维包裹的热电偶一直正常,后来客户换用带接地屏蔽网的热电偶就有问题,
然后,想了佷多办法都解决不了,最后还是用了无接地的屏蔽网热电偶敷衍过关


工程师
2021-05-08 23:05:11     打赏
4楼

搭车问一下,这个芯片有没有国产替代型号?


工程师
2021-05-08 23:25:48     打赏
5楼

代码写的非常不错


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]