IIC读卡器设计.docx

上传人:b****3 文档编号:10515451 上传时间:2023-05-26 格式:DOCX 页数:33 大小:422.20KB
下载 相关 举报
IIC读卡器设计.docx_第1页
第1页 / 共33页
IIC读卡器设计.docx_第2页
第2页 / 共33页
IIC读卡器设计.docx_第3页
第3页 / 共33页
IIC读卡器设计.docx_第4页
第4页 / 共33页
IIC读卡器设计.docx_第5页
第5页 / 共33页
IIC读卡器设计.docx_第6页
第6页 / 共33页
IIC读卡器设计.docx_第7页
第7页 / 共33页
IIC读卡器设计.docx_第8页
第8页 / 共33页
IIC读卡器设计.docx_第9页
第9页 / 共33页
IIC读卡器设计.docx_第10页
第10页 / 共33页
IIC读卡器设计.docx_第11页
第11页 / 共33页
IIC读卡器设计.docx_第12页
第12页 / 共33页
IIC读卡器设计.docx_第13页
第13页 / 共33页
IIC读卡器设计.docx_第14页
第14页 / 共33页
IIC读卡器设计.docx_第15页
第15页 / 共33页
IIC读卡器设计.docx_第16页
第16页 / 共33页
IIC读卡器设计.docx_第17页
第17页 / 共33页
IIC读卡器设计.docx_第18页
第18页 / 共33页
IIC读卡器设计.docx_第19页
第19页 / 共33页
IIC读卡器设计.docx_第20页
第20页 / 共33页
亲,该文档总共33页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

IIC读卡器设计.docx

《IIC读卡器设计.docx》由会员分享,可在线阅读,更多相关《IIC读卡器设计.docx(33页珍藏版)》请在冰点文库上搜索。

IIC读卡器设计.docx

IIC读卡器设计

 

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.24X4矩阵键盘电路

矩阵键盘又称行列式键盘。

用I/O口线组成行列结构,按键设置在行列交点上。

N条口线最多可构造N²个按键。

4X4的行列结构可构成16个键的键盘,如图2.2所示。

无按键时各行各列彼此相交而不相连。

由行列线的电平状态可以识别唯一与之相连的按键,此过程成为读键值。

图2.24x4矩阵键盘

键盘读键采用反转读键法。

第一步:

先置行线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.1I²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)无应答信号(NOACK)

在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个NOACK,NOACK有两种用途:

a、一般表示接收器未成功接收数据字节;b、当接收器是主控器时,它收到最后一个字节后,应发送一个NOACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。

2.4.2E²PROM芯片

24C02是2KB二线制I²C串行E²PROM,其特征码为1010B。

模块的电路图如图2.6所示。

图2.6模块电路连接

写数据过程:

写操作时,SDA线上的信号依次为:

启动START1010B2B1B0(0~111B)0低电平为写操作应答ACK8位的地址ACK数据0ACK……数据15应答ACK结束STOP.

24C02每一次写操作最多可连续写8字节(一页),也可以少于8字节。

一旦停止信号被接收到,则24C02内部写周期将开始。

在内部写周期期间,不响应外部信号,直到写周期完成。

如图2.7所示为24系列存储器写周期时序图。

图2.724c02页写入方式

2)读数据过程:

读操作时,SDA线上的信号依次为:

启动START1010B2B1B0(0~111B)0低电平为写操作应答ACK8位的地址ACKSTART1010B2B1B0(0~111B)1高电平为读操作应答ACK数据0ACK……数据N非应答NOACK结束STOP

在读数据之前,先写入要读的数据所在的地址。

然后,主器件在“应答”位后产生一个启动信号,以终止刚才的写地址操作。

随后主器件再次发出控制字,R/W位为1,。

24C02接收“应答”信号后,便可读数据,可以读一字节、两字节、……N字节的数据。

读完最后一个数据后,主器件发出“非应答”(NOACK)信号和停止(STOP)信号。

如图2.8所示为24系列存储器读操作时序图。

图2.824c02读时序

3软件设计

3.1软件总体流程

软件的设计主要包括:

数据从I²C器件的读写,键盘反转读键,数码管扫描显示,数据读取储存逻辑等。

其总体流程图如图3.1所示。

 

 

CD

任意键

 

EF

 

图3.1程序总体流程

3.2I²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"

voidmain(void)

