|
sbit Lock = P3^7; //代表鎖控的繼電器IO 高電平關(guān)鎖,低電平開鎖
sbit LEDRED = P3^3; //代表密碼輸入錯(cuò)誤的紅燈IO 高電平熄滅,低電平點(diǎn)亮
sbit LEDGREEN = P3^4; //代表密碼輸入正確的綠燈IO 高電平熄滅,低電平點(diǎn)亮
uchar genPasswd[4]; //存儲(chǔ)生成的四位隨機(jī)數(shù)密碼
uchar inpPasswd[4]; //存儲(chǔ)取包時(shí)輸入的四位密碼
uchar code welcome[9]="welcome!"; //開機(jī)顯示的歡迎標(biāo)語
uchar code set[7]="Passwd"; //顯示生成的密碼標(biāo)題
uchar code close[12]="close door!"; //提示關(guān)門
uchar code input[13]="input passwd"; //提示請(qǐng)輸入密碼
/****************定時(shí)器設(shè)置相關(guān)的變量***********************/
unsigned char TL0_temp; /*暫存TL0的初值*/
unsigned char TH0_temp; /*暫存TH0的初值*/
#define INT_CLOCK 10 /*INT_CLOCK為定時(shí)值,單位為ms ,此處定義為10ms*/
#define CRY_FREQUENCY 11059200 /*CRY_FREQUENCY為晶振頻率,單位為Hz*/
/*延時(shí)程序*/
void delay(uint z)
{
unsigned int i,j;
for(i=0;i<z;i++)
for(j=0;j<100;j++);
}
/******************************
顯示首頁 welcome
******************************/
void display1()
{
unsigned char i;
for(i = 0;i < 8;i++)
{
wr_com(0x84+i);
wr_dat(welcome[ i]);
}
}
/************************************
顯示密碼生成界面
************************************/
void display2()
{
unsigned char i;
for(i = 0;i < 6;i++)
{
wr_com(0x85+i);
wr_dat(set[ i]);
}
for(i = 0;i < 4;i++)
{
wr_com(0xc6+i);
wr_dat(genPasswd[ i]+0x30);
}
}
/************************************
顯示請(qǐng)關(guān)門界面
************************************/
void display3()
{
unsigned char i;
for(i = 0;i < 11;i++)
{
wr_com(0x83+i);
wr_dat(close[ i]);
}
}
/************************************
顯示密碼輸入界面
************************************/
void display4()
{
unsigned char i;
for(i = 0;i < 12;i++)
{
wr_com(0x82+i);
wr_dat(input[ i]);
}
for(i = 0;i < 4;i++)
{
wr_com(0xc6+i);
wr_dat(inpPasswd[ i]+0x30);
}
}
/***********************************
定時(shí)器0初始化
***********************************/
void Timer0_init()
{
unsigned long T0_temp; /*暫存T0的初始值 */
T0_temp = 65536-((INT_CLOCK *CRY_FREQUENCY /1000)/12); /*T0初始值計(jì)算公式,參考教科書*/
TL0_temp = T0_temp & 0xff;
TH0_temp = T0_temp >> 8;
TL0 = TL0_temp;
TH0 = TH0_temp;
TMOD |= 0x01;
TR0 = 1; /*開定時(shí)器0中斷*/
ET0 = 1;
EA = 1; /*開總中斷*/
}
void T0_interrupt(void) interrupt 1
{
TH0 += TH0_temp;
TL0 += TL0_temp;
}
void writestring(uchar x,uchar y,uchar *s) //LCD 寫字符串
{
if (y == 0) wr_com(0x80 + x); //表示第一行
else wr_com(0xC0 + x); //表示第二行
while (*s) //判斷是否字符串的結(jié)尾
{
wr_dat( *s); //顯示當(dāng)前字符
s ++; //字符串地址加1
}
}
void writeChar(uchar x,uchar y,uchar s) //LCD 寫字符串
{
if (y == 0) wr_com(0x80 + x); //表示第一行
else wr_com(0xC0 + x); //表示第二行
{
wr_dat( s); //顯示當(dāng)前字符
}
}
sbit DQ=P2^3; //ds18b20與單片機(jī)連接口
sbit SetKey = P2^0; //設(shè)置按鍵
sbit UpKey = P2^1; //加按鍵
sbit DnKey = P2^2; //減按鍵
uchar data disdata[5];
uint tvalue,CurrentT=0; //溫度值
uchar tflag; //溫度正負(fù)標(biāo)志
//bit SPL_tflag=0;
//unsigned char AlarmTempLow=0,AlarmTempTop=30,Set=0;
/************************************
溫度控制界面
************************************/
void display5()
{
writestring(0,0," Low=0 Top=30 "); //顯示“ Low=0 Top=30 ”
writestring(0,1,"Current T= "); //顯示“Current T= ”
}
void delay_18B20(unsigned int i)//延時(shí)1微秒
{
while(i--);
}
void ds1820rst(void)/*ds1820復(fù)位*/
{
unsigned char x=0;
DQ = 1; //DQ復(fù)位
delay_18B20(4); //延時(shí)
DQ = 0; //DQ拉低
delay_18B20(100); //精確延時(shí)大于480us
DQ = 1; //拉高
delay_18B20(40);
}
uchar ds1820rd(void)/*讀數(shù)據(jù)*/
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; //給脈沖信號(hào)
dat>>=1;
DQ = 1; //給脈沖信號(hào)
if(DQ)
dat|=0x80;
delay_18B20(10);
DQ=1;
}
return(dat);
}
void ds1820wr(uchar wdata)/*寫數(shù)據(jù)*/
{
unsigned char i=0;
for (i=8; i>0; i--) //寫一個(gè)字節(jié)數(shù)據(jù)到DS18B20
{
DQ = 0;
DQ = wdata&0x01; //寫一位數(shù)據(jù)
delay_18B20(10); //延時(shí)
DQ = 1; //拉高數(shù)據(jù)線
wdata>>=1; //準(zhǔn)備下一位
}
}
unsigned int Read_Temperature(void)/*讀取溫度值并轉(zhuǎn)換*/
{
uchar a,b;
ds1820rst();
ds1820wr(0xcc);//*跳過讀序列號(hào)*/
ds1820wr(0x44);//*啟動(dòng)溫度轉(zhuǎn)換*/
ds1820rst();
ds1820wr(0xcc);//*跳過讀序列號(hào)*/
ds1820wr(0xbe);//*讀取溫度*/
a=ds1820rd(); //讀取低位數(shù)據(jù)
b=ds1820rd(); //讀取高位數(shù)據(jù)
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a; //取得16位數(shù)據(jù)
if(tvalue<0x0fff) tflag=0; //判斷是否正溫度
else {tvalue=~tvalue+1;tflag=1;} //負(fù)溫度,數(shù)據(jù)取反,溫度標(biāo)志位為1
tvalue=tvalue*(0.625);//溫度值擴(kuò)大10倍,精確到1位小數(shù)
CurrentT=tvalue;//保存當(dāng)前溫度
return(tvalue);//返回溫度值
}
void Display_Temperature() //顯示溫度
{
uchar flagdat;
disdata[0]=tvalue/1000+0x30;//百位數(shù)
disdata[1]=tvalue%1000/100+0x30;//十位數(shù)
disdata[2]=tvalue%100/10+0x30;//個(gè)位數(shù)
disdata[3]=tvalue%10+0x30;//小數(shù)位
if(tflag==0) flagdat=0x20;//正溫度不顯示符號(hào)
else flagdat=0x2d;//負(fù)溫度顯示負(fù)號(hào):-
if(tflag==1)
{
writeChar(10,1,flagdat);//顯示符號(hào)位
writeChar(11,1,disdata[0]);//顯示百位
writeChar(12,1,disdata[1]);//顯示十位
writeChar(13,1,disdata[2]);//顯示個(gè)位
writeChar(14,1,0X2E);//顯示小數(shù)點(diǎn)
writeChar(15,1,disdata[3]);//顯示小數(shù)位
}
else
{
writeChar(10,1,disdata[0]);//顯示百位
writeChar(11,1,disdata[1]);//顯示十位
writeChar(12,1,disdata[2]);//顯示個(gè)位
writeChar(13,1,0X2e);//顯示小數(shù)點(diǎn)
writeChar(14,1,disdata[3]);//顯示小數(shù)位
writeChar(15,1,' ');//顯示小數(shù)位
}
}
//void SetFun(void) //進(jìn)入設(shè)置參數(shù)子函數(shù)
//{
// if(SetKey==0) //設(shè)置按鍵
// {
// delay(20); //延時(shí)防抖
// if(SetKey==0) //設(shè)置按鍵
// {
// if(Set<2) Set++; //設(shè)置按鍵次數(shù)累計(jì)
// else Set=0;
// }
// switch(Set) //根據(jù)設(shè)置按鍵次數(shù),指向?qū)?yīng)設(shè)置位置
// {
// case 0: writestring(0,0," ");writestring(8,0," ");break;//清除設(shè)置符號(hào)
// case 1: writestring(0,0,">");writestring(8,0," ");break;//指向設(shè)置下限
// case 2: writestring(0,0," ");writestring(8,0,">");break;//指向設(shè)置上限
// }
// while(SetKey==0);//等待按鍵松開
// }
//
// if((UpKey==0)&&(Set!=0))//加按鍵按下
// {
// delay(20);//延時(shí)防抖
// if(UpKey==0)//加按鍵按下
// {
// switch(Set)//根據(jù)設(shè)置按鍵次數(shù),設(shè)置上下限
// {
// case 1:
// if(!SPL_tflag)
// {
// if(AlarmTempLow<99) AlarmTempLow++;
// else AlarmTempLow=99;
// }
// else
// {
// if(AlarmTempLow>1) AlarmTempLow--;
// else
// {
// AlarmTempLow=0;
// SPL_tflag=0;
// }
// }
// break; //設(shè)置下限
// case 2:
// if(AlarmTempTop<99) AlarmTempTop++;
// else AlarmTempTop=99;
// break;//設(shè)置上限
// }
// while(UpKey==0); //等待按鍵松開
// }
// }
//
// if((DnKey==0)&&(Set!=0))//減按鍵
// {
// delay(20);
// if(DnKey==0)//減按鍵
// {
// switch(Set)//根據(jù)設(shè)置按鍵次數(shù),設(shè)置上下限
// {
// case 1:
// if(!SPL_tflag)
// {
// if(AlarmTempLow>0) AlarmTempLow--;
// else
// {
// AlarmTempLow=1;
// SPL_tflag=1;
// }
// }
// else
// {
// if(AlarmTempLow<99) AlarmTempLow++;
// else AlarmTempLow=99;
// }
// break;//設(shè)置下限
// case 2:
// if(AlarmTempTop>0) AlarmTempTop--;
// else AlarmTempTop=0; break;//設(shè)置上限
// }
//
// }
// }
//}
/*主函數(shù)*/
uchar global_state = 0;
uchar count_num = 0; //輸入的數(shù)字個(gè)數(shù)
void main()
{
uchar i;
uchar passwd;
uchar key_value = 0;
uchar temp_key_value = 0xff;
Lock = 1; //剛上電 鎖是需要保持閉合
Timer0_init(); //定時(shí)器初始化
lcd_init(); //LCD1602初始化
while(1) //進(jìn)入不斷循環(huán)
{
temp_key_value = Calkey_scan(); //讀取矩陣按鍵的鍵值
if(temp_key_value != 0xff)
{
key_value = temp_key_value;
}
switch(global_state)
{
case 0: //初始化狀態(tài)
display1(); //顯示歡迎語句 -- "welcome"
writestring(0,1,"Current T= "); //顯示“Current T= ”
{
Read_Temperature(); //讀取溫度值
Display_Temperature(); //顯示溫度值
}
if(SetKey==0)
{
display5();
{
Read_Temperature(); //讀取溫度值
Display_Temperature(); //顯示溫度值
}
while(1);
}
if(key_value == 13) //存包按鍵被按下
{
key_value = 0xff; //將按鍵值清除
Lock = 0; //開鎖
clear(); //清屏,準(zhǔn)備下一屏的顯示
display3(); //顯示關(guān)門提示語 -- "close door!"
delay(1900); //等待關(guān)門 大約3秒
Lock = 1; //關(guān)門
clear(); //清屏,準(zhǔn)備下一屏的顯示
global_state = 1; //切換運(yùn)行狀態(tài)
passwd = TL0; //采用定時(shí)器寄存器的值作為密碼
genPasswd[0] = passwd/100; //存儲(chǔ)密碼
genPasswd[1] = passwd%100/10;
genPasswd[2] = passwd%10;
genPasswd[3] = (genPasswd[1]+genPasswd[2])%10;
}
if(key_value == 14) //取包按鍵被按下
{
key_value = 0xff; //將按鍵值清除
clear(); //清屏,準(zhǔn)備下一屏的顯示
global_state = 2; //切換運(yùn)行狀態(tài)
count_num = 0; //清除數(shù)字按鍵變量
for(i = 0;i < 4;i++) //清空輸入的密碼數(shù)組
inpPasswd[ i] = ' '-0x30;
}
break;
case 1: //密碼生成狀態(tài)
display2(); //顯示密碼生成界面
delay(1900); //等待大約3秒
global_state = 0; //返回到初始界面
clear(); //清屏,準(zhǔn)備下一屏的顯示
break;
case 2: //輸入密碼狀態(tài)
display4(); //顯示輸入密碼界面
if((key_value >= 0) && (key_value <= 9)) //如果按下的為0-9的數(shù)字按鍵
{
if(count_num <= 3) //如果按鍵次數(shù)小于4次
{
inpPasswd[count_num] = key_value; //將按鍵值存入數(shù)組,并顯示
count_num++;
}
key_value = 0xff; //將按鍵值清除
}
if(key_value == 15) //清除按鍵被按下
{
key_value = 0xff; //將按鍵值清除
for(i = 0;i < 4;i++)
inpPasswd[ i] = ' '-0x30; //清除剛剛輸入的密碼
count_num=0;
}
if(key_value == 16) //確認(rèn)按鍵被按下
{
key_value = 0xff; //將按鍵值清除
for(i = 0;i < 4;i++)
{
if(inpPasswd[ i] != genPasswd[ i])
break;
}
if(i == 4) //密碼輸入正確
{
LEDRED = 1; //紅燈熄滅
LEDGREEN = 0; //綠燈亮
Lock = 1; //開鎖
delay(1900); //等待大約3秒
Lock = 0; //關(guān)鎖
LEDGREEN = 1; //綠燈熄滅
}
else //密碼輸入錯(cuò)誤
{
LEDRED = 0; //紅燈亮
LEDGREEN = 1; //綠燈熄滅
Lock = 0; //關(guān)鎖
delay(1900); //等待大約3秒
LEDRED = 1; //紅燈熄滅
}
clear(); //清屏,準(zhǔn)備下一屏的顯示
global_state = 0; //返回到初始界面
}
break;
}
}
}
|
|