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

发布者:bln898最新更新时间:2016-09-07 来源: eefocus关键字:单片机  接触式  IC卡  读写控制 手机看文章 扫描二维码
随时随地手机看文章
从上高中开始,我们学校用的餐卡就为接触式的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卡芯片;结束主内存页读指令

 

       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);

}

关键字:单片机  接触式  IC卡  读写控制 引用地址:单片机实现接触式的IC卡读写控制

上一篇:用集成芯片MAX038实现智能信号发生器
下一篇:基于DS12C887的日历时钟显示系统设计

推荐阅读最新更新时间:2024-03-16 15:08

AVR单片机atmega16串口中断接收和发送程序
// Target : M16 // Crystal: 8.0000Mhz // AVR单片机 atmega16串口中断接收和发送程序。接收到字符后再发送出去 #include iom16v.h #include macros.h unsigned char com_in_buf ; void port_init(void) { PORTA = 0xFF; DDRA = 0xFF; PORTB = 0x00; DDRB = 0x00; PORTC = 0x00; DDRC = 0x00; PORTD = 0x00; DDRD = 0x00; } //UART0 initialize // desired ba
[单片机]
单片机对12M和11.0592M的选择
1单片机常用晶振频率是1.2M-12M,一般情况下,一个机器周期是12个时钟周期,所以用12M时,一个机器周期是1US,好计算,而且速度相对是最高的,当然现在也有更高频率的单片机。 而进行通信是,一般选择11.0592M,12M频率进行串行通信不容易实现标准的波特率,比如9600,4800,而11.0592M计算时正好可以得到,因此在有通信接口的单片机中,一般选11.0592M 计算一下就知道了。如我们要得到9600 的波特率,晶振为11.0592M 和12M,定时器1 为模式2,SMOD 设为1,分别看看那所要求的TH1 为何值。 代入公式: 11.0592M 9600=(2 32)
[单片机]
新一代网络打印机国产主控制器:N32G457系列MCU芯片
网络打印机是指将内置或外置打印服务器作为独立的设备接入局域网或者Internet或者无线网,从而使打印机摆脱一直以来作为电脑外设的附属地位,使之成为物联网终端设备中的独立成员,并可实现多机联网共享打印。 图1:网络热敏打印机 网络打印机的组成 网络打印机广泛应用于餐饮票据、物流标签、零售门店、彩票等行业的网络打印应用场景。主要由热敏打印头及其外围电路,主控制器( MCU )电路,电源供电,通讯接口电路以及人机交互五大部分组成。 图2 网络打印机结构图 2、主流网络打印机的关键特性 打印质量 打印质量是评价网络打印机的一个重要指标,打印质量的优劣主要以打印的清晰度来体现,而决定清晰度的
[物联网]
新一代网络打印机国产主<font color='red'>控制</font>器:N32G457系列<font color='red'>MCU</font>芯片
基于51单片机IAP技术的LED显示屏控制系统
  LED显示屏由于其具有耗电少、使用寿命长、成本低、亮度高、故障少、视角大、可视距离远等特点,已经成为新一代的信息传播媒体工具。LED与LCD相比较最突出的特点是,亮度高、成本低且屏幕尺寸可根据现场情况用标准LED单元板拼制。按安装位置可分为室外、半室外和室内;按颜色可分为单色、双基色和彩色;按发光二极管点距可分为φ5.0、φ3.75及φ3.0等。本文以市场上常见的室内双色LED单元板为控制对象,说明基于单片机IAP技术的LED显示屏控制系统工作原理以及数据组织方法。 1 双色LED单元板硬件组成及工作原理   常见的室内双色LED单元板电路框图如图1(a)所示。其中行扫描电路由2片74HC138(3-8译码器)构成的4
[单片机]
基于51<font color='red'>单片机</font>IAP技术的LED显示屏<font color='red'>控制</font>系统
基于单片机和CPLD的数字频率计的设计与应用
引言 在传统的控制系统中,通常将单片机作为控制核心并辅以相应的元器件构成一个整体。但这种方法硬件连线复杂、可靠性差,且在实际应用中往往需要外加扩展芯片,这无疑会增大控制系统的体积,还会增加引入干扰的可能性。对一些体积小的控制系统,要求以尽可能小的器件体积实现尽可能复杂的控制功能,直接应用单片机及其扩展芯片就难以达到所期望的效果。 复杂可编程逻辑器件(CPLD)具有集成度高、运算速度快、开发周期短等特点,它的出现,改变了数字电路的设计方法、增强了设计的灵活性。基于此,本文提出了一种采用Altera公司的CPLD(ATF1508AS)和Atmel公司的单片机(AT89S52)相结合的数字频率计的设计方法。该数字频率计电路简洁,软
[单片机]
基于<font color='red'>单片机</font>和CPLD的数字频率计的设计与应用
PIC单片机入门_同步/异步通信技术基础
1.前言 通用同步 / 异步收发器 (Universal Synchronous/Asynchronous Receiver/Transmitter, USART) 模块是两个串行 I/O 模块之一 ( 另一个是 Synchronous Serial,SSP 模块 )。 USART也称为串行通讯接口(Serial Communication Interface,SCI)。 USART 可以配置为全双工异步系统,可与 CRT 终端和个人计算机等外设进行通信(RC6=TX, RC7=RX);也可配置为半双工同步系统,可与 A/D 或 D/A 集成电路,以及串行 EEPROM等外设器件进行通信。USART 可配置为以下几种工作模式:全
[单片机]
ATmega168 简介
ATmega168是基于增强的AVR RISC结构的低功耗8 位CMOS微控制器。由于其先进的指令集以及单时钟周期指令执行时间,ATmega168 的数据吞吐率高达1 MIPS/MHz,从而可以缓减系统在功耗和处理速度之间的矛盾。 ATmega168 AVR 内核具有丰富的指令集和32 个通用工作寄存器。所有的寄存器都直接与算逻单元(ALU) 相连接,使得一条指令可以在一个时钟周期内同时访问两个独立的寄存器。这种结构大大提高了代码效率,并且具有比普通的CISC 微控制器最高至10 倍的数据吞吐率。 ATmega168 有如下特点:16K字节的系统内可编程Flash(具有同时读写的能力,即RWW),512 字节EEPROM,1K
[单片机]
解析8051单片机的三种数据传输方式
单片机CPU与外部设备交换信息通常有如下几种方式:无条件传送方式,查询传送方式和中断传送方式。我们以单片机与微型打印机接口为例讲述这三种方式。假定用户要打印三个数据,这三个数据保存在单片机的内部数据存储器10H,11H,和12H中,8051用并口P2与微型打印机的并行数据口DB进行数据交换。 (1)无条件传送方式 这种数据传送方式中没有联络信号,即CPU总是认为打印机在如何时候都是处于“准备好”的状态。这种传送方式中只需要在程序中加入数据送往P2的指令,数据传送便可以实现。但这种数据传送方式有一个致命弱点,数据易丢失,这是因为CPU的速度相当快,而打印机的速度相对来说较慢,其结果是在打印机打印一个数据的时间内,CPU已送来了多
[单片机]
解析8051<font color='red'>单片机</font>的三种数据传输方式
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
502 Bad Gateway

502 Bad Gateway


openresty
设计资源 培训 开发板 精华推荐

502 Bad Gateway

502 Bad Gateway


openresty
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
随便看看
    502 Bad Gateway

    502 Bad Gateway


    openresty
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
502 Bad Gateway

502 Bad Gateway


openresty