標題: 一套完整的門禁系統(tǒng)(原理圖+源程序),包括電源充電 [打印本頁]

作者: hubaba    時間: 2016-3-30 14:11
標題: 一套完整的門禁系統(tǒng)(原理圖+源程序),包括電源充電

門禁系統(tǒng)原理圖:




全部資料下載: 一套完整的門禁系統(tǒng)(原理圖 源程序),包括電源充電.rar (168.5 KB, 下載次數: 1128)

門禁系統(tǒng)源碼預覽(部分):
  1. /******************************************************************************************************************
  2. 程序名:      射頻卡門禁系統(tǒng)
  3. 功能概述:
  4.                          1、  點陣LCD(128*64)顯示。在正常、設置情況下LCD顯示系統(tǒng)各個時期的菜單以供選擇。
  5.                          2、  射頻卡開鎖,開鎖時用射頻卡放在讀卡器上(距離<15CM)即可開鎖,如果用非法卡連續(xù)刷寫次數超過3
  6.                               次則報警(報警功能沒有添加),這時系統(tǒng)將關閉刷卡器30分鐘,在30分鐘后再允許刷卡。
  7.                          3          本系統(tǒng)分為:
  8.                                       1)、1個主機。
  9.                                       2)、2個讀卡頭(一個在門外供刷卡用、一個在主機旁用于管理操作)
  10.                          4、  本鎖開鎖時供電,平時斷電(12V)。
  11.                          5、  8個按鍵(AD轉換采樣取值)(設置、+、-、↑、↓、確認、返回、說明)
  12.                          6、  每次按下鍵、刷卡時有峰鳴器指示
  13.                          7、  LCD背光在有按鍵按下時、或刷卡時自動點亮,延時30秒關閉
  14.                          8、  門外有人體紅外傳感器探頭,發(fā)現(xiàn)2米內有人,自動進入預警狀態(tài),如果是在晚上超過7點鐘,則點亮門前的燈泡照明,
  15.                               如果此時有人破壞(比如取下燈泡、剪斷燈炮的線、打爛燈泡)也要報警。否則、連續(xù)在門前超過1分鐘,就開始報警。
  16.                               (此功能沒有添加)
  17.                          9、  開門時發(fā)出“歡迎光臨”,并提示關門(此功能沒有添加)
  18.                          10、 本機帶有門鈴,并能記錄前10天門鈴按下的次數。(此功能沒有添加)
  19.                          11、 LCD顯示日期、星期、時間、室內溫度、鎖的狀態(tài)、功能設置(菜單顯示)等
  20.                          12、 可以查詢過去10天內的開門記錄并由LCD顯示出來(此功能沒有添加)
  21.                          13、 可以于電腦通過RS-232接口連接進行通信,監(jiān)看門的狀態(tài)、開門記錄等,方便打印(此功能沒有添加)
  22.                          14、 要求鎖誤判率小于1PPM
  23.                          15、 系統(tǒng)配有UPS(12V) 平時用UPS電能,只有當主機檢測到電壓低于11.5V時,自動接入火電進行充電。
  24.                               電瓶充滿時(大約5小時)自動斷電。
  25.                          16、 電壓:12V   
  26.                          17、 電流:待機時<50MA  

  27. 射頻卡類型: 4001、EM4100和含E2PROM的RF卡。如E5550。
  28. MCU類型:     ATmega16
  29. 晶振頻率:    7.3728MHZ
  30. 版本:             V0.1
  31. 編程:        于軍峰
  32. 編譯日期:    2007-05-01
  33. ******************************************************************************************************************/
  34. #include<iom16v.h>
  35. #include<macros.h>
  36. #include<stdio.h>
  37. #include"LCD_12864.H"                                                                                //LCD頭文件
  38. #include"read_card.H"                                                                                //讀卡頭文件
  39. #define key_inc  (PINC&(1<<PC0))                                                        //按鍵+,選擇日期、時間時用
  40. #define key_dec  (PINC&(1<<PC1))                                                        //按鍵-,選擇日期、時間時用
  41. #define BAUDRATE        9600                                                                //波特率
  42. #define F_CPU                        7372800                                                          //晶振頻率
  43. #define LCD_LAMP                60                                                                  //LCD默認30S后關閉
  44. #define BATTERY_TIME        5                                                                        //每十分鐘檢測一次電池電量

  45. #define ADC_PINA0                 0x00                                                                //ADC0                按鍵AD    單端通道,不放大
  46. #define ADC_PINA1                 0x01                                                                //ADC1                溫度采樣
  47. #define ADC_PINA2                 0x02                                                                //ADC2                電平電量檢測

  48. #define LCD_BACK_ON           PORTC&=~(1<<PC5)
  49. #define LCD_BACK_OFF           PORTC|=(1<<PC5)
  50. #define buzzer_on                  PORTD&=~(1<<PD7)
  51. #define buzzer_off          PORTD|=(1<<PD7)

  52. #define charge_on                  PORTC&=~(1<<PC6)
  53. #define charge_off          PORTC|=(1<<PC6)


  54. #define LOCK_ON                  PORTC&=~(1<<PC3)
  55. #define LOCK_OFF                  PORTC|=(1<<PC3)


  56. #define CHARGE_STATUS          (PINC&(1<<PC2))

  57. #define null                 0
  58. #define vref            5000                                                                                //AD轉換參考電壓
  59. #define OVER_FLOW          10                                                                                //進入菜單設置時,如果在10S內沒有按下任何鍵,則自動退出

  60. #pragma data:code
  61. //const uchar manage_card[5]={0x0b,0,0x2d,0x23,0x5f};                        //住房卡-----當作管理卡       
  62. const uchar manage_card[5]={0x33,0,0x7c,0x09,0xb1};                        //000 8128945-----當作管理卡       
  63. //*************************************************溫度測定查表****************************************************       
  64. //******************************************溫度范圍是:-30度----+99度*********************************************
  65. const uint temp_1[130]={
  66.                                                         4304,4270,4235,4198,4161,4122,4083,4042,4001,3958,
  67.                                                         3914,3870,3824,3778,3731,3683,3635,3585,3535,3484,
  68.                                                         3433,3381,3329,3276,3223,3169,3116,3062,3008,2953,
  69.                                                         2899,2844,2789,2733,2678,2622,2568,2514,2459,2405,
  70.                                                         2353,2299,2248,2196,2145,2095,2045,1996,1948,1901,
  71.                                                         1854,1808,1763,1719,1676,1599,1590,1549,1508,1468,
  72.                                                         1429,1391,1354,1318,1282,1247,1214,1181,1149,1117,
  73.                                                         1087,1057,1028,1000,973 ,946 ,920 ,895 ,870 ,846 ,
  74.                                                         823 ,800 ,777 ,755 ,755 ,713 ,692 ,673 ,654 ,632 ,
  75.                                                         617 ,600 ,583 ,567 ,551 ,536 ,521 ,506 ,491 ,478 ,
  76.                                                         465 ,452 ,440 ,428 ,417 ,405 ,394 ,384 ,373 ,364 ,
  77.                                                         354 ,345 ,335 ,326 ,318 ,310 ,302 ,294 ,286 ,279 ,
  78.                                                         271 ,265 ,258 ,252 ,245 ,239 ,233 ,227 ,222 ,216 ,
  79.                                                  };               
  80. //*****************************************************************************************************************
  81. #pragma data:data
  82. uchar card_data[5][5]={
  83.                                                 {0,0,0,0,0},                                                //卡1
  84.                                                 {0,0,0,0,0},                                                //卡2
  85.                                                 {0,0,0,0,0},                                                //卡3
  86.                                                 {0,0,0,0,0},                                                //卡4
  87.                                                 {0,0,0,0,0},                                                //卡5
  88.                                           };                       
  89. uchar tem[7]={7, 5, 1, 8, 0, 0, 6};                                                        //日期、時間、星期數組
  90. //                          年/月/日 /H /M /S /W

  91. //********************************************目錄結構體定義*******************************************************
  92. struct menu_item      
  93. {
  94.     short menu_count;
  95.     char *display_string;
  96.     void (*subs)();
  97.     struct menu_item *children_menus;
  98.     struct menu_item *parent_menus;
  99. };
  100. //**********************************************結構數組聲明*******************************************************
  101. struct menu_item main_menu[4];
  102. struct menu_item alarm_menu[2];
  103. struct menu_item infrared_menu[2];
  104. struct menu_item lamp_menu[2];
  105. struct menu_item (*menu_point) = main_menu;

  106. struct menu_item card_main_menu[4];
  107. struct menu_item card_inc_menu[2];
  108. struct menu_item card_dec_menu[2];
  109. struct menu_item (*menu_card) = card_main_menu;

  110. uchar user_choose = 0;
  111. uchar max_items=0;
  112. uint temp_value=0;                                                        //溫度檢測AD值
  113. //********************************************變量定義*************************************************************
  114. uchar second_temp=0;                                                //秒變量
  115. uchar scan_en=0;                                                        //主屏掃描標志位
  116. uchar key=0;                                                                //按鍵變量
  117. uchar kk=0;                                                                        //按鍵按下標志位
  118. uchar auto_return=0;                                                //菜單自動返回變量
  119. uchar return_en=0;                                                        //菜單自動返回標志位
  120. uchar left_right=0;                                                        //左右鍵變量
  121. uchar choose_temp=0;                                                //子菜單標題變量
  122. uchar return_temp=0;                                                //返回臨時變量
  123. uchar set_time_temp=0;                                                //設置時間時菜單變量,如果=1表示屏顯在設置時間菜單
  124. uchar twinkling_addr=0x91;                                        //設置時間時閃動顯示位置變量
  125. uchar inc_card_en=0;                                                //添加新卡允許變量
  126. uchar manage_card_inc_en=0;                                        //管理卡
  127. uchar cold=0;                                                                //溫度正負極標志位
  128. uchar temp0=0;                                                                //溫度值變量
  129. uchar xx=88;                                                                //溫度更新變量,開機賦一個比較大的數,目的是開機就顯示溫度
  130. uchar close_read=0;
  131. lcd_back_en=0;                                                                //LCD背光計時變量允許
  132. lcd_back_time=0;                                                        //LCD背光計時變量
  133. //*****************************************************************************************************************
  134. void delay_ms (unsigned int m);                                //延時
  135. void read_adc(void);                                                //按鍵ADC處理
  136. void date_time_display(void);                                //時間日期顯示
  137. void root_directory(void);                                        //引導主畫面
  138. void set_menu(void);                                                //設置菜單
  139. void clear_screen(void);                                        //清屏
  140. void clear_gdram(void);                                                //清全部GDRAM
  141. void select_menu(uchar data1);                                //選擇菜單時,標志
  142. void time_set_display(void);                                //時間、日期設置顯示
  143. uint adc_sampling(uchar adc_input);                        //ADC采樣
  144. uchar get_degree(void);                                                //溫度查表
  145. uchar temperature_check(void);                                //室溫檢測
  146. uchar charge_tem=0;                                                        //每十分鐘,檢測一次電池電量,此變量主要是計時
  147. uint battery_temp=0;                                                //電平電壓變量
  148. //************************************************函 數 聲 明 區(qū)***************************************************
  149. void main_menu_initial(void);                                 //主菜單初始化
  150. void alarm_menu_initial(void);                          //報警菜單初始化
  151. void infrared_menu_initial(void);
  152. void lamp_menu_initial(void);
  153. void menu_initial(void);

  154. void card_main_menu_initial(void);
  155. void card_inc_menu_initial(void);
  156. void card_dec_menu_initial(void);

  157. void show_menu(void);
  158. void date_time_set(void);
  159. void alarm_set(void);
  160. void infrared_set(void);
  161. void lamp_set(void);
  162. void nullsubs(void);
  163. void twinkling_addr_pro(void);
  164. void lcd_week_pro(void);
  165. void key_inc_dec(void);
  166. void lcd_menu_set(void);
  167. void card_pro(void);
  168. void buzzer_pro(uchar p);
  169. //*****************************************************************************************************************
  170. void inc_new_card(void);                                                //添加新卡的處理函數
  171. void query_card(void);                                                        //查詢卡函數
  172. void save_card(void);                                                        //保存卡時處理函數
  173. void no_save_card(void);                                                //取消保存卡時處理函數
  174. void clear_card(void);                                                        //刪除全部卡
  175. void no_clear_card(void);                                                //取消刪除卡
  176. void card_menu_show(void);                                                //管理卡菜單顯示
  177. void card_menu_pro(void);                                                //管理卡菜單處理
  178. void char_twinkling(uchar data_1);                                //字符消隱                                       
  179. //*****************************************************************************************************************
  180. void eeprom_write(uint eeprom_address, uchar eeprom_data);                        //寫----EEPROM 操作
  181. uchar eeprom_read(uint eeprom_address);                                                                //讀----EEPROM 操作
  182. //*************************************************主程序**********************************************************
  183. void main(void)
  184. {
  185.         PORTA=0XF8;                                                        //PA0---按鍵AD;PA1---室內溫度AD;PA2---電平電量檢測
  186.         PORTB=0XFF;
  187.         PORTC=0XFF;
  188.         PORTD=0XFF;
  189.         DDRA =0XF8;                                                        //AD轉換時要設為輸入、且端口要清0
  190.         DDRB =0XFF;
  191.         DDRC =0b11111000;
  192.         DDRD =0b11110010;                                        //INT0、INT1、RXD設成輸入;TXD設成輸出
  193.         TIMSK=(1<<OCIE1A);                                        //輸出比較A 匹配中斷使能
  194.         TCCR1A=0;                                       
  195.         TCCR1B=0X0D;                                                //CTC模式,1024分頻
  196.         OCR1A=7200;                                                        //定時1S
  197.         GICR=(1<<INT1)|(1<<INT0);                        //打開外部中斷0、1
  198.         MCUCR=(1<<ISC00);                                        //INT0 引腳上任意的邏輯電平變化都將引發(fā)中斷
  199.         ADCSRA=(1<<ADEN)|0x06;                                //使能ADC,時鐘64分頻 125KHz@8MHz system clock
  200.         WDTCR=0x0f;                                                        //(1<<WDE)|(1<<WDP2)|(1<<WDP1);        //打開看門狗,溢出時間為2.1S
  201.         write_com(0x01);                                        //清除顯示,并且設定地址指針為00H
  202.         menu_initial();                                                //菜單數組初始化
  203.         send_initial();                                                //串口初始化
  204.         WDR();                                                                //喂狗
  205.         card_pro();                                                        //讀EEPROM,到RAM中
  206.         lcd_reset();                                                //LCD初始化
  207.         write_com(0x90);
  208.         buzzer_on;
  209.         LCD_BACK_ON;                                                                                                        //打開LCD背光
  210.         han_zi_display("  系統(tǒng)正在啟動  ");
  211.         write_com(0x88);
  212.         han_zi_display("    請稍后......");
  213.         delay_ms(500);
  214.         clear_gdram();                                                //清除GDRAM--繪圖RAM
  215.         clear_screen();                                                //清屏
  216.         buzzer_off;                                                                                                        //峰鳴器指示
  217.         lcd_back_en=0xaa;                                                                                                //打開計時變量
  218.         lcd_back_time=0;                                                                                                //計時變量清0
  219.         SEI();                                                                //使能全局中斷
  220.         while(1)
  221.         {
  222.                 WDR();                                                        //喂狗
  223.                 if(scan_en==0)                                        //只有在scan_en=0的時候掃描主屏,平時只更新時間
  224.                 {
  225.                         scan_en=~scan_en;
  226.                         clear_screen();
  227.                         temp0=temperature_check();        //溫度檢測
  228.                         root_directory();
  229.                 }
  230.                 if(second_temp!=tem[5])                        //每秒鐘掃描一次
  231.                 {
  232.                         second_temp=tem[5];
  233.                         date_time_display();
  234.                 }
  235.                 if(close_read==1)
  236.                 {
  237.                         if(xx>=5)
  238.                         {
  239.                                 xx=0;
  240.                                 close_read=0;
  241.                                 second_temp=0;
  242.                                 GICR=((1<<INT1)|(1<<INT0));                                                        //開外部中斷0、1
  243.                         }
  244.                 }
  245.                 if(kk)                                                                                                                //=1表示有按鍵按下
  246.                 {
  247.                         kk=0;
  248.                         read_adc();                                                                                                //AD轉換,取得鍵值
  249.                         buzzer_pro(1);                                                                                        //峰鳴器指示
  250.                         LCD_BACK_ON;                                                                                        //打開LCD背光
  251.                         lcd_back_en=0xaa;                                                                                                //打開計時變量
  252.                         lcd_back_time=0;                                                                                //計時變量清0
  253.                         if(key==1)
  254.                         {
  255.                                 GICR&=~(1<<INT0);                                                                        //關閉讀卡外部中斷0
  256.                                 lcd_menu_set();                                                                                //LCD菜單設置
  257.                                 GICR=((1<<INT1)|(1<<INT0));                                                        //開外部中斷0、1
  258.                         }
  259.                         else if(key==8)
  260.                         {
  261.                                 GICR&=~((1<<INT1)|(1<<INT0));                                                //關閉部中斷0、1
  262.                                 key=0;
  263.                                 clear_screen();                                                                                //清屏
  264.                                 write_com(0x80);                               
  265.                                 han_zi_display("      警  告  ");
  266.                                 write_com(0x88);                               
  267.                                 han_zi_display("版權歸于軍峰所有");
  268.                                 write_com(0x98);                               
  269.                                 han_zi_display("    拷貝必究!!!");
  270.                                 delay_ms(6000);
  271.                                 scan_en=0;                                                                                        //主菜單調用允許標志位
  272.                                 clear_screen();                //**************
  273.                                 GICR=((1<<INT1)|(1<<INT0));                                                        //開外部中斷0、1
  274.                         }
  275.                         else
  276.                         {
  277.                                 key=0;
  278.                                 GICR=((1<<INT1)|(1<<INT0));                                                        //開外部中斷0、1
  279.                         }
  280.                 }
  281.                 WDR();                                                                                                        //喂狗
  282.                 if(inc_card_en==0xaa)                                                                        //=0xaa表示調用管理菜單允許
  283.                 {
  284.                         inc_card_en=0;
  285.                         rev_dat[0]=rev_dat[1]=rev_dat[2]=rev_dat[3]=rev_dat[4]=0xff;
  286.                         lcd_dis_num=0;
  287.                         card_menu_pro();
  288.                         GICR=((1<<INT1)|(1<<INT0));                                                        //開外部中斷0、1
  289.                 }
  290.                 if(charge_tem>=BATTERY_TIME)       
  291.                 {
  292.                         charge_tem=0;
  293.                         battery_temp=0;
  294.                         WDR();                                                                                                //喂狗
  295.                         battery_temp=adc_sampling(ADC_PINA2);                                //AD采樣電平電量
  296.                         if(battery_temp<=3750)                                                                //3750=12V,當電平電壓小于12V時,開始充電
  297.                         {
  298.                                 charge_on;
  299.                                 if(CHARGE_STATUS!=0)
  300.                                 {
  301.                                         buzzer_pro(10);                                                                                        //峰鳴器指示
  302.                                 }
  303.                         }
  304.                         else if((CHARGE_STATUS==1)||(battery_temp>=4375))        //如果大于4375=14V,表示要關閉充電器
  305.                         {
  306.                                 charge_off;
  307.                         }
  308.                 }                                                       
  309.         }
  310. }
  311. //************************************************管理卡主菜單操作*************************************************
  312. void card_menu_pro(void)
  313. {
  314.         clear_screen();
  315.         menu_card= card_main_menu;
  316.         user_choose=0;
  317.         card_menu_show();
  318.         return_en=1;                                                                                                //打開菜單自動返回變量
  319.         GICR|=(1<<INT1);                                                                                        //打開外部中斷1***********************       
  320.         while(auto_return<OVER_FLOW)
  321.         {
  322.                 WDR();                                                                                                        //喂狗
  323.                 if(kk)
  324.                 {
  325.                         kk=0;
  326.                         auto_return=0;                                                                                //清除菜單自動返回累計時間變量
  327.                         read_adc();
  328.                         buzzer_pro(1);                                                                                //峰鳴器指示
  329.                         LCD_BACK_ON;                                                                                //打開LCD背光
  330.                         lcd_back_en=0xaa;                                                                        //打開計時變量
  331.                         lcd_back_time=0;                                                                        //計時變量清0
  332.                         WDR();
  333.                         switch(key)
  334.                         {
  335.                                 case 0:                                                                                        //沒有按下按鍵
  336.                                                 break;
  337.                                 case 1:                                                                                        //設置
  338.                                                 key=0;
  339.                                                 break;
  340.                                 case 2:                                                                                        //向上
  341.                                                 key=0;
  342.                             if (user_choose == 0)
  343.                             {
  344.                                 user_choose = max_items;
  345.                             }
  346.                             user_choose --;
  347.                                                 break;
  348.                                 case 3:                                                                                        //向下
  349.                                                 key=0;
  350.                             user_choose ++;
  351.                             if (user_choose == max_items)
  352.                             {
  353.                                 user_choose = 0;
  354.                             }
  355.                                                 break;
  356.                                 case 4:                                                                                        //向左
  357.                                                 key=0;
  358.                                                 break;
  359.                                 case 5:                                                                                        //向右
  360.                                                 key=0;
  361.                                                 break;
  362.                                 case 6:                                                                                        //確認
  363.                                                 key=0;
  364.                             if (menu_card[user_choose].subs != nullsubs)
  365.                             {
  366.                                    
  367.                                                         (*menu_card[user_choose].subs)();
  368.                             }
  369.                             WDR();                                                                                                                //喂狗       
  370.                             if(menu_card[user_choose].children_menus != null)
  371.                             {
  372.                                     choose_temp=user_choose;
  373.                                 menu_card = menu_card[user_choose].children_menus;                 //把結構指針還指向子菜單
  374.                                 user_choose = 0;
  375.                             }
  376.                                                 break;
  377.                                 case 7:                                                                                                        //返回
  378.                                                 key=0;
  379.                             menu_card= card_main_menu;
  380.                                                 auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  381.                                                 break;
  382.                                 case 8:                                                                                                        //說明
  383.                                                 key=0;
  384.                                                 break;
  385.                                 default:
  386.                                                 key=0;
  387.                                                 break;
  388.             }
  389.             card_menu_show();
  390.             GICR|=(1<<INT1);                        //打開外部中斷1***********************       
  391.             key=0;
  392.             kk=0;
  393.         }
  394.         }
  395.         scan_en=0;                                                                //主菜單調用允許標志位
  396.         return_en=0;                                                        //菜單自動計時返回允許標志位
  397.         auto_return=0;                                                        //菜單自動計時返回變量
  398.         key=0;                                                                        //按鍵值清0
  399.         return_temp=0;                                                        //返回臨時變量清0
  400.     user_choose = 0;
  401.     choose_temp=0;
  402.     inc_card_en=0;
  403.     menu_card = card_main_menu;                                //把結構指針還指向主菜單
  404.     clear_screen();                                                        //清除DDRAM--顯示資料寄存器
  405.     GICR=((1<<INT1)|(1<<INT0));                                //開外部中斷0、1
  406. }
  407. //*********************************************字符消隱************************************************************
  408. void char_twinkling(uchar data_1)
  409. {
  410.         write_com(data_1);
  411.         write_com(data_1);
  412.         write_data(0x20);                                                        //設置時間時,字符閃動
  413.         write_data(0x20);
  414. }
  415. //**********************************************管理操作時的菜單***************************************************
  416. void card_menu_show(void)
  417. {
  418.     uchar n = 0;
  419.     WDR();                                                                                                        //喂狗
  420.     max_items = menu_card[0].menu_count;
  421.         if (max_items >= 3)
  422.         {
  423.         for (n = 0;n<3;n++)
  424.         {
  425.                 switch(n)
  426.                 {
  427.                         case 0:
  428.                                         write_com(0x80);
  429.                                         break;
  430.                         case 1:
  431.                                         write_com(0x90);
  432.                                         break;
  433.                         case 2:
  434.                                         write_com(0x88);
  435.                                         break;
  436.                         default:
  437.                                         break;
  438.                 }
  439.                         han_zi_display(menu_card[n].display_string);
  440.             if (n == user_choose)
  441.             {
  442.                         switch(n)
  443.                         {
  444.                                 case 0:
  445.                                                 select_menu(0x80);
  446.                                                 break;
  447.                                 case 1:
  448.                                                 select_menu(0x90);
  449.                                                 break;       
  450.                                 case 2:
  451.                                                 select_menu(0x88);
  452.                                                 break;       
  453.                                 default:
  454.                                                 break;
  455.                         }
  456.             }
  457.         }
  458.         }
  459.         else                                                                                                                         //子菜單選擇
  460.     {
  461.             clear_screen();
  462.         for (n = 0;n<max_items;n++)
  463.         {
  464.                 write_com(0x80);
  465.                 switch(choose_temp)
  466.                 {
  467.                         case 0:
  468.                                         han_zi_display("  1.添加新卡?");
  469.                                         break;
  470.                         case 1:
  471.                                         han_zi_display("  2.刪除全部卡?");
  472.                                         break;       
  473.                         case 2:
  474.                                         han_zi_display("  3.查詢卡記錄?");
  475.                                         break;
  476.                         default:
  477.                                         break;
  478.                 }
  479.             if(n==0)
  480.             {
  481.                                 write_com(0x88);
  482.                         }
  483.             else if(n==1)
  484.             {
  485.                                 write_com(0x98);
  486.                         }
  487.                         han_zi_display(menu_card[n].display_string);
  488.             if (n == user_choose)
  489.             {
  490.                     if(n==0)
  491.                     {
  492.                             select_menu(0x89);
  493.                     }
  494.                     else if(n==1)
  495.                     {
  496.                             select_menu(0x99);
  497.                     }               
  498.             }
  499.         }
  500.     }
  501. }
  502. //**********************************************UART初始化*********************************************************
  503. void send_initial(void)
  504. {
  505.     UBRRL= (F_CPU/BAUDRATE/16-1)%256;
  506.     UBRRH= (F_CPU/BAUDRATE/16-1)/256;
  507.         UCSRB=(1<<TXEN);                                                                        //發(fā)送使能,
  508.         UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);                                //無奇偶校驗,設置幀格式: 8 個數據位, 1 個停止位
  509. }
  510. //*********************************************EEPROM 操作*********************************************************
  511. //*********************************************寫----EEPROM 操作***************************************************
  512. void eeprom_write(uint eeprom_address, uchar eeprom_data)
  513. {
  514.         CLI();
  515.         while(EECR & (1<<EEWE));                                                        //等待上一次寫操作結束
  516.         EEAR = eeprom_address;                                                                 //設置地址和數據寄存器
  517.         EEDR = eeprom_data;
  518.         EECR |= (1<<EEMWE);                                                                        //置位EEMWE
  519.         EECR |= (1<<EEWE);                                                                        //置位EEWE 以啟動寫操作
  520.         SEI();
  521. }
  522. //********************************************讀----EEPROM 操作****************************************************
  523. uchar eeprom_read(uint eeprom_address)
  524. {
  525.         CLI();
  526.         while(EECR & (1<<EEWE));                                                        //等待上一次寫操作結束
  527.         EEAR = eeprom_address;                                                                         //設置地址寄存器
  528.         EECR |= (1<<EERE);                                                                        //設置EERE 以啟動讀操作
  529.         SEI();
  530.         return EEDR;                                                                                //自數據寄存器返回數據
  531. }
  532. //***********************************************LCD菜單設置*******************************************************
  533. //說明:如果進入菜單在30秒內沒有動作,將自動反回主畫面
  534. //*****************************************************************************************************************
  535. void lcd_menu_set(void)
  536. {
  537.         uchar tem_2[7]={0,0,0,0,0,0,0};                                                                //日期、時間、星期數組備份
  538. //                               年/月/日/H/M/S/W
  539.         key=0;
  540.         menu_point = main_menu;                                                                         //把結構指針還指向主菜單
  541.         user_choose=0;
  542.         clear_screen();
  543.         WDR();
  544.         show_menu();                                                                                                 //顯示菜單
  545.         return_en=1;                                                                                                //打開菜單自動返回變量
  546.         GICR|=(1<<INT1);                                                                                        //打開外部中斷1
  547.         while(auto_return<OVER_FLOW)
  548.         {
  549.                 WDR();                                                                                                        //喂狗
  550.                 if(kk)
  551.                 {
  552.                         kk=0;
  553.                         auto_return=0;                                                                                //清除菜單自動返回累計時間變量
  554.                         read_adc();
  555.                         buzzer_pro(1);                                                                                //峰鳴器指示
  556.                         LCD_BACK_ON;                                                                                //打開LCD背光
  557.                         lcd_back_en=0xaa;                                                                        //打開計時變量
  558.                         lcd_back_time=0;                                                                        //計時變量清0
  559.                         WDR();                                                                                                //喂狗
  560.                         switch(key)
  561.                         {
  562.                                 case 0:                                                                                        //沒有按下按鍵
  563.                                                 break;
  564.                                 case 1:                                                                                        //設置
  565.                                                 break;
  566.                                 case 2:                                                                                        //向上
  567.                                                 key=0;
  568.                             if (user_choose == 0)
  569.                             {
  570.                                 user_choose = max_items;
  571.                             }
  572.                             user_choose --;
  573.                             return_temp=0;                                                        //返回臨時變量清0
  574.                                                 break;
  575.                                 case 3:                                                                                        //向下
  576.                                                 key=0;
  577.                             user_choose ++;
  578.                             if (user_choose == max_items)
  579.                             {
  580.                                 user_choose = 0;
  581.                             }
  582.                             return_temp=0;                                                        //返回臨時變量清0
  583.                                                 break;
  584.                                 case 4:                                                                                        //向左
  585.                                                 key=0;
  586.                                                 if(left_right==0)
  587.                                                 {
  588.                                                         left_right=6;
  589.                                                 }
  590.                                                 left_right--;
  591.                                                 twinkling_addr_pro();                                        //調用閃動地址選擇
  592.                                                 break;
  593.                                 case 5:                                                                                        //向右
  594.                                                 key=0;
  595.                                                 left_right++;
  596.                                                 if(left_right>=6)
  597.                                                 {
  598.                                                         left_right=0;
  599.                                                 }
  600.                                                 twinkling_addr_pro();                                        //調用閃動地址選擇
  601.                                                 break;
  602.                                 case 6:                                                                                        //確認
  603.                                                 key=0;
  604.                             if(set_time_temp==1)
  605.                                                 {
  606.                                                         auto_return=88;                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  607.                                                         set_time_temp=0;
  608.                                                         clear_screen();
  609.                                                         write_com(0x90);                               
  610.                                                         han_zi_display("  時間設置完成");
  611.                                                         delay_ms(2000);
  612.                                                         break;
  613.                                                 }
  614.                             if (menu_point[user_choose].subs != nullsubs)
  615.                             {
  616.                                     left_right=0;
  617.                                 tem_2[0]=tem[0];                                        //把日期、時間變量做個備份
  618.                                                         tem_2[1]=tem[1];
  619.                                                         tem_2[2]=tem[2];
  620.                                                         tem_2[3]=tem[3];
  621.                                                         tem_2[4]=tem[4];
  622.                                                         tem_2[5]=tem[5];
  623.                                                         tem_2[6]=tem[6];
  624.                                                         (*menu_point[user_choose].subs)();
  625.                             }
  626.                             else if(menu_point[user_choose].children_menus != null)        
  627.                             {
  628.                                     choose_temp=user_choose;
  629.                                 menu_point = menu_point[user_choose].children_menus;                 //把結構指針還指向子菜單
  630.                                 user_choose = 0;
  631.                             }
  632.                                                 break;
  633.                                 case 7:                                                                                                        //返回
  634.                                                 key=0;
  635.                                                 return_temp++;
  636.                                                 if(return_temp==1)
  637.                                                 {
  638.                                     menu_point = main_menu;
  639.                                     user_choose = 0;
  640.                                     left_right=0;
  641.                                     if(set_time_temp==1)
  642.                                     {
  643.                                                                 clear_screen();
  644.                                                                 set_time_temp=0;
  645.                                             tem[0]=tem_2[0];                                                //還原設置前的日期、時間數據
  646.                                             tem[1]=tem_2[1];
  647.                                             tem[2]=tem_2[2];
  648.                                             tem[3]=tem_2[3];
  649.                                             tem[4]=tem_2[4];
  650.                                             tem[5]=tem_2[5];
  651.                                             tem[6]=tem_2[6];
  652.                                             auto_return=88;                                                        //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  653.                                             break;
  654.                                                         }
  655.                                                 }
  656.                                                 else
  657.                                                 {
  658.                                                         return_temp=0;
  659.                                                         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  660.                                                 }
  661.                                                 break;
  662.                                 case 8:                                                                                                        //說明
  663.                                                 key=0;
  664.                                                 break;
  665.                                 default:
  666.                                                 key=0;
  667.                                                 break;
  668.             }
  669.                    if(set_time_temp==0)
  670.                    {
  671.                     show_menu();
  672.             }
  673.             else                                                                                                                //!=0表示菜單處在修改日期一欄
  674.             {
  675.                     date_time_set();
  676.             }   
  677.             key=0;
  678.             kk=0;
  679.             GICR|=(1<<INT1);                                                                                        //打開外部中斷1
  680.         }
  681.         if(set_time_temp==1)
  682.         {
  683.                 GICR&=~(1<<INT1);                                                                                                //關閉按鍵中斷
  684.                        key_inc_dec();                                                                                                        //按鍵+、-處理
  685.                        GICR|=(1<<INT1);                                                                                                //打開按鍵中斷
  686.                         time_set_display();
  687.                         delay_ms(100);
  688.                         char_twinkling(twinkling_addr);
  689.                         delay_ms(100);
  690.                }
  691.    
  692.         }
  693.         clear_screen();                                                        //清除DDRAM--顯示資料寄存器
  694.         scan_en=0;                                                                //主菜單調用允許標志位
  695.         return_en=0;                                                        //菜單自動計時返回允許標志位
  696.         auto_return=0;                                                        //菜單自動計時返回變量
  697.         key=0;                                                                        //按鍵值清0
  698.         return_temp=0;                                                        //返回臨時變量清0
  699.     user_choose = 0;
  700.     menu_point = main_menu;                                 //把結構指針還指向主菜單
  701.     set_time_temp=0;                                                //日期、時間設置菜單變量
  702.         twinkling_addr=0x91;
  703.         left_right=0;
  704. }
  705. //***************************************************按鍵+、-處理**************************************************
  706. void key_inc_dec(void)
  707. {
  708.     if(key_inc==0)
  709.     {
  710.             delay_ms(5);
  711.             if(key_inc==0)
  712.             {
  713.                         buzzer_pro(1);                                                                                                        //峰鳴器指示
  714.                         LCD_BACK_ON;                                                                                                        //打開LCD背光
  715.                         lcd_back_time=0;                                                                                                //計時變量清0
  716.                         lcd_back_en=0xaa;                                                                                                //打開計時變量
  717.                         auto_return=0;                                                                                                        //清除菜單自動返回累計時間變量
  718.                     switch(twinkling_addr)
  719.                     {
  720.                             case 0x88:                                                                                                        //小時選項
  721.                                                     do
  722.                                                     {
  723.                                                             tem[3]++;
  724.                                                             if(tem[3]>=24)
  725.                                                             {
  726.                                                                     tem[3]=0;
  727.                                                             }
  728.                                                                 time_set_display();                                                        //更新顯示
  729.                                                                 delay_ms(200);
  730.                                                             auto_return=0;
  731.                                                     }
  732.                                                     while(key_inc==0);
  733.                                                     break;
  734.                             case 0x8a:                                                                                                        //分鐘選項
  735.                                                     do
  736.                                                     {
  737.                                                             tem[4]++;
  738.                                                             if(tem[4]>=60)
  739.                                                             {
  740.                                                                     tem[4]=0;
  741.                                                             }
  742.                                                                 time_set_display();                                                        //更新顯示
  743.                                                                 delay_ms(120);
  744.                                                             auto_return=0;
  745.                                                     }
  746.                                                     while(key_inc==0);
  747.                                                     break;
  748.                             case 0x8f:                                                                                                        //星期選項
  749.                                                     do
  750.                                                     {
  751.                                                             tem[6]++;
  752.                                                             if(tem[6]>=7)
  753.                                                             {
  754.                                                                     tem[6]=0;
  755.                                                             }
  756.                                                             time_set_display();                                                        //更新顯示
  757.                                                                 delay_ms(200);
  758.                                                             auto_return=0;
  759.                                                     }
  760.                                                     while(key_inc==0);
  761.                                                     break;
  762.                             case 0x91:                                                                                                        //年選項
  763.                                                     do
  764.                                                     {
  765.                                                             tem[0]++;
  766.                                                             if(tem[0]>=29)
  767.                                                             {
  768.                                                                     tem[0]=7;
  769.                                                             }
  770.                                                                 time_set_display();                                                        //更新顯示
  771.                                                                 delay_ms(200);
  772.                                                             auto_return=0;
  773.                                                     }
  774.                                                     while(key_inc==0);
  775.                                                     break;
  776.                             case 0x93:                                                                                                        //月選項
  777.                                                     do
  778.                                                     {
  779.                                                             tem[1]++;
  780.                                                             if(tem[1]>=13)
  781.                                                             {
  782.                                                                     tem[1]=1;
  783.                                                             }
  784.                                                                 time_set_display();                                                        //更新顯示
  785.                                                                 delay_ms(200);
  786.                                                             auto_return=0;
  787.                                                     }
  788.                                                     while(key_inc==0);
  789.                                                     break;                                                                   
  790.                             case 0x95:                                                                                                        //日選項
  791.                                                     do
  792.                                                     {
  793.                                                             tem[2]++;
  794.                                                             if(tem[2]>=32)
  795.                                                             {
  796.                                                                     tem[2]=1;
  797.                                                             }
  798.                                                                 time_set_display();                                                        //更新顯示
  799.                                                                 delay_ms(150);
  800.                                                             auto_return=0;
  801.                                                     }
  802.                                                     while(key_inc==0);
  803.                                                     break;
  804.                             default:
  805.                                                     break;               
  806.                     }
  807.             }
  808.     }
  809.     if(key_dec==0)
  810.     {
  811.             delay_ms(5);
  812.             if(key_dec==0)
  813.             {
  814.                         buzzer_pro(1);                                                                                                        //峰鳴器指示
  815.                         LCD_BACK_ON;                                                                                                        //打開LCD背光
  816.                         lcd_back_time=0;                                                                                                //計時變量清0
  817.                         lcd_back_en=0xaa;                                                                                                //打開計時變量
  818.                         auto_return=0;                                                                                                        //清除菜單自動返回累計時間變量
  819.                     switch(twinkling_addr)
  820.                     {
  821.                             case 0x88:                                                                                                        //小時選項
  822.                                                     do
  823.                                                     {
  824.                                                             if(tem[3]==0)
  825.                                                             {
  826.                                                                     tem[3]=24;
  827.                                                             }
  828.                                                             tem[3]--;
  829.                                                                 time_set_display();                                                        //更新顯示
  830.                                                                 delay_ms(200);
  831.                                                             auto_return=0;
  832.                                                     }
  833.                                                     while(key_dec==0);
  834.                                                     break;
  835.                             case 0x8a:                                                                                                        //分鐘選項
  836.                                                     do
  837.                                                     {
  838.                                                             if(tem[4]==0)
  839.                                                             {
  840.                                                                     tem[4]=60;
  841.                                                             }
  842.                                                             tem[4]--;
  843.                                                                 time_set_display();                                                        //更新顯示
  844.                                                                 delay_ms(120);
  845.                                                             auto_return=0;
  846.                                                     }
  847.                                                     while(key_dec==0);
  848.                                                     break;
  849.                             case 0x8f:                                                                                                        //星期選項
  850.                                                     do
  851.                                                     {
  852.                                                             if(tem[6]==0)
  853.                                                             {
  854.                                                                     tem[6]=7;
  855.                                                             }
  856.                                                             tem[6]--;
  857.                                                                 time_set_display();                                                        //更新顯示
  858.                                                                 delay_ms(200);
  859.                                                             auto_return=0;
  860.                                                     }
  861.                                                     while(key_dec==0);
  862.                                                     break;
  863.                             case 0x91:                                                                                                        //年選項
  864.                                                     do
  865.                                                     {
  866.                                                             if(tem[0]==7)
  867.                                                             {
  868.                                                                     tem[0]=29;
  869.                                                             }
  870.                                                             tem[0]--;
  871.                                                                 time_set_display();                                                        //更新顯示
  872.                                                                 delay_ms(200);
  873.                                                             auto_return=0;
  874.                                                     }
  875.                                                     while(key_dec==0);
  876.                                                     break;
  877.                             case 0x93:                                                                                                        //月選項
  878.                                                     do
  879.                                                     {
  880.                                                             if(tem[1]==1)
  881.                                                             {
  882.                                                                     tem[1]=13;
  883.                                                             }
  884.                                                             tem[1]--;
  885.                                                                 time_set_display();                                                        //更新顯示
  886.                                                                 delay_ms(200);
  887.                                                             auto_return=0;
  888.                                                     }
  889.                                                     while(key_dec==0);
  890.                                                     break;                                                                   
  891.                             case 0x95:                                                                                                        //日選項
  892.                                                     do
  893.                                                     {
  894.                                                             if(tem[2]==1)
  895.                                                             {
  896.                                                                     tem[2]=32;
  897.                                                             }
  898.                                                             tem[2]--;
  899.                                                                 time_set_display();                                                        //更新顯示
  900.                                                                 delay_ms(150);
  901.                                                             auto_return=0;
  902.                                                     }
  903.                                                     while(key_dec==0);
  904.                                                     break;
  905.                             default:
  906.                                                     break;               
  907.                     }
  908.             }
  909.     }
  910. }
  911. //**************************************************字符閃動地址選擇***********************************************
  912. void twinkling_addr_pro(void)
  913. {
  914.         switch(left_right)
  915.         {
  916.                 case 0:
  917.                                 twinkling_addr=0x91;
  918.                                 break;
  919.                 case 1:
  920.                                 twinkling_addr=0x93;
  921.                                 break;
  922.                 case 2:
  923.                                 twinkling_addr=0x95;
  924.                                 break;
  925.                 case 3:
  926.                                 twinkling_addr=0x88;
  927.                                 break;               
  928.                 case 4:
  929.                                 twinkling_addr=0x8a;
  930.                                 break;
  931.                 case 5:
  932.                                 twinkling_addr=0x8f;
  933.                                 break;
  934.                 default:
  935.                                 break;
  936.         }       
  937.         clear_screen();       
  938.         return_temp=0;                                                                                        //返回臨時變量清0
  939. }
  940. //*************************************************顯示菜單********************************************************
  941. void show_menu(void)
  942. {
  943.     uchar n = 0;
  944.     max_items = menu_point[0].menu_count;
  945.     WDR();                                                                                                        //喂狗
  946.         if (max_items >= 4)
  947.         {
  948.         for (n = 0;n<4;n++)
  949.         {
  950.                 switch(n)
  951.                 {
  952.                         case 0:
  953.                                         write_com(0x80);
  954.                                         break;
  955.                         case 1:
  956.                                         write_com(0x90);
  957.                                         break;
  958.                         case 2:
  959.                                         write_com(0x88);
  960.                                         break;
  961.                         case 3:
  962.                                         write_com(0x98);
  963.                                         break;
  964.                         default:
  965.                                         break;
  966.                 }
  967.                         han_zi_display(menu_point[n].display_string);
  968.             if (n == user_choose)
  969.             {
  970.                         switch(n)
  971.                         {
  972.                                 case 0:
  973.                                                 select_menu(0x80);
  974.                                                 break;
  975.                                 case 1:
  976.                                                 select_menu(0x90);
  977.                                                 break;       
  978.                                 case 2:
  979.                                                 select_menu(0x88);
  980.                                                 break;
  981.                                 case 3:
  982.                                                 select_menu(0x98);
  983.                                                 break;
  984.                                 default:
  985.                                                 break;
  986.                         }
  987.             }
  988.         }
  989.         }
  990.         else                                                                                                                         //子菜單選擇
  991.     {
  992.             WDR();                                                                                                                //喂狗
  993.             clear_screen();
  994.         for (n = 0;n<max_items;n++)
  995.         {
  996.                 write_com(0x80);
  997.                 switch(choose_temp)
  998.                 {
  999.                         case 0:
  1000.                                         han_zi_display("  1.時間日期設置");
  1001.                                         break;
  1002.                         case 1:
  1003.                                         han_zi_display("  2.報警開關設置");
  1004.                                         break;       
  1005.                         case 2:
  1006.                                         han_zi_display("  3.人體紅外設置");
  1007.                                         break;
  1008.                         case 3:
  1009.                                         han_zi_display("  4.路燈開關設置");
  1010.                                         break;
  1011.                         default:
  1012.                                         break;
  1013.                 }
  1014.             if(n==0)
  1015.             {
  1016.                                 write_com(0x88);
  1017.                         }
  1018.             else if(n==1)
  1019.             {
  1020.                                 write_com(0x98);
  1021.                         }
  1022.                         han_zi_display(menu_point[n].display_string);
  1023.             if (n== user_choose)
  1024.             {
  1025.                     if(n==0)
  1026.                     {
  1027.                             select_menu(0x89);
  1028.                     }
  1029.                     else if(n==1)
  1030.                     {
  1031.                             select_menu(0x99);
  1032.                     }               
  1033.             }
  1034.         }
  1035.     }
  1036. }
  1037. //******************************************************初始化菜單目錄*********************************************
  1038. void menu_initial(void)
  1039. {
  1040.     main_menu_initial();
  1041.     alarm_menu_initial();
  1042.     infrared_menu_initial();
  1043.     lamp_menu_initial();
  1044.     card_main_menu_initial();
  1045.     card_inc_menu_initial();
  1046.     card_dec_menu_initial();
  1047. }
  1048. //******************************************************主目錄初始化函數*******************************************
  1049. void main_menu_initial(void)
  1050. {
  1051.      main_menu[0].menu_count = 4;
  1052.      main_menu[0].display_string = "  1.時間日期設置";
  1053.      main_menu[0].subs = date_time_set;
  1054.      main_menu[0].children_menus =null;  
  1055.      main_menu[0].parent_menus = null;  
  1056.      
  1057.      main_menu[1].menu_count = 4;
  1058.      main_menu[1].display_string = "  2.報警開關設置";
  1059.      main_menu[1].subs = nullsubs;
  1060.      main_menu[1].children_menus = alarm_menu;
  1061.      main_menu[1].parent_menus = null;  
  1062.      
  1063.      main_menu[2].menu_count = 4;
  1064.      main_menu[2].display_string = "  3.人體紅外設置";
  1065.      main_menu[2].subs = nullsubs;
  1066.      main_menu[2].children_menus = infrared_menu;
  1067.      main_menu[2].parent_menus = null;  

  1068.      main_menu[3].menu_count = 4;
  1069.      main_menu[3].display_string = "  4.路燈開關設置";
  1070.      main_menu[3].subs = nullsubs;
  1071.      main_menu[3].children_menus = lamp_menu;
  1072.      main_menu[3].parent_menus = null;
  1073. }
  1074. //**************************************************報警開關設置目錄初始化函數*************************************
  1075. void alarm_menu_initial(void)
  1076. {
  1077.     alarm_menu[0].menu_count = 2;
  1078.     alarm_menu[0].display_string = "    1.  打開    ";
  1079.     alarm_menu[0].subs = alarm_set;
  1080.     alarm_menu[0].children_menus = null;  //&null
  1081.     alarm_menu[0].parent_menus = main_menu;
  1082.      
  1083.     alarm_menu[1].menu_count = 2;
  1084.     alarm_menu[1].display_string = "    2.  關閉    ";
  1085.     alarm_menu[1].subs = alarm_set;
  1086.     alarm_menu[1].children_menus = null;  //&null
  1087.     alarm_menu[1].parent_menus = main_menu;
  1088. }
  1089. //*************************************************人體紅外開關設置目錄初始化函數**********************************
  1090. void infrared_menu_initial(void)
  1091. {
  1092.     infrared_menu[0].menu_count = 2;
  1093.     infrared_menu[0].display_string = "    1.  打開    ";
  1094.     infrared_menu[0].subs = infrared_set;
  1095.     infrared_menu[0].children_menus = null;  //&null
  1096.     infrared_menu[0].parent_menus = main_menu;
  1097.      
  1098.     infrared_menu[1].menu_count = 2;
  1099.     infrared_menu[1].display_string = "    2.  關閉    ";
  1100.     infrared_menu[1].subs = infrared_set;
  1101.     infrared_menu[1].children_menus = null;  //&null
  1102.     infrared_menu[1].parent_menus = main_menu;
  1103. }
  1104. //*************************************************路燈開關設置目錄初始化函數**************************************
  1105. void lamp_menu_initial(void)
  1106. {
  1107.     lamp_menu[0].menu_count = 2;
  1108.     lamp_menu[0].display_string = "    1.  打開    ";
  1109.     lamp_menu[0].subs = lamp_set;
  1110.     lamp_menu[0].children_menus = null;  
  1111.     lamp_menu[0].parent_menus = main_menu;
  1112.      
  1113.     lamp_menu[1].menu_count = 2;
  1114.     lamp_menu[1].display_string = "    2.  關閉    ";
  1115.     lamp_menu[1].subs = lamp_set;
  1116.     lamp_menu[1].children_menus = null;
  1117.     lamp_menu[1].parent_menus = main_menu;
  1118. }
  1119. //**********************************************管理卡操作主菜單***************************************************
  1120. void card_main_menu_initial(void)
  1121. {
  1122.      card_main_menu[0].menu_count = 3;
  1123.      card_main_menu[0].display_string = "  1.添加新卡?";
  1124.      card_main_menu[0].subs =inc_new_card;
  1125.      card_main_menu[0].children_menus =card_inc_menu;  
  1126.      card_main_menu[0].parent_menus = null;  
  1127.      
  1128.      card_main_menu[1].menu_count = 3;
  1129.      card_main_menu[1].display_string = "  2.刪除全部卡?";
  1130.      card_main_menu[1].subs = nullsubs;
  1131.      card_main_menu[1].children_menus = card_dec_menu;
  1132.      card_main_menu[1].parent_menus = null;  
  1133.      
  1134.      card_main_menu[2].menu_count = 3;
  1135.      card_main_menu[2].display_string = "  3.查詢卡記錄?";
  1136.      card_main_menu[2].subs = query_card;
  1137.      card_main_menu[2].children_menus = null;
  1138.      card_main_menu[2].parent_menus = null;  
  1139. }
  1140. //************************************************添加新卡子菜單***************************************************
  1141. void card_inc_menu_initial(void)
  1142. {
  1143.     card_inc_menu[0].menu_count = 2;
  1144.     card_inc_menu[0].display_string = "    1.  確認    ";
  1145.     card_inc_menu[0].subs = save_card;
  1146.     card_inc_menu[0].children_menus = null;
  1147.     card_inc_menu[0].parent_menus = main_menu;
  1148.      
  1149.     card_inc_menu[1].menu_count = 2;
  1150.     card_inc_menu[1].display_string = "    2.  取消    ";
  1151.     card_inc_menu[1].subs = no_save_card;
  1152.     card_inc_menu[1].children_menus = null;
  1153.     card_inc_menu[1].parent_menus = main_menu;
  1154. }
  1155. //************************************************刪除全部卡子菜單*************************************************
  1156. void card_dec_menu_initial(void)
  1157. {
  1158.     card_dec_menu[0].menu_count = 2;
  1159.     card_dec_menu[0].display_string = "    1.  確認    ";
  1160.     card_dec_menu[0].subs = clear_card;
  1161.     card_dec_menu[0].children_menus = null;
  1162.     card_dec_menu[0].parent_menus = main_menu;
  1163.      
  1164.     card_dec_menu[1].menu_count = 2;
  1165.     card_dec_menu[1].display_string = "    2.  取消    ";
  1166.     card_dec_menu[1].subs =no_clear_card;
  1167.     card_dec_menu[1].children_menus = null;
  1168.     card_dec_menu[1].parent_menus = main_menu;
  1169. }
  1170. //**************************************************增加新卡*******************************************************
  1171. void inc_new_card(void)
  1172. {
  1173.         uchar eeprom_addr=0;
  1174.         uchar uu=0;
  1175.         if(user_choose==0)
  1176.         {
  1177.                 manage_card_inc_en=0xaa;                                                                                //準備接收新卡號碼
  1178.                 clear_screen();
  1179.                 auto_return=0;                                                                                                        //菜單自動返回變量清0                                                                                               
  1180.                 write_com(0x80);
  1181.                 han_zi_display("    請刷卡!");
  1182.                 GICR|=(1<<INT0);                                                                                                //開外部中斷0
  1183.                 while((manage_card_inc_en==0xaa)&&(auto_return<OVER_FLOW))
  1184.                 {
  1185.                         WDR();                                                                                                                //喂狗       
  1186.                 }
  1187.                 if(manage_card_inc_en==0)
  1188.                 {
  1189.                         GICR&=~((1<<INT1)|(1<<INT0));                                                                //關閉外部中斷0、1
  1190.                         write_com(0x90);
  1191.                         han_zi_display("卡號:");       
  1192.                         write_com(0x93);
  1193.                         write_data(lcd_dis_num/10000000+0x30);
  1194.                         write_data(lcd_dis_num%10000000/1000000+0x30);
  1195.                         write_data(lcd_dis_num%10000000%1000000/100000+0x30);
  1196.                         write_data(lcd_dis_num%10000000%1000000%100000/10000+0x30);
  1197.                         write_data(lcd_dis_num%10000000%1000000%100000%10000/1000+0x30);
  1198.                         write_data(lcd_dis_num%10000000%1000000%100000%10000%1000/100+0x30);
  1199.                         write_data(lcd_dis_num%10000000%1000000%100000%10000%1000%100/10+0x30);
  1200.                         write_data(lcd_dis_num%10000000%1000000%100000%10000%1000%100%10+0x30);       
  1201.                         write_com(0x88);
  1202.                         han_zi_display("    請核對!");       
  1203.                         delay_ms(3000);
  1204.                 }
  1205.                 else
  1206.                 {
  1207.                         manage_card_inc_en=0;                                                                                //在請刷卡界面,如果沒有刷卡,自動返回后要清0此變量
  1208.                         lcd_dis_num=0;
  1209.                         auto_return=88;                                                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  1210.                 }
  1211.                 GICR|=(1<<INT1);                                                                                                //打開外部中斷1
  1212.                 auto_return=0;                                                                                                        //菜單自動返回變量清0
  1213.                 WDR();                                                                                                                        //喂狗
  1214.         }
  1215. }
  1216. //***************************************************卡數量查詢****************************************************
  1217. void query_card(void)
  1218. {
  1219.         ulong tem_1=0;
  1220.         uchar hh;
  1221.         card_pro();                                                                                                                        //把EEPROM數據讀出來
  1222.         GICR&=~((1<<INT1)|(1<<INT0));                                                                                //關閉外部中斷0、1
  1223.         clear_screen();
  1224.         WDR();                                                                                                                                //喂狗
  1225.         write_com(0x80);
  1226.         han_zi_display("卡記錄: 共五張卡");
  1227.         for(hh=0;hh<3;hh++)
  1228.         {
  1229.                 if(card_data[hh][4]==0xff)
  1230.                 {
  1231.                         tem_1=0;
  1232.                 }
  1233.                 else
  1234.                 {
  1235.                         tem_1=card_data[hh][1];
  1236.                         tem_1<<=8;
  1237.                         tem_1+=card_data[hh][2];
  1238.                         tem_1<<=8;
  1239.                         tem_1+=card_data[hh][3];
  1240.                         tem_1<<=8;
  1241.                         tem_1+=card_data[hh][4];
  1242.                 }
  1243.                 switch(hh)
  1244.                 {
  1245.                         case 0:
  1246.                                         write_com(0x90);
  1247.                                         han_zi_display("1.");       
  1248.                                         break;
  1249.                         case 1:
  1250.                                         write_com(0x88);
  1251.                                         han_zi_display("2.");       
  1252.                                         break;
  1253.                         case 2:
  1254.                                         write_com(0x98);
  1255.                                         han_zi_display("3.");       
  1256.                                         break;
  1257.                         default:
  1258.                                         break;               
  1259.                 }
  1260.                 WDR();                                                                                                                        //喂狗
  1261.                 write_data(tem_1/10000000+0x30);                                                                //顯示卡號
  1262.                 write_data(tem_1%10000000/1000000+0x30);
  1263.                 write_data(tem_1%10000000%1000000/100000+0x30);
  1264.                 write_data(tem_1%10000000%1000000%100000/10000+0x30);
  1265.                 write_data(tem_1%10000000%1000000%100000%10000/1000+0x30);
  1266.                 write_data(tem_1%10000000%1000000%100000%10000%1000/100+0x30);
  1267.                 write_data(tem_1%10000000%1000000%100000%10000%1000%100/10+0x30);
  1268.                 write_data(tem_1%10000000%1000000%100000%10000%1000%100%10+0x30);       
  1269.         }
  1270.         delay_ms(5000);
  1271.         clear_screen();
  1272.         write_com(0x80);
  1273.         han_zi_display("卡記錄: 共五張卡");
  1274.         for(hh=3;hh<5;hh++)
  1275.         {
  1276.                 if(card_data[hh][4]==0xff)
  1277.                 {
  1278.                         tem_1=0;
  1279.                 }
  1280.                 else
  1281.                 {
  1282.                         tem_1=card_data[hh][1];
  1283.                         tem_1<<=8;
  1284.                         tem_1+=card_data[hh][2];
  1285.                         tem_1<<=8;
  1286.                         tem_1+=card_data[hh][3];
  1287.                         tem_1<<=8;
  1288.                         tem_1+=card_data[hh][4];
  1289.                 }
  1290.                 switch(hh)
  1291.                 {
  1292.                         case 3:
  1293.                                         write_com(0x90);
  1294.                                         han_zi_display("4.");       
  1295.                                         break;
  1296.                         case 4:
  1297.                                         write_com(0x88);
  1298.                                         han_zi_display("5.");       
  1299.                                         break;
  1300.                         default:
  1301.                                         break;               
  1302.                 }
  1303.                 WDR();                                                                                                                                //喂狗
  1304.                 write_data(tem_1/10000000+0x30);
  1305.                 write_data(tem_1%10000000/1000000+0x30);
  1306.                 write_data(tem_1%10000000%1000000/100000+0x30);
  1307.                 write_data(tem_1%10000000%1000000%100000/10000+0x30);
  1308.                 write_data(tem_1%10000000%1000000%100000%10000/1000+0x30);
  1309.                 write_data(tem_1%10000000%1000000%100000%10000%1000/100+0x30);
  1310.                 write_data(tem_1%10000000%1000000%100000%10000%1000%100/10+0x30);
  1311.                 write_data(tem_1%10000000%1000000%100000%10000%1000%100%10+0x30);       
  1312.         }
  1313.         write_com(0x98);
  1314.         han_zi_display("稍后自動返回!");
  1315.         delay_ms(5000);
  1316.         clear_screen();
  1317.         GICR|=(1<<INT1);                                                        //打開外部中斷1
  1318.         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  1319. }
  1320. //*****************************************************保存新卡****************************************************
  1321. void save_card(void)                                               
  1322. {
  1323.         uchar eeprom_addr=0;
  1324.         uchar uu=0;
  1325.         uchar yy=0;
  1326.         WDR();                                                                                                        //喂狗       
  1327.         if((card_data[0][3]==0xff)&&(card_data[0][4]==0xff))
  1328.         {
  1329.                 eeprom_addr=1;                                                                                //從EEPROM的地址1處開始寫數據
  1330.         }
  1331.         else if((card_data[1][3]==0xff)&&(card_data[1][4]==0xff))
  1332.         {
  1333.                 eeprom_addr=6;                                                                                //從EEPROM的地址6處開始寫數據
  1334.         }
  1335.         else if((card_data[2][3]==0xff)&&(card_data[2][4]==0xff))
  1336.         {
  1337.                 eeprom_addr=11;                                                                                //從EEPROM的地址11處開始寫數據
  1338.         }       
  1339.         else if((card_data[3][3]==0xff)&&(card_data[3][4]==0xff))
  1340.         {
  1341.                 eeprom_addr=16;                                                                                //從EEPROM的地址16處開始寫數據
  1342.         }       
  1343.         else if((card_data[4][3]==0xff)&&(card_data[4][4]==0xff))
  1344.         {
  1345.                 eeprom_addr=21;                                                                                //從EEPROM的地址21處開始寫數據
  1346.         }       
  1347.         else
  1348.         {
  1349.                 clear_screen();
  1350.                 WDR();                                                                                                //喂狗       
  1351.                 write_com(0x80);
  1352.                 han_zi_display("    卡已存滿!");
  1353.                 write_com(0x90);
  1354.                 han_zi_display("請全部刪除, 再增");
  1355.                 write_com(0x88);
  1356.                 han_zi_display("    加新卡!");
  1357.                 auto_return=88;                                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  1358.                 GICR|=(1<<INT1);                                                                        //打開外部中斷1
  1359.                 delay_ms(6000);
  1360.                 return;
  1361.         }
  1362.         yy=eeprom_addr;
  1363.         for(uu=0;eeprom_addr<(yy+5);eeprom_addr++)
  1364.         {
  1365.                 eeprom_write(eeprom_addr,rev_dat[uu++]);
  1366.                 WDR();                                                                                                //喂狗       
  1367.         }
  1368.         clear_screen();
  1369.         write_com(0x90);
  1370.         han_zi_display("  已保存卡號!");
  1371.         card_pro();                                                                        //把EEPROM數據讀出來,更新RAM中的card_data數組
  1372.         delay_ms(4000);
  1373.         GICR|=(1<<INT1);                                                        //打開外部中斷1
  1374.         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  1375. }
  1376. //*********************************************不保存卡函數********************************************************
  1377. void no_save_card(void)
  1378. {
  1379.         rev_dat[0]=rev_dat[1]=rev_dat[2]=rev_dat[3]=rev_dat[4]=0;
  1380.         lcd_dis_num=0;
  1381.         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  1382. }
  1383. //*********************************************清除全部卡函數******************************************************
  1384. void clear_card(void)
  1385. {
  1386.         uchar ii;
  1387.         for(ii=1;ii<36;ii++)                                                //從EEPROM地址1處開始寫0XFF
  1388.         {
  1389.                 eeprom_write(ii,0xff);                                        //把前EEPROM 的前30位內容全部清成0xff
  1390.                 WDR();                                                                        //喂狗       
  1391.         }
  1392.         clear_screen();
  1393.         write_com(0x90);
  1394.         han_zi_display("已刪除全部卡號!");
  1395.         write_com(0x88);
  1396.         han_zi_display("請盡快添加新卡!");
  1397.         card_pro();                                                                        //把EEPROM數據讀出來
  1398.         delay_ms(4000);
  1399.         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  1400. }
  1401. //********************************************取消刪除卡時處理的函數***********************************************
  1402. void no_clear_card(void)                                                //不處理任何數據
  1403. {
  1404.         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出子菜單,進入主屏
  1405. }
  1406. //***********************************************日期時間設置******************************************************
  1407. void date_time_set(void)                                               
  1408. {
  1409.         clear_screen();
  1410.         tem[5]=0;                                                                        //秒變量清0
  1411.         set_time_temp=1;
  1412.         time_set_display();                                               
  1413. }
  1414. //******************************************報警開關設置***********************************************************
  1415. void alarm_set(void)
  1416. {
  1417.         clear_screen();
  1418.         write_com(0x90);                                       
  1419.         han_zi_display("    設置完成      ");
  1420.         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出菜單,進入主屏
  1421.         delay_ms(500);
  1422.         //添加相應的功能(此程序沒有此功能)
  1423. }
  1424. //******************************************人體紅外傳感器設置*****************************************************
  1425. void infrared_set(void)
  1426. {
  1427.         clear_screen();
  1428.         write_com(0x90);                                       
  1429.         han_zi_display("    設置完成      ");
  1430.         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出菜單,進入主屏
  1431.         delay_ms(500);
  1432.         //添加相應的功能(此程序沒有此功能)
  1433. }
  1434. //******************************************路燈開關設置***********************************************************
  1435. void lamp_set(void)
  1436. {
  1437.         clear_screen();
  1438.         write_com(0x90);                                       
  1439.         han_zi_display("    設置完成      ");
  1440.         auto_return=88;                                                                //隨便賦一個比OVER_FLOW大的數字,目的是退出菜單,進入主屏
  1441.         delay_ms(500);
  1442.         //添加相應的功能(此程序沒有此功能)
  1443. }
  1444. //******************************************空函數,不處理任何數據*************************************************
  1445. void nullsubs(void)
  1446. {
  1447. }
  1448. //*****************************************************************************************************************
  1449. void time_set_display(void)
  1450. {
  1451.         write_com(0x80);                                                        //第一行(如果是地址是:80H,即LCD的第一行的第一個位置顯示)
  1452.         han_zi_display("  日期時間設置  ");
  1453.         write_com(0x91);
  1454.         write_data((tem[0]/10)+0x30);
  1455.         write_data((tem[0]%10)+0x30);
  1456.         han_zi_display("年");
  1457.         write_data((tem[1]/10)+0x30);
  1458.         write_data((tem[1]%10)+0x30);
  1459.         han_zi_display("月");
  1460.         write_data((tem[2]/10)+0x30);
  1461.         write_data((tem[2]%10)+0x30);
  1462.         han_zi_display("日");
  1463.         date_time_display();
  1464.         write_com(0x8d);
  1465.         lcd_week_pro();                                                                //星期處理
  1466.         write_com(0x98);
  1467.         han_zi_display("  OK設置; NG退出");
  1468. }
  1469. //***********************************************星期處理**********************************************************
  1470. void lcd_week_pro(void)
  1471. {
  1472.         switch(tem[6])
  1473.         {
  1474.                 case 0:
  1475.                                 han_zi_display("星期日");
  1476.                                 break;
  1477.                 case 1:
  1478.                                 han_zi_display("星期一");
  1479.                                 break;
  1480.                 case 2:
  1481.                                 han_zi_display("星期二");
  1482.                                 break;
  1483.                 case 3:
  1484.                                 han_zi_display("星期三");
  1485.                                 break;
  1486.                 case 4:
  1487.                                 han_zi_display("星期四");
  1488.                                 break;
  1489.                 case 5:
  1490.                                 han_zi_display("星期五");
  1491.                                 break;
  1492.                 case 6:
  1493.                                 han_zi_display("星期六");
  1494.                                 break;
  1495.                 default:
  1496.                                 break;
  1497.         }
  1498. }
  1499. //**********************************************菜單選中標志"●"****************************************************
  1500. void select_menu(uchar data1)
  1501. {
  1502.         write_com(data1);
  1503.         write_data(0xa1);                                                                        //哪個菜單項選中時顯示"●"
  1504.         write_data(0xf1);
  1505. }
  1506. //*************************************************清整個GDRAM空間*************************************************
  1507. void clear_gdram(void)
  1508. {
  1509.         uchar x,y;
  1510.         for(y=0;y<64;y++)                                                        //64
  1511.         {
  1512.                 for(x=0;x<16;x++)                                                //16
  1513.                 {  
  1514.                         write_com(0x34);
  1515.                         write_com(y+0x80);                                 //行地址
  1516.                         write_com(x+0x80);                                     //列地址
  1517.                         write_com(0x30);
  1518.                         write_data(0x00);
  1519.                         write_data(0x00);
  1520.                         WDR();                                                                //喂狗
  1521.                 }
  1522.         }
  1523. }
  1524. //********************************************清屏*****************************************************************
  1525. void clear_screen(void)
  1526. {
  1527.         write_com(0x01);
  1528.         delay_ms(10);
  1529. }
  1530. //*********************************************系統(tǒng)起動引導主畫面**************************************************
  1531. void root_directory(void)
  1532. {
  1533.         write_com(0x80);                                        //第一行(如果是地址是:80H,即LCD的第一行的第一個位置顯示)
  1534.         han_zi_display("    門禁系統(tǒng)    ");
  1535.         write_com(0x91);
  1536.         write_data((tem[0]/10)+0x30);
  1537.         write_data((tem[0]%10)+0x30);
  1538.         han_zi_display("年");
  1539.         write_data((tem[1]/10)+0x30);
  1540.         write_data((tem[1]%10)+0x30);
  1541.         han_zi_display("月");
  1542.         write_data((tem[2]/10)+0x30);
  1543.         write_data((tem[2]%10)+0x30);
  1544.         han_zi_display("日");
  1545.         write_com(0x8d);
  1546.         switch(tem[6])
  1547.         {
  1548.                 case 0:
  1549.                                 han_zi_display("星期日");
  1550.                                 break;
  1551.                 case 1:
  1552.                                 han_zi_display("星期一");
  1553.                                 break;
  1554.                 case 2:
  1555.                                 han_zi_display("星期二");
  1556.                                 break;
  1557.                 case 3:
  1558.                                 han_zi_display("星期三");
  1559.                                 break;
  1560.                 case 4:
  1561.                                 han_zi_display("星期四");
  1562.                                 break;
  1563.                 case 5:
  1564.                                 han_zi_display("星期五");
  1565.                                 break;
  1566.                 case 6:
  1567.                                 han_zi_display("星期六");
  1568.                                 break;
  1569.                 default:
  1570.                                 break;
  1571.         }
  1572.         write_com(0x98);
  1573.         han_zi_display("室內溫度:");
  1574.         if(cold==0xaa)
  1575.         {
  1576.                 write_data('-');
  1577.         }
  1578.         else
  1579.         {
  1580.                 write_data(0x20);
  1581.         }
  1582.         write_data(temp0/10+0x30);
  1583.         write_data(temp0%10+0x30);
  1584.         write_com(0x9e);
  1585.         han_zi_display("℃");
  1586. }
  1587. //**********************************************時間、日期顯示*****************************************************
  1588. void date_time_display(void)
  1589. {
  1590.         write_com(0x88);
  1591.         write_data((tem[3]/10)+0x30);                                        //HOUR
  1592.         write_data((tem[3]%10)+0x30);
  1593.         if(set_time_temp==0)                                                        //=0 表示沒有進入時間設置菜單
  1594.         {
  1595.                 write_data(':');                                                        //通常情況下,":"要顯示為半角,目的:好看
  1596.         }
  1597.         else
  1598.         {
  1599.                 han_zi_display("時");                                                //進入設置時間菜單時,顯示為漢字,目的:方便反白顯示
  1600.         }
  1601.         write_data((tem[4]/10)+0x30);                                        //MINUTE
  1602.         write_data((tem[4]%10)+0x30);
  1603.         if(set_time_temp==0)                                                        //=0 表示沒有進入時間設置菜單
  1604.         {
  1605.                 write_data(':');                                                        //通常情況下,":"要顯示為半角,目的:好看
  1606.                 write_data((tem[5]/10)+0x30);                                //SECOND
  1607.                 write_data((tem[5]%10)+0x30);
  1608.         }
  1609.         else
  1610.         {
  1611.                 han_zi_display("分");                                                //進入設置時間菜單時,顯示為漢字,目的:方便反白顯示
  1612.         }
  1613. }
  1614. //*********************************************讀EEPROM,到RAM中***************************************************
  1615. void card_pro(void)
  1616. {
  1617.         uchar i=0,u=0,r=1;                                                                        //EEPROM地址從0x01處保存
  1618.         for(i=0;i<5;i++)                                                                        //共有5張開門卡,1張管理卡
  1619.         {
  1620.                 for(u=0;u<5;u++)                                                                //每個卡有5個字節(jié)數據
  1621.                 {
  1622.                         card_data[i][u]=eeprom_read(r++);                        //把EEPROM中的5張開門卡復制到RAM中
  1623.                         WDR();                                                                                //喂狗
  1624.                 }
  1625.         }
  1626. }
  1627. //********************************************比較匹配A 中斷*******************************************************
  1628. #pragma interrupt_handler time1_comp:7                                        //工作在CTC模式  每1S中斷一次
  1629. void time1_comp(void)
  1630. {
  1631.         if(return_en)                                                                                //菜單不動作自動返回允許變量
  1632.         {       
  1633.                 auto_return++;                                                                        //當auto_return>=OVER_FLOW時自動退出菜單設置
  1634.         }
  1635.         xx++;
  1636.         if(lcd_back_en==0xaa)                                                                //LCD背光計時變量允許
  1637.         {
  1638.                 lcd_back_time++;
  1639.                 if(lcd_back_time>=LCD_LAMP)                                                        //30秒后關閉LCD背光
  1640.                 {
  1641.                         lcd_back_time=0;
  1642.                         lcd_back_en=0;
  1643.                         LCD_BACK_OFF;
  1644.                 }
  1645.         }
  1646.         if(set_time_temp==0)
  1647.         {
  1648.                 tem[5]++;
  1649.                 if(tem[5]>=60)                                                                        //60        秒進位
  1650.                 {
  1651.                         tem[5]=0;
  1652.                         tem[4]++;
  1653.                         charge_tem++;
  1654.                         scan_en=0;
  1655.                         if(tem[4]>=60)                                                                //60        分進位
  1656.                         {
  1657.                                 tem[4]=0;
  1658.                                 tem[3]++;
  1659.                                 if(tem[3]>=24)                                                        //24        小時進位
  1660.                                 {
  1661.                                         tem[3]=0;
  1662.                                         tem[6]++;
  1663.                                         tem[2]++;
  1664.                                         if(tem[6]>=7)                                                //7             星期進位
  1665.                                         {
  1666.                                                 tem[6]=0;
  1667.                                         }
  1668.                                         if((tem[1]==1)||(tem[1]==3)||(tem[1]==5)||(tem[1]==7)||(tem[1]==8)||(tem[1]==10)||(tem[1]==12))   //判斷大小月
  1669.                                         {
  1670.                                                 if(tem[2]>=32)                                        //如果為大月,則有31天
  1671.                                                 {
  1672.                                                         tem[2]=1;
  1673.                                                         tem[1]++;
  1674.                                                 }
  1675.                                         }
  1676.                                         else
  1677.                                         {       
  1678.                                                 if(tem[2]>=31)                                        //如果為小月,則代表只有30天
  1679.                                                 {       
  1680.                                                         tem[2]=1;
  1681.                                                         tem[1]++;
  1682.                                                 }
  1683.                                         }
  1684.                                         if(tem[1]>=13)                                                //月進位
  1685.                                         {
  1686.                                                 tem[1]=1;
  1687.                                                 tem[0]++;
  1688.                                                 if(tem[0]>=29)                                        //當年大于2029年時,清零即2007年
  1689.                                                 {
  1690.                                                         tem[0]=7;
  1691.                                                 }
  1692.                                         }
  1693.                                 }
  1694.                         }
  1695.                 }
  1696.         }
  1697. }
  1698. //*********************************************讀卡中斷INT0********************************************************
  1699. #pragma interrupt_handler int0_inter:2                                //讀卡
  1700. void int0_inter(void)
  1701. {
  1702.         uchar i;
  1703.         uchar card_num=0;
  1704.         card_num=read_card_number();                                        //讀卡
  1705.         if(card_num==0xaa)
  1706.         {
  1707.                 buzzer_pro(1);                                                                                //峰鳴器指示
  1708.                 LCD_BACK_ON;                                                                                //打開LCD背光
  1709.                 lcd_back_en=0xaa;                                                                        //打開計時變量
  1710.                 lcd_back_time=0;                                                                        //計時變量清0
  1711.                 WDR();                                                                                                //喂狗
  1712.                 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))
  1713.                 {
  1714.                         inc_card_en=0xaa;                                                //管理卡
  1715.                         GIFR=(1<<INTF0);
  1716.                         GICR&=~((1<<INT1)|(1<<INT0));                        //關閉外部中斷0、1
  1717.                         return;
  1718.                 }
  1719.                 if(manage_card_inc_en==0xaa)                                //添加卡
  1720.                 {
  1721.                         manage_card_inc_en=0;
  1722.                         GIFR=(1<<INTF0);
  1723.                         GICR&=~(1<<INT0);                                                //關閉外部中斷0
  1724.                         return;
  1725.                 }
  1726.                 for(i=0;i<5;i++)
  1727.                 {
  1728.                         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]))
  1729.                         {                                                                                        //卡1
  1730.                                 GICR&=~((1<<INT1)|(1<<INT0));                        //關閉外部中斷0、1
  1731.                                 xx=0;
  1732.                                 WDR();                                                                                                //喂狗
  1733.                                 LOCK_ON;                                                                                        //開鎖
  1734.                                 delay_ms(500);
  1735.                                 LOCK_OFF;
  1736.                                 rev_dat[0]=rev_dat[1]=rev_dat[2]=rev_dat[3]=rev_dat[4]=0xff;
  1737.                                 i=6;
  1738.                         }
  1739.                 }
  1740.                 close_read=1;
  1741.                 card_num=0;
  1742.                 xx=0;
  1743.                 GICR&=~(1<<INT0);                                                //關閉外部中斷0
  1744.                 card_num=0;
  1745.         }
  1746.         GIFR=(1<<INTF0);
  1747. }
  1748. //*********************************************按鍵中斷INT1********************************************************
  1749. #pragma interrupt_handler int1_on:3
  1750. void int1_on(void)
  1751. {
  1752.         delay_ms(10);                                                                //按鍵采樣,  注意,一定要延時8MS以上,否則會造成連鍵現(xiàn)象
  1753.         kk=1;
  1754.         GICR&=~(1<<INT1);                                                        //關閉外部中斷1
  1755.         GIFR=(1<<INTF1);
  1756. }
  1757. //*****************************************************************************************************************
  1758. //文件名:    用AD來檢測按鍵
  1759. //編譯日期:  2007-01-21
  1760. //功能描述:
  1761. //                     1、共8個KEY,利用AD口其中的一個,來測電壓不同來判斷哪個按鍵按下。
  1762. //CPU類型:   ATmega16
  1763. //晶振頻率:  7.3728MHZ
  1764. //版本:             V0.1
  1765. //編程:      于軍峰
  1766. //*****************************************************************************************************************
  1767. //理論值:
  1768. //                S1=0V        S2=0.45V        S3=0.83V        S4=1.15V        S5=1.42V        S6=1.66V        S7=1.875V        S8=2.05V        無按下時=5V
  1769. //
  1770. //                S1=SET  S2=向上  S3=向下   S4=向左   S5=向右    S6=確認    S7=返回     S8=關于
  1771. //
  1772. //**********************************************AD來檢測按鍵*******************************************************
  1773. void read_adc(void)
  1774. {
  1775.         uint key_val=0;
  1776.     key_val=adc_sampling(ADC_PINA0);
  1777.     if(key_val<400)
  1778.         {
  1779.                 key=1;
  1780.         }
  1781.         else if(key_val<600)                                //向上
  1782.         {
  1783.                 key=2;
  1784.         }
  1785.         else if(key_val<1000)                                //向下
  1786.         {
  1787.                 key=3;
  1788.         }
  1789.         else if(key_val<1200)                                //向左
  1790.         {
  1791.                 key=4;
  1792.         }
  1793.         else if(key_val<1500)                                //向右
  1794.         {
  1795.                 key=5;
  1796.         }
  1797.         else if(key_val<1700)                                //OK
  1798.         {
  1799.                 key=6;
  1800.         }
  1801.         else if(key_val<1900)                                //返回
  1802.         {
  1803.                 key=7;
  1804.         }
  1805.         else if(key_val<2200)                                //說明
  1806.         {
  1807.                 key=8;
  1808.         }
  1809.         else
  1810.         {
  1811.                 key=0;
  1812.                 return;
  1813.         }
  1814. }
  1815. //************************************************ADC 采樣*********************************************************
  1816. uint adc_sampling(uchar adc_input)
  1817. {
  1818.         ulong temp32=0;       
  1819.         uint tem_3=0;       
  1820.         CLI();                                                                //關中斷
  1821.     ADMUX=(0x40|adc_input);                                //選擇外接參考電壓,AVCC, AREF 引腳外加濾波電容       
  1822.                                                                                 //adc_input:單端通道 0x00~0x07,0x1E,0x1F
  1823.     ADCSRA|=(1<<ADSC);                                        //啟動AD轉換
  1824.         while ((ADCSRA&(1<<ADIF))==0);  
  1825.     ADCSRA|=(1<<ADIF);                                        //寫1清除標志位
  1826.     temp32=ADC;
  1827. //**************************************第一次采樣的值舍去不要*****************************************************
  1828.     ADMUX=(0x40|adc_input);                                //選擇外接參考電壓,AVCC, AREF 引腳外加濾波電容       
  1829.                                                                                 //adc_input:單端通道 0x00~0x07,0x1E,0x1F                               
  1830.     ADCSRA|=(1<<ADSC);                                        //啟動AD轉換
  1831.         while ((ADCSRA&(1<<ADIF))==0);  
  1832.     ADCSRA|=(1<<ADIF);                                        //寫1清除標志位
  1833.     temp32=ADC;
  1834.     temp32*=vref;
  1835.     tem_3=((uint)(temp32/1024));
  1836.     SEI();                                                                //開中斷
  1837.     return(tem_3);
  1838. }
  1839. //**********************************************室溫檢測***********************************************************
  1840. uchar temperature_check(void)
  1841. {
  1842.         uchar adc_result1=0;
  1843.         temp_value=adc_sampling(ADC_PINA1);                        //AD采樣
  1844.         adc_result1=get_degree();
  1845.         if(adc_result1<=30)                                                        //是否為零下
  1846.         {
  1847.                 adc_result1=31-adc_result1;                               
  1848.                 cold=0xaa;
  1849.         }
  1850.         else
  1851.         {
  1852.                 cold=0;
  1853.                 adc_result1-=31;
  1854.         }       
  1855.         return(adc_result1);
  1856. }
  1857. //**********************************************溫度查表***********************************************************
  1858. uchar get_degree(void)                                 
  1859. {  
  1860.    uchar x=129;                                                                         //只檢測溫度-30---+99
  1861.    for (x=129;x>0;x--)                                                                 // 查表  
  1862.    {  
  1863.       if (temp_1[x]>=temp_value)
  1864.       {
  1865.         return x;   
  1866.       }
  1867.    }   
  1868.    return x;      
  1869. }
  1870. //********************************************峰鳴器處理***********************************************************
  1871. void buzzer_pro(uchar p)
  1872. {
  1873.         for(;p>0;p--)
  1874.         {       
  1875.                 WDR();                                                                                                //喂狗
  1876.                 buzzer_on;
  1877.                 delay_ms(15);
  1878.                 buzzer_off;
  1879.                 delay_ms(15);
  1880.         }
  1881. }
  1882. //**************************************************Program End****************************************************
復制代碼




作者: 河馬    時間: 2016-4-1 09:09
很好,要是帶樓層對講的就更完美了.
作者: weimada    時間: 2016-4-4 12:45
黑B不足.....
作者: leileiq910    時間: 2016-5-11 21:40
謝謝分享,正需要
作者: nwpchennan    時間: 2016-5-27 13:13
這個有實用價值,支持
作者: FANGWEI    時間: 2016-5-30 07:10

 不錯,收下了,謝謝!
作者: hhdsdy    時間: 2016-5-30 09:07
不知道有些什么功能
作者: lanpizhu    時間: 2016-5-30 14:43
黑B不足
作者: Robal影    時間: 2016-6-1 11:51
哇,不錯啊
作者: 1013344248    時間: 2016-6-2 09:27
好厲害!。!
作者: Mordy    時間: 2016-7-18 12:16
黑B不足=-=
作者: sunshine2016    時間: 2016-7-20 16:02
真厲害!
作者: fuguoding    時間: 2016-9-23 21:01
不錯的資料,學習下。。。
作者: JIMMYWANG    時間: 2016-10-18 20:29
好東西大家一起玩
作者: chjx0132    時間: 2016-10-22 10:09
過兩天做個出來玩下試試。
作者: 鐵峰66666    時間: 2016-10-22 19:03
不錯,如果程序能下載就更好了
作者: lietu    時間: 2016-10-26 22:19
庭不錯額
作者: w815984065    時間: 2016-11-2 18:35
好棒學習學習
作者: supeng    時間: 2017-2-22 21:58
非常感謝分享,正在學習這方面的知識,正是想要的參考,再次感謝樓主的付出。
作者: bevence    時間: 2017-2-23 18:16
非常感謝分享,正在學習這方面的知識,正是想要的參考,再次感謝樓主的付出。

作者: powerxia    時間: 2017-2-25 17:06
沒黑B啊,頂起
作者: 190778317    時間: 2017-2-28 23:50
真厲害!
作者: bbxyzzj    時間: 2017-3-1 08:57
感謝分享!
作者: bevence    時間: 2017-3-3 15:00
非常感謝分享,正在學習這方面的知識,正是想要的參考,再次感謝樓主的付出。

作者: supeng    時間: 2017-3-22 17:23
哇,我怎么還是缺少黑幣,干看著著急呀。
作者: li3    時間: 2017-3-24 10:11
感謝樓主分享
作者: coolboy_81    時間: 2017-3-25 21:04
好東西 感謝樓主分享
作者: sj偶像大羅    時間: 2017-3-27 13:01
很好,要是帶樓層對講的就更完美了.
作者: 123ed    時間: 2017-3-28 20:55
哇,我怎么還是缺少黑幣,干看著著急呀。
作者: kenvy    時間: 2017-4-8 17:57
正需要這資料,謝謝。
作者: WE1866    時間: 2017-4-11 08:37
不錯,收下了,謝謝!
作者: dragon19790000    時間: 2017-4-29 23:56
謝謝分享.樓主威武
作者: 阿苗子666    時間: 2017-5-3 00:35
棒棒噠
作者: 阿苗子666    時間: 2017-5-3 00:35
真的很厲害
作者: LWSZ    時間: 2017-5-20 09:55
很好很好
作者: wuxin2004    時間: 2017-9-12 00:05
很好的資料,多謝樓主分享
作者: 517563585    時間: 2017-9-14 16:01
FANGWEI 發(fā)表于 2016-5-30 07:10
 不錯,收下了,謝謝!

