微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机实现接触式的IC卡读写控制

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

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

主要器件:

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

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

试验流程图:



试验电路图:

试验程序代码:
//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卡芯

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top