#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SO = P2^7; //P3.6口与SO相连
sbit CS = P2^6; //P3.5口与CS相连
sbit SCK = P2^5; //P3.4口与SCK相连
sbit COL0 = P1^2; //数码管3脚
sbit COL1 = P1^1; //数码管2脚
sbit COL2 = P1^0; //数码管1脚
sbit aj = P2^0; //设置温度按键
sbit ac = P2^1; //设置温度按键
sbit KG = P1^3; //温度值 开关
unsigned char sz[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
/******************MAX6675用******************/
const unsigned char DevID = 1; //本机设备ID
unsigned char buffer; //串口接收缓冲区
unsigned char rcv_buffer[20];
unsigned char send_buffer[20];
unsigned char flag_ok = 0; //接收完毕的标识
unsigned int MAX6675_Temp;
unsigned char Flag_connect;
unsigned char CRCH,CRCL;
unsigned char wd[2]; //wd[]:BCD码的温度
unsigned char flag_dis; //显示刷新的标识
/******************延时函数******************/
void delay(float t) //延时含数
{
unsigned int j,i;
j=t*100;
while(j--)
{
for(i=10;i;i--);
}
}
/******************延时函数******************/
void DelayMs(unsigned int i) //一个延时函数,这个函数在11.0592M晶振下的延时时间大概为1ms
{
unsigned int j,k;
for(j=i; j>0; j--)
for(k=114; k>0; k--);
}
/******************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;
}
/******************数码管显示******************/
void Display(unsigned int a)
{
unsigned char bit1000,bit100,bit10,bit1;
bit1000=a/1000; /*整除,提取千位1*/
a=a%1000; /*取余 234*/
bit100=a/100; /*整除,提取百位2*/
a=a%100; /*取余34*/
bit10=a/10; /*整除,提取十位3*/
bit1=a%10; /*提取个位4*/
COL2=1; //关闭百位
P0=sz[bit1]; //送出欲显示数的字形码,个位
COL0=0; /*选数码管个位,打开*/
delay(0.1); //延时
COL0=1; //关闭个位
P0=sz[bit10]; //送出欲显示数的字形码,十位
COL1=0; /*选数码管十位,打开*/
delay(0.1); //延时
COL1=1; //关闭十位
P0=sz[bit100]; //送出欲显示数的字形码,百位
COL2=0; /*选数码管百位,打开*/
delay(0.1); //延时
}
/******************定义命令字节******************/
#define Read_COM 0x01 //字节读数据命令
#define Prog_COM 0x02 //字节编程数据命令
#define Erase_COM 0x03 //扇区擦除数据命令
#define En_Wait_TIME 0x81 //设置等待时间 ,并使能ISP/IAP
#define Start_ADDRH 0x20 //扇区地址高位
#define Start_ADDRL 0x00 //扇区地址低位
/****************特殊功能寄存器声明****************/
sfr ISP_DATA = 0xe2;
sfr ISP_ADDRH = 0xe3;
sfr ISP_ADDRL = 0xe4;
sfr ISP_CMD = 0xe5;
sfr ISP_TRIG = 0xe6;
sfr ISP_CONTR = 0xe7;
/*****************关闭ISP&IAP功能*****************/
void ISP_IAP_disable(void)
{
ISP_CONTR = 0x00;
ISP_CMD = 0x00;
ISP_TRIG = 0x00;
}
/*********************字节读**********************/
uchar Byte_read(uint byte_addr)
{
EA = 0; //关中断
ISP_CONTR = En_Wait_TIME; //开启ISP&IAP,并送等待时间
ISP_CMD = Read_COM; //送字节读命令字
ISP_ADDRH = (uchar)(byte_addr >> 8); //送地址高字节
ISP_ADDRL = (uchar)(byte_addr & 0x00ff); //送地址低字节
ISP_TRIG = 0x46; //送触发命令字0x46
ISP_TRIG = 0xB9; //送触发命令字0xB9
_nop_();
ISP_IAP_disable(); //关闭ISP&IAP功能
EA = 1; //开中断
return (ISP_DATA);
}
/*********************字节编程*********************/
void Byte_program(uint byte_addr,uchar isp_iap_data)
{
EA = 0; //关中断
ISP_CONTR = En_Wait_TIME; //开启ISP&IAP,并送等待时间
ISP_CMD = Prog_COM; //送字节编程命令字
ISP_ADDRH = (uchar)(byte_addr >> 8); //送地址高字节
ISP_ADDRL = (uchar)(byte_addr & 0x00ff); //送地址低字节
ISP_DATA = isp_iap_data; //送数据进ISP_DATA
ISP_TRIG = 0x46; //送触发命令字0x46
ISP_TRIG = 0xB9; //送触发命令字0xB9
_nop_();
ISP_IAP_disable(); //关闭ISP&IAP功能
EA = 1; //开中断
}
/*********************扇区擦除*********************/
void Sector_erase(uint sector_addr)
{
EA = 0; //关中断
ISP_CONTR = En_Wait_TIME; //开启ISP&IAP;并送等待时间
ISP_CMD = Erase_COM; //送扇区擦除命令字
ISP_ADDRH = (uchar)(sector_addr >> 8); //送地址高字节
ISP_ADDRL = (uchar)(sector_addr & 0X00FF); //送地址低字节
ISP_TRIG = 0X46; //送触发命令字0x46
ISP_TRIG = 0XB9; //送触发命令字0xB9
_nop_();
ISP_IAP_disable(); //关闭ISP&IAP功能
EA = 1;
}
/*********************主程序*********************/
void main()
{
unsigned int cnt;
unsigned int c;
unsigned int t;
unsigned int b;
b=Byte_read(0x2000); //读EEPROM值 = b值
cnt=b;
while(1)
{
/*********************检测按键aj是否按下,按下则执行以下内容*********************/
if(aj==0)
{
while(aj==0)
{
cnt++;
if(cnt==99)
{
cnt=0;
}
while(t<30) //显示温度设置值
{
t++;
Display(cnt*10); //数码管显示b的值
}
t=0;
}
Sector_erase(0x2000); //扇区擦除
Byte_program(0x2000,cnt); //把cnt的值 写EEPROM
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
b=Byte_read(0x2000); //读EEPROM值 = b值
while(t<400) //显示温度设置值
{
t++;
Display(b*10); //数码管显示b的值
}
t=0;
}
/******************************************/
/*********************检测按键ac是否按下,按下则执行以下内容*********************/
if(ac==0)
{
while(ac==0)
{
cnt--;
if(cnt==0)
{
cnt=99;
}
while(t<30) //显示温度设置值
{
t++;
Display(cnt*10); //数码管显示b的值
}
t=0;
}
Sector_erase(0x2000); //扇区擦除
Byte_program(0x2000,cnt); //把cnt的值 写EEPROM
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
b=Byte_read(0x2000); //读EEPROM值 = b值
while(t<400) //显示温度设置值
{
t++;
Display(b*10); //数码管显示b的值
}
t=0;
}
/******************************************/
/*********************检测按键ac与ac是否按下,没按下则执行以下内容*********************/
if(aj==1,ac==1)
{
c=Byte_read(0x2000); //读EEPROM值
t=MAX6675_ReadReg();
Flag_connect=t&0x04; //读出数据的D2位是热电偶掉线标志位,该位为1表示掉线,该位为0表示连接
Flag_connect=Flag_connect>>2; //MAX6675是否在线
t = t<<1; //读出来的数据的D3~D14是温度值
t = t>>4;
MAX6675_Temp = t/4; //测得的温度单位是0.25,所以要乘以0.25(即除以4)才能得到以度为单位的温度值
for(t=0; t<200; t++) //显示温度
{
Display(MAX6675_Temp);
if(MAX6675_Temp<c) ????????? //如果超温则提示 这里把C直接改成数值 if(MAX6675_Temp<50) 就能执行 为什么读不了C的值
{
KG=0;
}
if(MAX6675_Temp>c) ?????????//如果低温则提示 这里把C直接改成数值 if(MAX6675_Temp>50) 就能执行 为什么读不了C的值
{
KG=1;
}
}
/******************************************/
}
}
}
|