⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lock_main.c

📁 ID卡读卡器源程序 用Mega32通过U2270B读取H4001RFID卡号的范例
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************************************************
程序名:      射频卡门禁系统
功能概述:
			 1、  点阵LCD(128*64)显示。在正常、设置情况下LCD显示系统各个时期的菜单以供选择。
			 2、  射频卡开锁,开锁时用射频卡放在读卡器上(距离<15CM)即可开锁,如果用非法卡连续刷写次数超过3
			      次则报警(报警功能没有添加),这时系统将关闭刷卡器30分钟,在30分钟后再允许刷卡。
			 3	  本系统分为:
			              1)、1个主机。
			              2)、2个读卡头(一个在门外供刷卡用、一个在主机旁用于管理操作)
			 4、  本锁开锁时供电,平时断电(12V)。
			 5、  8个按键(AD转换采样取值)(设置、+、-、↑、↓、确认、返回、说明)
			 6、  每次按下键、刷卡时有峰鸣器指示
			 7、  LCD背光在有按键按下时、或刷卡时自动点亮,延时30秒关闭
			 8、  门外有人体红外传感器探头,发现2米内有人,自动进入预警状态,如果是在晚上超过7点钟,则点亮门前的灯泡照明,
			      如果此时有人破坏(比如取下灯泡、剪断灯炮的线、打烂灯泡)也要报警。否则、连续在门前超过1分钟,就开始报警。
			      (此功能没有添加)
			 9、  开门时发出“欢迎光临”,并提示关门(此功能没有添加)
			 10、 本机带有门铃,并能记录前10天门铃按下的次数。(此功能没有添加)
			 11、 LCD显示日期、星期、时间、室内温度、锁的状态、功能设置(菜单显示)等
			 12、 可以查询过去10天内的开门记录并由LCD显示出来(此功能没有添加)
			 13、 可以于电脑通过RS-232接口连接进行通信,监看门的状态、开门记录等,方便打印(此功能没有添加)
			 14、 要求锁误判率小于1PPM
			 15、 系统配有UPS(12V) 平时用UPS电能,只有当主机检测到电压低于11.5V时,自动接入火电进行充电。
			      电瓶充满时(大约5小时)自动断电。
			 16、 电压:12V   
			 17、 电流:待机时<50MA  

射频卡类型: 4001、EM4100和含E2PROM的RF卡。如E5550。
MCU类型:     ATmega16
晶振频率:    7.3728MHZ
版本:	     V0.1
编程:        于军峰
编译日期:    2007-05-01
******************************************************************************************************************/
#include<iom16v.h>
#include<macros.h>
#include<stdio.h>
#include"LCD_12864.H"										//LCD头文件
#include"read_card.H"										//读卡头文件
#define key_inc  (PINC&(1<<PC0))							//按键+,选择日期、时间时用
#define key_dec  (PINC&(1<<PC1))							//按键-,选择日期、时间时用
#define BAUDRATE        9600								//波特率
#define F_CPU			7372800  							//晶振频率
#define LCD_LAMP		60  								//LCD默认30S后关闭
#define BATTERY_TIME	5									//每十分钟检测一次电池电量

#define ADC_PINA0		 0x00								//ADC0		按键AD    单端通道,不放大
#define ADC_PINA1		 0x01								//ADC1		温度采样
#define ADC_PINA2		 0x02								//ADC2		电平电量检测

#define LCD_BACK_ON   	PORTC&=~(1<<PC5)
#define LCD_BACK_OFF   	PORTC|=(1<<PC5)
#define buzzer_on  		PORTD&=~(1<<PD7)
#define buzzer_off  	PORTD|=(1<<PD7)

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


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


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

#define null		 0
#define vref 	   5000										//AD转换参考电压
#define OVER_FLOW  	10										//进入菜单设置时,如果在10S内没有按下任何键,则自动退出

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

//********************************************目录结构体定义*******************************************************
struct menu_item      
{ 
    short menu_count; 
    char *display_string; 
    void (*subs)(); 
    struct menu_item *children_menus; 
    struct menu_item *parent_menus; 
}; 
//**********************************************结构数组声明*******************************************************
struct menu_item main_menu[4]; 
struct menu_item alarm_menu[2]; 
struct menu_item infrared_menu[2]; 
struct menu_item lamp_menu[2]; 
struct menu_item (*menu_point) = main_menu; 

struct menu_item card_main_menu[4]; 
struct menu_item card_inc_menu[2]; 
struct menu_item card_dec_menu[2]; 
struct menu_item (*menu_card) = card_main_menu; 

