加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > 技术文章

ATMEL接触式IC卡及开发实例

时间:2012-11-29  来源:123485.com  作者:9stone

设备设置寄存器(DCR)
设备设置寄存器位于设置区的$18地址,存储结构:(使能为“0”,默认为“1”)
位7 位6 位5 位4 位3 位2 位1 位0
SME UCR UAT ETA CS3 CS2 CS1 CS0
CS0-CS3:可编程片选。ATMEL出厂时写为$B(即1011)。它为访问卡的所有命令字的高4位。
ETA:8次计数使能。ETA=0,可以使AAC和PAC的计数次数为8,否则为4。
UAT:使认证错误计数无校标志。UAT=0,AAC无校,否则AAC有校。
UCR:不限制读校验和次数标志。UCR=1时,每次认证只能读校验和方式一次(默认),UCR=0时,没有次数限制。
SME:超级管理方式。SME=0时,通过1WP校验,就可以读写全部的读写密码及密码错误计数器。

认证协议
产出随机数Nc(往往当作卡号)和Ci,计算出Gc=F1(Ks,Nc),把Nc、Ci、Gc写入卡中
卡 Nc Gc Ci 认证协议 读写器 Ks Q0(随机数)
识别码: Nc Ci Ci+1=F2(Gc,Ci,Q0); if(Ci+1==Q1) Ci+2=F2(Gc,C1+1); Ci=Ci+2; //修改Ci 认证正确; else Ci=Ci; 认证错误; Ci (使用读命令) (初始化认证命令) (校验认证命令) (读命令) Gc=F1(Ks,Nc); Q0 Q1=F2(Gc,Ci,Q0); Q1 Q2=F2(Gc,Q1); if(Q2=Ci) 认证正确; else 认证错误;
F1算法:64BIT 用户自定义算法。
F2算法:卡内64BIT 算法(Des 算法的变种,提供C语言和51汇编语言程序)
该协议包括卡和读写器CPU的互相认证(ELVA专利),而且认证数据加密传送,可以防止通讯数据被窃取。

下面的伪码程序在AT88SC153卡完成初始化操作和在一应用区ADDR地址开始写LEN个字节,并读出校对。
Open(AT88SC153)
IF CheckSC(Pwd) = OK THEN 继续 ELSE 非法卡
WriteIC(IC) ;写发布号
WriteDCR(DCR)
InitAuth(Nc,Ci,Gc)
SetZone(1)
SetAR(AR)
UpdateWP(NewWP)
UpdateRP(NewRP)
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Fuse()
Close()

下面的伪码程序判断AT88SC153卡是否是本系统支持的卡和对一应用区ADDR地址开始的LEN个字节完成某种操作。
Open(AT88SC153)
ReadIC(IC) ;读出发布号
if IC = 发布号 THEN 继续 ELSE 非法卡
CheckAuth(Gc)
SetZone(1)
IF CheckRP(Pwd) = OK THEN 继续 ELSE 非法卡
RDATA = Read(ADDR,LEN)
<一些其它操作>
IF CheckWP(Pwd) = OK THEN 继续 ELSE 非法卡
Write(ADDR,LEN,WDATA)
RDATA = Read(ADDR,LEN)
IF WDATA = RDATA THEN 写成功 ELSE 写失败
Close()
三、AT45D041
这种型号的IC卡为ATMEL存储卡,是一种不具备加密功能大容量的FLASH 存储卡,存储容量为4M位,主存储区有2048页(每页容量为264字节),同时还提供两个独立双向的数据缓存区(每个数据缓存区容量为264字节),页写方式为264字节,页写入时间为7ms。存储结构简单,主要用于存放一些保密性要求不高、数据量极大的数据,如声音、图像或数据。
AT45D041的工作频率为10MHz(最大);工作电压为5V±10%;工作电流读为25mA,写为50mA;数据保持100年;工作温度为0—70℃,根据要求可超过指定工作温度;通讯协议为SPI串行接口方式0和方式3。

