找回密码
 立即注册
查看: 517|回复: 9

STC15W408AS单片机设计的K型热电偶温度控制显示报警器

[复制链接]

该用户从未签到

42

主题

7

回帖

246

积分

中级会员

积分
246
发表于 2023-6-7 12:09:07 | 显示全部楼层 |阅读模式
GYJ-0303 淘宝描述_01.jpg


#include<STC15W408AS.H>                 //库文件
#include<intrins.h>
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int  //宏定义无符号整型
#define ADC_POWER   0x80            //ADC 电源控制位
#define ADC_FLAG    0x10            //ADC 转换结束标志位
#define ADC_START   0x08            //ADC 开始转换控制位
#define ADC_SPEEDLL 0x00            //210 个时钟周期转换一次
#define ADC_SPEEDL  0x20            //420 个时钟周期转换一次
#define ADC_SPEEDH  0x40            //630 个时钟周期转换一次
#define ADC_SPEEDHH 0x60            //840 个时钟周期转换一次

typedef unsigned char  INT8U;
typedef unsigned int   INT16U;
#define ENABLE_ISP 0x82 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值
#define WD1        0x5a        //使用STC11xx系列单片机时,先写入0x5a,然写入0xa5
#define WD2        0xa5
char IAPAddr=0;
/********************************************************************
                            初始定义
*********************************************************************/
code uchar seg7code[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //显示段码 数码管字跟
/********************************************************************
                            I/O定义
*********************************************************************/
bit ba=0,ba1=0,ba2=0,ba3=0,ba4=0,ba5=0,zs=0,k=0,z=0;
uchar smg2=0,y=0,s1=0,s2=0;
uint qian=0,bai=0,shi=0,ge=0,wendu=0,wendu1=0,wendu2=0,wendu3=0,wendu4=0,js=0,s3=0,s=0,s4=0;
sbit SO=P1^7;//
sbit CS=P5^4;
sbit SCK=P5^5;
sbit aj1=P3^1;
sbit aj2=P3^0;
sbit out=P3^4;
sbit L1=P3^5;//数码管位控制
sbit L2=P3^6;//数码管位控制
sbit L3=P3^7;//数码管位控制
sbit dp=P3^3;//小数点
bit kt=0,kt_1=0;
unsigned long Temp_3=0;
uchar trg=0,trg_1=0,cont=0,cont_1=0;
uchar ReadData=0,ReadData_1=0;
/********************************************************************
                            E2P函数
*********************************************************************/
union union_temp16
{
    INT16U un_temp16;
    INT8U  un_temp8[2];
}my_unTemp16;

INT8U Byte_Read(INT16U add);              //读一字节,调用前需打开IAP 功能
void Byte_Program(INT16U add, INT8U ch);  //字节编程,调用前需打开IAP 功能
void Sector_Erase(INT16U add);            //擦除扇区
void IAP_Disable();                       //关闭IAP 功能
/*******************************************************************
*                       MAX6675读取程序
********************************************************************/
uint Re_Convert() //热电偶数据读取,返回温度
{ uchar i=0;
        unsigned long Temp_2=0;
  CS=1;
  SCK=0;  
  _nop_();_nop_();
  //这个_nop_()等效与汇编里面的NOP指令,也就是空一个机器周期,
  //在51单片机中_nop_()等于空12个时钟周期【即一个机器周期】
  CS=0;
        for(i=0;i<16;i++)//16位数据读取
     {
                                Temp_2<<=1;//向右移一位
                                _nop_();
                                SCK=1;//上升
                                if(SO==1){Temp_2=Temp_2|0x01;}
                                else Temp_2=Temp_2|0x00;
                                _nop_();                                                                                   
                                SCK=0;
                                _nop_();
     }
                CS=1;                 //读取完后对CS置1进行温度转换!MAX6675的转换时间是典型值:0.17s,最大值0.22s。
            Temp_3=Temp_2;
                Temp_2=Temp_2<<1;        //向左移一位,取0-14位
                Temp_2=Temp_2>>4;        //向右移4位,取3-14位         
                Temp_2=(Temp_2*10)/4;//变换为温度值--每LSB代表0.25度,注意:在此处先乘了个10
//                Temp_2=Temp_2&0x7fff;//去掉最后一位
//                Temp_2=Temp_2>>3;  //去掉前三位
//                Temp_2=Temp_2*10/4;
                Temp_2=Temp_2-50;//补偿温度
                return(Temp_2);   
}
/*******************************************************************
*                        读取按键状态
********************************************************************/
void KeyRead()//读取按键IO口函数
{
     ReadData = aj1^0xff;  // 读取按键状态取反后赋值给ReadData
     trg = ReadData & (ReadData ^ cont);  //trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0
     cont = ReadData;   //cont长按,长按cont=1,抬手后cont=0

         ReadData_1 = aj2^0xff;  // 读取按键状态取反后赋值给ReadData
     trg_1 = ReadData_1 & (ReadData_1 ^ cont_1);  //trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0
    cont_1 = ReadData_1;   //cont长按,长按cont=1,抬手后cont=0
}
/*******************************************************************
*                        按键
********************************************************************/
void key_1()
{          
  if(trg & 0x01) //短按
  {       
     kt_1=0;
         kt=1; //这是短按标志位,kt=1说明短按了
  }
  if((aj1!=0)&&(kt==1))//判断
        {
         z=1; // 选位标志位
         y++; //选位
//         out=1;
         if(y==5)
          {
           s4=s;
           z=0;
           k=1;
           y=0;
//           s=s1+s2+s3;
          }
         kt=0;
    }           // 短按

}

void key_2()
{          
  if(trg_1 & 0x01) //短按
  {       
     kt=0;
         kt_1=1; //这是短按标志位,kt=1说明短按了
  }
  if((aj2!=0)&&(kt_1==1))//判断
        {
         if(y==1)
          {
           s1++;
           if(s1>9)
            {
                 s1=0;
                }
          }
         if(y==2)
          {
           s2+=10;
           if(s2>90)
            {
                 s2=0;
                }
          }
         if(y==3)
          {
           s3+=100;
           if(s3>900)
            {
                 s3=0;
                }
          }
         
         kt_1=0;
    }           // 短按
}
/*******************************************************************
*                        定时器配置
********************************************************************/
void ConfigTimer0(){
        TMOD=0x01;//将定时器0,1都设置为模式1
    TL0 = 0x66;                //设置定时初值
        TH0 = 0xFC;                //设置定时初值1ms
        TR0=1;//开启定时器0
        ET0=1;//开定时器0的中断
        EA=1;//开总中断
}

/*******************************************************************
*                         显示
********************************************************************/
void led(uint date)
{
bai=date/100;
shi=date%100/10;
ge=date%10;
}
/*******************************************************************
*                         t0定时器
********************************************************************/
void timer0() interrupt 1
{
    TL0 = 0x66;                //设置定时初值1ms
        TH0 = 0xFC;                //设置定时初值
        js++;
        if(js==100){ba=1;}
        if(js==400){ba1=1;}
        if(js==700){ba2=1;}
        if(js==1000){ba3=1;}
        KeyRead(); //按键扫描
        if(z==0){
          smg2++;
          }
           else{
             smg2=y;//让逐个显示位
           }
             switch(smg2){                 //数码管扫描
        /**************数码管-开始*****************/
          case 1:  P1=seg7code[ge];L3=1;L2=1;L1=0;dp=0;break;//从P2进P0出
          case 2:  P1=seg7code[shi];L3=1;L2=0;L1=1;if(zs==0){dp=0;}else{dp=1;}break;
          case 3:  P1=seg7code[bai]; L3=0;L2=1;L1=1;dp=0;break;
        /**************数码管-结束*****************/       
          default: smg2=0;L3=1;L2=1;L1=1;break;
         }
}
/********************************************************************
                            主函数
*********************************************************************/
void main()
{
  
    P1M0 = 0xff;   //设置强推挽和开漏模式
    P1M1 = 0x80;
        P3M0 = 0x08;   //小数点使用
        P3M1 = 0x00;
        ConfigTimer0();
        if(Byte_Read(0X0001)==0xff){s1=0;s2=0;s3=0;}//首次读取,如果读到0xFF说明没有存过数据,直接付给00值
        else
        {
         s1=Byte_Read(0X0001);
         s2=Byte_Read(0X0002);
         s3=Byte_Read(0X0003);
        }
        s3=s3*100;
        s2=s2*10;
        s=s3+s2+s1;
   while(1)
    {
          if(ba==1) {zs=0;wendu = Re_Convert();ba=0;}
          if(ba1==1){zs=0;wendu1 = Re_Convert();ba1=0;}
          if(ba2==1){zs=0;wendu2 = Re_Convert();ba2=0;}
          if(ba3==1){zs=0;wendu3 = Re_Convert();wendu4 = ((wendu+wendu1+wendu2+wendu3)/40);ba3=0;js=0;}
          if((y==0)&&(z==0))
          {
            if((Temp_3&0x04)==0){led(wendu4);}else{led(0);}        //断线归0
          }
          if(y==1){zs=0;led(s1);}
          if(y==2){zs=0;led(s2);}
          if(y==3){zs=0;led(s3);}
          if(y==4){zs=0;z=0;s=s1+s2+s3;led(s);}
          if(wendu4>s4){out=0;}else{out=1;}
          key_1();
          key_2();
          if(k==1)
          {
             Sector_Erase(0);
                 Byte_Program(0x0001,s1);  //写入扇区
                 Byte_Program(0x0002,(s2/10));  //写入扇区
                 Byte_Program(0x0003,(s3/100));  //写入扇区
                 k=0;
          }
        }
}

//读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节
INT8U Byte_Read(INT16U add)
{
    IAP_DATA = 0x00;
    IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x01;                 //IAP/ISP/EEPROM 字节读命令

    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
    IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址

    //EA = 0;
    IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    return (IAP_DATA);
}
/*********************************************************************************************/
//字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据
void Byte_Program(INT16U add, INT8U ch)
{
    IAP_CONTR = ENABLE_ISP;         //打开 IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x02;                 //IAP/ISP/EEPROM 字节编程命令

    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
    IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址

    IAP_DATA = ch;                  //要编程的数据先送进IAP_DATA 寄存器
    //EA = 0;
    IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
/*********************************************************************************************
//擦除扇区, 入口:DPTR = 扇区地址 */
void Sector_Erase(uint addr)
{
    IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 3;                 //IAP/ISP/EEPROM 扇区擦除命令

//    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = addr>>8;    //设置目标单元地址的高8 位地址
    IAP_ADDRL = addr;    //设置目标单元地址的低8 位地址

    IAP_TRIG = 0x5a;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xa5;   //送完WD2 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
/*********************************************************************************************/
void IAP_Disable()
{
    //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    IAP_CONTR = 0;      //关闭IAP 功能
    IAP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
    IAP_TRIG  = 0;      //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
    IAP_ADDRH = 0x80;
    IAP_ADDRL = 0;
}
/*********************************************************************************************/

STC15W408AS单片机设计的K型热电偶温度控制显示报警器.rar

1.16 MB, 下载次数: 48

回复 送花

使用道具 举报

  • TA的每日心情
    开心
    12 小时前
  • 签到天数: 153 天

    [LV.7]常住居民III

    67

    主题

    831

    回帖

    2750

    积分

    金牌会员

    积分
    2750
    发表于 2023-12-2 10:10:31 | 显示全部楼层
    请问用K型热电偶+MAX6675就可以直接读取温度吗?
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    16 小时前
  • 签到天数: 155 天

    [LV.7]常住居民III

    17

    主题

    279

    回帖

    380

    积分

    中级会员

    积分
    380
    发表于 2023-12-10 09:23:15 来自手机 | 显示全部楼层
    谢谢分享,学习
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-5 14:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    7

    回帖

    32

    积分

    新手上路

    积分
    32
    发表于 2024-1-2 12:00:55 来自手机 | 显示全部楼层
    厉害👍
    回复 送花

    使用道具 举报

  • TA的每日心情
    无聊
    2024-1-28 21:02
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    0

    主题

    8

    回帖

    36

    积分

    新手上路

    积分
    36
    发表于 2024-1-2 14:14:38 | 显示全部楼层
    这个不错,可以学习一下
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 14:06
  • 签到天数: 124 天

    [LV.7]常住居民III

    4

    主题

    235

    回帖

    856

    积分

    高级会员

    积分
    856
    发表于 2024-1-2 16:29:31 | 显示全部楼层
    高手
    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 137 天

    [LV.7]常住居民III

    0

    主题

    381

    回帖

    483

    积分

    中级会员

    积分
    483
    发表于 2024-1-2 16:53:01 | 显示全部楼层
    很详细,可以借鉴,感谢
    靡不有初,鲜克有终
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    12 小时前
  • 签到天数: 91 天

    [LV.6]常住居民II

    5

    主题

    72

    回帖

    264

    积分

    中级会员

    积分
    264
    发表于 2024-2-15 09:03:08 | 显示全部楼层
    MAX6675+热电偶采集220V加热管温度,如果加热管漏电会不会损坏stc单片机
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9234

    回帖

    1万

    积分

    管理员

    积分
    13942
    发表于 2024-2-15 09:27:46 | 显示全部楼层
    刚瞄了眼楼主的原理图,建议大批量量产的产品,要防止外围电源IC 有问题:
    加 大功率稳压二极管和保护大功率稳压二极管的自恢复保险丝


    截图202402150929098684.jpg
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9234

    回帖

    1万

    积分

    管理员

    积分
    13942
    发表于 2024-2-15 09:32:51 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-4-28 19:58 , Processed in 0.071935 second(s), 67 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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