当前位置:首页 > 单片机 > 单片机
[导读] AVR单片机IC卡程序#include#include#defineucharunsignedchar#defineuintunsignedint//**********定义全局变量*******************////查表0123456789EFPOFFuchartable[14]={0x3f,0x06,0x5b,0x4f,0x66,

AVR单片机IC卡程序


#include
#include
#defineucharunsignedchar

#defineuintunsignedint

//**********定义全局变量*******************//
//查表0123456789EFPOFF
uchartable[14]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x79,0x71,0x73,0x00};
ucharICCode[4];//定义IC卡复位时读出的4字节代码;
ucharICcontent[14];//定义IC卡有效信息;
ucharMoney[5];//定义IC卡内金额;
ucharEEEEE[5]={0x79,0x79,0x79,0x79};
ucharFFFFF[5]={0x71,0x71,0x71,0x71};
ucharIC_Flag;//定义IC卡上电标志;
ucharNum_Flag;//数标志;
ucharAdd_Flag;//加标志
ucharSub_Flag;//减标志
ucharInit_Flag;//初始化标志
ucharRepair_Flag;//修卡标志;
ucharEnter_Flag;//确认标志
ucharPoint_Flag;//.标志
ucharKey_Flag;//按键标志;


//***********IC卡引脚信号处理***************//
voidVoice(ucharPD)//Voice=PD^7
{if(PD==1)PORTD|=0x80;//Voice置1
elsePORTD&=~80;//Voice置0
}

voidRST(ucharPD)//RST=PD^6
{if(PD==1)PORTD|=0x40;//RST置1
elsePORTD&=~0x40;//RST置0
}

voidCLK(ucharPD)//CLK=PD^5
{if(PD==1)PORTD|=0x20;//CLK置1
elsePORTD&=~0x20;//CLK置0
}

voidIO(ucharPD)//IO=PD^4
{if(PD==1)PORTD|=0x10;//IO置1
elsePORTD&=~0x10;//IO置0
}

voidSetIO(uchari)//设置IO口属性
{if(i==1)DDRD=0xf0;//IO口输出:11110000
elseDDRD=0xe0;//IO口输如:11100000
PORTD=0x00;//不带上拉电阻;
}

//**********延时函数(Us数量级)*********//
//单周期指令执行时间,执行时间1/8us*分频系数(取8分频则刚好1us);
voidDelayUs(uchari)
{for(;i!=0;i--)
NOP();
}

//****************延时函数(Ms数量级)*********//
voidDelayMs(uinti)
{ucharj,k;
for(;i!=0;i--)
{for(k=0;k<4;k++)
{for(j=250;j!=0;j--)NOP();}
}
}

//****************接收数据**************//
ucharReceivEDAta(void)
{ucharcount;
ucharvalue;
uchario_value;
value=0;
SetIO(0);//设置IO脚为输入;
CLK(0);
//IO=1;
for(count=0;count<8;count++)
{value=value>>1;
CLK(1);
DelayUs(2);
io_value=PIND;
CLK(0);
DelayUs(2);
if(io_value&0x10==0x10)value|=0x80;//判断IO脚是否为1
elsevalue&=0x7f;
}
return(value);
}

//********************发送数据************//
voidSendData(ucharXdata)
{ucharcount;
ucharvalue;
SetIO(1);////设置IO脚为输出;
value=Xdata;
for(count=8;count!=0;count--)
{CLK(0);
if((Xdata<<(count-1))&0x80)IO(1);
elseIO(0);
CLK(1);
DelayUs(2);
CLK(0);}
}

//****************IC卡复位************************//
voidResetIC(uchar*Xdata)
{ucharcount;
SetIO(1);//设置IC卡引脚的属性
RST(0);
CLK(0);
IO(1);
DelayUs(5);
RST(1);
DelayUs(5);
CLK(1);
DelayUs(5);
CLK(0);
DelayUs(5);
RST(0);
for(count=4;count!=0;count--)
{*Xdata=ReceiveData();
Xdata+=2;}
}

//*******************Start条件****************//
voidStart(void)
{SetIO(1);
CLK(0);
IO(0);
DelayUs(2);
CLK(1);
IO(1);
DelayUs(2);
IO(0);
CLK(0);
}