缓存区1、缓存区2和主存储区的读写方式如上图所示,分别为:
1. 直接从主存储区的某页读数据;
2. 把主存储区的某页数据写入缓存区1或缓存区2;
3. 把主存储区的某页数据和缓存区1或缓存区2的数据进行比较;
4. 把缓存区1或缓存区2的数据写入主存储区的某页(带内建式擦除);
5. 把缓存区1或缓存区2的数据写入主存储区的某页(不6. 带内建式擦除);
7. 把数据写入主存储区的某页;
8. 自动页回写;
9. 读缓存区1、缓存区2;
10. 写缓存区1、缓存区2;
11. 读状态位。

状态位结构:
位7 位6 位5 位4 位3 位2 位1 位0
忙闲 比较 0 1 1 x x x
注:位7为0表示忙;为1表示闲,可以接收下一条指令。
位6为0表示主存储区数据与缓存区比较匹配,否则为不匹配。
位5、位4、位3对于AT45D041为“011”(二进制)。

下面的伪码程序通过AT45D041卡的缓存1更新主存储区的页1的某些数据:
OpenCard(AT45D041)
SetPage(1)
SetBuff(1)
PageToBuff()
WHILE ReadStatus() = Busy LOOP
WriteBuff(Addr,Len,cData)
BuffToPage()
WHILE ReadStatus() = Busy LOOP
AutoRWrite()
WHILE ReadStatus() = Busy LOOP
Close()

OpenCard(AT45D041)
SetPage(1)
SetBuff(1)
WritePage(Addr,Len.cData)
WHILE ReadStatus() = Busy LOOP
AutoRWrite()
WHILE ReadStatus() = Busy LOOP
Close()

下面的伪码程序通过AT45D041卡的缓存1页写主存储区的页1:
OpenCard(AT45D041)
SetPage(1)
SetBuff(1)
WriteBuff(0,264,cData)
BuffToPage()
WHILE ReadStatus() = Busy LOOP
Close()

OpenCard(AT45D041)
SetPage(1)
SetBuff(1)
WritePage(0,264.cData)
WHILE ReadStatus() = Busy LOOP
Close()

注:本章内容可为用户在接触式IC卡选型时参考。


第二章 接触式IC卡的接口函数
IC卡软件应用系统的开发是在读写器提供的接口函数基础上进行软件开发的。每个系统公司的接口函数虽有不同,但大同小异。下面以德诚系统有限公司的MCS-C接触式IC卡通用读写器提供的FoxPro for DOS的PLB接口函数为例,用户由此可基本上对接触式IC卡接口函数有所了解。
在FoxPro程序执行开始前,先执行语句SET LIBRARY TO ICFOX.PBL。FoxPro将会自动登录库ICFOX.PLB中的IC卡函数,您可以象使用FoxPro的内部函数一样的使用接口函数。编译成EXE文件时,将ICFOX.PLB链入。
1、 函数列表(函数名2? , 简单说明)
1. 通用函数
InitComm 初始化指定的串口并连接读写设备
ExitComm 退出串口连接
ErrorMsg 返回错误信息
GetInfo 获取设备的版本号

TestCard 测试读写器内是否插卡
OpenCard 打开对某种型号卡的操作
ReadChr 从卡上指定地址读取指定长度的字符串
WriteChr 向卡内指定地址写入指定长度的字符串
ReadInt 从卡上指定地址读取一个双精度数
WriteInt 向卡内指定地址写入一个双精度数
CloseCard 关闭卡操作
2? ATMEL AT88SC102/AT88SC1604加密卡专用函数
ReadFZ 读厂商代码
ReadIZ 读卡商代码
ReadCPZ 读代码保护区
WriteCPZ 写代码保护区
ReadMTZ 读测试区
WriteMTZ 写测试区

SetZone 选择应用区
CheckSC 比较密码(或区密码)
UpdateSC 更新密码(或区密码)
ReadSCAC 读密码(或区密码)校验错误计数
CheckEZ 比较区擦除密码
UpdateEZ 更新区擦除密码
ReadEAC 读区擦除密码校验错误计数
Erase 从卡内指定位置起擦除指定长度字节

