[STC单片机] 开源一个双路热电偶测温系统(基于MAX6675)

[复制链接]
4249|18
 楼主| 一路向北lm 发表于 2018-10-27 12:40 | 显示全部楼层 |阅读模式
本帖最后由 一路向北lm 于 2018-10-27 12:46 编辑

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




代码:




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评论

正是我要参考的  发表于 2022-11-17 14:56
 楼主| 一路向北lm 发表于 2018-10-27 12:41 | 显示全部楼层
max6675 驱动
  1. #include "max6675.h"

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


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


  8. //读取MAX6675内存器
  9. unsigned int MAX6675_ReadReg(void)
  10. {
  11.        
  12.         unsigned char i;   
  13.         unsigned int dat;
  14.         i   = 0;   
  15.         dat = 0;   
  16.        
  17.         CS  = 0;
  18.         SCK = 0;     
  19.        
  20.         for(i=0; i<16; i++)                //get D15-D0 from 6675  
  21.         {      
  22.                 SCK = 1;     
  23.                 dat = dat<<1;   
  24.                 if( SO==1 )   
  25.                         dat = dat|0x01;   
  26.                 SCK = 0;   
  27.         }
  28.         CS = 1;   
  29.         return dat;   
  30. }

  31. unsigned int MAX6675_ReadReg1(void)
  32. {
  33.        
  34.         unsigned char i;   
  35.         unsigned int dat;
  36.         i   = 0;   
  37.         dat = 0;   
  38.        
  39.         CS1  = 0;
  40.         SCK1 = 0;     
  41.        
  42.         for(i=0; i<16; i++)                //get D15-D0 from 6675  
  43.         {      
  44.                 SCK1 = 1;     
  45.                 dat = dat<<1;   
  46.                 if( SO1==1 )   
  47.                         dat = dat|0x01;   
  48.                 SCK1 = 0;   
  49.         }
  50.         CS1 = 1;   
  51.         return dat;   
  52. }



  1. #ifndef __MAX6675_H_
  2. #define  __MAX6675_H_
  3. #include "reg52.h"
  4. #include "intrins.h"       

  5. unsigned int MAX6675_ReadReg(void);
  6. unsigned int MAX6675_ReadReg1(void);

  7. #endif


 楼主| 一路向北lm 发表于 2018-10-27 12:43 | 显示全部楼层