//*******************Stop条件****************//
voidStop(void)
{CLK(0);
IO(0);
DelayUs(2);
CLK(1);
IO(0);
DelayUs(2);
IO(1);
DelayUs(2);
IO(0);
}

//******************处理过程**************//
voidProcess(void)
{uintj;
SetIO(1);//设置IO脚为输出脚
CLK(0);
DelayUs(5);
IO(0);
for(j=255;j>0;j--)
{CLK(1);
DelayUs(5);
CLK(0);
DelayUs(5);
}
IO(1);
}

//****************说明*********************//
//*********输出模式接口命令,包括读主存储器30H,读保护存储器34H,读安全代码的接口命令31H***********//
//******处理模式数据接口命令,包括写主存储器38H,写保护存储器3CH,写安全代码39H,校验安全代码33H*******//

voidCommand(ucharByte1,ucharByte2,ucharByte3)
{Start();
SendData(Byte1);
SendData(Byte2);
SendData(Byte3);
Stop();
}


/**********读主存储器**************/
voidReaDMAinMemory(ucharaddr,uchar*p,ucharN)
{Command(0x30,addr,0xff);
do{*p=ReceiveData();
p++;}while(--N);
}

/**********读保护存储器***********/
voidReadProtectMemory(uchar*p)
{uchari=4;
Command(0x34,0xff,0xff);
do{*p=ReceiveData();
p++;}while(i--);
}

/************写主存储器************/
voidWriteMainMemory(ucharAddress,ucharData)
{Command(0x38,Address,Data);
Process();
}

/**************写保护存储器**********/
voidWriteProtectMemory(ucharAddress,ucharData)
{Command(0x3c,Address,Data);
Process();
}

/**************读安全存储器************/
voidReadSafeMemory(uchar*p)
{uchari;
Command(0x31,0xff,0xff);
for(i=0;i<4;i++)
{*p=ReceiveData();
p++;}
}

/*************写安全存储器***************/
voidWriteSafeMemory(ucharAddress,ucharData)
{Command(0x39,Address,Data);//Address=0,1,2,3
Process();
}

/**************校验密码*******************/
ucharVerifyPassword(uchar*p)
{uchartemp[4];//暂存4字节保护密码;
uchari;
ReadSafeMemory(temp);//读安全代码以取得错误计数器
if((temp[0]&0x07)!=0)
{if((temp[0]&0x07)==0x07)i=0x06;
if((temp[0]&0x07)==0x06)i=0x04;
if((temp[0]&0x07)==0x04)i=0x00;
WriteSafeMemory(0,i);
for(i=1;i<4;i++,p++)
{Command(0x33,i,*p);
Process();}
WriteSafeMemory(0,0xff);
ReadSafeMemory(temp);
if((temp[0]&0x07)==0x07)return(0x1);

}
return(0);
}
//*************SLE4442函数结束*****************//

//*************数据变换**********//
voidChange(uchar*Source,uchar*Destination,ucharN)
{uchari,temp;
for(i=0;i{temp=Source[i];
Destination[i]=temp>>4;
Destination[2*i+1]=temp&0x0f;}
}

//***********密码错误报警***********************//
voidBuzzle_Password(void)
{uchari;
for(i=0;i<2;i++)
{Voice(0);
DelayMs(1000);
Voice(1);
DelayMs(1000);}
}

//**********非法卡错误报警*************************//
voidBuzzle_Card(void)
{uchari;
for(i=0;i<2;i++)
{Voice(0);
DelayMs(3000);}
}

//*************余额不足报警**********************//
voidBuzzle_Money(void)
{uchari;
for(i=0;i<1;i++)
{Buzzle_Password();
Buzzle_Card();}
}

//*********************读卡函数********************//
//说明:
//函数使用的数组参数用来存放读出的余额值;
//返回值信息:
//0:卡坏!
//1:非法卡(特征值不正确)
//2:非法卡(特征值正确,帐号不正确)
//3:读卡成功!
ucharRead_Card(uchar*p)
{uchari,tag=0,temp[4];
ReadSafeMemory(temp);
if(temp[0]==0x07)
{ReadMainMemory(32,p,14);//读主存储器14字节:32-35特征码;36-3A帐号;3B-3F余额
if(p[0]==0x00&&p[1]==0x0f&&p[2]==0xf0&&p[3]==0xff)//特征码:0x00,0x0f,0xf0,0xff
{for(i=0;i<10;i++)
if((p[i+4]>=0&&p[i+4]<=9))tag=tag+1;
if(tag!=10)return(2);
elsereturn(3);
}
else
return(1);
}
elsereturn(0);
}

//*********************卡初始化函数********************//
//说明:
//函数使用的数组参数用来存放写入的的ID值;
//返回值信息:
//2:初始化失败!
//3:初始化成功!
ucharInitial_Card(uchar*p)
{ucharPsw[3]={0xff,0xff,0xff};
uchari,j,temp=0;
uchartp[20];
//ResetIC(ICcode);//IC卡复位,读出复位后的厂家信息代码A2131091;
j=VerifyPassword(Psw);
WriteMainMemory(32,0x00);//写特征码:
WriteMainMemory(33,0x0f);
WriteMainMemory(34,0xf0);
WriteMainMemory(35,0xff);
for(i=0;i<5;i++)//写帐号
WriteMainMemory(36+i,p[i]);//从32+i地址开始写5字节帐号;
for(i=0;i<5;i++)
WriteMainMemory(41+i,0);//从32+i地址开始写5字节初始化金额0000.0
j=Read_Card(tp);
if(j==3)
{for(i=0;i<10;i++)
if(p[i]==tp[i+4])temp=temp+1;
}
if(temp==10)return(3);
elsereturn(2);
}

//***************卡修复函数********************//
//说明:
//返回值信息:
//0:修复失败!
//1:修复成功!
ucharRepair_Card(void)
{ucharPsw[3]={0xff,0xff,0xff};
uchari,j,temp;
i=VerifyPassword(Psw);
return(i);
}

//********************加卡函数***********//
voidAdd_Card(uchar*p)
{uchari;
uchartemp[14];
i=Read_Card(temp);
if(i==3)
{temp[13]=temp[13]+p[4];
if(temp[13]>9){temp[13]=temp[13]-10;temp[12]=temp[12]+1;}
temp[12]=temp[12]+p[3];
if(temp[12]>9){temp[12]=temp[12]-10;temp[11]=temp[11]+1;}
temp[11]=temp[11]+p[2];
if(temp[11]>9){temp[11]=temp[11]-10;temp[10]=temp[10]+1;}
temp[10]=temp[10]+p[1];
if(temp[10]>9){temp[10]=temp[10]-10;temp[9]=temp[9]+1;}

WriteMainMemory(41,temp[9]);
WriteMainMemory(42,temp[10]);
WriteMainMemory(43,temp[11]);
WriteMainMemory(44,temp[12]);
WriteMainMemory(45,temp[13]);
}
}

//********************减卡函数***********//
voidSub_Card(uchar*p)
{uchari,B_Flag;
uchartemp[14];
i=Read_Card(temp);
if((i==3)&&(!(temp[9]{if(temp[13]elsetemp[13]=temp[13]-p[4];
//以上处理小数点右边的数字;
if(B_Flag==1)
{if(temp[12]==0){temp[12]=9;B_Flag=0;}
elsetemp[12]=temp[12]-1;}
//以上对存在借位情况时对小数点左边第一位进行预处理;
if(temp[12]elsetemp[12]=temp[12]-p[3];
//以上处理小数点小数点左边第一位数字;
if(B_Flag==1)
{if(temp[11]==0){temp[11]=9;B_Flag=0;}
elsetemp[11]=temp[11]-1;}
//以上对存在借位情况时对小数点左边第二位进行预处理;
if(temp[11]elsetemp[11]=temp[11]-p[2];
//以上处理小数点小数点左边第二位数字;
if(B_Flag==1)
{if(temp[10]==0){temp[10]=9;B_Flag=0;}
elsetemp[10]=temp[10]-1;}
//以上对存在借位情况时对小数点左边第三位进行预处理;
if(temp[10]elsetemp[10]=temp[10]-p[1];
//以上处理小数点小数点左边第三位数字;
if(B_Flag==1)
{if(temp[9]==0){temp[9]=0;B_Flag=0;}
elsetemp[9]=temp[9]-1;}
//以上对存在借位情况时对小数点左边第二位进行预处理;
temp[9]=temp[9]-p[0];
//以上处理小数点小数点左边第二位数字;

WriteMainMemory(41,temp[9]);
WriteMainMemory(42,temp[10]);
WriteMainMemory(43,temp[11]);
WriteMainMemory(44,temp[12]);
WriteMainMemory(45,temp[13]);
}
}

//*****************数码管显示函数********************//
voidDisplay(uchar*p)
{ucharsel,i;
sel=0x01;
for(i=0;i<6;i++)
{PORTA=table[p[i]];
PORTB=sel;
DelayMs(2);
sel=sel<<1;}
}


//****************键盘扫描函数***********************//
ucharKey_SCAN(void)
{ucharsccode,recode;
PORTC=0xf0;
if((PINC&0xf0)!=0xf0)
{DelayMs(10);
if((PINC&0xf0)!=0xf0)
{sccode=0xfe;
while(sccode&0x10!=0x00)
{PORTC=sccode;//对第一行键盘测试
if((PINC&0xf0)!=0xf0)
{recode=(PINC&0xf0)|0x0f;
return((~sccode)+(~recode));}
else
sccode=(sccode<<1)|0x01;
}
}
}
return(0x00);
}

//******************按键处理函数*******************//
voidKey_Process(uchar*p)
{uchartemp,value;
temp=Key_Scan();
switch(temp)
{case0x11:value=9;Num_Flag=1;break;
case0x21:value=8;Num_Flag=1;break;
case0x41:value=7;Num_Flag=1;break;
case0x12:value=6;Num_Flag=1;break;
case0x22:value=5;Num_Flag=1;break;
case0x42:value=4;Num_Flag=1;break;
case0x14:value=3;Num_Flag=1;break;
case0x24:value=2;Num_Flag=1;break;
case0x44:value=1;Num_Flag=1;break;
case0x18:value=0;Num_Flag=1;break;
case0x28:Point_Flag=1;break;
case0x82:Add_Flag=1;Sub_Flag=0;Key_Flag=1;break;
case0x84:Sub_Flag=1;Add_Flag=0;Key_Flag=1;break;
case0x48:Repair_Flag=1;Key_Flag=1;break;
case0x81:Init_Flag=1;Key_Flag=1;break;
case0x88:Enter_Flag=1;Key_Flag=0;break;
default:NOP();
}
if(Num_Flag==1){p[4]=p[3];p[3]=p[2];p[2]=p[1];p[1]=value;Num_Flag=0;}
if(Point_Flag==1){p[0]=value;Point_Flag=0;}
if(Add_Flag==1){Add_Flag=1;Sub_Flag=0;}
if(Sub_Flag==1){Sub_Flag=1;Add_Flag=0;}
if(Init_Flag==1){Init_Flag=1;}
if(Repair_Flag==1){Repair_Card();Repair_Flag=0;}
if(Enter_Flag==1)
{if(Add_Flag==1){Add_Card(p);Enter_Flag=0;Add_Flag=0;}
if(Sub_Flag==1){Sub_Card(p);Enter_Flag=0;Sub_Flag=0;}
if(Init_Flag==1){Initial_Card(p);Init_Flag=0;}}
}

//***************中断处理********************//
//**********定时器2:16ms中断显示一次*******//
#pragmainterrupt_handlerTIMER1_INT:9
voidTIMER1_INT(void)
{uchartemp[5],i;
for(i=0;i<5;i++)
temp[i]=ICcontent[9+i];
if(IC_Flag==0)Display(EEEEE);
if(IC_Flag==1)Display(FFFFF);
if(IC_Flag==3)
{if(Key_Flag==1)//显示此次操作金额;
{Money[1]|=0x80;//显示时加上小数点;
Display(Money);}
else//显示卡内余额;
{temp[4]|=0x80;
Display(temp);}
}
}

//*************系统初始化*************//
voidInitial_System(void)
{//系统初始化
//SPL=0x5f;//AT90S8535的堆栈指针指向最高RAM地址;
//SPH=0x02;
//IO口初始化;
DDRA=0xff;//A口输出高电平
PORTA=0xff;
DDRB=0xff;//B口输出低电平
PORTB=0x00;
DDRC=0x0f;//C口高四位输入(不带上拉电阻)低四位输出0
PORTC=0xf0;
DDRD=0xff;//D口输出低电平
PORTD=0x00;
//中断系统初始化(定时器1中断)
SREG=SREG|0x80;//I(SREG^7)全局中断使能置位
TIMSK=TIMSK|0x40;//TOIE1(TIMSK^2)T/C1溢出中断使能置位
TIFR=TIFR|0x40;//TOV1(TIFR^2)T/C1溢出中断标志位写"1"清0
//定时器初始化
TCCR1B=TCCR1B|0x20;//定时器时钟分频=CLK/8(1uS计数)
TCNT1H=0xc1;//需要计数16000=0x3E80次,
TCNT1L=0x7f;//计数初值0xff-0x3e80=0xc17f;
//显示系统初始化
IC_Flag=0;//如果IC卡没有上电,则显示的是8.8.8.8.,否则显示IC卡的内容
}

voidmain(void)
{uchari,j;
Initial_System();
while(IC_Flag==1)
{DelayMs(5);
ResetIC(ICcode);
i=Read_Card(ICcontent);
if(i==0){IC_Flag=0;Buzzle_Password();}//显示EEEE,提示卡坏
if((i==1)|(i==2)){IC_Flag=1;Buzzle_Card();}//显示FFFF,提示非法卡
if(i==3)
{if(ICcontent[12]<5)
{IC_Flag=3;Buzzle_Money();}
else
{doKey_Process(Money);
while(Enter_Flag!=0);
Enter_Flag=0;}
}
}
}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

单片机是一种嵌入式系统,它是一块集成电路芯片,内部包含了处理器、存储器和输入输出接口等功能。

关键字: 单片机 编写程序 嵌入式

在现代电子技术的快速发展中,单片机以其高度的集成性、稳定性和可靠性,在工业自动化、智能家居、医疗设备、航空航天等诸多领域得到了广泛应用。S32单片机,作为其中的佼佼者,其引脚功能丰富多样,是实现与外部设备通信、控制、数据...

关键字: s32单片机引脚 单片机

在微控制器领域,MSP430与STM32无疑是两颗璀璨的明星。它们各自凭借其独特的技术特点和广泛的应用领域,在市场上占据了重要的位置。本文将深入解析MSP430与STM32之间的区别,探讨它们在不同应用场景下的优势和局限...

关键字: MSP430 STM32 单片机

该系列产品有助于嵌入式设计人员在更广泛的系统中轻松实现USB功能

关键字: 单片机 嵌入式设计 USB

单片机编程语言是程序员与微控制器进行交流的桥梁,它们构成了单片机系统的软件开发基石,决定着如何有效、高效地控制和管理单片机的各项资源。随着微控制器技术的不断发展,针对不同应用场景的需求,形成了丰富多样的编程语言体系。本文...

关键字: 单片机 微控制器

单片机,全称为“单片微型计算机”或“微控制器”(Microcontroller Unit,简称MCU),是一种高度集成化的电子器件,它是现代科技领域的关键组件,尤其在自动化控制、物联网、消费电子、汽车电子、工业控制等领域...

关键字: 单片机 MCU

STM32是由意法半导体公司(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器系列,以其高性能、低功耗、丰富的外设接口和强大的生态系统深受广大嵌入式开发者喜爱。本文将详细介绍S...

关键字: STM32 单片机

在当前的科技浪潮中,单片机作为嵌入式系统的重要组成部分,正以其强大的功能和广泛的应用领域受到越来越多行业的青睐。在众多单片机中,W79E2051以其卓越的性能和稳定的工作特性,成为市场上的明星产品。本文将深入探讨W79E...

关键字: 单片机 w79e2051单片机

单片机,又称为微控制器或微处理器,是现代电子设备中的核心部件之一。它集成了中央处理器、存储器、输入输出接口等电路,通过外部信号引脚与外部设备进行通信,实现对设备的控制和管理。本文将详细介绍单片机的外部信号引脚名称及其功能...

关键字: 单片机 微控制器 中央处理器

随着科技的飞速发展,单片机和嵌入式系统在现代电子设备中的应用越来越广泛。它们不仅提高了设备的智能化水平,还推动了各行各业的创新与发展。在单片机和嵌入式系统的开发中,编程语言的选择至关重要。本文将深入探讨单片机和嵌入式系统...

关键字: 单片机 嵌入式系统 电子设备
关闭
关闭