Fuse 烧断卡上熔丝
3? ATMEL AT88SC1608及AT88SC153加密卡专用函数
ReadFZ 读厂商代码
ReadIZ 读卡商代码
ReadIC 读发布号(AT88SC153专用)
WriteIC 写发布号(AT88SC153专用)
ReadDCR 读设备设置寄存器(AT88SC153专用)
WriteDCR 写设备设置寄存器(AT88SC153专用)
ReadMTZ 读测试区
WriteMTZ 写测试区

InitAuth 初始化认证状态
CheckAuth 认证校验
ReadAAC 读认证错误计数

CheckSC 比较传输密码
UpdateSC 更新传输密码
ReadSCAC 读传输密码校验错误计数

SetZone 选择应用区
ReadAR 读应用区的访问权限
WriteAR 设置应用区的访问权限

CheckWP 比较写密码
UpdateWP 更新写密码
ReadWPAC 读写密码校验错误计数
CheckRP 比较读密码
UpdateRP 更新写密码
ReadRPAC 读读密码校验错误计数

FuseStatus 读取卡内熔丝状态
Fuse 烧断卡上熔丝
4? ATMEL AT45D041 Flash存储卡专用函数
SetPage 选择主存储区的当前页
SetBuff 选择缓冲区
ReadPage 读取主存储区页内的字符
ReadBuff 读取缓冲区1/缓冲区2内的字符
WritePage 写字符到主存储区页
WriteBuff 写字符到缓冲区1/缓冲区2
CompPB 比较主存储区页与缓冲区1/缓冲区2的内容
PageToBuff 从主存储区页提取数据到缓冲区1/缓冲区2
BuffToPage 从缓冲区1/缓冲区2写数据到主存储区页
ReadStatus 读状态字(忙闲)
AutoRWrite 自动回写
3、 函数说明
InitComm(Port)
说明:初始化指定的串口并连接读写设备。
参数:Port----串口标号,整数0,1分别代表串口1,串口2。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = InitComm(0) 初始化串口1。

ExitComm()
说明:退出串口连接。
参数:无。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = ExitComm() 退出串口。

ErrorMsg(ErrNo)
说明:返回错误信息。
参数:错误号。
返回值: 错误信息。
举例:Msg = ErrorMsg(0) 返回“成功”。

GetInfo()
说明:获取设备的版本号。
参数:无。
返回值: 设备的版本号。
举例:Vno = GetInfo()。

TestCard()
说明:测试读写器内是否插卡。
参数:无。
返回值: =0,正确。
<0,读写器内没有插卡。返回值代表错误号。
举例:Ret = TestCard()

OpenCard(CardType)
说明:打开对某种型号卡的操作
参数:CardType----IC卡类型。具体值参见附录一。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = OpenCard(AT24C01A) 选择卡型为AT24C01A。

ReadChr(Addr,Len)
说明:从卡上指定地址读取指定长度的字符串。
参数:Addr----读操作的卡内起始地址。
Len----字符串长度。
返回值:从卡上读取的字符串。
读操作出错。返回""。
举例:cData = ReadChr(0, 10) 从卡上应用区地址0读取10个字符。

WriteChr(Addr,Len,cData)
说明:将指定长度的字符串写入到卡片的指定起始地址上。
参数:Addr----写操作的卡内起始地址。
Len----字符串长度。
cData----要向卡片写入的字符串。
返回值: =0,正确。
<0,写操作出错。返回值代表错误号。
举例:Ret = WriteChr(0, 14, "Testing MCS-C!") 将字符串写入卡地址0处。

ReadInt(Addr)
说明:从卡上指定的起始地址读取一个双精度数。
参数:Addr----读操作的卡内起始地址。
返回值:从卡上读取的双精度数。
举例:iData = ReadInt(0) 从卡上应用区地址0读取双精度数。

WriteInt(Addr,iData)
说明:将一个双精度数写入到卡内指定起始地址处。
参数:Addr----写操作的卡内起始地址。
iData----要向卡内写入的双精度数。
返回值: =0,正确。
<0,写操作出错。返回值代表错误号。
举例:Ret = WriteInt(0, 12345.6789) 将12345.6789写入到卡内地址0处。

CloseCard()
说明:关闭卡操作
参数:无。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = CloseCard()

ReadFZ()
说明:读厂商代码。
参数:无。
返回值:从卡上读取厂商代码(16进制字符串)。
读操作出错。返回""。
举例:FZ = ReadFZ()

ReadIZ()
说明:读卡商代码。
参数:无。
返回值:从卡上读取卡商代码(16进制字符串)。
读操作出错。返回""。
举例:IZ = ReadIZ()

ReadCPZ()
说明:读代码保护区。
参数:无。
返回值:从卡上读取代码保护区(16进制字符串)。
读操作出错。返回""。
举例:CPZ = ReadCPZ()

WriteCPZ(CPZ)
说明:写代码保护区。
参数:长度为为16个字节的字符串(16进制字符串)。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = WriteCPZ("0123456789ABCDEF")

ReadMTZ()
说明:读测试区。
参数:无。
返回值:从卡上读取代码保护区(16进制字符串)。
读操作出错。返回""。
举例:MTZ = ReadMTZ()

WriteMTZ(MTZ)
说明:写测试区。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<>0,出错。返回值代表错误号。
举例:Ret = WriteMTZ("ABCDEF")

SetZone(Zone)
说明:选择应用区。
参数:Zone----要选择的应用区号。0-n代表应用区0至应用区n。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = SetZone(1)

CheckSC(SC)
说明:比较密码(或区密码)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckSC("FFFF")

UpdateSC(SC)
说明:更新密码(或区密码)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = UpdateSC("9999")

ReadSCAC()
说明:读密码(或区密码)校验错误计数。
参数:无。
返回值:密码校验错误计数值。
举例:SCAC = ReadSCAC()

CheckEZ(EZ)
说明:比较擦除密码(或区擦除密码)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckEZ("FFFF")

UpdateEZ(EZ)
说明:更新擦除密码(或区擦除密码)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = UpdateEZ("9999")

ReadEZAC()
说明:读擦除密码(或区擦除密码)校验错误计数。
参数:无。
返回值:密码校验错误计数值。
举例:EZAC = ReadEZAC()

Erase(Addr,Len)
说明:从指定位置起擦除指定长度的字节。
参数:Addr----要擦除的起始地址。
Len----要擦除的长度。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = Erase(0, 10)

Fuse()
说明:烧断卡上熔丝。
参数:无。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = Fuse()

ReadIC()
说明:读发布号(AT88SC153专用)。
参数:无。
返回值:发布号(16进制字符串)。
举例:Ret = ReadIC()

WriteIC(IC)
说明:写发布号(AT88SC153专用)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = WriteIC("012456789ABCDEF")

ReadDCR()
说明:读设备设置寄存器(AT88SC153专用)。
参数:无。
返回值:设备设置寄存器的值(16进制字符串)。
举例:Ret = ReadDCR()

WriteDCR(DCR)
说明:写设备设置寄存器(AT88SC153专用)。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = WriteDCR("FF")

InitAuth(Nc,Ci,Gc)
说明:初始化认证协议。
参数:Nc----识别码。
Ci----密文。
Gc----密钥。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = InitAuth(Nc,Ci,Gc)

CheckAuth(Gc)
说明:认证协议。
参数:Gc----密钥。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckAuth(Gc)

ReadAAC()
说明:读认证错误计数。
参数:无。
返回值:认证校验错误计数值。
举例:AAC = ReadAAC()

ReadAR()
说明:读应用区的访问权限。
参数:无。
返回值:当前访问区权限字节(16进制字符串)。
举例:AR = ReadAR()

