打印
[STC单片机]

开源一个双路热电偶测温系统(基于MAX6675)

[复制链接]
3563|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 一路向北lm 于 2018-10-27 12:46 编辑

基于单片机 的双路热电偶测量系统
1. 识别热电偶是否在线。
2. 精度为0.5度。
3. 液晶实时显示。
4. 可玩性很高。
5. 练手也不错。
6. 实用性也挺强。




代码: 热电偶.zip (52.12 KB)




评论
yf_gao 2022-11-17 14:56 回复TA
正是我要参考的 

相关帖子

沙发
一路向北lm|  楼主 | 2018-10-27 12:41 | 只看该作者
max6675 驱动
#include "max6675.h"

sbit  SO  = P1^0;                                  //P3.6口与SO相连
sbit  SCK = P1^2;                                 //P3.4口与SCK相连
sbit  CS  = P1^1;                                  //P3.5口与CS相连


sbit  SO1  = P1^5;                                  //P3.6口与SO相连
sbit  SCK1 = P1^3;                                 //P3.4口与SCK相连
sbit  CS1  = P1^4;                                  //P3.5口与CS相连


//读取MAX6675内存器
unsigned int MAX6675_ReadReg(void)
{
       
        unsigned char i;   
        unsigned int dat;
        i   = 0;   
        dat = 0;   
       
        CS  = 0;
        SCK = 0;     
       
        for(i=0; i<16; i++)                //get D15-D0 from 6675  
        {      
                SCK = 1;     
                dat = dat<<1;   
                if( SO==1 )   
                        dat = dat|0x01;   
                SCK = 0;   
        }
        CS = 1;   
        return dat;   
}

unsigned int MAX6675_ReadReg1(void)
{
       
        unsigned char i;   
        unsigned int dat;
        i   = 0;   
        dat = 0;   
       
        CS1  = 0;
        SCK1 = 0;     
       
        for(i=0; i<16; i++)                //get D15-D0 from 6675  
        {      
                SCK1 = 1;     
                dat = dat<<1;   
                if( SO1==1 )   
                        dat = dat|0x01;   
                SCK1 = 0;   
        }
        CS1 = 1;   
        return dat;   
}



#ifndef __MAX6675_H_
#define  __MAX6675_H_
#include "reg52.h"
#include "intrins.h"       

unsigned int MAX6675_ReadReg(void);
unsigned int MAX6675_ReadReg1(void);

#endif


使用特权

评论回复
板凳
一路向北lm|  楼主 | 2018-10-27 12:43 | 只看该作者
LCD 驱动
#include "lcd.h"

/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能                   : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/

void Lcd1602_Delay1ms(uint c)   //误差 0us
{
    uchar a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
           
}