6666666666
作者: YQS    時間: 2017-9-14 16:38
謝謝樓主分享好資源!資料不錯。
作者: bleach    時間: 2017-9-18 11:59
很好的材料,感謝分享,正在學RFID識別
作者: wthdyfg    時間: 2017-9-20 09:08
好東東。多謝分享,想問下電源部分那個變壓器的部分看不太懂。
作者: weixao000888    時間: 2017-9-22 21:38
不錯不錯  學習了
作者: lsrly    時間: 2017-9-28 21:47
這么大的系統(tǒng),文件這么小
作者: 739388596    時間: 2017-10-7 17:00
很不錯,學習下
作者: skyker    時間: 2017-10-13 00:14
不錯嘛
作者: Ipluto    時間: 2017-10-17 15:39
資料很齊全。
作者: 西蒙貝克    時間: 2017-10-18 09:54
非常感謝分享,正在學習這方面的知識,正是想要的參考,再次感謝樓主的付出。

作者: piplxh    時間: 2017-10-22 11:05
牛!學習啦!
作者: liurend    時間: 2017-10-24 13:08
正好用到,就是黑幣不夠啊
作者: as77    時間: 2017-12-1 16:29
試了下有錯誤
作者: 2604233734    時間: 2017-12-3 17:23
感謝樓主分享
作者: 2604233734    時間: 2017-12-3 17:27
正好需要,謝謝樓主分享
作者: HelloPan111    時間: 2017-12-6 14:24
學習了,非常感謝
作者: harverli    時間: 2017-12-7 15:33
感謝分享
作者: 天窗    時間: 2017-12-12 21:55
好資料,多謝分享!
作者: Dream丶    時間: 2017-12-13 22:42
好復雜
作者: shenshang    時間: 2017-12-14 21:45
厲害  厲害
作者: harly2200    時間: 2017-12-18 00:04
學習備用,很好的資料
作者: xiaoxufei    時間: 2017-12-19 11:59
這個好!正需要呢,謝謝樓主分享
作者: 高頻驅動-春哥    時間: 2017-12-20 12:09
話說這個是什么12864,看著像1602
作者: eocoto    時間: 2017-12-21 18:53
黑B不夠呀,專門來看你的貼子,謝謝樓主的胸懷。
作者: jizi    時間: 2018-1-8 18:53
這資源很贊
作者: dpdr    時間: 2018-1-30 14:29
感謝分享。
作者: akzyzj    時間: 2018-2-3 15:14
謝謝分享
作者: jsj3ban35    時間: 2018-2-8 15:22
謝謝分享.樓主威武
作者: ID_DZAHZ666    時間: 2018-2-12 23:59
樓主厲害了
作者: 201730645473    時間: 2018-2-25 12:46
不錯的資料,學習下。。
作者: jxsjl168    時間: 2018-3-1 23:06
下不了,先占個位!
作者: 飛天的貓    時間: 2018-3-15 15:53
有價值!贊!
作者: 用戶2111153    時間: 2018-3-21 14:23
很久沒看到這么好的東西了  很喜歡  拿走了
作者: 天涯無芳    時間: 2018-3-21 14:46
謝謝分享努力學習中

