为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

51单片机的FM1702射频卡例程

2019-05-27 49页 doc 77KB 48阅读

用户头像

is_882336

暂无简介

举报
51单片机的FM1702射频卡例程51单片机的FM1702射卡程序历程许昌美景电子产品有限公司 #include #include #include #define uchar unsigned char #define uint unsigned int uchar Fbuff[16]; //发送FIFO缓存 uchar Jbuff[16]; //接收FIFO缓存 uchar UID[7]; //卡型及卡号 uchar Data[4]; //按键值存储区 uchar code seg[16]={0xC0,0xF9,0xA4,0xB0,0...
51单片机的FM1702射频卡例程
51单片机的FM1702射卡程序历程许昌美景电子产品有限公司 #include #include #include #define uchar unsigned char #define uint unsigned int uchar Fbuff[16]; //发送FIFO缓存 uchar Jbuff[16]; //接收FIFO缓存 uchar UID[7]; //卡型及卡号 uchar Data[4]; //按键值存储区 uchar code seg[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6, 0xA1,0x86,0x8E}; //数码管段选对应0~f uchar count=0 ; //按键回传的值 uchar shuaka,chongzhi,keyflag=0; sbit k2=P3^5; //充值‘加值键(实现加1或者加10) sbit k3=P3^2; //刷卡’减值键(实现减1或者减10) sbit k4=P3^3; //确认键 sbit nWR=P2^4; //74hc373片选 /*****************1702函数声明**************************/ uchar spi(uchar m); void fifo_clear(); void resig_write(uchar reg,uchar da); uchar resig_read(uchar reg); uchar fifo_read(uchar count,uchar *s); void fifo_write(uchar count,uchar *s); uchar inti_1702(); void card_halt(); uchar request(); uchar card_anticoll(); uchar card_select(); uchar card_authtication(uchar m) ; uchar card_read(uchar m); uchar card_write(uchar m); uchar loadkey(); void delay(uchar m); /********************按键显示函数声明***************/ void display(); void keyscan() ; void data1deal() ; void data2deal(uchar m); void lcdclear(); /***********************子函数解释******************/ /*********************************************************/ //解释:这是spi总线的读写时序,所有的寄存器操作基于此时序,非常重要 // // //输入:要写入的16进制参数 // // //输出:内部传回的16进制参数 // /********************************************************/ uchar spi(uchar m) { uchar i,temp=0; for(i=0;i<8;i++) { sck=0; if(m&0x80) mosi=1; else mosi=0; m<<=1; sck=1; temp<<=1; if(miso) temp|=0x01; } sck=0; mosi=0; return temp; } /*********************************************************/ //解释:写寄存器函数 // // //输入:寄存器地址以及要写入的参数 // // //输出: // //注意!!在所有的资料中都没有给出寄存器寻址时的格式,下边的有,看仔细了,如果连寄存器都找不到,后边的就不用看了 /********************************************************/ void resig_write(uchar reg,uchar da) { sck=0; reg<<=1; cs=0; reg=reg&0x7e; spi(reg); spi(da); cs=1; } /*********************************************************/ //解释:读寄存器函数 // // //输入:寄存器地址 // // //输出:该寄存器目前的值 // //注意!!读写寄存器时指令不一样,仔细看。 /********************************************************/ uchar resig_read(uchar reg) { uchar temp; sck=0; _nop_(); _nop_(); cs=0; reg<<=1; reg|=0x80; spi(reg); temp=spi(0x00); cs=1; return temp; } /*********************************************************/ //解释:FIFO缓冲器的读函数 // // //输入:读取的字节个数,返回的值存放首地址 // // //输出:读成功的话会返回真值,否则返回0 // // /********************************************************/ uchar fifo_read(uchar count,uchar *s) uchar i,temp; temp=resig_read(FIFOLength); if(temp协议
,次程序执行成功后才可以与卡进行交易 /********************************************************/ uchar card_authtication(uchar m) { uchar i,temp; temp=resig_read(Control); temp=temp|0x01; resig_write(Control,temp); Fbuff[0]=0x60; Fbuff[1]=m; for(i=0;i<4;i++) { Fbuff[i+2]=UID[i]; } fifo_write(6,Fbuff); resig_write(InterruptEn,0xa5); resig_write(Command,0x0c); delay(2); temp=resig_read(SecondaryStatus); temp=temp&0x07; if(temp==0) { temp=resig_read(Control); temp=temp|0x01; resig_write(Control,temp); resig_write(InterruptEn,0xa4); resig_write(Command,0x14); delay(2); temp=temp=resig_read(Control); temp&=0x08; if(temp==0x08) return 1; else return 0; } return 0; } /*********************************************************/ //解释:读卡函数 // // //输入:要读的考号 // // //输出:读卡成功的话返回真值,否则返回0 // //实现功能:读取指定卡号的内容,并传送给FIFO /********************************************************/ uchar card_read(uchar m) { uchar temp; temp=resig_read(Control); temp=temp|0x01; resig_write(Control,temp); resig_write(ChannelRedundancy,0x0f); temp=resig_read(Control); temp=temp|0x01; resig_write(Control,temp); Fbuff[0]=0x30; Fbuff[1]=m; fifo_write(2,Fbuff); resig_write(Command,0x1e); delay(0x04); temp=resig_read(FIFOLength); if(temp==16) { fifo_read(16,Jbuff); return 1; } else return 0; } /*********************************************************/ //解释:写卡函数 // // //输入:要写入的卡号 // // //输出:写卡成功的话返回真值,否则返回0 // //实现功能:将发送缓冲区的数据写入指定的块号 /********************************************************/ uchar card_write(uchar m) { uchar temp; temp=resig_read(Control); temp=temp|0x01; resig_write(Control,temp); Fbuff[0]=0xA0; Fbuff[1]=m; fifo_write(2,Fbuff); resig_write(Command,0x1e); delay(2); temp=resig_read(FIFOLength); if(temp==1) { temp=resig_read(Control); temp=temp|0x01; resig_write(Control,temp); Fbuff[0]=Jbuff[0]; fifo_write(16,Fbuff); resig_write(Command,0x1e); delay(10); temp=resig_read(FIFOLength); if(temp==1) return 1; else return 0; } else return 0; } /*********************************************************/ //解释:加载密匙函数 // // //输入: // // //输出:成功的话返回真值,否则返回0 // //实现功能:建立与卡通信协议的第一步,将密匙发送给卡,验证密匙是否成功,成功的话执行三重认证 /********************************************************/ uchar loadkey() { uchar temp; temp=resig_read(Control); temp=temp|0x01; resig_write(Control,temp); fifo_write(12,changekey); resig_write(Command,0x19); delay(3); temp=resig_read(ErrorFlag); if(temp==0) return 1; else return 0; } /*********************************************************/ //解释:设置卡的暂停态函数 // // //输入: // // //输出:执行成功的话返回真值,否则返回0 // //实现功能:将卡设置为终止交易态,若要再次交易必须从头重新开始认证/********************************************************/ void card_halt() { uchar temp; resig_write(InterruptEn,0x7f); resig_write(InterruptRq,0x7f); resig_write(Command,0x00); temp=resig_read(Control); temp=temp|0x01; resig_write(Control,temp); Fbuff[0]=0x50; Fbuff[1]=0x00; fifo_write(2,Fbuff); resig_write(InterruptEn,0xbd); resig_write(Command,0x1e); delay(2); } /****************按键显示子函数解释********************/ /*********************************************************/ //解释:卡的高两位序列号函数 // // //输入: // // //输出: // //实现功能:将卡的高两位序列号处理为16进制后存放在相应显示区/********************************************************/ void data1deal() //序列号处理 { uchar temp,i; for(i=0;i<4;i++) Data[i]=0; temp=UID[3]; Data[1]=temp/16; Data[0]=temp%16; temp=UID[2]; Data[3]=temp/16; Data[2]=temp%16; } /*********************************************************/ //解释:显示数据处理函数 // // //输入: // // //输出: // //实现功能:将要现实的数据处理为10进制后存放在相应显示区 /********************************************************/ void data2deal(uchar m) //显示数据及按键处理 { uchar i,temp; for(i=0;i<4;i++) Data[i]=0; temp=m; Data[0]=temp%10; Data[1]=temp%100/10; Data[2]=temp/100; } /*********************************************************/ //解释:按键扫描函数 // // //输入: // // //输出:输出相应的交易种类以及交易数额(会在说明里做详细说明) // // /********************************************************/ void keyscan() { if(k2==0||k3==0) { if(k2==0) { delay(100); if(k2==0) delay(250); if(keyflag==1) { if(k2==1) { if(count==255) count=0 ; else count++; } if(k2==0) { while(!k2) display(); if(count>=246) count=count+11; else count=count+10; } } else { chongzhi=1; shuaka=0; } } if(k3==0) { delay(100); if(k3==0) delay(250); if(keyflag==1) { if(k3==1) { if(count==0) count=255; else count--; } if(k3==0) { while(!k3) display(); if(count<=9) count=245+count; else count=count-10; } } else { shuaka=1; chongzhi=0; } } } if(k4==0) { delay(180); if(k4==0) keyflag=keyflag+1; } } /*********************************************************/ //解释:显示函数 // // //输入: // // //输出: // // /********************************************************/ void display() { unsigned char time=0; nWR=0; P2=0x0f; WR=0; P0=seg[Data[3]]; WR=1; P2=0X0e; time=5000; while(time--); nWR=0; P2=0x0f; WR=0; P0=seg[Data[2]]; WR=1; P2=0X0d; time=5000; while(time--); nWR=0; P2=0x0f; WR=0; P0=seg[Data[1]]; WR=1; P2=0X0b; time=5000; while(time--); nWR=0; P2=0x0f; WR=0; P0=seg[Data[0]]; WR=1; P2=0X07; time=5000; while(time--); } /*********************************************************/ //解释:lcd清屏函数 // // //输入: // // //输出: // /********************************************************/ void lcdclear() { nWR=0; P2=0x0f; WR=0; P0=0xff; WR=1; P2=0X0e; nWR=0; P2=0x0f; WR=0; P0=0xff; WR=1; P2=0X0d; nWR=0; P2=0x0f; WR=0; P0=0xff; WR=1; P2=0X0b; nWR=0; P2=0x0f; WR=0; P0=0xff; WR=1; P2=0X07; } /*****************************主函数****************************/ void main() { uchar temp,p,i,j; temp=inti_1702(); while(1) { switch(temp) { case 0: p=inti_1702();if(p) temp++;else temp=0;break; case 1: p=request(); if(p) {temp++;led5=~led5;}else temp=1;break; case 2: p=card_anticoll(); if(p){ temp++;led6=~led6;}else temp=1;break; case 3: p=card_select(); if(p) temp++; else temp=1;break; case 4: p=loadkey();if(p){temp++;led7=~led7;} else temp=1;break; case 5: p=card_authtication(PICC_BLOCK);if(p){ temp++;led8=~led8;}else temp=1;break; case 6: p=card_read(PICC_BLOCK); if(p) { temp++; data1deal(); for(i=0;i<2;i++) for(j=0;j<150;j++) display(); data2deal(Jbuff[0]); i=10; j=200; while(i--) { while(j--) { display(); keyscan(); if(shuaka||chongzhi) { data2deal(count); display(); if(keyflag==0x02) { if(shuaka) Jbuff[0]=Jbuff[0]-count ; if(chongzhi) Jbuff[0]=Jbuff[0]+count; keyflag=0; shuaka=0; chongzhi=0; count=0; j=0; i=0; } else j=100; } } } } else temp=0;break; case 7: p=card_write(PICC_BLOCK);if(p){temp++;led9=~led9;} else temp=0;break; case 8: p=card_read(PICC_BLOCK); if(p) { temp++; data1deal(); for(i=0;i<2;i++) for(j=0;j<150;j++) display(); data2deal(Jbuff[0]); i=5; j=200; while(i--) { while(j--) display(); } lcdclear() ; } else temp=0; break; case 9: card_halt();temp=0;break; default: break; } } }
/
本文档为【51单片机的FM1702射频卡例程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索