AT89S8252单片机实现接触式IC卡读写控制的设计

发布时间:2023-08-01  

从上高中开始,我们学校用的餐卡就为接触式的IC卡,在校园里还分布着很多的IC卡电话,上大学以后学校使用的校园一卡通,为非接触式是射频式IC卡,因此对IC卡有了兴趣,在学习单片机的过程中,了解到单片机可以实现IC卡的读写控制,在参考有关资料的基础上,学习的利用单片机实现接触式的IC卡读写控制。


主要器件:

1、 AT89S8252单片机芯片,此芯片具有SPI接口,可以用来读写IC卡芯片。

2、 使用与SPI接口兼容的串行数据接口的IC卡芯片AT45D041A,支持在系统重编程,可用于数字语音、图像和数据的存储。

试验流程图:

AT89S8252单片机实现接触式IC卡读写控制的设计

试验电路图:

AT89S8252单片机实现接触式IC卡读写控制的设计

试验程序代码:

//ICRdWr.h程序

#ifndef _ICRDWR_H // 防止ICRdWr.h被重复引用

#define _ICRDWR_H

#include // 重要的头文件引用

#define uchar unsigned char

#define uint unsigned int

/* 指令宏定义 */

#define BUFFER_1_WRITE 0x84 // buffer1写指令代码

#define B1_TO_MM_PAGE_NO_ERA 0x88 // 无在线擦除的buffer1写主内存页指令代码

#define MM_PAGE_READ 0xD2 // 主内存页读指令代码

#define STAT_REG_READ 0xD7 // 状态寄存器读指令代码

#define DATA_IN_MAX_LEN 8

#define DATA_OUT_MAX_LEN 8

uint page_start_addr; // 页中起始字节地址

uint page_addr; // 页地址,16位中低9位为有效位

uint buf_start_addr; // buffer中起始字节地址,16位中低11位为有效位

uchar data_in[DATA_IN_MAX_LEN]; // 要写入IC卡的数据

uchar data_out[DATA_OUT_MAX_LEN]; // 要从IC卡中读出的数据

#endif

//ICRdWr.c程序

#include “ICRdWr.h”

/* 延时t毫秒 */

void delay(uint t)

{

uint i;

while(t--)

{

/* 对于11.0592M时钟,约延时1ms */

for (i=0;i《125;i++)

{}

}

}

/* 获取需要存入IC卡数据的函数*/

void getdata()

{

// 此函数简化如下:

uchar i;

for (i=0;i《8;i++)

data_in[i]=i+1;

}

/* 写单片机AT89S8252的SPDR寄存器,数据通过SPI口串行输出给IC卡芯片 */

void write_spi(uchar dat)

{

SPDR = dat;

while (!(SPSR & 0x80)) ; // 等待一次传输完成

}

/* 获取IC卡芯片状态函数 */

uchar IC_stat(void)

{

P1_1 = 0; // 使能IC卡芯片;/cs=0

write_spi(STAT_REG_READ); // 写入读IC卡芯片状态指令

write_spi(0x00); // 写无关比特

P1_1 = 1; // 禁用IC卡芯片;/cs=1

return SPDR; // 返回IC卡芯片状态字节

}

/* 写IC卡芯片函数:将数据写入buffer,如果buffer满,

则将buffer中数据写入主内存页 */

void write_to_IC(uchar dat)

{

uchar stat;

/* 检查IC卡芯片是否忙 */

stat = IC_stat();

while ((stat&0x80)==0x00);

/* 数据写入buffer */

P1_1 = 0; // 使能IC卡芯片;/cs=0

write_spi(BUFFER_1_WRITE); // buffer1写指令代码

write_spi(0x00); // 写入8位无关位

write_spi((uchar)(buf_start_addr》》8)); // 写入7位无关位加上9位buffer起始字节地址的第1位

write_spi((uchar)buf_start_addr); // 写入9位buffer起始字节地址的后8位

write_spi(dat); // 写入数据

P1_1 = 1; // 禁用IC卡芯片;结束buffer write指令

buf_start_addr++; // 下一buffer起始字节地址

/* 如果buffer写满,则将buffer中数据写入主内存页 */

if (buf_start_addr 》 263)

{

buf_start_addr = 0; // buffer起始字节地址重置0

if (page_addr 《 2047) // 如果主内存页不满

{

/* buffer数据写入主内存页 */

P1_1 = 0; // 使能IC卡芯片;/cs=0

write_spi(B1_TO_MM_PAGE_NO_ERA); // 写入无在线擦除的buffer1写主内存页指令代码

write_spi((uchar)(page_addr》》7)); // 写入4位保留位加上11位页地址的高4位

write_spi((uchar)(page_addr《《1)); // 写入11位页地址的低7位和1位无关位

write_spi(0x00); // 再写入8位无关位

P1_1 = 1; // 禁用IC卡芯片;结束无在线擦除的buffer写主内存页指令

page_addr++; // 下一页地址

}

}

}

/* 读IC卡芯片函数,如果一页读完,则读取下一页 */

uchar read_from_IC()

{

uchar stat;

uchar tmp;

/* 检查IC卡芯片是否忙 */

stat = IC_stat();

while ((stat&0x80)==0x00);

/* 从主内存页中读出数据 */

P1_1 = 0; // 使能IC卡芯片;/cs=0

write_spi(MM_PAGE_READ) ; // 写入主内存页读指令代码

tmp = (uchar)(page_addr》》7);

write_spi(tmp); // 写入4位保留位加上11位页地址的高4位

tmp = (uchar)(page_addr《《1)|((uchar)(page_start_addr》》8)&0x01);

write_spi(tmp); // 写入11位页地址的低7位和9位页起始字节地址的最高位

tmp = (uchar)(page_start_addr);

write_spi(tmp); // 写入9位页起始字节地址的低8位

write_spi(0x00) ; // 写入8位无关位

write_spi(0x00) ; // 写入8位无关位

write_spi(0x00) ; // 写入8位无关位

write_spi(0x00) ; // 再写入8位无关位,共写入32位无关位

write_spi(0xff) ; // 写入8位无意义值以确保完成一字节数据的读出

P1_1 = 1; // 禁用IC卡芯片;结束主内存页读指令

page_start_addr++; // 下一页中起始字节地址

/* 如果读完一页,则读取下一页 */

if (page_start_addr 》 263)

{

page_start_addr = 0; // 页起始字节地址重置0

if (page_addr 《 2047) // 如果主内存页没有读完

page_addr++; // 下一页地址

}

return SPDR; // 返回读出数据

}

接上篇程序:

/* 主函数 */

void main()

{

uchar i;

P1_0 = 1; // /RST引脚置高

/* SPIE=0,SPE=1,DORD=0,MSTR=1,CPOL=CPHA=1,SPR1=0,SPR0=1*/

SPCR=0x5d;

buf_start_addr = 0;

page_start_addr = 0;

page_addr = 0;

/* 获取需要写入IC卡的数据,存放在data_in[]中 */

getdata();

/* 将data_in[]中存放数据写入IC卡 */

for (i=0;i

{

write_to_IC(data_in[i]);

delay(2); // 延时2ms

}

delay(10); // 延时10ms

buf_start_addr = 0;

page_start_addr = 0;

page_addr = 0;

/* 数据读出IC卡,存放在data_out[]中 */

for (i=0;i

{

data_out[i] = read_from_IC();

delay(2); // 延时2ms

}

while(1);

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。需要注意的是51系列的单片机一般不具备自编程能力。 AT89C51单片机8051单片机区别 8051:第二代单片机代表,属MCS-51......
    始态如下表: 8051的复位方式可以是自动复位,也可以是手动复位,见下图。此外,RESET/Vpd还是一复用脚,Vcc掉电其间,此脚可接上备用电源,以保证单片机内部RAM的数据不丢失。 ·Pin31:EA/Vpp......
    存储器的内外部选通线,8051和8751单片机,内置有4kB的程序存储器,当EA为高电平并且程序地址小于 4kB时,读取内部程序存储器指令数据,而超过4kB地址则读取外部指令数据。如EA为低电平,则不管地址大小,一律......
    8051单片机快速入门--我的第一盏灯;学习单片机之前呢,给大家推荐一本单片机学习的书籍《爱上单片机》,内容结构浅显易懂,实践性很强,非常容易上手,好了,废话不多说,直接上干活,带你快速入门单片机......
    8051内核的使用;8051内核结构 8051内核说明管脚 该部分的8051内核的顶层信号引脚在8051内核的顶层便可查看到各个引脚模块的定义。引脚的定义和普通的8051单片机相似,区别在于P3......
    8031,8051,8751,8032,8052,8752等,其中8051是最早最典型的产品,该系列其它单片机都是在8051的基础上进行功能的增、减、改变而来的,所以人们习惯于用8051来称呼MCS51系列单片机。   Intel公司......
    学习51单片机必知的寄存器知识;说起单片机存储器,大家可能知道RAM和ROM,但具体需要怎么用,还需要深入了解下,那今天通程创品就来大家详细了解下51单片机存储器的相关知识,希望......
    / PROG 这个引脚已很少用到,我们了解即可。在设计电路时一般悬空,不作使用。 EA /VPP( 31 脚):具有两种功能。EA :程序存储器选择。 EA =1 时,单片机执行内部程序存储器的程序,当扩......
    8051单片机各种引脚的用法及功能解析;8051系列各种芯片的引脚是互相兼容的,8051,8751和8031均采用40脚双列直播封装型式。当然,不同芯片之间引脚功能也略有差异。8051单片机是高性能的单片机......
    51单片机引脚简介;第一部分。单片机简介 MSC-51单片机指以8051为核心的单片机,由美国的Intel公司在1980年推出,80C51是MCS-51系列中的一个典型品种;其它厂商以8051为基......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>