STM32F407+MAX31855实现热电偶测温

2019-07-20 05:36发布

之前一直在论坛里寻求大家的帮助,第一次回馈论坛,发经验分享帖,有不足的地方欢迎大家批评指正。
最近的项目里需要用到温控方面的内容,采用的方案是用电热片(12V,1A供电)进行加热,用K热电偶进行测温,测温芯片选用的是MAX31855。
首先硬件方面的实现:
MAX31855测温电路原理图 MAX31855测温电路原理图
图1.MAX31855测温电路原理图

软件方面,参考了MAX31855的datasheet,和论坛里一位大神分享的经验贴http://www.openedv.com/forum.php?mod=viewthread&tid=17328&highlight=max31855
我觉得软件部分总的来说还是两部分比较重要。
1.是要看懂MAX31855读数据的时序图,这个芯片应该说比较简单了,控制引脚只有三个一个片选(cs),一个时钟(sck),一个读数据(sc)
2.对读取到的32位的数据进行处理,分清楚哪个是你所需要的数据。
程序大概分为三部分
1.MAX31855的初始化
2.MAX31855读取数据
3.对MAX31855读取到的数据进行处理
首先是一些声明和定义
[mw_shl_code=c,true]#define  GPIOA_MAX31855_SCK                       GPIO_Pin_1
#define  GPIOC_MAX31855_CS                        GPIO_Pin_5
#define  GPIOC_MAX31855_SC                        GPIO_Pin_4
#define  GPIOA_MAX31855_SCK_H                                                               GPIO_SetBits(GPIOA,GPIOA_MAX31855_SCK)
#define  GPIOA_MAX31855_SCK_L                                                                     GPIO_ResetBits(GPIOA,GPIOA_MAX31855_SCK)
#define  GPIOC_MAX31855_CS_H                                                                             GPIO_SetBits(GPIOC,GPIOC_MAX31855_CS)
#define  GPIOC_MAX31855_CS_L                                                                             GPIO_ResetBits(GPIOC,GPIOC_MAX31855_CS)
#define  GPIOC_MAX31855_SC_IN                                                                                        (GPIOC->IDR & GPIOC_MAX31855_SC)[/mw_shl_code]


下面是MAX31855的初始化

串口时序图.PNG
图2.时序图
[mw_shl_code=c,true]void MAX31855_Init(){
        GPIO_InitTypeDef  GPIO_InitStructure;
       
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
       
        GPIO_InitStructure.GPIO_Pin = GPIOA_MAX31855_SCK;//max31855 sck
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin = GPIOC_MAX31855_CS;//max31855 cs
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin = GPIOC_MAX31855_SC;//max31855 sc
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//注意读数据的端口要设置为普通输入模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
       
        GPIOA_MAX31855_SCK_L;
        GPIOC_MAX31855_CS_H;
}[/mw_shl_code]

位加权和功能.PNG
图3.位加权和功能
热电偶.PNG
图4.我用的热电偶
热电偶温度格式.PNG
图5.热电偶温度格式
根据datasheet可以知道,在data的32位数据中,[31:18]为14位带符号的热电偶温度,[15:4]为12位带符号的内部温度。最初迷惑这两个温度究竟代表什么含义,后来实践证明,14位的数据表示是热电偶远端,即你想测量的物体的温度。而12位的数据则代表与电路板接触的那一端的热电偶的温度,通常这个温度是固定不变的,与室温接近。
下面是MAX31855读数据和数据处理的过程

[mw_shl_code=c,true]
float MAX31855_ReadData()
{
  u32 data=0;//用于存储从max31855读取的数据
u16 Thermocouple=0;  //
float Ther=0;
        int i;       
        GPIOC_MAX31855_CS_L; //片选,低电平有效
        delay_us(1);
        for(i=31;i>=0;i--){         //按位读取一共是32位数据,从高位开始读取
                GPIOA_MAX31855_SCK_H;                //时序是在上升沿的时候读取数据,在初始化的时候,SCK为低,所以此时拉高
                delay_us(1);

                if(GPIOC_MAX31855_SC_IN)//开始读数据,如果当前位为1的话,则通过左移至相应位置,如果是0则不处理
                {
                        data|=((u32)1<<i);                //左移至i位,赋值给data的i位
                }
               
                GPIOA_MAX31855_SCK_L;//读取一位完成
                delay_us(1);
        }
        GPIOC_MAX31855_CS_H;//32位读取完成后取消片选
/*********************下面对data进行处理***************************/
Thermocouple=((temp_data>>18)&0x1fff);//取出[30:18]热电偶的数据 ,我这里没有取出符号位
Ther=Thermocouple*0.25;  //从图5中可以看出,温度的分辨率是0.25摄氏度,固数据应乘0.25,参考端的温度应该乘0.0625,我这里没有对这部分数据进行处理。

return Ther;
}
[/mw_shl_code]


最后,当我以为万事俱备的时候,给电热片通电加热,发现热电偶测得的温度是随温度递减的。。。。。经检查原来热电偶与MAX31855接通的两根腿是分正反的,所以你也有这个问题,就把两个线反过来插就好了。

以上。希望对大家有所帮助。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。