IC卡门禁系统

来源:岁月联盟 作者:未知 时间:2010-08-21

  关键词  单片机 IC电话卡读写 信息存储 信息识别


  论文摘要  常见的门禁系统有:密码门禁系统,IC卡门禁系统,指纹识别门禁系统等。密码门禁系统由于安全性弱和便捷性差已经面临淘汰 ,指纹识别门禁系统安全性高,但由于成本高等问题而没有得到广泛的市场认同。现在流行和通用的还是IC卡门禁系统。IC卡由于其较高的安全性、便捷性和性价比成为门禁系统的主流,但市面上的门禁系统都要配置相应的IC卡才能使用,如果由于遗失或各种原因导致没有足够的IC卡,便要再联系厂商购买,不但带来不便 ,而且价格昂贵。本文介绍的环保型IC卡门禁系统使用的是电信公司的IC电话卡作为门禁的IC卡 ,不但成本低 ,而且到处都能买到,很好的解决了IC卡成本高和难购买的问题。

  1引言

  门禁,又称出入管理控制系统。是一种管理人员进出的数字化管理系统.随着智能化、数字化信息社会的到来,“卡”已逐渐深入到了人们生活的方方面面,人们正在一步步地适应着卡,也渐渐地离不开卡,毫不夸张地说,人类将走向“卡”的世界。卡是实现智能化管理和自动化管理工作的一种重要手段。在需要控制人员出入情况的场所,比如人员阶段性流动的实验室,宾馆的客房,有特殊需求的保密部门等等,如果使用卡开启门,代替传统的出入证和钥匙,就能使管理工作实现自动化、智能化。不但用者方便,管理者也方便,而且工作效率和安全性都可以大大地提高。下面介绍的环保型IC卡门禁系统就是一个安全、可靠的门锁系统。使用该系统,可以方便地管理和控制应用场所的人员进出情况,验明出入人员的身份和出入权限。在IC卡应用日益广泛的今天,IC卡门禁系统以其门禁管理的安全、可靠、高效、灵活、方便,已逐步取代其他现有各类门锁,成为目前门禁系统的主流方式。


  2系统功能设计

  ◆必须输入正确密码才能进入系统菜单设置各项功能,如:增加新的IC卡、删除已有的IC卡、修改密码等。

  ◆能增加新的IC卡,最多可以发卡83张。

  ◆能删除已有的IC卡

  ◆能识别IC卡并提示卡号

  ◆能识别不正确的插卡并提示

  ◆能读出IC电话卡内的余额,并能按设置减去卡内相应的余额(为防止人为误操作,每次最高只能减去0.9元)

  ◆以绿灯亮代表开门信号


  3系统硬件原理

  3.1 系统原理图

  系统原理图如图1所示:

图1  系统原理图

  3.2  主控芯片:ATmega8

  ATmega8是ATMEL公司推出的一款新型AVR高档单片机。在AVR家族中,Atmega8是一种非常特殊的单片机,它的芯片内部集成了较大容量的存储器和丰富强大的硬件接口电路,具备AVR高档单片机MEGA系列的全部性能和特点。Atmega8是一款采用低功耗CMOS工艺生产的基于AVR RISC结构的8位单片机。AVR单片机的核心是将32个工作寄存器和丰富的指令集联结在一起,所有的工作寄存器都与ALU(算术逻辑单元)直接相连,实现了在一个时钟周期内执行一条指令同时访问(读写)两个独立寄存器的操作。这种结构提高了全码效率,使得大部分指令的执行时间仅为一个时钟周期。因此,Atmega8可以达到接近1MIPS/MHz的性能,运行速度比普通CISC单片机高出10倍。

  Atmega8的部分主要性能如下:

  ●      高性能、低功耗的8位AVR微控制器,先进的RISC精简指令集结构

  ◇      130条功能强大的指令,大多数为单周期指令

  ◇      32个8位通用工作寄存器

  ◇      工作在16MHz时,具有16MIPS的性能

  ◇      片内集成硬件乘法器(执行速度为2个时钟周期)

  ●      片内集成了较大容量的非易失性程序和数据存储器以及工作存储器

  ◇      8K字节的Flash程序存储器,擦写次数:>10000次

  ◇      支持可在线编程(IPS)、可在应用自编程(IAP)

  ◇      带有独立加密位的可先BOOT区,可通过BOOT区内的引导程序区(用户自己写入)来实现IPA编程。

  ◇      512个字节的EEPROM,擦写次数:100000次

  ◇      1K字节内部SRAM

  ◇      可编程的程序加密位

  ●      特殊的微控制器性能

  ◇      可控制的上电复位延时电路和可编程的欠电压检测电路

  ◇      内部集成了可选择频率(1/2/4/8MHz)、可校准的RC振荡器、外部和内部的中断源18个

  ◇      最多23个可编程I/O口,可任意定义I/O的输入/输出方向;输出时为推挽输出,驱动能力强,可直接驱动LED等大电流负载;输入口可定义为三态输入,可以设定带内部上拉电阻,省去外接上拉电阻

  ◇      宽工作电压:2.7V~5.5V(Atmega8L)

  本系统使用Atmega8作为主控芯片,主要作用为:使用其I/O口读写IC电话卡内的全部信息,并将卡内的全部信息存储在Atmega8的EEPROM内,一张卡占用6个字节,一共可存储83张IC电话卡的信息,存储地址为EEPROM(0~497);验证插入的IC卡是否允许通行,可通行则绿灯亮;验证输入的登录密码是否与EEPROM(地址为:504~511)内存储的密码相同;检测3x4键盘是否有按键按下;将各类信息显示到液晶1602,以进行人机交换操作。

  3.3  IC电话卡

  90年代的初期IC电话卡的出现,就已经取代了当时独霸一时的电话磁卡了,由于电话磁卡存在严重的安全性问题,所以推出不久就被黑客破解,所以讫今亦彻底淘汰了。IC电话卡实质是一个带串行输出的128位的EPROM,片内的前64位已经写了保护,在出厂时已经编程而且其熔丝位已被加密,所以无法更改片内的数据,。而其后的40位计数单元是受内部逻辑控制的,在读写时卡片内只能作减法计数,不能作加法计数,直至存储单元内装入的预置值减到0为止,因为IC电话卡是一种一次性的计数卡片,所以卡片内的存储单元减至空,卡片也就用完了,也就是作废了。

  很多人都会把用完的IC卡扔掉,但是电信公司发行的IC电话卡不计其数,这样一来就会对环境造成污染。本文介绍的门禁系统使用的IC卡就是电信公司的IC电话卡,无论IC电话卡内有无余额都能作为门禁的IC卡使用,完全符合环保的概念,并能很好的解决门禁IC卡成本高和难购买的问题。

  IC电话卡消费计数的单位价格是根据各种应用系统设定的,例如:30元面值的IC电话卡,对应的片内的存储单元的预置是#300,那每单位值就是0.1元了,IC电话机以每分钟产生一个扣费脉冲信号,扣费值是由当地IC电话管理系统设定的。一般是0.3元和0.8元,卡片内被减值是3次或8次了。而其它国家的IC电话卡也是如此。一般IC电话卡的引脚如图2所示:

图2  IC电话卡引脚图

  IC电话卡一般采用8脚封装和6脚封装,如果采用6脚封装的则无下面两个空脚。它的存储单元分布 :64位EPROM(8字节)写保护区  芯片数据代码区  发行商数据代码区,40位EEPROM(5字节)预置值计数区24位为1(3字节)共16字节数据,如图3所示:

              图3  IC卡存储单元分布图


  3.4  IC电话卡的原理:                    

  3.4.1  复位:要使地址计数器复位“0”,先让Resct复位端由“0”变成“1”,然后跟着一个Clock脉冲从“0”变成“1”再降回“0”电平,Resct复位端再至“0”,把Clock脉冲包住,随着Reset端变低,地址0单元的数据从I/O上输出。对应 Clock端的每个脉冲,其上升沿使地址计数器增加。其下降沿使被选通地址单元的数据从I/O上输出。地址计数器增加到127后返回到0,如图4的时序图所示: 

                       

图4  复位时序图

  3.4.2  写位: 在Reset和Clk端均为低的情况下,如果某地址单元允许写操作(64-103位,且该位必需为1),则Reset端上的一个脉冲(即从低到高再回低)将允许芯片进行位写操作。在紧跟着的时钟脉冲期间执行写操作,调整写操作维持时间至少10ms,在这个CLK脉冲期间,地址计数器不会增加,在CLK写脉冲下降沿,数据0从I/O端输出。从Reset脉冲的上升沿到CLK写脉冲的下降沿期间,I/O端的数据是无效的。在下一个才CLK脉冲,且Reset为低时,地址计数器又增1,并在下降沿时,把选通的地址单元的数据送到I/O端。如图5的时序图所示:

 