{

unsignedcharkey;

unsignedcharcount,t;

unsignedcharge,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"

 

voiddelay(void)//延时函数

{

unsignedchari,j;

for(i=0;i<10;i++)

for(j=0;j<248;j++)_nop_();

}

voidstart(void)//起始函数

{

sdak=1;

_nop_();

sclk=1;

_nop_();

_nop_();

_nop_();

_nop_();

sdak=0;

_nop_();

_nop_();

_nop_();

sclk=0;

_nop_();

}

voidstop(void)//停止子函数

{

sdak=0;

sclk=1;

_nop_();

_nop_();

_nop_();

_nop_();

sdak=1;

_nop_();

_nop_();

_nop_();

_nop_();

sclk=0;

_nop_();

_nop_();

}

voidtack(void)//iic响应子函数

{

sdak=0;

_nop_();

sclk=1;

_nop_();

_nop_();

_nop_();

_nop_();

sclk=0;

_nop_();

_nop_();

_nop_();

}

voidnotack(void)//iic非响应子函数

{

sdak=1;

_nop_();

_nop_();

sclk=1;

_nop_();

_nop_();

_nop_();

_nop_();

sclk=0;

_nop_();

_nop_();

}

voidwrbyt(unsignedchara)//iic写数据

{

unsignedcharb;

unsignedchari=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;

}

}

unsignedcharrdbyt(void)//iic读数据函数

{

unsignedchari=8;

unsignedcharrdd;

while(i--)

{

sdak=1;

sclk=1;

rdd<<=1;

_nop_();

_nop_();

if(sdak==1)

{rdd|=0x01;}

else

{rdd&=0xfe;}

sclk=0;

}

returnrdd;

}

unsignedcharread_add(unsignedcharaddress)//iic读一个字节

{

unsigneda;

start();

wrbyt(0xa0);

tack();

wrbyt(address);

tack();

start();

wrbyt(0xa1);

tack();

a=rdbyt();

notack();

stop();

returna;

}

voidwrite_add(unsignedcharaddress,unsignedchardate)//iic写入一字节

{

start();

wrbyt(0xa0);

tack();

wrbyt(address);

tack();

wrbyt(date);

tack();

stop();

delay();

delay();

delay();

}

at24c02.h

#ifndef__AT24C02_H__

#define__AT24C02_H__

sbitsclk=P3^2;//iic数据口定义

sbitsdak=P3^3;

externvoidwrite_add(unsignedcharaddress,unsignedchardate);//向固定地址写入一个字节数据

externunsignedcharread_add(unsignedcharaddress);//读取某个固定地址一个字节数据

#endif

Key.c///////////////////////////////////////////////////////////////

/*反转法读键值IO口使用P2*/

#include

#include"key.h"

 

voiddelayms(unsignedintxms)

{

unsignedinti,j;

for(i=xms;i>0;i--)

for(j=110;j>0;j--);

}

//键值对应表

unsignedchardatakey_tab[]={0x11,0x21,0x41,0x81,0x12,0x22,0x42,0x82,0x14,0x24,0x44,0x84,0x18,0x28,0x48,0x88};

/*函数:

keyscan()

功能:

从矩阵键盘中读取键值

参数:

返回:

kunsignedchar型

说明:

k值大于15时代表没有按下按键

*/

unsignedcharKeyScan(void)

{

unsignedchari;

unsignedcharj;

unsignedchark;//返回值

P2=0x0f;

i=P2;

i=(~i)&0x0f;

if(i==0)return255;

P2=0xf0;

j=P2;

j=(~j)&0xf0;

if(j==0)return255;

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;

}

returnk;

}

Key.h/////////////////////////////////////////////////////////////

#ifndef__KEY_H__

#define__KEY_H__

externunsignedcharKeyScan(void);

#endif

Led.c/////////////////////////////////////////////////////////

#include

#include"led.h"

unsignedintdataseg_7[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};

voidLedDelay(unsignedinti)//大约延时i*2个微秒

{while(--i);}

/*

函数:

LedShow()

功能:

传入一个4位的整型数,在4位数码管上显示

*/

voidLedShow(unsignedcharge,unsignedcharshi,unsignedcharbai,unsignedcharqian)

{

if(qian<10)

{

P0=seg_7[qian];//段选数码管

P3=0x7F;//位选数码管

Led

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2