WriteAR(AR)
说明:设置应用区的访问权限。
参数:AR----当前访问区权限字节(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = WriteAR("FF")

CheckWP(WP)
说明:比较当前区写密码。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckWP("FFFFFF")

UpdateWP(WP)
说明:更新当前区写密码。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = UpdateWP("999999")

ReadWPAC()
说明:读当前区写密码校验错误计数。
参数:无。
返回值:当前区写密码校验错误计数值。
举例:WPAC = ReadWPAC()

CheckRP(RP)
说明:比较当前区读密码。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = CheckRP("FFFFFF")

UpdateRP(RP)
说明:更新当前区读密码。
参数:字符串(16进制字符串)。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = UpdateRP("999999")

ReadRPAC()
说明:读当前区读密码校验错误计数。
参数:无。
返回值:当前区读密码校验错误计数值。
举例:RPAC = ReadRPAC()

FuseStatus()
说明:读取卡内熔丝状态
参数:无。
返回值: =0,已熔。
=1,未熔。
举例:PER = FuseStatus()

SetPage(Page)
说明:选择主存储区的当前页。
参数:Page----要选择的页号。1-n代表页1至页n。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = SetPage(1)

SetBuff(Buff)
说明:选择缓冲区。
参数:Buff----要选择的缓冲区。1,2代表缓冲区1,缓冲区2。
返回值: =0,正确。
<0,出错。返回值代表错误号。
举例:Ret = SetBuff(1)

ReadPage(Addr,Len)
说明:读取主存储区页内的字符。
参数:Addr----要读取的起始字节地址。
Len----要读取的长度。
返回值:返回的数据字符串。
举例:cData = ReadPage(0,10)

ReadBuff(Addr,Len)
说明:读取缓冲区内的字符。
参数:Addr----要读取的起始字节地址。
Len----要读取的长度。
返回值:返回的数据字符串。
举例:cData = ReadBuff(0,10)

WritePage(Addr,Len,cData)
说明:写字符到主存储区页。
参数:Addr----要写入的起始字节地址。
Len----要写入的长度。
cData----用于存放写入卡片的数据的字符串。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = WritePage(0,10,"1234567890")

WriteBuff(Addr,Len,cData)
说明:写字符到缓冲区。
参数:Addr----要写入的起始字节地址。
Len----要写入的长度。
cData----用于存放写入缓冲区的数据的字符串。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = WriteBuff(0,10,"1234567890")

CompPB()
说明:比较主存储区页与缓冲区的内容。
参数:无。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = CompPB()

PageToBuff()
说明:主存储区内容向缓冲区传送。
参数:无。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = PageToBuff()

BuffToPage()
说明:从缓冲区写数据到主存储区页。
参数:无。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = BuffToPage()

ReadStatus()
说明:读状态字(忙闲)
参数:无。
返回值: =0,闲。
<0,返回值代表忙或错误号。
举例:Ret = ReadStatus()

AutoRWrite()
说明:自动回写。
参数:无。
返回值: =0,正确。
<0,返回值代表错误号。
举例:Ret = AutoRWrite()
附录一:卡类型预定义
AT24C01 = 0
AT24C01A = 1
AT24C02 = 2
AT24C04 = 3
AT24C08 = 4
AT24C16 = 5
AT24C32 = 6
AT24C64 = 7
AT24C128 = 8
AT24C256 = 9

AT88SC102 = 12
AT88SC1604_E = 15
AT88SC6603 = 15
AT88SC1604_N = 16
AT88SC6601 = 16
AT88SC1608 = 17
AT88SC153 = 18

AT45D041 = 23
附录二:ICFOX.PLB测试例程
SET TALK OFF
SET LIBR TO ICFOX
? ErrorMsg(InitComm(0))
? ErrorMsg(TestCard(0))
? ErrorMsg(OpenCard(1))
? ErrorMsg(WriteChr(0,10,”0123456789”))
rData=ReadChr(0,10)
=Close()
IF rData <> “0123456789”
? “读卡错误”
ELSE
? “测试正常”
ENDIF
RETURN
第三章 接触式IC卡底层软件开发实例
对了更好地说明接触式IC卡读写器是如果工作的,本章公布了部分德诚系统有限公司MCS-C读写器低层CPU的C51程序,包括了IC卡操作底层函数,以AT24C64卡为例的实例程序。这些程序是根据德诚系统有限公司实际使用的函数向用户公开的,也可供其它打算生产接触式IC卡读写器的厂家参考,以便开发自已的IC卡驱动函数。
??2 IC卡操作底层函数
1? IC卡操作底层函数说明:
IC卡座的引脚定义示意图如下:

VCC [C1] [C5] GND
RESET [C2] [C6] No Use
CLK [C3] [C7] I / O
FUS [C4] [C8] PGM

void _CardSetPower(uchar Level);
功能:将IC卡读写器Vcc段上电或下电。
输入:Level
当Level=1,给IC卡读写器上电。
当Level=0,给IC卡读写器下电。
输出:无

void _CardSetReset(uchar Level);
功能:置IC卡读写器Reset高或低。
输入:Level
当Level=1,给IC卡读写器Reset端置高。
当Level=0,给IC卡读写器Reset端置低。
输出:无

void _CardSetClock(uchar Level);
功能:置IC卡读写器Clock高或低。
输入:Level
当Level=1,给IC卡读写器Clock置高。
当Level=0,给IC卡读写器Clock置低。
输出:无

void _CardSetPGM(uchar Level);
功能:置IC卡读写器PGM高或低。
输入:Level
当Level=1,给IC卡读写器PGM置高。
当Level=0,给IC卡读写器PGM置低。
输出:无

void _CardSetFUS(uchar Level);
功能:置IC卡读写器FUS高或低。
输入:Level
当Level=1,给IC卡读写器FUS置高。
当Level=0,给IC卡读写器FUS置低。
输出:无

void _CardPutIO(uchar IOData);
功能:将数据由IC卡读写器IO端输出。
输入:IOData输出数据,值是0或1。
输出:无

uchar _CardReadIO();
功能:读取IC卡读写器IO端数据
输入:无
输出:IC卡输出的数据,值是0或1。
2? IC卡低层通讯头文件(Base.h)
低层通讯函数用户可根据自已的设备编写。
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
/****************************************************
IC卡低层通讯头文件:
****************************************************/
void _CardSetPower(uchar Level);
void _CardSetReset(uchar Level);
void _CardSetClock(uchar Level);
void _CardSetPGM(uchar Level);
void _CardSetFUS(uchar Level);
void _CardPutIO(uchar IOData);
uchar _CardReadIO();
2? AT24C64卡应用实例
1.AT24C64卡函数头文件(AT24C64.h)
/****************************************************
the AT24C64 Card Declare:
****************************************************/
uchar AT24C64_Open();
uchar AT24C64_Read(uint Addr,uint DataLen,uchar *DataBuff);
uchar AT24C64_Write(uint Addr,uint DataLen,uchar* DataBuff);
uchar AT24C64_Close();
2.AT24C64卡函数
//**********************************************************
//* This is source of 24C64.LIB *
//* This program demo how to program 24C64.LIB *
//**********************************************************
#include <Base.h>
#include <AT24C64.h>

void AT24C64_Pulse();
void AT24C64_Start();
void AT24C64_Stop();
void AT24C64_OutB(uchar OutData);
uchar AT24C64_InB();

/*******************************
This function used by the
external user's function
*******************************/
void AT24C64_Pulse()
{
_CardSetClock(1);
_CardSetClock(0);
}
void AT24C64_Start()
{
_CardPutIO(1); _CardSetClock(1);
_CardPutIO(0); _CardSetClock(0);
}
void AT24C64_Stop()
{
_CardPutIO(0); _CardSetClock(1);
_CardPutIO(1); _CardSetClock(0);
}

void AT24C64_OutB(uchar OutData)
{
uchar i;
for (i = 0;i < 8;i++)
{
if ( (OutData & 0x80) == 0x80 ) _CardPutIO(1); else _CardPutIO(0);
AT24C64_Pulse(); OutData = OutData << 1;
}
_CardPutIO(1); AT24C64_Pulse();
}

uchar AT24C64_InB()
{
uchar i,InData = 0;
for (i = 0;i < 8;i++)
{
InData = InData << 1; _CardSetClock(1);
InData = InData + _CardReadIO(); _CardSetClock(0);
}
return InData;
}

/***************************************
This function used by user
****************************************/
// open card
uchar AT24C64_Open()
{
uchar i,InData,TmpSt[10];
_CardSetPower(1);
_CardSetClock(0);
_CardSetReset(0);
_CardSetReset(1);
_CardPutIO(1);
AT24C64_Pulse();
_CardSetReset(0);
for(i = 0;i < 4;i++) TmpSt[i] = AT24C64_InB();
if (TmpSt[0] == 0xFF) return 1;
if (TmpSt[1] == 0xFF) return 1;
if (TmpSt[2] == 0xFF) return 1;
if (TmpSt[3] == 0xFF) return 1;
return 0;
}

uchar AT24C64_Read(uint Addr,uint DataLen,uchar *DataBuff)
{
uint i;

_CardSetReset(1); _CardSetReset(0);
AT24C64_Start();
AT24C64_OutB(0xA0);
AT24C64_OutB((uchar)(Addr >> 8));
AT24C64_OutB((uchar)Addr);
AT24C64_Start();
_CardPutIO(1);
AT24C64_OutB(0xA1);
for (i = 0;i < DataLen;i++) {
*(DataBuff + i) = AT24C64_InB();
_CardPutIO(0); AT24C64_Pulse(); _CardPutIO(1);
}
AT24C64_Stop();
for (i = 0;i < 32; i++) AT24C64_Pulse();
return 0;
}

uchar AT24C64_Write(uint Addr,uint DataLen,uchar* DataBuff)
{
uint i;

for (i = 0;i < DataLen;i++) {
AT24C64_Start();
AT24C64_OutB(0xA0);
AT24C64_OutB((uchar)((Addr + i) >> 8));
AT24C64_OutB((uchar)(Addr + i));
AT24C64_OutB(*(DataBuff + i));
AT24C64_Stop();
_Delay(20);
}
return 0;
}

uchar AT24C64_Close()
{
// set power pin low
_CardPutIO(0);
_CardSetClock(0);
_CardSetReset(0);
_CardSetPower(0);
return 0;
}
3? AT24C64卡应用例程(App24C64.c)
#include<AT24C64.h>

uchar _App24C64(uchar *cData)
{
AT24C64_Open();
AT24C64_Write(0x0050, 16,cData);
AT24C64_Close();

AT24C64_Open();
AT24C64_Read(0x0050, 16,cData);
AT24C64_Close();

return 0x00;
}

第一章 ATMEL CPU卡简介
AT89SC系列是低电压、高性能的8位微处理器。内含可编程的FLASH、只可一次编程的内存单元(PEROM)和电可擦写数据存储单元(EEPROM)。该89SC系列产品运用ATMEL的高密度CMOS工艺制造,同工业标准的80C51和80C52指令集相兼容。
AT90SC系列产品与ATMEL的AVR指令集相兼容,内部带有协处理器。
通过将FLASH和一个多性能的8位微处理器集成在单一片上,AT89SC/90SC系列为多种智能卡的应用提供了高度灵活和性能完备的解决方案。
值得一提的是,AT89SC/90SC具有专为智能卡应用而设计的特性:如符合ISO7816标准的串行接口,随机数发生器,电源和频率保护逻辑。

Device Name Flash EEPROM RAM
AT89SC168 16 K bytes 8 K bytes 256 bytes
AT89SC168A 16 K bytes 8 K bytes 512 bytes
AT89SC1616A 16 K bytes 16 K bytes 512 bytes
AT90SC3232 32 K bytes 32K bytes 1.5Kbytes
AT90SC3232C (协处理器) 32 K bytes 32K bytes 1K bytes

分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->技术文章
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门