LCD 驱动
  1. #include "lcd.h"

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

  9. void Lcd1602_Delay1ms(uint c)   //误差 0us
  10. {
  11.     uchar a,b;
  12.         for (; c>0; c--)
  13.         {
  14.                  for (b=199;b>0;b--)
  15.                  {
  16.                           for(a=1;a>0;a--);
  17.                  }      
  18.         }
  19.            
  20. }

  21. /*******************************************************************************
  22. * 函 数 名         : LcdWriteCom
  23. * 函数功能                   : 向LCD写入一个字节的命令
  24. * 输    入         : com
  25. * 输    出         : 无
  26. *******************************************************************************/
  27. #ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  28. void LcdWriteCom(uchar com)          //写入命令
  29. {
  30.         LCD1602_E = 0;     //使能
  31.         LCD1602_RS = 0;           //选择发送命令
  32.         LCD1602_RW = 0;           //选择写入
  33.        
  34.         LCD1602_DATAPINS = com;     //放入命令
  35.         Lcd1602_Delay1ms(1);                //等待数据稳定

  36.         LCD1602_E = 1;                  //写入时序
  37.         Lcd1602_Delay1ms(5);          //保持时间
  38.         LCD1602_E = 0;
  39. }
  40. #else
  41. void LcdWriteCom(uchar com)          //写入命令
  42. {
  43.         LCD1602_E = 0;         //使能清零
  44.         LCD1602_RS = 0;         //选择写入命令
  45.         LCD1602_RW = 0;         //选择写入

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

  48.         LCD1602_E = 1;         //写入时序
  49.         Lcd1602_Delay1ms(5);
  50.         LCD1602_E = 0;

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

  53.         LCD1602_E = 1;         //写入时序
  54.         Lcd1602_Delay1ms(5);
  55.         LCD1602_E = 0;
  56. }
  57. #endif
  58. /*******************************************************************************
  59. * 函 数 名         : LcdWriteData
  60. * 函数功能                   : 向LCD写入一个字节的数据
  61. * 输    入         : dat
  62. * 输    出         : 无
  63. *******************************************************************************/                  
  64. #ifndef         LCD1602_4PINS                  
  65. void LcdWriteData(uchar dat)                        //写入数据
  66. {
  67.         LCD1602_E = 0;        //使能清零
  68.         LCD1602_RS = 1;        //选择输入数据
  69.         LCD1602_RW = 0;        //选择写入

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

  72.         LCD1602_E = 1;   //写入时序
  73.         Lcd1602_Delay1ms(5);   //保持时间
  74.         LCD1602_E = 0;
  75. }
  76. #else
  77. void LcdWriteData(uchar dat)                        //写入数据
  78. {
  79.         LCD1602_E = 0;          //使能清零
  80.         LCD1602_RS = 1;          //选择写入数据
  81.         LCD1602_RW = 0;          //选择写入

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

  84.         LCD1602_E = 1;          //写入时序
  85.         Lcd1602_Delay1ms(5);
  86.         LCD1602_E = 0;

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

  89.         LCD1602_E = 1;          //写入时序
  90.         Lcd1602_Delay1ms(5);
  91.         LCD1602_E = 0;
  92. }
  93. #endif
  94. /*******************************************************************************
  95. * 函 数 名       : LcdInit()
  96. * 函数功能                 : 初始化LCD屏
  97. * 输    入       : 无
  98. * 输    出       : 无
  99. *******************************************************************************/                  
  100. #ifndef                LCD1602_4PINS
  101. void LcdInit()                                                  //LCD初始化子程序
  102. {
  103.         LcdWriteCom(0x38);  //开显示
  104.         LcdWriteCom(0x0c);  //开显示不显示光标
  105.         LcdWriteCom(0x06);  //写一个指针加1
  106.         LcdWriteCom(0x01);  //清屏
  107.         LcdWriteCom(0x80);  //设置数据指针起点
  108. }
  109. #else
  110. void LcdInit()                                                  //LCD初始化子程序
  111. {
  112.         LcdWriteCom(0x32);         //将8位总线转为4位总线
  113.         LcdWriteCom(0x28);         //在四位线下的初始化
  114.         LcdWriteCom(0x0c);  //开显示不显示光标
  115.         LcdWriteCom(0x06);  //写一个指针加1
  116.         LcdWriteCom(0x01);  //清屏
  117.         LcdWriteCom(0x80);  //设置数据指针起点
  118. }
  119. #endif

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

  8. /**********************************
  9. 包含头文件
  10. **********************************/
  11. #include<reg52.h>

  12. //---重定义关键词---//
  13. #ifndef uchar
  14. #define uchar unsigned char
  15. #endif

  16. #ifndef uint
  17. #define uint unsigned int
  18. #endif

  19. /**********************************
  20. PIN口定义
  21. **********************************/
  22. #define LCD1602_DATAPINS P0
  23. sbit LCD1602_RS=P2^0;
  24. sbit LCD1602_RW=P2^1;
  25. sbit LCD1602_E=P2^2;
  26. /**********************************
  27. 函数声明
  28. **********************************/
  29. /*在51单片机12MHZ时钟下的延时函数*/
  30. void Lcd1602_Delay1ms(uint c);   //误差 0us
  31. /*LCD1602写入8位命令子函数*/
  32. void LcdWriteCom(uchar com);
  33. /*LCD1602写入8位数据子函数*/       
  34. void LcdWriteData(uchar dat);
  35. /*LCD1602初始化子程序*/               
  36. void LcdInit();                                                  

  37. #endif


 楼主| 一路向北lm 发表于 2018-10-27 12:44 | 显示全部楼层
主函数
  1. #include "reg52.h"
  2. #include "lcd.h"
  3. #include "max6675.h"

  4.    

  5. uint temp,temp1;
  6. bit temp_flag,flag,flag1;
  7. sbit SO=P1^0;

  8. void main()
  9. {
  10.        
  11.         LcdInit();                      //LCD1602初始化
  12.         TMOD|=0x01;
  13.         TH0=(65536-50000)/256;
  14.         TL0=(65536-50000)%256;
  15.         ET0=1;
  16.         TR0=1;
  17.         EA=1;
  18.                                   //LCD1602液晶初始化

  19.         while(1)
  20.         {
  21.                
  22.                 if(temp_flag==1)
  23.                 {
  24.                         temp_flag=0;
  25.                        
  26.                   temp=MAX6675_ReadReg();
  27.                        
  28.                   temp = temp<<1;
  29.                   temp = temp>>4;
  30.                   temp = temp*2.5;       
  31.                
  32.                        
  33.                         temp1=MAX6675_ReadReg1();
  34.                         temp1= temp1<<1;
  35.                   temp1= temp1>>4;
  36.                   temp1= temp1*2.5;       
  37.                        
  38.                         if((temp==10237))
  39.                         {
  40.                           temp=0;        flag=1;
  41.                         }
  42.                         else
  43.                         {
  44.                           flag=0;
  45.                         }
  46.                         if((temp1==10237))
  47.                         {
  48.                           temp1=0; flag1=1;
  49.                         }
  50.                         else
  51.                         {
  52.                           flag1=0;
  53.                         }

  54.                        
  55.         }
  56.                               LcdWriteCom(0x80);  
  57.                                                 LcdWriteData('C');
  58.                                                 LcdWriteCom(0x81);
  59.                                                 LcdWriteData('H');
  60.                                                 LcdWriteCom(0x82);
  61.                                                 LcdWriteData('1');
  62.                                                 LcdWriteCom(0x83);
  63.                   LcdWriteData(':');
  64.                                        
  65.        
  66.                                           LcdWriteCom(0x85);
  67.                                                 LcdWriteData(temp1/10000+0x30);
  68.                                                 LcdWriteCom(0x86);
  69.                                                 LcdWriteData(temp1%10000/1000+0x30);
  70.                   LcdWriteCom(0x87);
  71.                   LcdWriteData(temp1%1000/100+0x30);
  72.                   LcdWriteCom(0x88);
  73.                   LcdWriteData(temp1%100/10+0x30);
  74.                   LcdWriteCom(0x89);
  75.                          LcdWriteData('.');
  76.                                                 LcdWriteCom(0x80+10);
  77.                                                 LcdWriteData(temp1%10+0x30);
  78.                                                 LcdWriteCom(0x80+10+1);
  79.                                                 LcdWriteData('C');
  80.                                                
  81.                                                 if(flag1==1)   // 掉线
  82.                                                 {
  83.                                                           LcdWriteCom(0x80+10+3);
  84.                                                                 LcdWriteData('O');
  85.                                                                 LcdWriteCom(0x80+10+4);
  86.                                                                 LcdWriteData('F');
  87.                                                                 LcdWriteCom(0x80+10+5);
  88.                                                                 LcdWriteData('F');
  89.                                                 }
  90.                                                 if(flag1==0)   //在线
  91.                                                 {
  92.                                                     LcdWriteCom(0x80+10+3);
  93.                                                                 LcdWriteData(' ');
  94.                                                                 LcdWriteCom(0x80+10+4);
  95.                                                                 LcdWriteData('O');
  96.                                                                 LcdWriteCom(0x80+10+5);
  97.                                                                 LcdWriteData('N');
  98.                                                 }
  99.                                                
  100.                
  101.                         LcdWriteCom(0x80+0x40);   
  102.                         LcdWriteData('C');
  103.                                                 LcdWriteCom(0x80+0x40+1);
  104.                                                 LcdWriteData('H');
  105.                                                 LcdWriteCom(0x80+0x40+2);
  106.                                                 LcdWriteData('2');
  107.                                                 LcdWriteCom(0x80+0x40+3);
  108.                   LcdWriteData(':');
  109.                                        
  110.                                        
  111.                                                 LcdWriteCom(0x80+0x40+5);
  112.                                                 LcdWriteData(temp/10000+0x30);
  113.                                                 LcdWriteCom(0x80+0x40+6);
  114.                                                 LcdWriteData(temp%10000/1000+0x30);
  115.                                                 LcdWriteCom(0x80+0x40+7);
  116.                                                 LcdWriteData(temp%1000/100+0x30);
  117.                                        
  118.                                                 LcdWriteCom(0x80+0x40+8);
  119.                                                 LcdWriteData(temp%100/10+0x30);
  120.                                                
  121.                                                 LcdWriteCom(0x80+0x40+9);
  122.                                                 LcdWriteData('.');
  123.                                                
  124.                                                 LcdWriteCom(0x80+0x40+10);
  125.                                                 LcdWriteData(temp%10+0x30);
  126.                                                 LcdWriteCom(0x80+0x40+11);
  127.                                                 LcdWriteData('C');

  128.                     if(flag==1)   // 掉线
  129.                                                 {
  130.                                                           LcdWriteCom(0x80+0x40+13);
  131.                                                                 LcdWriteData('O');
  132.                                                                 LcdWriteCom(0x80+0x40+14);
  133.                                                                 LcdWriteData('F');
  134.                                                                 LcdWriteCom(0x80+0x40+15);
  135.                                                                 LcdWriteData('F');
  136.                                                 }
  137.                                                 if(flag==0)   //在线
  138.                                                 {
  139.                                                     LcdWriteCom(0x80+0x40+13);
  140.                                                                 LcdWriteData(' ');
  141.                                                                 LcdWriteCom(0x80+0x40+14);
  142.                                                                 LcdWriteData('O');
  143.                                                                 LcdWriteCom(0x80+0x40+15);
  144.                                                                 LcdWriteData('N');
  145.                                                 }
  146.                
  147.                          
  148.         }
  149. }

  150. void time() interrupt 1
  151. {
  152.         uint count1,count2,t;
  153.   TH0=(65536-50000)/256;
  154.         TL0=(65536-50000)%256;
  155.         count1++;count2++;
  156.         if(count1==20)
  157.         {
  158.          count1=0;
  159.          temp_flag=1;
  160.         }
  161. }


shenghux 发表于 2018-10-27 21:34 | 显示全部楼层
感谢分享!
caijie001 发表于 2018-10-29 14:09 | 显示全部楼层
 楼主| 一路向北lm 发表于 2018-10-29 20:59 | 显示全部楼层

小玩意,我啥牛X的
6688hyc 发表于 2018-10-30 11:42 | 显示全部楼层
电路呢?
 楼主| 一路向北lm 发表于 2018-10-30 18:34 | 显示全部楼层

电路就不用画了吧,51最小系统  引脚已经定义好了,没难度
zhanan 发表于 2018-12-8 15:59 | 显示全部楼层
你用了两个6675,可以用一个6675,用低阻模拟开关来选择热电偶,又省掉一个6675钱又节省mcu引脚。
gx_huang 发表于 2018-12-8 16:18 | 显示全部楼层
用2个MAX6675的,可以保证市场上找不到类似的批量的产品的,实用性肯定不高的。
性价比低的,实用性肯定差了呀。
 楼主| 一路向北lm 发表于 2018-12-10 12:54 | 显示全部楼层
gx_huang 发表于 2018-12-8 16:18
用2个MAX6675的,可以保证市场上找不到类似的批量的产品的,实用性肯定不高的。
性价比低的,实用性肯定差 ...

是的,这个不能跟专业产品比
gx_huang 发表于 2018-12-10 13:40 | 显示全部楼层
一路向北lm 发表于 2018-12-10 12:54
是的,这个不能跟专业产品比

如果你能用TM7711之类的ADC芯片,自己搭电路,自己做冷端补偿,自己做线性修正,
这比用MAX6675的方案便宜多了,分辨率也可以更好,也让你知道K型热电偶的特性了。
我甚至不用ADC芯片,只用运放放大,然后LM393之类的比较器,也可以采集热电偶的温度。
 楼主| 一路向北lm 发表于 2018-12-10 16:38 | 显示全部楼层
gx_huang 发表于 2018-12-10 13:40
如果你能用TM7711之类的ADC芯片,自己搭电路,自己做冷端补偿,自己做线性修正,
这比用MAX6675的方案便 ...

这个更强了,真没有深入研究过
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
工业
叶春勇 发表于 2020-6-10 19:52 | 显示全部楼层
maximQ820270087 发表于 2020-6-9 12:17
再有新方案的话,推荐这个max31855   max6675停产!
【MAX31855关键特性】
冷端补偿

max31855多少钱
maximQ820270087 发表于 2020-6-16 16:17 | 显示全部楼层
10块左右  具体要看哪个版本的热电偶了
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绝对是个奇迹,应该改为静态或全局变量
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3837

帖子

81

粉丝
快速回复 在线客服 返回列表 返回顶部