找回密码
 注册会员
img_loading
智能检测中
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

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

[复制链接]
admin 发表于 2012-9-3 02:51:09 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
IC 卡芯片为AT45D041A 数据通过SPI接口传输

5_3_89ab30f64673272.jpg


/*****************************************/
/* Copyright (c) 2005, 通信工程学院 */
/* All rights reserved. */
/* 作 者:戴 佳 */
/*****************************************/

#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+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<DATA_IN_MAX_LEN;i++)
{
write_to_IC(data_in);
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_MAX_LEN;i++)
{
data_out = read_from_IC();
delay(2); // 延时2ms
}

while(1);
}
LGQ 发表于 2012-9-8 12:13:26 | 显示全部楼层
楼住谢谢你了{:e151:}
您需要登录后才可以回帖 登录 | 注册会员

*滑块验证:
加载失败,请点击重试! (img)
本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2025-7-8 16:14 , Processed in 0.075159 second(s), 11 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表