作者: wzqshy    時間: 2018-3-29 19:53
好長的代碼
作者: root0    時間: 2018-4-7 12:04
感謝分享
作者: 939458979    時間: 2018-4-26 14:14
誰能幫忙發(fā)一下這個系統(tǒng)的仿真、調試
作者: heron    時間: 2018-5-21 14:58
拿了東西總要留個印的
作者: yang.kun    時間: 2018-5-23 13:53
下載后的文件能直接仿真跑起來嗎

作者: yang.kun    時間: 2018-6-6 12:13
請問電源充電部分可以舍去嗎

作者: wangtianbao    時間: 2018-6-8 15:45
好厲害呀         
作者: wuyijwr    時間: 2018-6-14 22:18
很給力!
作者: 聽風丶    時間: 2018-6-22 20:16
感謝分享~
作者: 97423842    時間: 2018-6-28 09:52
好東西,可惜沒黑幣
作者: filuer    時間: 2018-7-24 09:53
可惜,沒有黑比啊,哎
作者: 23680069    時間: 2018-7-24 16:08
很厲害
作者: 23680069    時間: 2018-7-24 16:27
好東西,多謝分享,樓主也是厲害的
作者: 23680069    時間: 2018-7-24 16:28
好東西,多謝分享
作者: danpianji111    時間: 2018-7-26 20:59
很好,正在學習中
作者: 沒事轉轉    時間: 2018-8-3 17:27
好東西!感謝分享!

