单片机实现接触式的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卡芯
单片机接触式IC卡读写控 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)