图5  写位时序图

  3.4.3  字节擦除: 对位地址72-103的字节单元来说,只要在每个字节的前面一位进行一次正常的写操作,就可以对此字节后一字节进行字节擦除操作。也就是说,每向高一字节进行借位(即写一位0),紧接着的擦除时序可以对后一字节按字节擦除(即整个字节写1)。被擦除的字节总是比借位写的字节低一字节。从以下时序图可以看出,首先,完成一个“位写”操作,在CLK的写脉冲结束后,在CLK为低电平时,在发一个Reset脉冲即启动字节擦除操作。在第二个CLK脉冲完成字节擦除,脉冲维持时间整定为擦除周期时间(至少1ms)。芯片逻辑控制电路验证了借位写确已完成从“1”写“0”后,才擦除其低位字节。从Reset的上升沿到擦除操作的CLK脉冲的下降沿,I/O脚上的数据无效。地址计数器仍然停留在借位写的地址上。如图6的时序图所示:

 

图6  字节擦除时序图

  3.4.4  计数方法:在67-103地址单元中分为5个不可重置8单元计数器,芯片初始化时,72-103地址单元所对应的4个较低的8单元计数器中可以放0到8个“1”而67-71地址单元所对应的第5个计数器可以放0到5个“1”。所谓计数一次,就是将一个单元从“1”写成“0”。一个计数器中8位全为“0”后,要计数,需借位操作,即将高位计数器的一位从“1”写成“0”而相应其低位计数器整个字节从“0”擦除成“1”。可见4个8单元计数器如此逐一递减,其最大计数为8的4次方=4096。第5个计数器中5个单元因处在最高位只能被写“0”无法擦成“1”。因此只能计数5次。故芯片总计数为5X4096=20480。当全部计数单元(地址67-103)都被写成“0”时,卡片就用完了,不过,芯片出厂初始化时,初置的计数值由国家不同和卡片面值不同而不同,如100元卡初置计数值为1000。如图7所示:       

                                   

图7  IC卡计数方法图

  3.5  3x4行列式键盘 本系统使用4x3行列式键盘控制门禁系统,从左到右(从上到下)分别为:按键“1”, 按键“2”, 按键“3”, 按键“4”, 按键“5”, 按键“6”, 按键“7”, 按键“8”, 按键“9”, 按键“0”, 按键“取消”, 按键“确定”。键盘输入信息的主要过程下:

  3.5.1  CPU判断是否有键按下。首先单片机向列扫描口PD0~PD2输出 全为0的扫描码F0H,然后从行检测口PD4~PD7输入行检测信号,中要有一列信号不为1,即PD口不为F0H,则表示有键按下。 

  3.5.2  查询按下键所在的行、列位置。单片机将得到的信号取反,PD4~PD7口中为了的位便是按键所在的列,确定行位置原理相同。

  3.5.3  键的抖动处理。当用手按下一个键时,往往会出现所按键在闭合位置和断开位置之间跳几下才稳定到闭合状态的情况;在释放一个键时,也会出现类似的情况这就是键抖动。抖动的持续时间不一,通常不会大于10ms。若抖动问题不解决,就会引起对闭合键的多次读入。解决键抖动最方便的方法就是:当发现有键按下后,不要立即进行逐行扫描,而是延时10ms后现进行。由于键按下的时间持续上百ms,延时后再扫描也不迟。

  3.6  字符型LCD显示模块 液晶显示器以其微功耗、体积小、重量轻、超薄型等诸多其他显示器件无法比拟的优点,在袖珍式登记表和低功耗系统中,得到越来越广泛的应用。本系统使用液晶显示模块作为人机交换界面显示,采用四线接法,大大节省了单片机的I/O口。

  4系统软件设计

  4.1  系统总体理论设计方框图 本系统最主要的部分是软件,所有的控制都是由单片机程序控制实现。上电开机后,LCD显示器第一行显示“Jason  Janito”,第二行显“Total : 卡数/83”;然后门禁系统进入等待状态,等待期间不断检测是否有卡插入或按键按下,若有卡插入则验证该卡,若有键按下,在输入正确密码后进入设置菜单。整体操作流程图如图8所示。

 SHAPE  /* MERGEFORMAT     

 

图8  整体流程图

  4.2  IC电话卡验证、显示及减钱程序

  当系统检测到有IC卡插入时,CPU Atmega8首先将IC卡内的全部数据读出并存储在数组IC_Codes_8[16]内,然后将数组与预先存储在EEPROM中的IC卡数据作比较,如果全部数据相同则表示该卡允许放行,以绿灯提示,并将IC电话卡内的余额显示在液晶显示器上;如果此时按下确定键,则进入IC卡减钱程序,在提示处输入要减去的金额(每次最多可减0.9元),按下确定键即可。部分程序如下:

void Read_Card ( void )         // 读卡程序(读取IC电话卡内的数据)
{
   unsigned char  I = 0 , j = 0 , k = 0 ,    // 循环用变量                                IC_Codes_2[128] = { 0 } ;   // IC卡内128bit数据
   for( i = 0 ; i < 16 ; i++ )
   {
      IC_Codes_8[i] = 0 ;     // 上次读卡的全局变量数据清除
   }
 
   Reset_0 ;                     // IC电话卡复位
   CLK_0 ;               
   delay_nms(10) ;                      // 延时10ms
 
   Reset_1 ;              //   为使地址计数器复位到0,先让Reset端变高。
   delay_nus(8) ;        //  紧跟着一个Clock脉冲(从低到高再降到0),
   CLK_1 ;            //  Reset重新变低,把Clock脉冲包住。随着Reset
   delay_nus(44) ;       //  端变低,地址0单元的数据从I/O上输出。对应
   CLK_0 ;            //  Clock端的每个脉冲,其上升沿使地址计数器增加。
   delay_nus(8) ;       //   其下降沿使被选通地址单元的数据从I/O上输出。
   Reset_0 ;             //  地址计数器增加到127后返回到0。
   delay_nus(5) ;      
   if ( ( PINB & 0x02 ) == 0 )
   {
         IC_Codes_2[0] = 0 ;       //   读取IC卡地址0的数据(数据为0时)
   }
   else                    
   {                    
         IC_Codes_2[0] = 1 ;       //   读取IC卡地址0的数据(数据为1时)

   }
   delay_nus(27) ;                      // 延时27us
 
   for ( i = 1 ; i < 128 ; i++ )
   {
      CLK_1 ;
      delay_nus(40) ;                //  IC卡时钟脉冲
      CLK_0 ;
      delay_nus(20) ;
      if ( ( PINB & 0x02 ) == 0 )    
         {
            IC_Codes_2[i] = 0 ;   //  读取IC卡地址1~127的数据(数据为0时)
         }
         else
         {                      
            IC_Codes_2[i] = 1 ;   //  读取IC卡地址1~127的数据(数据为1时)
         }
         delay_nus(20) ;
   }
   for( i = 0 ; i < 16 ; i++ )     //  将128bit 数据按顺序转换成16个字节
   {              
      for ( j = 0 ; j < 8 ; j++ )    
         {                  //  把16个字节存储到数组IC_Codes_8[16]
         IC_Codes_8[i] |= ( IC_Codes_2[k] << ( 8 - j ) ) ;
             k++ ;
         }
   }
}

  4.3  液晶显示与键盘扫描程序单片机应用系统通常都需要进行人—机对话。其中包括人对应用系统的状态干预与数据输入,应用系统向操作者显示状态与运行结果等信息。显示器与键盘是单片机应用系统中最常用的人—机交互设备。本系统应用到的液晶显示与键盘扫描程序如下:4.3.1  液晶显示程序(主要部分):                                          // 液晶显示器命令、数据写入函数     // 命令形参   //  数据形参               void LCD_write_char( unsigned command , unsigned data )
{
   unsigned command_temp , data_temp ;       // 变量定义
 
   command_temp = command ;     //  命令传递
   data_temp = data ;             //  数据传递
   delay_nus(16) ;                  //  延时16us
 
   if( command == 0 )         //   如果命令为0则写入数据
   {
      LCD_RS_PORT |= LCD_RS ;  // RS=1
      LCD_DATA_PORT& = 0Xf0 ;         // 初始化I/O口
      LCD_DATA_PORT |= ( ( data_temp & 0xf0 ) >> 4 ) ; 
      LCD_en_write() ;         //  调整位置后写高四位数据
      LCD_DATA_PORT &= 0Xf0 ;        // 初始化I/O口
      LCD_DATA_PORT |= data_temp & 0x0f ;  
      LCD_en_write() ;          //  写低四位数据
   }
   else                    //   如果命令为1则写入命令
   {
      LCD_RS_PORT& = ~LCD_RS ;   // RS=0
      LCD_DATA_PORT &= 0Xf0 ;        // 初始化I/O口
      LCD_DATA_PORT |= ( ( command_temp & 0xf0 ) >> 4 ) ;
      LCD_en_write() ;          //  调整位置后写高四位命令
      LCD_DATA_PORT &= 0xf0 ;        // 初始化I/O口
      LCD_DATA_PORT |= command_temp & 0x0f ; 
      LCD_en_write() ;          //  写低四位命令
   }
}

  4.3.2  键盘扫描程序:  unsigned char Key_Scan( void )    // 键盘扫描程序  (返回按键值)
{
   unsigned char Key = 0 ;    //   定义按键值变量


   PORTD = 0x0f ;         //  PD0~PD3输出低电平,PD4~PD7上拉电阻
   DDRD  = 0xf0 ;        //  PD0~PD3定义为输出,PD4~PD7定义为输入
   if ( ( PIND & 0x04 ) == 0 )    
      Key_1 = 1 ;                     //   读取相应输入口的电平
   else if ( ( PIND & 0x02 ) == 0 )     //   以确定是否有按键按下
      Key_1 = 2 ;                      //   并赋予相应的Key值
   else if ( ( PIND & 0x01 ) == 0 )
      Key_1 = 3 ;


   delay_nms(50) ;                      //   延时50ms
   PORTD = 0xf0 ;         //  PD4~PD7输出低电平,PD0~PD3上拉电阻
   DDRD  = 0x0f ;        //  PD4~PD7定义为输出,PD0~PD3定义为输入
   if ( ( PIND & 0x80 ) == 0)      
      Key_1 += 0 ;
   else if ( ( PIND & 0x40 ) ==0 )         //   读取相应输入口的电平
      Key_1 += 3 ;
   else if ( ( PIND & 0x20 ) == 0 )     //   以确定是否有按键按下
      Key_1 += 6 ;
   else if ( ( PIND & 0x10 ) == 0 )       //   并赋予相应的Key值
      Key_1 += 9 ;
      
   return Key ;       //   返回按键值
}

  4.4  EEPROM读写程序  Atmega8芯片内集成有512个字节的EEPROM,擦写次数高达100000次。本系统的全部信息都存储在此EEPROM内,包括:登录密码、被允许的IC卡信息。所有输入的数据都要与EEPROM内的数据比较,符合要求的才能被允许。所以此EEPROM在本系统中起着到关重要的作用。EEPROM的读写程序如下:

// 写EEPROM程序      // 写入的地址形参    // 写入的数据                   void EEPROM_write( unsigned int uiAddress ,  unsigned char ucData )
{
   while(EECR & ( 1 << EEWE ) ) ;       // 等待上一次写操作结束
   EEAR = uiAddress ;              // 地址传递
   EEDR = ucData ;                     // 数据传递
   EECR |= ( 1 << EEMWE ) ;           //  置位EEMWE
   EECR |= ( 1 << EEWE ) ;          //  置位EEWE以启动写操作
}

 // 读EEPROM程序            // 读出的地址形参                            unsigned char EEPROM_read( unsigned int uiAddress )
{
   while ( EECR  &  ( 1 << EEWE ) ) ;       // 等待上一次写操作结束
   EEAR = uiAddress ;              // 地址传递
   EECR |= ( 1 << EERE ) ;            // 设置EERE以启动读操作
   return EEDR ;                    // 自数据寄存器返回数据
}

  :

  [1] 马潮、詹卫前、耿德根。Atmega8原理及应用手册。清华大学出版社,2004

  [2] 沈文、Eagle lee、詹卫前。AVR单片机C语言开发入门指导。清华大学出版社,2004

  [3] 马忠梅、籍顺心、张凯、马岩。单片机的C语言应用程序设计。北京航空航天大学出版社,2005

  [4] 郑莉、董渊。C++语言程序设计(第二版)。清华大学出版社,2004

  [5] 胡键。单片机原理及接口技术。机械出版社,2005

  [6] 谢自美。线路设计-实验-测试(第二版)。华中科技大学出版社,2004

  [7] 和飞、周苏平。2006届本科生优秀毕业(设计)选。广东人民出版社,2006