找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 58703|回复: 113
打印 上一主题 下一主题
收起左侧

一套完整的门禁系统(原理图+源程序),包括电源充电

  [复制链接]
跳转到指定楼层
楼主
ID:110653 发表于 2016-3-30 14:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

门禁系统原理图:




全部资料下载: 一套完整的门禁系统(原理图 源程序),包括电源充电.rar (168.5 KB, 下载次数: 1128)

门禁系统源码预览(部分):
  1. /******************************************************************************************************************
  2. 程序名:      射频卡门禁系统
  3. 功能概述:
  4.                          1、  点阵LCD(128*64)显示。在正常、设置情况下LCD显示系统各个时期的菜单以供选择。
  5.                          2、  射频卡开锁,开锁时用射频卡放在读卡器上(距离<15CM)即可开锁,如果用非法卡连续刷写次数超过3
  6.                               次则报警(报警功能没有添加),这时系统将关闭刷卡器30分钟,在30分钟后再允许刷卡。
  7.                          3          本系统分为:
  8.                                       1)、1个主机。
  9.                                       2)、2个读卡头(一个在门外供刷卡用、一个在主机旁用于管理操作)
  10.                          4、  本锁开锁时供电,平时断电(12V)。
  11.                          5、  8个按键(AD转换采样取值)(设置、+、-、↑、↓、确认、返回、说明)
  12.                          6、  每次按下键、刷卡时有峰鸣器指示
  13.                          7、  LCD背光在有按键按下时、或刷卡时自动点亮,延时30秒关闭
  14.                          8、  门外有人体红外传感器探头,发现2米内有人,自动进入预警状态,如果是在晚上超过7点钟,则点亮门前的灯泡照明,
  15.                               如果此时有人破坏(比如取下灯泡、剪断灯炮的线、打烂灯泡)也要报警。否则、连续在门前超过1分钟,就开始报警。
  16.                               (此功能没有添加)
  17.                          9、  开门时发出“欢迎光临”,并提示关门(此功能没有添加)
  18.                          10、 本机带有门铃,并能记录前10天门铃按下的次数。(此功能没有添加)
  19.                          11、 LCD显示日期、星期、时间、室内温度、锁的状态、功能设置(菜单显示)等
  20.                          12、 可以查询过去10天内的开门记录并由LCD显示出来(此功能没有添加)
  21.                          13、 可以于电脑通过RS-232接口连接进行通信,监看门的状态、开门记录等,方便打印(此功能没有添加)
  22.                          14、 要求锁误判率小于1PPM
  23.                          15、 系统配有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. //************************************************函 数 声 明 区***************************************************
  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 引脚上任意的逻辑电平变化都将引发中断
  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("  系统正在启动  ");
  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);                                                                        //发送使能,
  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. //*********************************************系统起动引导主画面**************************************************
  1531. void root_directory(void)
  1532. {
  1533.         write_com(0x80);                                        //第一行(如果是地址是:80H,即LCD的第一行的第一个位置显示)
  1534.         han_zi_display("    门禁系统    ");
  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个字节数据
  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以上,否则会造成连键现象
  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****************************************************
复制代码



评分

参与人数 6黑币 +51 收起 理由
delux3344 + 20
filuer + 5 赞一个!
深蓝远景 + 5 共享资料的黑币奖励!
练氏 + 11 很给力!
supeng + 5 很给力!
zhaok2013 + 5 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏69 分享淘帖 顶10 踩
回复

使用道具 举报

沙发
ID:105890 发表于 2016-4-1 09:09 | 只看该作者
很好,要是带楼层对讲的就更完美了.
回复

使用道具 举报

板凳
ID:109053 发表于 2016-4-4 12:45 | 只看该作者
黑B不足.....
回复

使用道具 举报

地板
ID:104183 发表于 2016-5-11 21:40 | 只看该作者
谢谢分享,正需要
回复

使用道具 举报

5#
ID:106429 发表于 2016-5-27 13:13 | 只看该作者
这个有实用价值,支持
回复

使用道具 举报

6#
ID:123930 发表于 2016-5-30 07:10 | 只看该作者

 不错,收下了,谢谢!
回复

使用道具 举报

7#
ID:88256 发表于 2016-5-30 09:07 | 只看该作者
不知道有些什么功能
回复

使用道具 举报

8#
ID:124005 发表于 2016-5-30 14:43 | 只看该作者
黑B不足
回复

使用道具 举报

9#
ID:124374 发表于 2016-6-1 11:51 | 只看该作者
哇,不错啊
回复

使用道具 举报

10#
ID:124620 发表于 2016-6-2 09:27 | 只看该作者
好厉害!!!!
回复

使用道具 举报

11#
ID:133129 发表于 2016-7-18 12:16 | 只看该作者
黑B不足=-=
回复

使用道具 举报

12#
ID:103832 发表于 2016-7-20 16:02 | 只看该作者
真厉害!
回复

使用道具 举报

13#
ID:63831 发表于 2016-9-23 21:01 | 只看该作者
不错的资料,学习下!!!!
回复

使用道具 举报

14#
ID:143299 发表于 2016-10-18 20:29 | 只看该作者
好东西大家一起玩
回复

使用道具 举报

15#
ID:136090 发表于 2016-10-22 10:09 | 只看该作者
过两天做个出来玩下试试。
回复

使用道具 举报

16#
ID:143113 发表于 2016-10-22 19:03 来自手机 | 只看该作者
不错,如果程序能下载就更好了
回复

使用道具 举报

17#
ID:144656 发表于 2016-10-26 22:19 | 只看该作者
庭不错额
回复

使用道具 举报

18#
ID:145765 发表于 2016-11-2 18:35 | 只看该作者
好棒学习学习
回复

使用道具 举报

19#
ID:166076 发表于 2017-2-22 21:58 | 只看该作者
非常感谢分享,正在学习这方面的知识,正是想要的参考,再次感谢楼主的付出。
回复

使用道具 举报

20#
ID:166230 发表于 2017-2-23 18:16 | 只看该作者
非常感谢分享,正在学习这方面的知识,正是想要的参考,再次感谢楼主的付出。
回复

使用道具 举报

21#
ID:18305 发表于 2017-2-25 17:06 | 只看该作者
没黑B啊,顶起
回复

使用道具 举报

22#
ID:167284 发表于 2017-2-28 23:50 | 只看该作者
真厉害!
回复

使用道具 举报

23#
ID:96326 发表于 2017-3-1 08:57 | 只看该作者
感谢分享!
回复

使用道具 举报

24#
ID:166230 发表于 2017-3-3 15:00 | 只看该作者
非常感谢分享,正在学习这方面的知识,正是想要的参考,再次感谢楼主的付出。
回复

使用道具 举报

25#
ID:166076 发表于 2017-3-22 17:23 | 只看该作者
哇,我怎么还是缺少黑币,干看着着急呀。
回复

使用道具 举报

26#
ID:182843 发表于 2017-3-24 10:11 | 只看该作者
感谢楼主分享
回复

使用道具 举报

27#
ID:183400 发表于 2017-3-25 21:04 | 只看该作者
好东西 感谢楼主分享
回复

使用道具 举报

28#
ID:183772 发表于 2017-3-27 13:01 | 只看该作者
很好,要是带楼层对讲的就更完美了.
回复

使用道具 举报

29#
ID:184265 发表于 2017-3-28 20:55 | 只看该作者
哇,我怎么还是缺少黑币,干看着着急呀。
回复

使用道具 举报

30#
ID:187494 发表于 2017-4-8 17:57 | 只看该作者
正需要这资料,谢谢。
回复

使用道具 举报

31#
ID:18572 发表于 2017-4-11 08:37 | 只看该作者
不错,收下了,谢谢!
回复

使用道具 举报

32#
ID:112693 发表于 2017-4-29 23:56 | 只看该作者
谢谢分享.楼主威武
回复

使用道具 举报

33#
ID:194714 发表于 2017-5-3 00:35 | 只看该作者
棒棒哒
回复

使用道具 举报

34#
ID:194714 发表于 2017-5-3 00:35 | 只看该作者
真的很厉害
回复

使用道具 举报

35#
ID:104760 发表于 2017-5-20 09:55 | 只看该作者
很好很好
回复

使用道具 举报

36#
ID:8691 发表于 2017-9-12 00:05 | 只看该作者
很好的资料,多谢楼主分享
回复

使用道具 举报

37#
ID:183356 发表于 2017-9-14 16:01 | 只看该作者
FANGWEI 发表于 2016-5-30 07:10
 不错,收下了,谢谢!

6666666666
回复

使用道具 举报

38#
ID:167337 发表于 2017-9-14 16:38 | 只看该作者
谢谢楼主分享好资源!资料不错。
回复

使用道具 举报

39#
ID:146874 发表于 2017-9-18 11:59 | 只看该作者
很好的材料,感谢分享,正在学RFID识别
回复

使用道具 举报

40#
ID:53468 发表于 2017-9-20 09:08 | 只看该作者
好东东。多谢分享,想问下电源部分那个变压器的部分看不太懂。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表