?? lock_main.c
字號:
}
//*************************************************清整個GDRAM空間*************************************************
void clear_gdram(void)
{
uchar x,y;
for(y=0;y<64;y++) //64
{
for(x=0;x<16;x++) //16
{
write_com(0x34);
write_com(y+0x80); //行地址
write_com(x+0x80); //列地址
write_com(0x30);
write_data(0x00);
write_data(0x00);
WDR(); //喂狗
}
}
}
//********************************************清屏*****************************************************************
void clear_screen(void)
{
write_com(0x01);
delay_ms(10);
}
//*********************************************系統起動引導主畫面**************************************************
void root_directory(void)
{
write_com(0x80); //第一行(如果是地址是:80H,即LCD的第一行的第一個位置顯示)
han_zi_display(" 門禁系統 ");
write_com(0x91);
write_data((tem[0]/10)+0x30);
write_data((tem[0]%10)+0x30);
han_zi_display("年");
write_data((tem[1]/10)+0x30);
write_data((tem[1]%10)+0x30);
han_zi_display("月");
write_data((tem[2]/10)+0x30);
write_data((tem[2]%10)+0x30);
han_zi_display("日");
write_com(0x8d);
switch(tem[6])
{
case 0:
han_zi_display("星期日");
break;
case 1:
han_zi_display("星期一");
break;
case 2:
han_zi_display("星期二");
break;
case 3:
han_zi_display("星期三");
break;
case 4:
han_zi_display("星期四");
break;
case 5:
han_zi_display("星期五");
break;
case 6:
han_zi_display("星期六");
break;
default:
break;
}
write_com(0x98);
han_zi_display("室內溫度:");
if(cold==0xaa)
{
write_data('-');
}
else
{
write_data(0x20);
}
write_data(temp0/10+0x30);
write_data(temp0%10+0x30);
write_com(0x9e);
han_zi_display("℃");
}
//**********************************************時間、日期顯示*****************************************************
void date_time_display(void)
{
write_com(0x88);
write_data((tem[3]/10)+0x30); //HOUR
write_data((tem[3]%10)+0x30);
if(set_time_temp==0) //=0 表示沒有進入時間設置菜單
{
write_data(':'); //通常情況下,":"要顯示為半角,目的:好看
}
else
{
han_zi_display("時"); //進入設置時間菜單時,顯示為漢字,目的:方便反白顯示
}
write_data((tem[4]/10)+0x30); //MINUTE
write_data((tem[4]%10)+0x30);
if(set_time_temp==0) //=0 表示沒有進入時間設置菜單
{
write_data(':'); //通常情況下,":"要顯示為半角,目的:好看
write_data((tem[5]/10)+0x30); //SECOND
write_data((tem[5]%10)+0x30);
}
else
{
han_zi_display("分"); //進入設置時間菜單時,顯示為漢字,目的:方便反白顯示
}
}
//*********************************************讀EEPROM,到RAM中***************************************************
void card_pro(void)
{
uchar i=0,u=0,r=1; //EEPROM地址從0x01處保存
for(i=0;i<5;i++) //共有5張開門卡,1張管理卡
{
for(u=0;u<5;u++) //每個卡有5個字節數據
{
card_data[i][u]=eeprom_read(r++); //把EEPROM中的5張開門卡復制到RAM中
WDR(); //喂狗
}
}
}
//********************************************比較匹配A 中斷*******************************************************
#pragma interrupt_handler time1_comp:7 //工作在CTC模式 每1S中斷一次
void time1_comp(void)
{
if(return_en) //菜單不動作自動返回允許變量
{
auto_return++; //當auto_return>=OVER_FLOW時自動退出菜單設置
}
xx++;
if(lcd_back_en==0xaa) //LCD背光計時變量允許
{
lcd_back_time++;
if(lcd_back_time>=LCD_LAMP) //30秒后關閉LCD背光
{
lcd_back_time=0;
lcd_back_en=0;
LCD_BACK_OFF;
}
}
if(set_time_temp==0)
{
tem[5]++;
if(tem[5]>=60) //60 秒進位
{
tem[5]=0;
tem[4]++;
charge_tem++;
scan_en=0;
if(tem[4]>=60) //60 分進位
{
tem[4]=0;
tem[3]++;
if(tem[3]>=24) //24 小時進位
{
tem[3]=0;
tem[6]++;
tem[2]++;
if(tem[6]>=7) //7 星期進位
{
tem[6]=0;
}
if((tem[1]==1)||(tem[1]==3)||(tem[1]==5)||(tem[1]==7)||(tem[1]==8)||(tem[1]==10)||(tem[1]==12)) //判斷大小月
{
if(tem[2]>=32) //如果為大月,則有31天
{
tem[2]=1;
tem[1]++;
}
}
else
{
if(tem[2]>=31) //如果為小月,則代表只有30天
{
tem[2]=1;
tem[1]++;
}
}
if(tem[1]>=13) //月進位
{
tem[1]=1;
tem[0]++;
if(tem[0]>=29) //當年大于2029年時,清零即2007年
{
tem[0]=7;
}
}
}
}
}
}
}
//*********************************************讀卡中斷INT0********************************************************
#pragma interrupt_handler int0_inter:2 //讀卡
void int0_inter(void)
{
uchar i;
uchar card_num=0;
card_num=read_card_number(); //讀卡
if(card_num==0xaa)
{
buzzer_pro(1); //峰鳴器指示
LCD_BACK_ON; //打開LCD背光
lcd_back_en=0xaa; //打開計時變量
lcd_back_time=0; //計時變量清0
WDR(); //喂狗
if((manage_card[0]==rev_dat[0])&&(manage_card[1]==rev_dat[1])&&(manage_card[2]==rev_dat[2])&&(manage_card[3]==rev_dat[3])&&(manage_card[4]==rev_dat[4])&&(manage_card_inc_en==0))
{
inc_card_en=0xaa; //管理卡
GIFR=(1<<INTF0);
GICR&=~((1<<INT1)|(1<<INT0)); //關閉外部中斷0、1
return;
}
if(manage_card_inc_en==0xaa) //添加卡
{
manage_card_inc_en=0;
GIFR=(1<<INTF0);
GICR&=~(1<<INT0); //關閉外部中斷0
return;
}
for(i=0;i<5;i++)
{
if((card_data[i][0]==rev_dat[0])&&(card_data[i][1]==rev_dat[1])&&(card_data[i][2]==rev_dat[2])&&(card_data[i][3]==rev_dat[3])&&(card_data[i][4]==rev_dat[4]))
{ //卡1
GICR&=~((1<<INT1)|(1<<INT0)); //關閉外部中斷0、1
xx=0;
WDR(); //喂狗
LOCK_ON; //開鎖
delay_ms(500);
LOCK_OFF;
rev_dat[0]=rev_dat[1]=rev_dat[2]=rev_dat[3]=rev_dat[4]=0xff;
i=6;
}
}
close_read=1;
card_num=0;
xx=0;
GICR&=~(1<<INT0); //關閉外部中斷0
card_num=0;
}
GIFR=(1<<INTF0);
}
//*********************************************按鍵中斷INT1********************************************************
#pragma interrupt_handler int1_on:3
void int1_on(void)
{
delay_ms(10); //按鍵采樣, 注意,一定要延時8MS以上,否則會造成連鍵現象
kk=1;
GICR&=~(1<<INT1); //關閉外部中斷1
GIFR=(1<<INTF1);
}
//*****************************************************************************************************************
//文件名: 用AD來檢測按鍵
//編譯日期: 2007-01-21
//功能描述:
// 1、共8個KEY,利用AD口其中的一個,來測電壓不同來判斷哪個按鍵按下。
//CPU類型: ATmega16
//晶振頻率: 7.3728MHZ
//版本: V0.1
//編程: 于軍峰
//*****************************************************************************************************************
//理論值:
// S1=0V S2=0.45V S3=0.83V S4=1.15V S5=1.42V S6=1.66V S7=1.875V S8=2.05V 無按下時=5V
//
// S1=SET S2=向上 S3=向下 S4=向左 S5=向右 S6=確認 S7=返回 S8=關于
//
//**********************************************AD來檢測按鍵*******************************************************
void read_adc(void)
{
uint key_val=0;
key_val=adc_sampling(ADC_PINA0);
if(key_val<400)
{
key=1;
}
else if(key_val<600) //向上
{
key=2;
}
else if(key_val<1000) //向下
{
key=3;
}
else if(key_val<1200) //向左
{
key=4;
}
else if(key_val<1500) //向右
{
key=5;
}
else if(key_val<1700) //OK
{
key=6;
}
else if(key_val<1900) //返回
{
key=7;
}
else if(key_val<2200) //說明
{
key=8;
}
else
{
key=0;
return;
}
}
//************************************************ADC 采樣*********************************************************
uint adc_sampling(uchar adc_input)
{
ulong temp32=0;
uint tem_3=0;
CLI(); //關中斷
ADMUX=(0x40|adc_input); //選擇外接參考電壓,AVCC, AREF 引腳外加濾波電容
//adc_input:單端通道 0x00~0x07,0x1E,0x1F
ADCSRA|=(1<<ADSC); //啟動AD轉換
while ((ADCSRA&(1<<ADIF))==0);
ADCSRA|=(1<<ADIF); //寫1清除標志位
temp32=ADC;
//**************************************第一次采樣的值舍去不要*****************************************************
ADMUX=(0x40|adc_input); //選擇外接參考電壓,AVCC, AREF 引腳外加濾波電容
//adc_input:單端通道 0x00~0x07,0x1E,0x1F
ADCSRA|=(1<<ADSC); //啟動AD轉換
while ((ADCSRA&(1<<ADIF))==0);
ADCSRA|=(1<<ADIF); //寫1清除標志位
temp32=ADC;
temp32*=vref;
tem_3=((uint)(temp32/1024));
SEI(); //開中斷
return(tem_3);
}
//**********************************************室溫檢測***********************************************************
uchar temperature_check(void)
{
uchar adc_result1=0;
temp_value=adc_sampling(ADC_PINA1); //AD采樣
adc_result1=get_degree();
if(adc_result1<=30) //是否為零下
{
adc_result1=31-adc_result1;
cold=0xaa;
}
else
{
cold=0;
adc_result1-=31;
}
return(adc_result1);
}
//**********************************************溫度查表***********************************************************
uchar get_degree(void)
{
uchar x=129; //只檢測溫度-30---+99
for (x=129;x>0;x--) // 查表
{
if (temp_1[x]>=temp_value)
{
return x;
}
}
return x;
}
//********************************************峰鳴器處理***********************************************************
void buzzer_pro(uchar p)
{
for(;p>0;p--)
{
WDR(); //喂狗
buzzer_on;
delay_ms(15);
buzzer_off;
delay_ms(15);
}
}
//**************************************************Program End****************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -