📄 icrdwr.c
字号:
#include <REG8253.H> //头文件
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define BUFFER1Write 0x84 // BUFFER1写指令代码
#define BUFFER1ToMain 0x88 //由缓冲区写主内存指令代码
#define MainPageRead 0xD2 //主内存页读指令代码
#define StatusRead 0xD7 //状态寄存器读指令代码
#define WriteICMaxLen 8 //写IC卡芯片最大长度
#define ReadICMaxLen 8 //读IC卡芯片最大长度
uint PageStartAddr; //页中起始字节地址
uint PageAddr; //页地址,16位中低9位为有效位
uint BufStartAddr; // BUFFER中起始字节地址,16位中低11位为有效位
uchar WriteIC[WriteICMaxLen]; //要写入IC卡的数据
uchar ReadIC[ReadICMaxLen]; //要从IC卡中读出的数据
void Delay(uint t); //延时函数
void SPIWrite(uchar dat); //写数据寄存器函数
uchar ICStatus(void); //读IC卡状态函数
void WriteICFun(uchar dat); //写IC卡芯片函数
uchar ReadICFun(); //读IC卡芯片函数
void main() //主函数
{
uchar i;
uchar status;
uchar Select_Menu; //功能选择
SCON=0x50; //初始化串行口模式1
TMOD=0x20; //初始化T1为定时功能,模式2
PCON=0x80; //设置SMOD=1
TL1=0xF4; //波特率4800bit/s,初值
TH1=0xF4;
TR1 = 1; //启动T1
TI = 1; //启动发送
P1_0 = 1;
SPCR=0x5d; //SPI控制寄存器
for (i=0;i<8;i++) //产生数据,用于写IC卡
{
WriteIC[i]=i;
}
while(1)
{
printf("A/D Converter MAX197 Control!");
printf (" Select Control Menu Option\n"); //菜单信息
printf (" 0. Write Data to IC Card.\n");
printf (" 1. Read Data from IC Card.\n");
printf (" 2. Read status of IC Card.\n");
printf (" 3. Reset IC Card.\n");
printf (" 4. EXIT.\n");
printf (" Please Input Menu Option:\n");
Select_Menu = _getkey(); //从键盘输入选择数字
switch(Select_Menu)
{
case '0': //写IC卡
printf ("\n You Select 0. Write Data to IC Card.\n");
BufStartAddr = 0; // BUFFER中起始字节地址
PageStartAddr = 0; //页起始地址
PageAddr = 0; //页地址
for (i=0;i<WriteICMaxLen;i++) //将数组WriteIC写入IC卡
{
WriteICFun(WriteIC[i]);
Delay(2); //延时
}
printf("Data have write into IC Card.\n");
break;
case '1': //读IC卡
printf ("\n You Select 1. Read Data from IC Card.\n");
BufStartAddr = 0; // BUFFER中起始字节地址
PageStartAddr = 0; //页起始地址
PageAddr = 0; //页地址
for (i=0;i<ReadICMaxLen;i++) //循环读IC卡
{
ReadIC[i] = ReadICFun();
Delay(2); //延时
}
printf("Data have read from IC Card.\n");
break;
case '2': //读IC卡状态
printf ("\n You Select 2. Read status of IC Card.\n");
status=ICStatus(); //读IC卡状态
printf("IC Card Status=%x\n",status);
break;
case '3': //复位IC卡
printf ("\n You Select 3. Reset IC Card.\n");
P1_0=0; //复位
Delay(5);
P1_0 = 1;
SPCR=0x5d; //重置SPI控制寄存器
printf("IC Card Reset!\n");
break;
case '4': //退出程序
printf ("\n You Select 4. Exit\n");
goto Exit; //转向Exit标号处
break;
default:
printf ("\n Error: Please Select Right Menu Option\n");
break;
};
}
Exit: printf("Exit the program!"); //退出
}
void Delay(uint t)
{
uint i,j;
for(j=0;j<t;j--)
{
for (i=0;i<125;i++) //空循环
{
}
}
}
void SPIWrite(uchar dat)
{
SPDR = dat; //写数据寄存器SPDR
while (!(SPSR & 0x80)) //读SPSR,等待传输完成
{
}
}
uchar ICStatus(void)
{
P1_1 = 0; //使能IC卡芯片
SPIWrite(StatusRead); //向IC卡芯片写入读IC卡芯片状态指令
SPIWrite(0x00); //写无关位
P1_1 = 1; //禁用IC卡芯片
return SPDR; //返回IC卡芯片状态
}
void WriteICFun(uchar dat)
{
uchar status;
status= ICStatus(); //检查IC卡芯片的状态
while ((status&0x80)==0x00) //如果IC卡芯片忙,则等待
{
}
P1_1 = 0; //使能IC卡芯片
SPIWrite(BUFFER1Write); //IC卡芯片的写BUFFER1指令代码
SPIWrite(0x00); //写入8位无关位
SPIWrite((uchar)(BufStartAddr>>8)); //写入7位无关位以及9位buffer起始字节地址的第1位
SPIWrite((uchar)BufStartAddr); //写入9位BUFFER起始字节地址的后8位
SPIWrite(dat); //写入数据
P1_1 = 1; //禁用IC卡芯片
BufStartAddr++; //指向下一BUFFER起始字节地址
if (BufStartAddr > 263) //如果BUFFER已满
{
BufStartAddr = 0; // buffer起始字节地址重置0
if (PageAddr < 2047) //如果IC卡芯片的主内存页不满
{
/* buffer数据写入主内存页 */
P1_1 = 0; //使能IC卡芯片
SPIWrite(BUFFER1ToMain); //由缓冲区写主内存指令代码
SPIWrite((uchar)(PageAddr>>7)); //写入4位保留位加上11位页地址的高4位
SPIWrite((uchar)(PageAddr<<1)); //写入11位页地址的低7位和1位无关位
SPIWrite(0x00); //写入8位无关位
P1_1 = 1; //禁用IC卡芯片
PageAddr++; //指向下一页地址
}
}
}
uchar ReadICFun()
{
uchar status;
uchar tmp;
status= ICStatus(); //检查IC卡芯片的状态
while ((status&0x80)==0x00) //如果IC卡芯片忙,则等待
{
}
P1_1 = 0; //使能IC卡芯片
SPIWrite(MainPageRead) ; //写入主内存页读指令代码
tmp = (uchar)(PageAddr>>7); //11位页地址的高4位
SPIWrite(tmp); //写入4位保留位以及11位页地址的高4位
tmp = (uchar)(PageAddr<<1)|((uchar)(PageStartAddr>>8)&0x01);
SPIWrite(tmp); //写入页地址的低7位以及9位页起始字节地址的最高位
tmp = (uchar)(PageStartAddr);
SPIWrite(tmp); //写入9位页起始字节地址的低8位
SPIWrite(0x00) ; //写入8位无关位
SPIWrite(0x00) ; //写入8位无关位
SPIWrite(0x00) ; //写入8位无关位
SPIWrite(0x00) ; //再写入8位无关位,共写入32位无关位
SPIWrite(0xff) ; //写入任意值,用来读IC卡芯片返回的数据
P1_1 = 1; //禁用IC卡芯片
PageStartAddr++; //指向下一页中起始字节地址
if (PageStartAddr > 263) //如果读完一页
{
PageStartAddr = 0; //页起始字节地址重置0
if (PageAddr < 2047) //如果主内存页没有读完
PageAddr++; //指向下一页地址
}
return SPDR; //返回数据
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -