为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

IC读卡器设计

2018-09-22 30页 doc 470KB 3阅读

用户头像 个人认证

北溟愚鱼

暂无简介

举报
IC读卡器设计IC卡读写器 IIC读卡器设计 目 录 1 设计目的和要求 1 1.1 设计目的 1 1.2 设计要求 1 2 硬件设计 2 2.1 硬件选择和总体系统框图 2 2.2 4x4矩阵键盘电路 2 2.3 数码管动态、静态显示电路 3 2.4 数据储存电路 4 3 软件设计 7 3.1 软件总体流程 7 3.2 I²C器件的读写 8 3.3 反转法读键值 9 3.4 数码管扫描显示 10 12 4 软硬件调试 4.1 软硬件协同调试 12 5 实习心得 13 参考文献 15 附录 16 1 设计目的和要求 ...
IC读卡器设计
IC卡读写器 IIC读卡器设计 目 录 1 设计目的和要求 1 1.1 设计目的 1 1.2 设计要求 1 2 硬件设计 2 2.1 硬件选择和总体系统框图 2 2.2 4x4矩阵键盘电路 2 2.3 数码管动态、静态显示电路 3 2.4 数据储存电路 4 3 软件设计 7 3.1 软件总体流程 7 3.2 I²C器件的读写 8 3.3 反转法读键值 9 3.4 数码管扫描显示 10 12 4 软硬件调试 4.1 软硬件协同调试 12 5 实习心得 13 参考文献 15 附录 16 1 设计目的和要求 1.1 设计目的 本课的主要内容是采用51系列微控制器实现IC读写器的设计,通过这个实习,增强C语言程序设能力,同时加强对51系列微控制器及相关知识理论的使用,熟练掌握51系列微控制器的编程、调试和应用系统的开发以及相关芯片总线的使用。 1.2 设计要求 1、密码存储在I²C器件AT24C02中,实现数据掉电不丢失。 2、系统在上电后四个数码管均显示“—”的初始化状态。 3、实现数字键0-9和相关功能键的设计, 4、四个功能键的说明: (1)输入键:按下此键时,四个数码管空白显示(全黑),每输入一个数字就在数码管上显示出来。 (2)读出键:按下此键后,读出24c02的数据,并显示在四个数码管上。 (3)复位键:在按下输入键之后,输入4个数字后,可以选择该键表示放弃输入不储存,或者选择储存键。 (4)储存键:当输入修改的数字后,按下此键,将修改的数据进行存储并同时回到初始状态,显示“—”。 2 硬件设计 2.1 硬件选择和总体系统框图 本设计采用STC89C52微控制器,用24C02作为存储密码的芯片,实现储存数据断电不丢失,采用4X4矩阵键盘输入,四位共阳数码管动态显示密码。管脚连接如图2.1所示。图中省略时钟电路和电源电路。 图 2.1 总体系统框图 2.2 4X4矩阵键盘电路 矩阵键盘又称行列式键盘。用I/O口线组成行列结构,按键设置在行列交点上。N条口线最多可构造N²个按键。4X4的行列结构可构成16个键的键盘,如图2.2所示。无按键时各行各列彼此相交而不相连。由行列线的电平状态可以识别唯一与之相连的按键,此过程成为读键值。 图 2.2 4x4矩阵键盘 键盘读键采用反转读键法。 第一步:先置行线P2.0~P2.3为输入线,列线P2.4~P2.7为输出线,且输出为0。相应的P2口写为0FH。若读入低4位的数据为F,则表明有键按下,保存低4位数据。低4位中电平0的位置对应的是被按下键的行位置。 第二步:设置输入输出口对换,行线P2.0~P2.3为输出线,且输出为0,列线P2.4~P2.7为输入线,I/O口编程数据为F0H。若读入高4位数据不等于F,则认为有键按下。读入高4位数据中为0的位为列位置。保存高4位数据,将两次所读数值按位或运算一次,便得按键值。 2.3 数码管显示电路 设计中显示4位数据时,采用数码管动态显示方式,它既满足4个数码管的显示要求,又节省了单片机的I/O管脚资源,只使用12条I/O口线。4个数码管共用一个I/O口P0,如图2.3所示,在每个瞬间,数码管段码相同。要达到多位显示的目的,就要在每一瞬间只有一位共阳端有效,即只选通一位数码管。段码由共用I/O口送来,各位数码管依次轮流选通,使每位显示该位的字符,并保持一段时间,以适应视觉暂留的效果。然后关闭该位数码管,防止“残影”现象。 在显示初始状态“—”时,四位数码管为静态显示,所有数码显示相同。 图 2.3 数码管显示电路 2.4 数据存储电路 2.4.1 I²C总线协议 I²C总线是由数据线SDA和时钟SCL构成的串行t通信总线,可发送和接收数据。在微控制器与IC之间、IC与IC之间进行双向传送,在信息的传输过程中,I²C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。 I²C总线基本状态如图2.4: 1)总线空闲(A) 数据线和时钟线同时为高电平。 2)启动数据传输(B) 时钟(SCL)为高电平时,SDA 从高电平变为低电平表示起始条件产生。起始条件必须先于所有的命令产生。 3)停止数据传输(C) 时钟(SCL)为高电平时, SDA 从低电平变为高电平表示停止条件产生。所有操作都必须以停止条件结束。 4)数据传送/数据有效 (D) 数据线的状态表明数据何时有效。在起始条件之后,数据线在时钟处于高电平期间保持稳定。必须在时钟信号为低电平期间改变数据线。一个数据位对应一个时钟脉冲。数据的每次传输以起始条件开始,以停止条件结束。在起始条件和停止条件之间传输的数据字节数目由主器件决定。 图 2.4 基本状态图 确认信号(ACK) 每一个被寻址的接收器在接收到每一字节数据后,应发送一个确认位。主器件必须提供一个额外的时钟以传输确认位。在确认时钟脉冲内,器件确认须拉低 SDA 线。在确认时钟的高电平期间,SDA线以这种方式保持稳定的低电平。当然,还必须考虑建立时间和保持时间。 图 2.5 6)无应答信号(NO ACK) 在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个 NO ACK,NO ACK有两种用途:a、一般表示接收器未成功接收数据字节;b、当接收器是主控器时,它收到最后一个字节后,应发送一个NO ACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。 2.4.2 E²PROM芯片 24C02是2KB二线制I²C串行E²PROM,其特征码为1010B。模块的电路图如图2.6所示。 图 2.6 模块电路连接 写数据过程: 写操作时,SDA线上的信号依次为:启动START 1010 B2B1B0(0~111B) 0低电平为写操作 应答ACK 8位的地址 ACK 数据0 ACK……数据15 应答ACK 结束STOP. 24C02每一次写操作最多可连续写8字节(一页),也可以少于8字节。一旦停止信号被接收到,则24C02内部写周期将开始。在内部写周期期间,不响应外部信号,直到写周期完成。如图2.7所示为24系列存储器写周期时序图。 图2.7 24c02页写入方式 2)读数据过程: 读操作时,SDA线上的信号依次为:启动START 1010 B2B1B0(0~111B) 0低电平为写操作 应答ACK 8位的地址 ACK START 1010 B2B1B0(0~111B) 1高电平为读操作 应答ACK 数据0 ACK……数据N 非应答NO ACK 结束STOP 在读数据之前,先写入要读的数据所在的地址。然后,主器件在“应答”位后产生一个启动信号,以终止刚才的写地址操作。随后主器件再次发出控制字,R/W位为1,。24C02接收“应答”信号后,便可读数据,可以读一字节、两字节、……N字节的数据。读完最后一个数据后,主器件发出“非应答”(NO ACK)信号和停止(STOP)信号。如图2.8所示为24系列存储器读操作时序图。 图 2.8 24c02读时序 3 软件设计 3.1 软件总体流程 软件的设计主要包括:数据从I²C器件的读写,键盘反转读键,数码管扫描显示,数据读取储存逻辑等。其总体流程图如图3.1所示。 C D 任意键 E F 图 3.1 程序总体流程 3.2 I²C器件的读写 该模块实现 I²C器件RAM中00单元为首地址的连续4个字节的数据读写。读写原理在硬件设计中叙述,由于过程过长在此不复述,其程序流程图3.2、3.3如下: 图3.2 读数据流程图 图 3.3 写数据流程图 3.3 键盘反转读键 本设计程序中用反转法对键盘进行行列扫描,做到去抖动且一次按键只读一次键值。做一次扫描的过程包括,检测是否有按键按下,如果有则延时10ms,以消除前抖动影响,再检测有无按键按下,若有扫描键值,则确认该按键按下,再检测按键是否弹起,延时10ms,消除后抖动影响。流程图如图3.4。 N Y N Y 图 3.4 键盘扫描流程 3.4 数码管扫描显示 数码管采用动态显示和静态显示两种方式做显示。动态显示中,先进行端选,再进行位选,然后延时几百微妙,达到暂留显示的目的,最后关闭所有数码管防止有重影的现象。其它位的数码管依次重复这个过程,最后在程序设计流程图如图3.5所示。 图 3.5 数码管扫描程序流图 4 软硬件调试 4.1 硬件协同调试 通过串口下载到单片机中的硬件调试,通过实际现象来查找代码中的错误,然后查找相关代码的错误,从而来改正相应的代码,初始状态如实物如图4.1所示。 图 4.1 初始状态显示 数码管在首次输入时,无法关闭未输入的数码管,修改代码后达到实际效果如图4.2所示,可以关闭未输入位的数码管。 图4.2 输入时数码管关闭未输入位 5 实习心得 刚开始实习的时候,我们都觉得学过的知识很生疏,因为好久没摸单片机了,虽然以前做过实验,但那时用的是汇编语言,而现在使用c语言,不过c更加容易理解,适合设计程序。从焊接硬件电路开始,阅读参考实验例程,相互探讨编程思路,寻找资料等等,我们都在努力的自学着。通过这次的设计,我们增加了好多的收获。 首先,是学习上的巩固。通过复习课本和实验,对单片机的基础知识又有了很大的巩固。其次,通过对用C语言实IC卡读写的功能,熟悉了keil软件的一些相关的操作和调试编译技巧,以及电子元器件的组装知识等等。增进了与同学的交流。平常除了上课,大家交流比较少。而每次做实习设计的时候,大家总会互相探讨,发表自己的看法,当遇到问题时,自己花了很长时间都不能够解决,同学的一些建议却很快的解决了这个问题。这让我了解到与人合作的重要性,团队的重要性,一个人不可能解决所有的问题。另外对单片机的接口电路有了进一步了解,比如矩阵键盘,动态扫描数码管,E²PROM的I²C时序的理解等。这样我们不仅了解单片机的原理,而是给我带来了很多的思考如何对多个器件的读写,如何传输数据到电脑,如何组建局域网通信等等。让我想学习更多的相关知识,进一步培养了我们的动手能力和兴趣。 参考文献 [1]李鸿等.单片机原理及应用[M].湖南大学出版社,2005. [2]何立民.单片机高级教程---应用与设计[M].北京航空航天大学出版社,2000,8. [3]戴佳.51单片机C语言应用程序设计实例精讲[M].北京:电子工业出版社,2006. [4]于京. 51系列单片机C程序设计与应用案例[M].北京:中国电力出版社,2006. [5]孙育才. ATMEL新型AT89S52系列单片机及其应用[M].北京:清华大学出版社, 2005. [6]李华.MCS-51系列单片机实用接口技术[M].北京:北京航空航天大学出版社,2000. 附录 程序清单: Main.c ///////////////////////////////////////////////////////////// #include #include #include "led.h" #include "key.h" #include "at24c02.h" void main(void) { unsigned char key; unsigned char count,t; unsigned char ge,shi,bai,qian; while(1) { LedLock(); //显示'-' key = KeyScan(); //读取键值.无按键按下值为255 if(key == 12 ) //读取iic的值,并显示 { ge=read_add(0x00); //读00单元的数据 _nop_(); shi=read_add(0x01); _nop_(); bai=read_add(0x02); _nop_(); qian=read_add(0x03); //读出iic的值,还原为整数 while( (KeyScan()>15) ) { LedShow(ge,shi,bai,qian); //显示读取值 } } if( key == 13) //修改iic的值,储存或放弃 { P3=0xff; //进入修改关闭数码管 count=0; qian=20; //让数码管在显示时,不显示未读入键值的位 bai=20; shi=20; ge=20; while( count < 4) //读取键值给sum { t=KeyScan(); if(t<10) count++; if( (count==1)&& (t<10) ) { qian=t; } if( (count==2)&&(t<10) ) { bai=t; } if( (count==3)&& (t<10)) { shi=t; } if( (count==4)&&(t<10) ) { ge=t; } if(count > 0) LedShow(ge,shi,bai,qian); } key=255; while( (key<13)||(key>16) ) { key=KeyScan(); LedShow(ge,shi,bai,qian); } //key == 14放弃输入值 if(key == 15) //储存输入值 { write_add(0x00,ge); _nop_();_nop_(); write_add(0x01,shi); _nop_();_nop_(); write_add(0x02,bai); _nop_();_nop_(); write_add(0x03,qian); } } } } At24c02.c/////////////////////////////////////////////////////////////// /*随机的位读写方式,8位地址读写*/ #include //at24c02 #include #include #include "at24c02.h" void delay(void) //延时函数 { unsigned char i,j; for(i=0;i<10;i++) for(j=0;j<248;j++) _nop_(); } void start(void) //起始函数 { sdak=1; _nop_(); sclk=1; _nop_(); _nop_(); _nop_(); _nop_(); sdak=0; _nop_(); _nop_(); _nop_(); sclk=0; _nop_(); } void stop(void) //停止子函数 { sdak=0; sclk=1; _nop_(); _nop_(); _nop_(); _nop_(); sdak=1; _nop_(); _nop_(); _nop_(); _nop_(); sclk=0; _nop_(); _nop_(); } void tack(void) //iic响应子函数 { sdak=0; _nop_(); sclk=1; _nop_(); _nop_(); _nop_(); _nop_(); sclk=0; _nop_(); _nop_(); _nop_(); } void notack(void) //iic非响应子函数 { sdak=1; _nop_(); _nop_(); sclk=1; _nop_(); _nop_(); _nop_(); _nop_(); sclk=0; _nop_(); _nop_(); } void wrbyt(unsigned char a) //iic写数据 { unsigned char b; unsigned char i=8; b=a; while(i--) { if( (b&0x80) == 0x80) { sdak=1; _nop_(); _nop_(); sclk=1; _nop_(); _nop_(); _nop_(); _nop_(); sclk=0; sdak=0; } else { sdak=0; _nop_(); _nop_(); sclk=1; _nop_(); _nop_(); _nop_(); _nop_(); sclk=0; } b<<=1; } } unsigned char rdbyt(void) //iic读数据函数 { unsigned char i=8; unsigned char rdd; while(i--) { sdak=1; sclk=1; rdd<<=1; _nop_(); _nop_(); if(sdak==1) {rdd|=0x01;} else {rdd&=0xfe;} sclk=0; } return rdd; } unsigned char read_add(unsigned char address) //iic读一个字节 { unsigned a; start(); wrbyt(0xa0); tack(); wrbyt(address); tack(); start(); wrbyt(0xa1); tack(); a=rdbyt(); notack(); stop(); return a; } void write_add(unsigned char address,unsigned char date) //iic写入一字节 { start(); wrbyt(0xa0); tack(); wrbyt(address); tack(); wrbyt(date); tack(); stop(); delay(); delay(); delay(); } at24c02.h #ifndef __AT24C02_H__ #define __AT24C02_H__ sbit sclk=P3^2; //iic数据口定义 sbit sdak=P3^3; extern void write_add(unsigned char address,unsigned char date); //向固定地址写入一个字节数据 extern unsigned char read_add(unsigned char address); //读取某个固定地址一个字节数据 #endif Key.c/////////////////////////////////////////////////////////////// /* 反转法读键值 IO口使用P2 */ #include #include "key.h" void delayms(unsigned int xms) { unsigned int i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } //键值对应表 unsigned char data key_tab[]={0x11,0x21,0x41,0x81,0x12,0x22,0x42,0x82,0x14,0x24,0x44,0x84,0x18,0x28,0x48,0x88}; /*函数:keyscan() 功能:从矩阵键盘中读取键值 参数:无 返回:kunsigned char型 说明:k值大于15时代表没有按下按键 */ unsigned char KeyScan(void) { unsigned char i; unsigned char j; unsigned char k; //返回值 P2=0x0f; i=P2; i=(~i)&0x0f; if (i==0) return 255; P2=0xf0; j=P2; j=(~j)&0xf0; if(j==0) return 255; delayms(10); do {k=P2;}while((~k)&0xf0); //等待按键放开 delayms(10); i=j|i; k=0; while(key_tab[k]!=i) {k++; if(k>15) break; } return k; } Key.h///////////////////////////////////////////////////////////// #ifndef __KEY_H__ #define __KEY_H__ extern unsigned char KeyScan( void ); #endif Led.c///////////////////////////////////////////////////////// #include #include "led.h" unsigned int data seg_7[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; void LedDelay(unsigned int i) //大约延时i*2个微秒 { while(--i);} /* 函数:LedShow() 功能:传入一个4位的整型数,在4位数码管上显示 */ void LedShow(unsigned char ge ,unsigned char shi,unsigned char bai,unsigned char qian) { if(qian<10) { P0=seg_7[qian]; //段选数码管 P3=0x7F; //位选数码管 LedDelay(100); P3=0xFF; } if(bai<10) { P0=seg_7[bai]; P3=0xbF; LedDelay(100); P3=0XFF; } if(shi<10) { P0=seg_7[shi]; P3=0xdF; LedDelay(100); P3=0XFF; } if(ge<10) { P0=seg_7[ge]; P3=0xeF; LedDelay(100); P3=0XFF; } } void LedLock(void) //让数码管'-'表示无数据显示 { P0=0xbf; P3=0x0f; //四个数码管同时打开 } Led.h #ifndef __LED_H__ #define __LED_H__ extern void LedShow(unsigned char ge,unsigned char shi, unsigned char bai,unsigned char qian); extern void LedLock(void); #endif 4位数码管 P0/P3 STC89C52RC P2 INT0/INT1 4x4矩阵键盘 IIC储存器 AT24C02 开始 显示“—”状态 键值扫描 关闭数码管 读取IIC数据 显示数据,并等待退出 输入数据 储存输入 放弃输入 开始 开始 启动 启动 启动 启动 写控制字 写控制字 应答 启动 应答 启动 8位地址 8位地址 应答 启动 应答 启动 启动 启动 写数据 写控制字 应答 启动 应答 启动 停止 启动 读一字节 非应答 启动 停止 启动 开始 有键按下吗? 返回值0xff 键盘行列扫描 延时 按键松开? 查找键值 返回键值 开始 第一位小于10显示,大于 10则不显示 第二位小于10显示,大于 10则不显示 第三位小于10显示,大于 10则不显示 第四位小于10显示,大于 10则不显示 返回
/
本文档为【IC读卡器设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索