找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1226|回复: 0
打印 上一主题 下一主题
收起左侧

单片机驱动MAX6675热电偶温度报警程序与Proteus仿真图

[复制链接]
跳转到指定楼层
楼主
使用stc89c52控制,LCD1602显示温度,显示设定报警值,功能简单,报警装置为BB响,代码较为粗糙,大佬可自行修改,小白可参考学习,第一个按键为安全按键,按住不放再按另外两个按键可以调节温度报警值,温度显示值可能有误差,误差大的话智能程序内调整了
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:

  1. //****************************************************************//
  2. //          1602液晶显示
  3. //单片机 AT89S52 或 STC89C52RC
  4. //功能 晶振 11.0592M 波特率 9600
  5. //****************************************************************//

  6. #include <reg51.h>
  7. #include <intrins.h>
  8. //
  9. typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable           无符号8位整型变量  */
  10. typedef signed   char  S8;       /* defined for signed 8-bits integer variable                  有符号8位整型变量  */
  11. typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable           无符号16位整型变量 */
  12. typedef signed   int   S16;      /* defined for signed 16-bits integer variable           有符号16位整型变量 */
  13. typedef unsigned long  U32;      /* defined for unsigned 32-bits integer variable           无符号32位整型变量 */
  14. typedef signed   long  S32;      /* defined for signed 32-bits integer variable           有符号32位整型变量 */
  15. typedef float          F32;      /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
  16. typedef double         F64;      /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
  17. //
  18. #define uchar unsigned char
  19. #define uint unsigned int
  20. #define   Data_0_time    4

  21. #define LCD1602_DB  P0

  22. sbit LCD1602_RS = P2^0;           //1602液晶引脚定义
  23. sbit LCD1602_RW = P2^1;
  24. sbit LCD1602_E  = P2^2;

  25. sbit xz = P2^5;    //按键
  26. sbit jia = P2^6;
  27. sbit jian = P2^7;

  28. sbit buzz = P3^7; //蜂鸣器


  29. sbit  SO  = P1^5;                                  //P3.6口与SO相连
  30. sbit  SCK = P1^6;                                 //P3.4口与SCK相连
  31. sbit  CS  = P1^7;                                  //P3.5口与CS相连


  32. //const unsigned char DevID = 1;                //本机设备ID
  33. unsigned char buffer;                        //串口接收缓冲区
  34. unsigned char rcv_buffer[20];
  35. //unsigned char send_buffer[20];
  36. //unsigned char flag_ok = 0;                //接收完毕的标识
  37. unsigned int MAX6675_Temp;
  38. unsigned char Flag_connect;
  39. //unsigned char CRCH,CRCL;
  40. //unsigned char wd[2];                          //wd[]:BCD码的温度
  41. //unsigned char flag_dis;                        //显示刷新的标识



  42. //-------------------------------------------------------------------------------------------
  43. /* 等待液晶准备好 */
  44. void LcdWaitReady()
  45. {
  46.     unsigned char sta;
  47.    
  48.     LCD1602_DB = 0xFF;
  49.     LCD1602_RS = 0;
  50.     LCD1602_RW = 1;
  51.     do {
  52.         LCD1602_E = 1;
  53.         sta = LCD1602_DB; //读取状态字
  54.         LCD1602_E = 0;
  55.     } while (sta & 0x80); //bit7等于1表示液晶正忙,重复检测直到其等于0为止
  56. }
  57. /* 向LCD1602液晶写入一字节命令,cmd-待写入命令值 */
  58. void LcdWriteCmd(unsigned char cmd)
  59. {
  60.     LcdWaitReady();
  61.     LCD1602_RS = 0;
  62.     LCD1602_RW = 0;
  63.     LCD1602_DB = cmd;
  64.     LCD1602_E  = 1;
  65.     LCD1602_E  = 0;
  66. }
  67. /* 向LCD1602液晶写入一字节数据,dat-待写入数据值 */
  68. void LcdWriteDat(unsigned char dat)
  69. {
  70.     LcdWaitReady();
  71.     LCD1602_RS = 1;
  72.     LCD1602_RW = 0;
  73.     LCD1602_DB = dat;
  74.     LCD1602_E  = 1;
  75.     LCD1602_E  = 0;
  76. }
  77. /* 设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */
  78. void LcdSetCursor(unsigned char x, unsigned char y)
  79. {
  80.     unsigned char addr;
  81.    
  82.     if (y == 0)  //由输入的屏幕坐标计算显示RAM的地址
  83.         addr = 0x00 + x;  //第一行字符地址从0x00起始
  84.     else
  85.         addr = 0x40 + x;  //第二行字符地址从0x40起始
  86.     LcdWriteCmd(addr | 0x80);  //设置RAM地址
  87. }
  88. /* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针 */
  89. void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
  90. {
  91.     LcdSetCursor(x, y);   //设置起始地址
  92.     while (*str != '\0')  //连续写入字符串数据,直到检测到结束符
  93.     {
  94.         LcdWriteDat(*str++);
  95.     }
  96. }
  97. /* 打开光标的闪烁效果 */
  98. void LcdOpenCursor()
  99. {
  100.         LcdWriteCmd(0x0F);
  101. }
  102. /* 关闭光标显示 */
  103. void LcdCloseCursor()
  104. {
  105.         LcdWriteCmd(0x0C);
  106. }
  107. /* 初始化1602液晶 */
  108. void InitLcd1602()
  109. {
  110.     LcdWriteCmd(0x38);  //16*2显示,5*7点阵,8位数据接口
  111.     LcdWriteCmd(0x0C);  //显示器开,光标关闭
  112.     LcdWriteCmd(0x06);  //文字不动,地址自动+1
  113.     LcdWriteCmd(0x01);  //清屏
  114. }


  115.        void Delay(U16 j)
  116.     {      U8 i;
  117.             for(;j>0;j--)
  118.           {         
  119.                 for(i=0;i<27;i++);

  120.           }
  121.     }
  122.                
  123. //------------------------------------------------------------------------------------------
  124. unsigned int MAX6675_ReadReg(void)
  125. {
  126.         unsigned char i;   
  127.         unsigned int dat;
  128.          
  129.         i   = 0;   
  130.         dat = 0;   
  131.         
  132.         CS  = 0;
  133.         SCK = 0;     
  134.         
  135.         for(i=0; i<16; i++)                //get D15-D0 from 6675  
  136.         {      
  137.                 SCK = 1;     
  138.                 dat = dat<<1;   
  139.                 if( SO==1 )   
  140.                         dat = dat|0x01;   
  141.                 SCK = 0;   
  142.         }
  143.         CS = 1;   
  144.          
  145.         return dat;   
  146. }  
  147. /*
  148. * 功  能:延时,若干毫秒
  149. * 参  数:毫秒数
  150. * 返回值:无
  151. */
  152. void DelayMs(unsigned int i)        //一个延时函数,这个函数在11.0592M晶振下的延时时间大概为1ms
  153. {
  154.         unsigned int j,k;

  155.         for(j=i; j>0; j--)
  156.                 for(k=114; k>0; k--);
  157. }

  158. unsigned char shezhi = 145; //数值设置默认值145
  159. U8 shezhi_zu[3];                                                //默认值设置
  160.         unsigned int temph;

  161.         U8 temp_zu[4];
  162.         U8 bba_zu[2];
  163. U8 kb[1] ;
  164. void Display(unsigned int temp)
  165. {
  166.         kb[0] = 0x0a;
  167.         
  168.         bba_zu[0] = 0xdf;
  169.         bba_zu[1] = 0x43;
  170.         temph = temp-2;     //误差
  171.                         temp_zu[0] = temph/100+'0';       //温度运算   
  172.                         temp_zu[1] = (temph/10)%10+'0';                                          
  173.                         temp_zu[2] = temph%10+'0';        
  174.                         
  175.         
  176.                         shezhi_zu[0] = shezhi/100+'0';                //数值设置1
  177.                         shezhi_zu[1] = (shezhi/10)%10+'0';
  178.                         shezhi_zu[2] = shezhi%10+'0';
  179.         
  180.         
  181.         if(Flag_connect==0)                          //Flag_connect为0 表示热电偶已连接,这时显示温度
  182.         {
  183.                 LcdShowStr(0,0,"T:");   
  184.                 LcdShowStr(3,0,temp_zu);
  185.                 //LcdShowStr(0,0,".");
  186.                
  187.                
  188.                 LcdShowStr(6,0,bba_zu);//单位

  189.                 LcdShowStr(0,3,"C:");
  190.                 LcdShowStr(3,3,shezhi_zu);
  191.                

  192.         }
  193.         else                                                //Flag_connect为1表示 热电偶未连接,这时显示FFFF
  194.         {        

  195.                 LcdShowStr(9,0,"ERROR");
  196.                 buzz = 0;
  197.                 Delay(1000);
  198.                 buzz = 1;
  199.                 Delay(1000);
  200.         }
  201. }


  202. /*****************定时器0中断服务*******************/

  203. void Int0()
  204. {
  205.                 TMOD=0x01; //设置定时器0为工作方式1
  206.                 TH0=(65536-45872)/256;
  207.                 TL0=(65536-45872)%256; //装初值
  208.                 EA=1;//开总中断
  209.                 ET0=1;//开启定时器0中断
  210.                 TR0=1;//启动定时器0
  211. }

  212. unsigned char num;

  213. void T0time() interrupt 1
  214. {
  215.                 TH0=(65536-45872)/256;

  216.                 TL0=(65536-45872)%256; //重装初值,保证每次进入中断函数都是50ms
  217.         num++;
  218.         if(num >= 15 ){
  219.         
  220.                                                         if (temph >= shezhi){
  221.                                                         buzz =~ buzz;
  222.                                                                 num = 0;
  223.                                 }        }
  224. }

  225.         
  226. //*****************************************************/
  227.                
  228. //main()功能描述:  AT89C51  11.0592MHz

  229.         

  230. void main()
  231. {        
  232.         unsigned char cnt = 11;
  233.         unsigned int t;
  234.         buzz = 1;

  235.         Int0();   //定时器0开启函数

  236.         Delay(100);         //延时100US(12M晶振)
  237.         InitLcd1602();                        /* 初始化1602液晶 */
  238.         
  239.         
  240.         while(1)
  241.         {  
  242.                 t=MAX6675_ReadReg();

  243.                   Flag_connect=t&0x04;                         //读出数据的D2位是热电偶掉线标志位,该位为1表示掉线,该位为0表示连接
  244.                   Flag_connect=Flag_connect>>2;         //MAX6675是否在线

  245.                 t = t<<1;                                                   //读出来的数据的D3~D14是温度值
  246.                 t = t>>4;
  247.                 MAX6675_Temp = t/4;                                //测得的温度单位是0.25,所以要乘以0.25(即除以4)才能得到以度为单位的温度值
  248.         /*-------------按键检测---------------------*/        
  249.         if(xz == 0 )
  250.         {
  251.                 Delay(50);
  252.                 if(xz == 0)
  253.                 {
  254.                         if(jia == 0)
  255.                         {
  256.                                 Delay(100);
  257.                                 if(jia == 0)
  258.                                 {
  259.                                         shezhi = shezhi+1;
  260.                                 }
  261.                         }
  262.                 }if(jian == 0){
  263.                                         Delay(100);
  264.                                 if(jian == 0)
  265.                                 {
  266.                                         shezhi = shezhi-1;
  267.                                 }}
  268.         }
  269. //                                                if (temph >= shezhi){
  270. //                                                        buzz = 0;
  271. //                                                        Delay(1000);        
  272. //                                                        buzz = 1;
  273. //                                                        Delay(1000);
  274. //                                }        

  275. //-------------------------------------------------               
  276.                 for(t=0; t<200; t++)                        //显示温度
  277.                 {  
  278.                         Display(MAX6675_Temp);
  279.                 }        
  280.         
  281.         }
  282.         
  283. }
复制代码

显示有一定的误差 大家自行在程序里面校正一下
Keil代码与Proteus仿真下载:
仿真程序.7z (91.06 KB, 下载次数: 51)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表