/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能                   : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
#ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
void LcdWriteCom(uchar com)          //写入命令
{
        LCD1602_E = 0;     //使能
        LCD1602_RS = 0;           //选择发送命令
        LCD1602_RW = 0;           //选择写入
       
        LCD1602_DATAPINS = com;     //放入命令
        Lcd1602_Delay1ms(1);                //等待数据稳定

        LCD1602_E = 1;                  //写入时序
        Lcd1602_Delay1ms(5);          //保持时间
        LCD1602_E = 0;
}
#else
void LcdWriteCom(uchar com)          //写入命令
{
        LCD1602_E = 0;         //使能清零
        LCD1602_RS = 0;         //选择写入命令
        LCD1602_RW = 0;         //选择写入

        LCD1602_DATAPINS = com;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;         //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

        LCD1602_DATAPINS = com << 4; //发送低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;         //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能                   : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/                  
#ifndef         LCD1602_4PINS                  
void LcdWriteData(uchar dat)                        //写入数据
{
        LCD1602_E = 0;        //使能清零
        LCD1602_RS = 1;        //选择输入数据
        LCD1602_RW = 0;        //选择写入

        LCD1602_DATAPINS = dat; //写入数据
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;   //写入时序
        Lcd1602_Delay1ms(5);   //保持时间
        LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)                        //写入数据
{
        LCD1602_E = 0;          //使能清零
        LCD1602_RS = 1;          //选择写入数据
        LCD1602_RW = 0;          //选择写入

        LCD1602_DATAPINS = dat;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;          //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

        LCD1602_DATAPINS = dat << 4; //写入低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;          //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能                 : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/                  
#ifndef                LCD1602_4PINS
void LcdInit()                                                  //LCD初始化子程序
{
        LcdWriteCom(0x38);  //开显示
        LcdWriteCom(0x0c);  //开显示不显示光标
        LcdWriteCom(0x06);  //写一个指针加1
        LcdWriteCom(0x01);  //清屏
        LcdWriteCom(0x80);  //设置数据指针起点
}
#else
void LcdInit()                                                  //LCD初始化子程序
{
        LcdWriteCom(0x32);         //将8位总线转为4位总线
        LcdWriteCom(0x28);         //在四位线下的初始化
        LcdWriteCom(0x0c);  //开显示不显示光标
        LcdWriteCom(0x06);  //写一个指针加1
        LcdWriteCom(0x01);  //清屏
        LcdWriteCom(0x80);  //设置数据指针起点
}
#endif

#ifndef __LCD_H_
#define __LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
//#define LCD1602_4PINS

/**********************************
包含头文件
**********************************/
#include<reg52.h>

//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

/**********************************
PIN口定义
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_RS=P2^0;
sbit LCD1602_RW=P2^1;
sbit LCD1602_E=P2^2;
/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c);   //误差 0us
/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);
/*LCD1602写入8位数据子函数*/       
void LcdWriteData(uchar dat);
/*LCD1602初始化子程序*/               
void LcdInit();                                                  

#endif


使用特权

评论回复
地板
一路向北lm|  楼主 | 2018-10-27 12:44 | 只看该作者
主函数
#include "reg52.h"
#include "lcd.h"
#include "max6675.h"

   

uint temp,temp1;
bit temp_flag,flag,flag1;
sbit SO=P1^0;

void main()
{
       
        LcdInit();                      //LCD1602初始化
        TMOD|=0x01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        ET0=1;
        TR0=1;
        EA=1;
                                  //LCD1602液晶初始化

        while(1)
        {
               
                if(temp_flag==1)
                {
                        temp_flag=0;
                       
                  temp=MAX6675_ReadReg();
                       
                  temp = temp<<1;
                  temp = temp>>4;
                  temp = temp*2.5;       
               
                       
                        temp1=MAX6675_ReadReg1();
                        temp1= temp1<<1;
                  temp1= temp1>>4;
                  temp1= temp1*2.5;       
                       
                        if((temp==10237))
                        {
                          temp=0;        flag=1;
                        }
                        else
                        {
                          flag=0;
                        }
                        if((temp1==10237))
                        {
                          temp1=0; flag1=1;
                        }
                        else
                        {
                          flag1=0;
                        }

                       
        }
                              LcdWriteCom(0x80);  
                                                LcdWriteData('C');
                                                LcdWriteCom(0x81);
                                                LcdWriteData('H');
                                                LcdWriteCom(0x82);
                                                LcdWriteData('1');
                                                LcdWriteCom(0x83);
                  LcdWriteData(':');
                                       
       
                                          LcdWriteCom(0x85);
                                                LcdWriteData(temp1/10000+0x30);
                                                LcdWriteCom(0x86);
                                                LcdWriteData(temp1%10000/1000+0x30);
                  LcdWriteCom(0x87);
                  LcdWriteData(temp1%1000/100+0x30);
                  LcdWriteCom(0x88);
                  LcdWriteData(temp1%100/10+0x30);
                  LcdWriteCom(0x89);
                         LcdWriteData('.');
                                                LcdWriteCom(0x80+10);
                                                LcdWriteData(temp1%10+0x30);
                                                LcdWriteCom(0x80+10+1);
                                                LcdWriteData('C');
                                               
                                                if(flag1==1)   // 掉线
                                                {
                                                          LcdWriteCom(0x80+10+3);
                                                                LcdWriteData('O');
                                                                LcdWriteCom(0x80+10+4);
                                                                LcdWriteData('F');
                                                                LcdWriteCom(0x80+10+5);
                                                                LcdWriteData('F');
                                                }
                                                if(flag1==0)   //在线
                                                {
                                                    LcdWriteCom(0x80+10+3);
                                                                LcdWriteData(' ');
                                                                LcdWriteCom(0x80+10+4);
                                                                LcdWriteData('O');
                                                                LcdWriteCom(0x80+10+5);
                                                                LcdWriteData('N');
                                                }
                                               
               
                        LcdWriteCom(0x80+0x40);   
                        LcdWriteData('C');
                                                LcdWriteCom(0x80+0x40+1);
                                                LcdWriteData('H');
                                                LcdWriteCom(0x80+0x40+2);
                                                LcdWriteData('2');
                                                LcdWriteCom(0x80+0x40+3);
                  LcdWriteData(':');
                                       
                                       
                                                LcdWriteCom(0x80+0x40+5);
                                                LcdWriteData(temp/10000+0x30);
                                                LcdWriteCom(0x80+0x40+6);
                                                LcdWriteData(temp%10000/1000+0x30);
                                                LcdWriteCom(0x80+0x40+7);
                                                LcdWriteData(temp%1000/100+0x30);
                                       
                                                LcdWriteCom(0x80+0x40+8);
                                                LcdWriteData(temp%100/10+0x30);
                                               
                                                LcdWriteCom(0x80+0x40+9);
                                                LcdWriteData('.');
                                               
                                                LcdWriteCom(0x80+0x40+10);
                                                LcdWriteData(temp%10+0x30);
                                                LcdWriteCom(0x80+0x40+11);
                                                LcdWriteData('C');

                    if(flag==1)   // 掉线
                                                {
                                                          LcdWriteCom(0x80+0x40+13);
                                                                LcdWriteData('O');
                                                                LcdWriteCom(0x80+0x40+14);
                                                                LcdWriteData('F');
                                                                LcdWriteCom(0x80+0x40+15);
                                                                LcdWriteData('F');
                                                }
                                                if(flag==0)   //在线
                                                {
                                                    LcdWriteCom(0x80+0x40+13);
                                                                LcdWriteData(' ');
                                                                LcdWriteCom(0x80+0x40+14);
                                                                LcdWriteData('O');
                                                                LcdWriteCom(0x80+0x40+15);
                                                                LcdWriteData('N');
                                                }
               
                         
        }
}

void time() interrupt 1
{
        uint count1,count2,t;
  TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        count1++;count2++;
        if(count1==20)
        {
         count1=0;
         temp_flag=1;
        }
}


使用特权

评论回复
5
shenghux| | 2018-10-27 21:34 | 只看该作者
感谢分享!

使用特权

评论回复
6
caijie001| | 2018-10-29 14:09 | 只看该作者
牛X啊

使用特权

评论回复
7
一路向北lm|  楼主 | 2018-10-29 20:59 | 只看该作者

小玩意,我啥牛X的

使用特权

评论回复
8
6688hyc| | 2018-10-30 11:42 | 只看该作者
电路呢?

使用特权

评论回复
9
一路向北lm|  楼主 | 2018-10-30 18:34 | 只看该作者

电路就不用画了吧,51最小系统  引脚已经定义好了,没难度

使用特权

评论回复
10
zhanan| | 2018-12-8 15:59 | 只看该作者
你用了两个6675,可以用一个6675,用低阻模拟开关来选择热电偶,又省掉一个6675钱又节省mcu引脚。

使用特权

评论回复
11
gx_huang| | 2018-12-8 16:18 | 只看该作者
用2个MAX6675的,可以保证市场上找不到类似的批量的产品的,实用性肯定不高的。
性价比低的,实用性肯定差了呀。

使用特权

评论回复
12
一路向北lm|  楼主 | 2018-12-10 12:54 | 只看该作者
gx_huang 发表于 2018-12-8 16:18
用2个MAX6675的,可以保证市场上找不到类似的批量的产品的,实用性肯定不高的。
性价比低的,实用性肯定差 ...

是的,这个不能跟专业产品比

使用特权

评论回复
13
gx_huang| | 2018-12-10 13:40 | 只看该作者
一路向北lm 发表于 2018-12-10 12:54
是的,这个不能跟专业产品比

如果你能用TM7711之类的ADC芯片,自己搭电路,自己做冷端补偿,自己做线性修正,
这比用MAX6675的方案便宜多了,分辨率也可以更好,也让你知道K型热电偶的特性了。
我甚至不用ADC芯片,只用运放放大,然后LM393之类的比较器,也可以采集热电偶的温度。

使用特权

评论回复
14
一路向北lm|  楼主 | 2018-12-10 16:38 | 只看该作者
gx_huang 发表于 2018-12-10 13:40
如果你能用TM7711之类的ADC芯片,自己搭电路,自己做冷端补偿,自己做线性修正,
这比用MAX6675的方案便 ...

这个更强了,真没有深入研究过

使用特权

评论回复
15
maximQ820270087| | 2020-6-9 12:17 | 只看该作者
再有新方案的话,推荐这个max31855   max6675停产!
【MAX31855关键特性】
冷端补偿
14位、0.25°C分辨率
转换器的温度分辨率为0.25°C,
温度读数为-270°C 至+1800°C,
对于K型热电偶,在-200°C至+700°C温度范围内,保持±2°C精度。
提供K、J、N、T和E型热电偶器件版本
简单的SPI兼容接口(只读)
检测热电偶对GND或VCC短路
检测热电偶开路
应用
电器设备
汽车
HVAC
工业

使用特权

评论回复
16
叶春勇| | 2020-6-10 19:52 | 只看该作者
maximQ820270087 发表于 2020-6-9 12:17
再有新方案的话,推荐这个max31855   max6675停产!
【MAX31855关键特性】
冷端补偿

max31855多少钱

使用特权

评论回复
17
maximQ820270087| | 2020-6-16 16:17 | 只看该作者
10块左右  具体要看哪个版本的热电偶了

使用特权

评论回复
18
ayb_ice| | 2022-11-23 08:53 | 只看该作者

void time() interrupt 1
{
        uint count1,count2,t;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        count1++;count2++;
        if(count1==20)
        {
                count1=0;
                temp_flag=1;
        }
}
这个count1能够等于20绝对是个奇迹,应该改为静态或全局变量

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

274

主题

3760

帖子

74

粉丝