#include "stc12c5a60s2.h"
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
#define FOSC 11059200L //系统频率
#define BAUD 9600 //串口波特率
#define RX1_Lenth 8 //串口接收缓冲长度
#define T1MS (65536-FOSC/1000) //1ms timer calculation method in 1T mode
bit busy;
/*定义数码管输出端=========*/
sbit W1 = P2^0;
sbit W2 = P2^1;
sbit W3 = P2^2;
sbit W4 = P2^3;
/*定义按键扫描和输出=========*/
sbit KEY_set = P3^5;
sbit KEY_plus = P3^4;
sbit KEY_lower = P3^3;
sbit OUT_hot = P1^0;
sbit OUT_fan = P1^1;
sbit OUT_buzzer = P1^2;
/*定义MAX6675输入=========*/
sbit M_SCK = P2^5;
sbit M_CS = P2^6;
sbit M_DAT = P2^7;
/*定义数码管位内容=========*/
unsigned char SE[5] = {0xff,0xff,0xff,0xff,0xff};
unsigned char LEDS;
unsigned int M_CONT,M_Temp,M_Recoup,M_Recoup_sum; //6675变量,6675实际温度,6675温度补偿
unsigned int ST_Temp_H = 0; //设定高温
unsigned int ST_Temp_H_sum = 0; //串口接收到临时数据
unsigned int ST_Temp_L = 0; //设定低温
unsigned int ST_Temp_L_sum = 0; //串口接收到临时数据
unsigned char KEYX = 0; //按键顺序
unsigned int KeyCount = 0; //按键扫描累计
unsigned char SET_zt = 0; //设置状态,0显示当前温度,1显示设置温度
unsigned int i = 0;
unsigned char code NumberX[] = //数码管值
{
//0 1 2 3 4 5 6 7 8 9 . - H L
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f,0xbf,0x89,0xc7
};
/************* 本地变量声明 **************/
unsigned char idata RX1_Buffer[RX1_Lenth]; //接收缓冲
unsigned char RX1_Cnt; //接收计数
unsigned char RX1_Status = 0x00; //接收计数
/*延时=========*/
void ys(unsigned int z)//延时
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=800;y>0;y--);
}
/*************字节写入**************/
void write_data_eeprom(uint address,char eeprom_data)
{
IAP_DATA = eeprom_data;
IAP_ADDRH = address >> 8;
IAP_ADDRL = address & 0x00FF;
IAP_CMD = 0x02;//write
IAP_CONTR |= 0x83;//EN
IAP_TRIG = 0x5A;//开始
IAP_TRIG = 0xA5;
}
/*************字节读取**************/
char read_data_eeprom(uint address)
{
uchar eeprom_data = 0;
IAP_ADDRH = address >> 8;
IAP_ADDRL = address & 0x00FF;
IAP_CMD = 0x01;//read
IAP_CONTR |= 0x83;//EN
IAP_TRIG = 0x5A;//开始
IAP_TRIG = 0xA5;
eeprom_data = IAP_DATA;
return eeprom_data;
}
/*************清空数据**************/
void IapEraseSector(uint address)
{
IAP_CONTR |=0x83; //Open IAP function, and set wait time
IAP_CMD = 0x03; //Set ISP/IAP/EEPROM ERASE command
IAP_ADDRL = address; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = address >> 8; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x5a; //Send trigger command1 (0x5a)
IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)
;;;;;;;;;;
}
/*************保存数据**************/
void SAVE()
{
IapEraseSector(0x00); //清空数据
EA = 0;
ys(8);
write_data_eeprom(0x02,M_Recoup); //写补偿数据
write_data_eeprom(0x03,ST_Temp_H); //写设置温度
EA = 1;
EA = 1;
}
/*************读取数据**************/
void READ()
{
M_Recoup = read_data_eeprom(0x02); //读补偿数据
ST_Temp_H = read_data_eeprom(0x03); //读设置温度
if((ST_Temp_H > 500) || (ST_Temp_H < 0))
ST_Temp_H = 100;
if((M_Recoup > 21) || (M_Recoup < 0))
M_Recoup=10;
EA = 1;
EA = 1;
}
/*返回MAX6675当前温度值,返回8888表示连接断开=========*/
unsigned long MAX6675()
{
unsigned char i ;
unsigned long TempX = 0;
M_SCK= 0 ;
M_CS = 0 ;
_nop_();
_nop_();
_nop_();
for(i = 0; i < 16; i++)
{
M_SCK= 1 ;
TempX <<= 1;
TempX |= M_DAT;
_nop_();
M_SCK= 0;
_nop_();
_nop_();
_nop_();
}
M_CS = 1;
_nop_();
_nop_();
_nop_();
if((TempX >> 2) & 1)
return (8888);
else
return ((TempX >>3 & 0x0fff)*25)/10-100+(M_Recoup*10); //10以下是负数补偿,10以上是正数补偿
}
/*输入状态灯位置,输入显示数值=========*/
void Num(unsigned char SEL,unsigned int NS)
{
if(SEL==0)
{
SE[0] = NS/1000%10;
SE[1] = NS/100%10;
SE[2] = NS/10%10;
SE[3] = NS%10;
}
else
{
SE[0] = SEL + 11;
SE[1] = NS/100%10;
SE[2] = NS/10%10;
SE[3] = NS%10;
}
}
/*串口发送数据=========*/
void TX1_Num(unsigned int TX1_NS)
{
SBUF = TX1_NS/1000%10+0x30;
ys(2);
SBUF = TX1_NS/100%10+0x30;
ys(2);
SBUF = TX1_NS/10%10+0x30;
ys(2);
SBUF = TX1_NS%10+0x30;
ys(2);
SBUF = 0x7F;ys(2);
}
void main()
{
unsigned int temp = 0;
OUT_buzzer = 1;
OUT_hot = 1;
OUT_fan = 1;
AUXR = 0x80; //定时器0在1T模式工作
P1M0=0xff; //推免输出
P1M1=0x00;
SCON = 0x50;
TMOD = 0x20;
TH1 = TL1 = -(FOSC/12/32/BAUD); //Set auto-reload vaule
TL0 = T1MS;
TH0 = T1MS >> 8;
TR1 = 1;
TR0 = 1;
ET0 = 1;
ES = 1;
EA = 1;
M_CONT = 580;
READ();
while(1)
{
if(i == 1000)
{
i = 0;
}
if(RX1_Status>0x00)
{
switch(RX1_Status) //选择显示状态
{
case 0x01:
ST_Temp_H = ST_Temp_H_sum;
SBUF = 0x4F;ys(2);SBUF = 0x4B;ys(2);SBUF = 0x7F;ys(2);SBUF = 0x7F;ys(2);SBUF = 0x7F;ys(2);
SAVE();
break;
case 0xF1:
SBUF = 0x45;ys(2);SBUF = 0x52;ys(2);SBUF = 0x45;ys(2);SBUF = 0x4F;ys(2);SBUF = 0x52;ys(2);
break;
case 0x05:
M_Recoup=M_Recoup_sum;
SBUF = 0x4F;ys(2);SBUF = 0x4B;ys(2);SBUF = 0x7F;ys(2);SBUF = 0x7F;ys(2);SBUF = 0x7F;ys(2);
SAVE();
break;
case 0xF5:
SBUF = 0x45;ys(2);SBUF = 0x52;ys(2);SBUF = 0x45;ys(2);SBUF = 0x4F;ys(2);SBUF = 0x52;ys(2);
break;
case 0x08:
TX1_Num(M_Temp);break;
case 0x09:
TX1_Num(ST_Temp_H);break;
}
RX1_Status=0x00;
}
if(SET_zt == 0)
{
Num(0,M_Temp); //6675
if(M_Temp < (ST_Temp_H*10))//小于设定温度就打开发热管,关闭风扇
{
OUT_hot = 0;
OUT_fan = 1;
}
else
{
OUT_hot = 1;
OUT_fan = 0;
}
if(M_Temp >= 5000)//200 度报警
{
OUT_buzzer = 0;
}
else
{
OUT_buzzer = 1;
}
}
else
{
Num(1,ST_Temp_H);//切换为显示设置温度
}
}
}
void LED_S() interrupt 1
{
unsigned char keys = 0;
if(!KEY_set)
KEYX = 0;
if(!KEY_plus)
KEYX = 1;
if(!KEY_lower)
KEYX = 2;
if(KEY_set & KEY_plus & KEY_lower)
{
KEYX = 0;
KeyCount = 0;
}
else
{
KeyCount++;
if(KeyCount > 1000)
KeyCount = 950;
if(((KeyCount == 100)|(KeyCount == 950)))
{
if(KEYX == 0)
{
SET_zt=0;
}
if(KEYX == 1)
{
SET_zt = 1;
if(ST_Temp_H < 500)
ST_Temp_H++;
SAVE();
}
if(KEYX == 2)
{
SET_zt = 1;
if(ST_Temp_H > 0)
ST_Temp_H--;
SAVE();
}
}
}
W1 = W2 = W3 = W4 = 1;
P0 = 0xff;
if(LEDS < 4)
{
switch(LEDS)
{
case 0 : W1 = 0;
break;
case 1 : W2 = 0;
break;
case 2 : W3 = 0;
break;
case 3 : W4 = 0;
break;
}
if(SET_zt == 0 & W3 == 0)
{
P0 = NumberX[SE[LEDS]]&0x7f;//第三位显示小数点
}
else
{
P0 = NumberX[SE[LEDS]];
}
}
LEDS++;
if(LEDS > 4)
LEDS = 0;
M_CONT++;
if(M_CONT > 1000)
{
M_CONT = 0;
M_Temp = MAX6675(); //转换
}
}
/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 1
{
if (TI)
{
TI = 0; //清除TI位
busy = 0; //清忙标志
}
if(RI == 1) //RI接受中断标志
{
RX1_Buffer[RX1_Cnt] = SBUF; //保存一个字节
if(RX1_Buffer[0]==0x53)
{
RX1_Cnt++;
}
else
{
RX1_Cnt=0;
}
if(RX1_Cnt>=8)
{ //SET H L 53 45 54 48 4C 10位数据SET+(H/L)+(三位数