uchar user_choose = 0; 
uchar max_items=0; 
uint temp_value=0;							//温度检测AD值
//********************************************变量定义*************************************************************
uchar second_temp=0;						//秒变量
uchar scan_en=0;							//主屏扫描标志位
uchar key=0;								//按键变量
uchar kk=0;									//按键按下标志位
uchar auto_return=0;						//菜单自动返回变量
uchar return_en=0;							//菜单自动返回标志位
uchar left_right=0;							//左右键变量
uchar choose_temp=0;						//子菜单标题变量
uchar return_temp=0;						//返回临时变量
uchar set_time_temp=0;						//设置时间时菜单变量,如果=1表示屏显在设置时间菜单
uchar twinkling_addr=0x91;					//设置时间时闪动显示位置变量
uchar inc_card_en=0;						//添加新卡允许变量
uchar manage_card_inc_en=0;					//管理卡
uchar cold=0;								//温度正负极标志位
uchar temp0=0;								//温度值变量
uchar xx=88;								//温度更新变量,开机赋一个比较大的数,目的是开机就显示温度
uchar close_read=0;
lcd_back_en=0;								//LCD背光计时变量允许
lcd_back_time=0;							//LCD背光计时变量
//*****************************************************************************************************************
void delay_ms (unsigned int m);				//延时
void read_adc(void);						//按键ADC处理
void date_time_display(void);				//时间日期显示
void root_directory(void);					//引导主画面
void set_menu(void);						//设置菜单
void clear_screen(void);					//清屏
void clear_gdram(void);						//清全部GDRAM
void select_menu(uchar data1);				//选择菜单时,标志
void time_set_display(void);				//时间、日期设置显示
uint adc_sampling(uchar adc_input);			//ADC采样
uchar get_degree(void);						//温度查表
uchar temperature_check(void);				//室温检测
uchar charge_tem=0;							//每十分钟,检测一次电池电量,此变量主要是计时
uint battery_temp=0;						//电平电压变量
//************************************************函 数 声 明 区***************************************************
void main_menu_initial(void); 				//主菜单初始化
void alarm_menu_initial(void);  			//报警菜单初始化
void infrared_menu_initial(void); 
void lamp_menu_initial(void); 
void menu_initial(void);

void card_main_menu_initial(void);
void card_inc_menu_initial(void);
void card_dec_menu_initial(void);