作者: 沒臉說    時間: 2018-8-30 17:36
好東西,下載下來學習一下 謝謝樓主分享
作者: Yuan_cn    時間: 2018-11-15 10:34
感謝分享,準備自己做個簡單的
作者: s496729028    時間: 2019-2-25 14:36
好資料,謝謝樓主分享,正找這個呢
作者: yqzhshke    時間: 2019-2-27 09:30

感謝分享!
作者: zgf123456    時間: 2019-2-27 10:00
好東西  感謝分享
作者: 盉飛沙    時間: 2019-3-1 21:20
mega16做的?用mega單片機的不多了吧?
作者: 三林六木    時間: 2019-3-2 06:57
非常感謝分享,可以看出樓主付出了很多,我以前也做過這個,不過稍有點不一樣,以前我用了指紋,藍牙,紅外,RFID等幾種開鎖方式,準備再試試人臉識別
作者: tigerzq    時間: 2019-3-3 13:00
好東西
作者: lwpcol    時間: 2019-4-8 00:04
謝謝.很給力
作者: 辰影效    時間: 2019-12-27 15:24
這個程序適應于所有的單片機的嵌入式應用嗎

作者: tieq1952    時間: 2020-6-3 06:59
謝謝分享!!!
作者: suma5213    時間: 2020-7-23 13:24
不錯,如果程序能下載就更好了
作者: 愛迪生電子    時間: 2020-8-19 17:50
在哪下載呢??這個怎么找不到??

作者: 6998    時間: 2020-8-19 22:20
好東西 剛好要做類似的東西




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1