#include<reg52.h>
#include<port.h>
#include<18b20.h>
#include<1602.h>
#include<delay.h>
char InitTemp=26;
int i=0;
unsigned int temphex;
float tempfloat;//存放DS18B20采集的溫度值-小數
unsigned char temp[];
sbit KEYPLUS=P3^2; //定義溫度加按鍵輸入端口
sbit KEYMINUS=P3^3; //定義溫度減按鍵輸入端口
void InitKey(void) //外部按鍵中斷初始化
{
EA=1; //全局中斷開
EX0=1; //外部中斷0開
IT0=1; //邊沿觸發
EX1=1; //外部中斷1開
IT1=1; //IT1=1表示邊沿觸發
}
void Init_Port(void) //串口初始化
{
SCON=0x40; //
TMOD=0x20; //定時器T1初始化
PCON=0x00;
TH1=0xFD;
TL1=0xFD;
TR1=1;
}
void Init_Timer0(void) //定時器0初始化
{
TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
TH0=0x00; //給定初值,這里使用定時器最大值從0開始計數一直到65535溢出
TL0=0x00;
EA=1; //總中斷打開
ET0=1; //定時器中斷打開
TR0=1; //定時器開關打開
}
void Init_Temp_OnComputer(char temperature)
{
SendByte(temperature/10+0x30);
SendByte(temperature%10+0x30);
SendByte('C');
}
void Display_18b20_OnComputer(float temperature)
{
unsigned long int wendu;
wendu=temperature*10000;//此變量類型一定要設置為unsigned long int,若定義為unsigned int則溢出
SendStr("實時溫度:");
SendByte(wendu/1000000+0x30); //百位
SendByte(wendu%1000000/100000+0x30);//十位
SendByte(wendu%100000/10000+0x30);//個位
SendByte('.');
SendByte(wendu%10000/1000+0x30);//小數點后第1位,小數點后千位
SendByte(wendu%1000/100+0x30);//小數點后第2位,小數點后百位
SendByte(wendu%100/10+0x30);//小數點后第3位,小數點后十位
SendByte(wendu%10+0x30);//小數點后第4位,小數點后個位
SendByte('C');//溫度單位
SendByte('\r'); //SendByte(0x0D); SendByte(0x0A); 換行
SendByte('\n');
}
void Display_LCD_OnLCD(float temperature)
{
unsigned long int wendu;
wendu=temperature*10000;//此變量類型一定要設置為unsigned long int,若定義為unsigned int則溢出
LCD_Write_Char(6,1,'+');
LCD_Write_Char(7,1,wendu/1000000+0x30);
LCD_Write_Char(8,1,wendu%1000000/100000+0x30);
LCD_Write_Char(9,1,wendu%100000/10000+0x30);
LCD_Write_Char(10,1,'.');
LCD_Write_Char(11,1,wendu%10000/1000+0x30);
LCD_Write_Char(12,1,wendu%1000/100+0x30);
LCD_Write_Char(13,1,wendu%100/10+0x30);
LCD_Write_Char(14,1,wendu%10+0x30);
LCD_Write_Char(15,1,'C');
}
void main()
{
InitKey();
Init_Port();
LCD_Init();
LCD_Write_String(0,0,"SetTemp:");
LCD_Write_String(0,1,"MTemp:");
LCD_Write_Char(8,0,'2');
LCD_Write_Char(9,0,'6');
LCD_Write_Char(10,0,'C');
Init_Timer0();
while(1);
}
/*------------------------------------------------
定時器中斷子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
static unsigned int j;
// ET0=0; //定時器中斷打開
// TR0=0;
j++;
if(j==51)
{
j=0;
temphex=ReadTemperature(); //定時時間1s到,采集一次溫度數據
tempfloat=(float)temphex*0.0625;//16進制溫度數據轉換為實際溫度值
Display_18b20_OnComputer(tempfloat);
Display_LCD_OnLCD(tempfloat);
}
TH0=(65536-10000)/256; //重新賦值 12M晶振計算,指令周期1uS,
//采集間隔10s,由于定時器
//最大值65536 即65.536ms 所以
TL0=(65536-10000)%256; //直接定時器不夠用,需要用循環處理,
//定時10ms,然后循環1000次后輸出 1000x10ms=10s
// ET0=1; //定時器中斷打開
//TR0=1;
}
/*------------------------------------------------
外部中斷0程序-溫度加
------------------------------------------------*/
void ISR_INT0(void) interrupt 0
{
DelayMs(5);
if(!KEYPLUS) //再次確認按鍵是否按下,沒有按下則退出
{
while(!KEYPLUS);//如果確認按下按鍵等待按鍵釋放,沒有釋放則一直等待
{
InitTemp++; //KEYPLUS按下觸發一次,溫度值加1
LCD_Write_String(0,0,"SetTemp:");
LCD_Write_Char(8,0,InitTemp/10+0x30);
LCD_Write_Char(9,0,InitTemp%10+0x30);
LCD_Write_Char(10,0,'C');
SendStr("設置溫度值:");
Init_Temp_OnComputer(InitTemp); //發送設定的加減溫度值
SendByte('\r');
SendByte('\n');
}
}
}
/*------------------------------------------------
外部中斷1程序-溫度減
------------------------------------------------*/
void ISR_INT1(void) interrupt 2
{
DelayMs(5);
if(!KEYMINUS) //再次確認按鍵是否按下,沒有按下則退出
{
while(!KEYMINUS);//如果確認按下按鍵等待按鍵釋放,沒有釋放則一直等待
{
InitTemp--; //KEYMINUS按下觸發一次,溫度值減1
LCD_Write_String(0,0,"SetTemp:");
LCD_Write_Char(8,0,InitTemp/10+0x30);
LCD_Write_Char(9,0,InitTemp%10+0x30);
LCD_Write_Char(10,0,'C');
SendStr("設置溫度值:");
Init_Temp_OnComputer(InitTemp); //發送設定的加減溫度值
SendByte('\r');
SendByte('\n');
}
}
}
|