void show_menu(void);
void date_time_set(void);
void alarm_set(void);
void infrared_set(void);
void lamp_set(void);
void nullsubs(void); 
void twinkling_addr_pro(void);
void lcd_week_pro(void);
void key_inc_dec(void);
void lcd_menu_set(void);
void card_pro(void);
void buzzer_pro(uchar p);
//*****************************************************************************************************************
void inc_new_card(void);						//添加新卡的处理函数
void query_card(void);							//查询卡函数
void save_card(void);							//保存卡时处理函数
void no_save_card(void);						//取消保存卡时处理函数
void clear_card(void);							//删除全部卡
void no_clear_card(void);						//取消删除卡
void card_menu_show(void);						//管理卡菜单显示
void card_menu_pro(void);						//管理卡菜单处理
void char_twinkling(uchar data_1);				//字符消隐					
//*****************************************************************************************************************
void eeprom_write(uint eeprom_address, uchar eeprom_data);			//写----EEPROM 操作
uchar eeprom_read(uint eeprom_address);								//读----EEPROM 操作
//*************************************************主程序**********************************************************
void main(void)
{
	PORTA=0XF8;							//PA0---按键AD;PA1---室内温度AD;PA2---电平电量检测
	PORTB=0XFF;
	PORTC=0XFF;
	PORTD=0XFF;
	DDRA =0XF8;							//AD转换时要设为输入、且端口要清0
	DDRB =0XFF;
	DDRC =0b11111000;
	DDRD =0b11110010;					//INT0、INT1、RXD设成输入;TXD设成输出
	TIMSK=(1<<OCIE1A);					//输出比较A 匹配中断使能
	TCCR1A=0;					
	TCCR1B=0X0D;						//CTC模式,1024分频
	OCR1A=7200;							//定时1S
	GICR=(1<<INT1)|(1<<INT0);			//打开外部中断0、1
	MCUCR=(1<<ISC00);					//INT0 引脚上任意的逻辑电平变化都将引发中断
	ADCSRA=(1<<ADEN)|0x06;				//使能ADC,时钟64分频 125KHz@8MHz system clock
	WDTCR=0x0f;							//(1<<WDE)|(1<<WDP2)|(1<<WDP1);	//打开看门狗,溢出时间为2.1S
	write_com(0x01);					//清除显示,并且设定地址指针为00H
	menu_initial();						//菜单数组初始化
	send_initial();						//串口初始化
	WDR();								//喂狗
	card_pro();							//读EEPROM,到RAM中
	lcd_reset();						//LCD初始化
	write_com(0x90);
	buzzer_on;
	LCD_BACK_ON;													//打开LCD背光
	han_zi_display("  系统正在启动  ");
	write_com(0x88);
	han_zi_display("    请稍后......");
	delay_ms(500);
	clear_gdram();						//清除GDRAM--绘图RAM
	clear_screen();						//清屏
	buzzer_off;													//峰鸣器指示
	lcd_back_en=0xaa;												//打开计时变量
	lcd_back_time=0;												//计时变量清0
	SEI();								//使能全局中断
	while(1)
	{
		WDR();							//喂狗
		if(scan_en==0)					//只有在scan_en=0的时候扫描主屏,平时只更新时间
		{
			scan_en=~scan_en;
			clear_screen();
			temp0=temperature_check();	//温度检测
			root_directory();
		}
		if(second_temp!=tem[5])			//每秒钟扫描一次
		{
			second_temp=tem[5];
			date_time_display();
		} 
		if(close_read==1)
		{
			if(xx>=5)
			{
				xx=0;
				close_read=0;
				second_temp=0;
				GICR=((1<<INT1)|(1<<INT0));							//开外部中断0、1
			}
		}
		if(kk)														//=1表示有按键按下
		{
			kk=0;
			read_adc();												//AD转换,取得键值
			buzzer_pro(1);											//峰鸣器指示
			LCD_BACK_ON;											//打开LCD背光
			lcd_back_en=0xaa;												//打开计时变量
			lcd_back_time=0;										//计时变量清0
			if(key==1)
			{
				GICR&=~(1<<INT0);									//关闭读卡外部中断0
				lcd_menu_set();										//LCD菜单设置
				GICR=((1<<INT1)|(1<<INT0));							//开外部中断0、1
			}
			else if(key==8)
			{
				GICR&=~((1<<INT1)|(1<<INT0));						//关闭部中断0、1
				key=0;
				clear_screen();										//清屏
				write_com(0x80);				
				han_zi_display("      警  告  ");
				write_com(0x88);				
				han_zi_display("版权归于军峰所有");
				write_com(0x98);				
				han_zi_display("    拷贝必究!!!");
				delay_ms(6000);
				scan_en=0;											//主菜单调用允许标志位
				clear_screen();		//**************
				GICR=((1<<INT1)|(1<<INT0));							//开外部中断0、1
			}
			else
			{
				key=0;
				GICR=((1<<INT1)|(1<<INT0));							//开外部中断0、1
			}
		}
		WDR();													//喂狗
		if(inc_card_en==0xaa)									//=0xaa表示调用管理菜单允许
		{
			inc_card_en=0;
			rev_dat[0]=rev_dat[1]=rev_dat[2]=rev_dat[3]=rev_dat[4]=0xff;
			lcd_dis_num=0;
			card_menu_pro();
			GICR=((1<<INT1)|(1<<INT0));							//开外部中断0、1
		}
		if(charge_tem>=BATTERY_TIME)	
		{
			charge_tem=0;
			battery_temp=0;
			WDR();												//喂狗
			battery_temp=adc_sampling(ADC_PINA2);				//AD采样电平电量
			if(battery_temp<=3750)								//3750=12V,当电平电压小于12V时,开始充电
			{
				charge_on;
				if(CHARGE_STATUS!=0)
				{
					buzzer_pro(10);											//峰鸣器指示
				}
			}
			else if((CHARGE_STATUS==1)||(battery_temp>=4375))	//如果大于4375=14V,表示要关闭充电器
			{
				charge_off;
			}
		}							
	}
}
//************************************************管理卡主菜单操作*************************************************
void card_menu_pro(void)
{
	clear_screen();
	menu_card= card_main_menu;
	user_choose=0;
	card_menu_show();
	return_en=1;												//打开菜单自动返回变量
	GICR|=(1<<INT1);											//打开外部中断1***********************	
	while(auto_return<OVER_FLOW)
	{
		WDR();													//喂狗
		if(kk)
		{
			kk=0;
			auto_return=0;										//清除菜单自动返回累计时间变量
			read_adc();
			buzzer_pro(1);										//峰鸣器指示
			LCD_BACK_ON;										//打开LCD背光
			lcd_back_en=0xaa;									//打开计时变量
			lcd_back_time=0;									//计时变量清0
			WDR();
			switch(key)
			{
				case 0:											//没有按下按键
						break;
				case 1:											//设置
						key=0;
						break;
				case 2:											//向上
						key=0;
	                    if (user_choose == 0) 
	                    { 
	                        user_choose = max_items; 
	                    } 
	                    user_choose --; 
						break;
				case 3:											//向下
						key=0;
	                    user_choose ++; 
	                    if (user_choose == max_items) 
	                    { 
	                        user_choose = 0; 
	                    } 
						break;
				case 4:											//向左
						key=0;
						break;
				case 5:											//向右
						key=0;
						break;
				case 6:											//确认
						key=0;
	                    if (menu_card[user_choose].subs != nullsubs) 
	                    { 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -