AVR单片机读卡器程序设计

来源:本站
导读:目前正在解读《AVR单片机读卡器程序设计》的相关信息,《AVR单片机读卡器程序设计》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《AVR单片机读卡器程序设计》的详细说明。
简介:在这里为大家提供一个基于AVR单片机读卡器程序设计。

#include <io8535v.h>#include <macros.h>#define uchar unsigned char#define uint unsigned int//**********定义全局变量*******************////查表0    1    2    3    4    5  6    7    8    9    E    F  P  OFFuchar table[14]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x79,0x71,0x73,0x00};uchar ICcode[4];//定义IC卡复位时读出的4字节代码;uchar ICcontent[14];//定义IC卡有效信息;uchar Money[5];//定义IC卡内金额;uchar EEEEE[5]={0x79,0x79,0x79,0x79};uchar FFFFF[5]={0x71,0x71,0x71,0x71};uchar IC_Flag;//定义IC卡上电标志;uchar Num_Flag;//数标志;uchar Add_Flag;//加标志uchar Sub_Flag;//减标志uchar Init_Flag;//初始化标志uchar Repair_Flag;//修卡标志;uchar Enter_Flag;//确认标志uchar Point_Flag;//.标志uchar Key_Flag; //按键标志;    //***********IC卡引脚信号处理***************//void Voice(uchar PD) //Voice=PD^7{if(PD==1) PORTD|=0x80;//Voice置1else      PORTD&=~80; //Voice置0}void RST(uchar PD)  //RST=PD^6{if(PD==1) PORTD|=0x40;//RST置1else      PORTD&=~0x40;//RST置0}void CLK(uchar PD) //CLK=PD^5{if(PD==1) PORTD|=0x20;//CLK置1else      PORTD&=~0x20;//CLK置0}void IO(uchar PD)  //IO=PD^4{if(PD==1) PORTD|=0x10;//IO置1else      PORTD&=~0x10;//IO置0}void SetIO(uchar i)//设置IO口属性{if(i==1) DDRD=0xf0; //IO口输出:1111 0000else    DDRD=0xe0; //IO口输如:1110 0000PORTD=0x00;//不带上拉电阻;}//**********延时函数(Us数量级)*********////单周期指令执行时间,执行时间1/8us*分频系数(取8分频则刚好1us);void DelayUs(uchar i){for(;i!=0;i--)  NOP();}//****************延时函数(Ms数量级)*********//void DelayMs(uint i){uchar j,k;for(;i!=0;i--)    {for(k=0;k<4;k++)      {for(j=250;j!=0;j--) NOP();}}}//****************接收数据**************//uchar ReceiveData(void){uchar count;uchar value;uchar io_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  else value&=0x7f;  }return (value);}//********************发送数据************//void SendData(uchar Xdata)  {uchar count;uchar value;SetIO(1);////设置IO脚为输出;value=Xdata;for(count=8;count!=0;count--)  {CLK(0);  if((Xdata<<(count-1))&0x80) IO(1);  else IO(0);  CLK(1);  DelayUs(2);  CLK(0);}}//****************IC卡复位************************//void ResetIC(uchar *Xdata){uchar count;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条件****************//void Start(void){SetIO(1);CLK(0);IO(0);DelayUs(2);CLK(1);IO(1);DelayUs(2);IO(0);CLK(0);}//*******************Stop条件****************//void Stop(void){CLK(0);IO(0);DelayUs(2);CLK(1);IO(0);DelayUs(2);IO(1);DelayUs(2);IO(0);}//******************处理过程**************//void Process(void){uint j;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*******//void Command(uchar Byte1,uchar Byte2,uchar Byte3){Start();SendData(Byte1);SendData(Byte2);SendData(Byte3);Stop();}/**********读主存储器**************/void ReadMainMemory(uchar addr,uchar *p,uchar N){Command(0x30,addr,0xff);do{*p=ReceiveData();    p++;}while(--N);}/**********读保护存储器***********/void ReadProtectMemory(uchar *p){uchar i=4;Command(0x34,0xff,0xff);do{*p=ReceiveData();    p++;}while(i--);}/************写主存储器************/void WriteMainMemory(uchar Address,uchar Data){Command(0x38,Address,Data);Process();}/**************写保护存储器**********/void WriteProtectMemory(uchar Address,uchar Data){Command(0x3c,Address,Data);Process();}/**************读安全存储器************/void ReadSafeMemory(uchar *p){uchar i;Command(0x31,0xff,0xff);for(i=0;i<4;i++)  {*p=ReceiveData();  p++;}}/*************写安全存储器***************/void WriteSafeMemory(uchar Address,uchar Data){Command(0x39,Address,Data);//Address=0,1,2,3Process();}/**************校验密码*******************/uchar VerifyPassword(uchar *p){uchar temp[4];//暂存4字节保护密码;uchar i;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函数结束*****************////*************数据变换**********//void Change(uchar *Source,uchar *Destination,uchar N){uchar i,temp;for(i=0;i<N;i++){temp=Source;  Destination=temp>>4;  Destination[2*i+1]=temp&0x0f;}}//***********密码错误报警***********************//void Buzzle_Password(void){uchar i;for(i=0;i<2;i++){Voice(0);    DelayMs(1000);    Voice(1);    DelayMs(1000);}}//**********非法卡错误报警*************************// void Buzzle_Card(void){uchar i;for(i=0;i<2;i++){Voice(0);    DelayMs(3000);}}//*************余额不足报警**********************//void Buzzle_Money(void){uchar i;for(i=0;i<1;i++)  {Buzzle_Password();  Buzzle_Card();}}  //*********************读卡函数********************////说明://函数使用的数组参数用来存放读出的余额值;//返回值信息://0:卡坏!//1:非法卡(特征值不正确)//2:非法卡(特征值正确,帐号不正确)//3:读卡成功!uchar Read_Card(uchar *p){uchar i,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);  else return(3);}  else    return(1);  }else return(0);}//*********************卡初始化函数********************////说明://函数使用的数组参数用来存放写入的的ID值;//返回值信息://2:初始化失败!//3:初始化成功!uchar Initial_Card(uchar *p){uchar Psw[3]={0xff,0xff,0xff};uchar i,j,temp=0;uchar tp[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);//从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==tp[i+4]) temp=temp+1;  }  if(temp==10)  return(3);  else return(2);}//***************卡修复函数********************////说明://返回值信息://0:修复失败!//1:修复成功!            uchar Repair_Card(void){uchar Psw[3]={0xff,0xff,0xff};uchar i,j,temp;i=VerifyPassword(Psw);return(i);}//********************加卡函数***********//void Add_Card(uchar *p){uchar i;uchar temp[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]);}}//********************减卡函数***********//void Sub_Card(uchar *p){uchar i,B_Flag;uchar temp[14];i=Read_Card(temp);if((i==3)&&(!(temp[9]<p[0])))  {if(temp[13]<p[4]) {temp[13]=temp[13]+10-p[4];B_Flag=1;}  else temp[13]=temp[13]-p[4];  //以上处理小数点右边的数字;  if(B_Flag==1)  {if(temp[12]==0) {temp[12]=9;B_Flag=0;}    else temp[12]=temp[12]-1;}  //以上对存在借位情况时对小数点左边第一位进行预处理;  if(temp[12]<p[3]) {temp[12]=temp[12]+10-p[3];B_Flag=1;}  else temp[12]=temp[12]-p[3];  //以上处理小数点小数点左边第一位数字;   if(B_Flag==1)  {if(temp[11]==0) {temp[11]=9;B_Flag=0;}    else temp[11]=temp[11]-1;}  //以上对存在借位情况时对小数点左边第二位进行预处理;  if(temp[11]<p[2]) {temp[11]=temp[11]+10-p[2];B_Flag=1;}  else temp[11]=temp[11]-p[2];  //以上处理小数点小数点左边第二位数字;   if(B_Flag==1)  {if(temp[10]==0) {temp[10]=9;B_Flag=0;}    else temp[10]=temp[10]-1;}  //以上对存在借位情况时对小数点左边第三位进行预处理;  if(temp[10]<p[1]) {temp[10]=temp[10]+10-p[1];B_Flag=1;}  else temp[10]=temp[10]-p[1];  //以上处理小数点小数点左边第三位数字;  if(B_Flag==1)  {if(temp[9]==0) {temp[9]=0;B_Flag=0;}    else temp[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]);}}//*****************数码管显示函数********************//void Display(uchar *p){uchar sel,i;sel=0x01;for(i=0;i<6;i++)  {PORTA=table[p];    PORTB=sel;DelayMs(2);sel=sel<<1;}}//****************键盘扫描函数***********************//uchar Key_Scan(void){uchar sccode,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);}  //******************按键处理函数*******************//void Key_Process(uchar *p){uchar temp,value;temp=Key_Scan();switch(temp)  {case 0x11:value=9;Num_Flag=1;break;  case 0x21:value=8;Num_Flag=1;break;  case 0x41:value=7;Num_Flag=1;break;  case 0x12:value=6;Num_Flag=1;break;  case 0x22:value=5;Num_Flag=1;break;  case 0x42:value=4;Num_Flag=1;break;  case 0x14:value=3;Num_Flag=1;break;  case 0x24:value=2;Num_Flag=1;break;  case 0x44:value=1;Num_Flag=1;break;  case 0x18:value=0;Num_Flag=1;break;  case 0x28:Point_Flag=1;break;  case 0x82:Add_Flag=1;Sub_Flag=0;Key_Flag=1;break;  case 0x84:Sub_Flag=1;Add_Flag=0;Key_Flag=1;break;  case 0x48:Repair_Flag=1;Key_Flag=1;break;  case 0x81:Init_Flag=1;Key_Flag=1;break;  case 0x88: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中断显示一次*******//#pragma interrupt_handler TIMER1_INT:9 void TIMER1_INT(void){uchar temp[5],i;for(i=0;i<5;i++)  temp=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);}  }}//*************系统初始化*************//void Initial_System(void){//系统初始化//SPL=0x5f;//AT90S8535的堆栈指针指向最高RAM地址;//SPH=0x02;//IO口初始化;DDRA=0xff; //A口输出高电平PORTA=0xff;DDRB=0xff; //B口输出低电平PORTB=0x00;DDRC=0x0f; //C口高四位输入(不带上拉电阻)低四位输出0PORTC=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卡的内容}    void main(void){uchar i,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       {do Key_Process(Money);    while(Enter_Flag!=0);    Enter_Flag=0;}  }    }}

提醒:《AVR单片机读卡器程序设计》最后刷新时间 2024-03-14 01:00:13,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《AVR单片机读卡器程序设计》该内容的真实性请自行鉴别。