
曼彻斯特解码原则
1. 曼彻斯特编码
曼彻斯特编码(Manchester Encoding),也叫做相位编码(PE),是一个同步时钟编码技术,被物理层使用来编码一个同步位流的时钟和数据。曼彻斯特编码被用在以太网媒介系统中。曼彻斯特编码提供一个简单的方式给编码简单的二进制序列而没有长的周期没有转换级别,因而防止时钟同步的丢失,或来自低频率位移在贫乏补偿的模拟链接位错误。在这个技术下,实际上的二进制数据被传输通过这个电缆,不是作为一个序列的逻辑1或0来发送的(技术上叫做反向不归零制(NRZ))。相反地,这些位被转换为一个稍微不同的格式,它通过使用直接的二进制编码有很多的优点。
曼彻斯特编码,常用于局域网传输。在曼彻斯特编码中,每一位的中间有一跳变,位中间的跳变既作时钟信号,又作数据信号;从高到低跳变表示"1",从低到高跳变表示"0"。还有一种是差分曼彻斯特编码,每位中间的跳变仅提供时钟定时,而用每位开始时有无跳变表示"0"或"1",有跳变为"0",无跳变为"1"。
对于以上电平跳变观点有歧义:关于曼彻斯特编码电平跳变,在雷振甲编写的<<网络工程师教程>>中对曼彻斯特编码的解释为:从低电平到高电平的转换表示1,从高电平到低电平的转换表示0,模拟卷中的答案也是如此,张友生写的考点分析中也是这样讲的,而《计算机网络(第4版)》中(P232页)则解释为高电平到低电平的转换为1,低电平到高电平的转换为0。清华大学的《计算机通信与网络教程》《计算机网络(第4版)》采用如下方式:曼彻斯特编码从高到低的跳变是 0 从低到高的跳变是 1 。
两种曼彻斯特编码是将时钟和数据包含在数据流中,在传输代码信息的同时,也将时钟同步信号一起传输到对方,每位编码中有一跳变,不存在直流分量,因此具有自同步能力和良好的抗干扰性能。但每一个码元都被调成两个电平,所以数据传输速率只有调制速率的1/2。
就是说主要用在数据同步传输的一种编码方式。
【在曼彻斯特编码中,用电压跳变的相位不同来区分1和0,即用正的电压跳变表示0,用负的电压跳变表示1。因此,这种编码也称为相应编码。由于跳变都发生在每一个码元的中间,接收端可以方便地利用它作为位同步时钟,因此,这种编码也称为自同步编码。】
2. 曼彻斯特编码(Manchester Encoding),也叫做相位编码(PE);常用于局域网传输。在曼彻斯特编码中,每一位的中间有一跳变,位中间的跳变既作时钟信号,又作数据信号。但在不同的书籍中,曼彻斯特编码中,电平跳动表示的值不同,这里产生很多歧义:
1、在网络工程师考试以及与其相关的资料中:
位中间电平从高到低跳变表示"0";
位中间电平从低到高跳变表示"1"。
2、在一些《计算机网络》书籍中:
位中间 电平从高到低跳变表示"1";
位中间电平从低到高跳变表示"0"。
在清华大学出版的《计算机通信与网络教程》《计算机网络(第4版)》也是这么说的,就以此为标准,我们就叫这为标准曼彻斯编码。至于第一种,我们在这里就叫它曼彻斯特编码。但是要记住,在不同的情况下懂得变通哦,否则会被老师扣分数的哦 。这两者恰好相反,千万别弄混淆了。
现在我们要讲的 就是差分曼彻斯特编码:
在信号位开始时不改变信号极性,表示辑"1"
在信号位开始时改变信号极性,表示逻辑"0" ;
【注意】:如果在最初信号的时候,即第一个信号时:
如果中间位电平从低到高,则表示0;
如果中间位电平从高到低,则表示1;
后面的(从第二个开始)就看每个信号位开始时有没有跳变来决定:
下面我们来举个例子,来比较标准曼彻斯特编码、曼彻斯特编码、差分曼彻斯特编码:
EM4100系列用的是:曼彻斯特编码!
125K;EM4100系列RFID卡解码源程序分析
1.
我们知道了曼彻斯特编码原则,那么反过来的过程就是解码了。
EM4100系列用的是:曼彻斯特编码!
2.传统只读射频卡读卡器的设计一般采用U2270B或EM4095读写基站芯片加MCU模式,其成本高、功耗大。本文介绍一种采用一片74HC4060+LM258/358加少量普通元件构成的读卡器电路和处理的程序设计方案,电路简单、功耗小、成本低。 74HC4060+LM258/358 电路为市面上已非常成熟 RFID-125KHZ-I卡且广泛采用的低功耗、低成本方案。该方案在门禁、保安、考勤、展览会、公园、旅店、餐厅等公共场所的门票、优惠卡以及生产过程、邮政包裹、航空铁路运输、产品包装、交通等部门的物流、电子标签、防伪标 志、一次性票证等众多领域上占据半壁江山。
3.推挽式放大电路输出後接LC串联谐振电路,当回路固有谐振频率与输入讯号频率相等时,电路发生串联谐振。本文只要求对125kHz频率的讯号放大,所以根据串联谐振公式计算电路中元件参数,可得L=737uH,C=2200pF。
4.包络检波电路
感应线圈产生谐振电压约有20V,所以载波讯号的电压也约为20V。对输入电压高於500mV检波,称为「大讯号检波」,利用二极体单向导电特性及检波负载RC充放电过程实现。RC参数的确定需要满足两个条件:1.不产生隋性失真,一般工程上按计算,f为载波频率。2.不产生负峰切割失真,即,m为调幅系数,R1是交流阻值,R0是直流阻值。联立上述两个条件,确定检波电路中R12、C36分别为470kΩ、4700pF。
5.波形整形电路
在单晶片处理之前,整形电路将检波後的讯号变成单片机可以识别的高低电平。LM358 (LM258) 内部整合两个运放,经过两次整形後可以得到很好的方波讯号。电路中R16、R17、R18、R19起到分压作用,确定输出翻转门限为2.5V;R15、R21将同向输入的电压叠加在反向输入端;C54、C55为耦合电容,能够隔离直流分量,传递交流讯号。当U+大於U-+2.5V时,输出高电平;当U+小於U-+2.5V时,输出低电平。
6.读卡程序是根据EM4100、EM4001系列射频卡的特点量身定做的一段程序,射频卡以曼彻斯特编码,传输一个资料的时间t=/125kHz=512μs。实际使用中,一般传输时间为,230μs<0.5t<280μs。280μs<定时器取样时间<512μs。所以本文中取样波形时,定时器时间设定为400μs,保证为取样留有足够的时间。
原程序分析:
1. 定时器时间设定为400μs
#define TH0_H 0xfe// 定时器0 取样定时值设定为400us
#define TL0_L 0x8f//8f
2. 定时器0中断优先级最高:
PT0=1;
3. //曼彻斯同步头检测,9个1采用逐个前移检测法
//逐个前移检测法,即每检测到一个数据,如果是"1并向数据库写入1,
//如果是"0就放弃当前检测的数据,并向当前数据流方向移动一位,
//这样一来,就保证了不管数据流是在何种状态下,都能正确无误地抓取9个1,
//同步头9个1的提取成功,曼彻斯译码器即和当前的数据流保持了同步,
//并把余下的55位数据全部译完。
4. uchar REM_Buffer[14];//曼彻斯解码后得到最终数据的缓存0~13
/*曼彻斯解码后的数据放在 REM_Buffer[0~13];
REM_Buffer[0]=0xff 数据格式:1111 1111 同步头,8个1
REM_Buffer[1]=0x8x 数据格式:1xxx xxxx 同步头,1个1,x表示无意义
REM_Buffer[2]= 数据格式:D00D01D02D03 P0xxx 八个版本位或厂商信息的前四位,x表示无意义;P0为行效验位
REM_Buffer[3]= 数据格式:D10D11D12D13 P1xxx 八个版本位或厂商信息的后四位,x表示无意义;P1为行效验位
REM_Buffer[4]= 数据格式:D20D21D22D23 P2xxx 三十二个数据,x表示无意义;P2为行效验位
REM_Buffer[5]= 数据格式:D30D31D32D33 P3xxx 三十二个数据,x表示无意义;P3为行效验位
REM_Buffer[6]= 数据格式:D40D41D42D43 P4xxx 三十二个数据,x表示无意义;P4为行效验位
REM_Buffer[7]= 数据格式:D50D51D52D53 P5xxx 三十二个数据,x表示无意义;P5为行效验位
REM_Buffer[8]= 数据格式:D60D61D62D63 P6xxx 三十二个数据,x表示无意义;P6为行效验位
REM_Buffer[9]= 数据格式:D70D71D72D73 P7xxx 三十二个数据,x表示无意义;P7为行效验位
REM_Buffer[10]= 数据格式:D80D81D82D83 P8xxx 三十二个数据,x表示无意义;P8为行效验位
REM_Buffer[11]= 数据格式:D90D91D92D93 P9xxx 三十二个数据,x表示无意义;P9为行效验位
REM_Buffer[12]= 数据格式:PC0PC1PC2PC3 0xxx 四个列效验位,x表示无意义;0为停止位
原程序:
//2008.10.15
//125K;EM4100系列RFID卡解码
//#include #include #include #define uint unsigned int//定义 #define uchar unsigned char//定义 #define ulong unsigned long//定义 sbit REM=P2^1;// 曼彻斯特编码输入端 sbit CLK=P3^3;//产生125KHZ 时钟信号端 sbit LED=P2^5;// 红灯 sbit SPP=P1^0;// 喇叭 bit REM_BIT;// 曼彻斯高、低边沿跳变标志位, bit Efficacy_BIT; //待效验标志位, bit P_PC_BIT; //行,列效验标志位 bit YES_NO_BIT; //效验正确,或效验错误标志位, //YES_NO_BIT=1 表示效验正确; //YES_NO_BIT=0 表示效验错误。 #define TH0_H 0xfe// 定时器0 取样定时值设定为400us #define TL0_L 0x8f//8f //350~420us //375~450us uchar U_D_Buffer[5];//User_Data//用户数据缓存, ulong long_D;//方法1,卡号在 long_D 中,不足10位,则在高位前面加 0 uchar char_D;//方法2,前两位卡号在 char_D 中, uint int_D;//方法2,卡号后4位卡号在 int_D 中, uchar volue;//volue 为曼彻斯译码时的临时运算缓存 uchar REM_Buffer[14];//曼彻斯解码后得到最终数据的缓存0~13 /*曼彻斯解码后的数据放在 REM_Buffer[0~13]; REM_Buffer[0]=0xff 数据格式:1111 1111 同步头,8个1 REM_Buffer[1]=0x8x 数据格式:1xxx xxxx 同步头,1个1,x表示无意义 REM_Buffer[2]= 数据格式:D00D01D02D03 P0xxx 八个版本位或厂商信息的前四位,x表示无意义;P0为行效验位 REM_Buffer[3]= 数据格式:D10D11D12D13 P1xxx 八个版本位或厂商信息的后四位,x表示无意义;P1为行效验位 REM_Buffer[4]= 数据格式:D20D21D22D23 P2xxx 三十二个数据,x表示无意义;P2为行效验位 REM_Buffer[5]= 数据格式:D30D31D32D33 P3xxx 三十二个数据,x表示无意义;P3为行效验位 REM_Buffer[6]= 数据格式:D40D41D42D43 P4xxx 三十二个数据,x表示无意义;P4为行效验位 REM_Buffer[7]= 数据格式:D50D51D52D53 P5xxx 三十二个数据,x表示无意义;P5为行效验位 REM_Buffer[8]= 数据格式:D60D61D62D63 P6xxx 三十二个数据,x表示无意义;P6为行效验位 REM_Buffer[9]= 数据格式:D70D71D72D73 P7xxx 三十二个数据,x表示无意义;P7为行效验位 REM_Buffer[10]= 数据格式:D80D81D82D83 P8xxx 三十二个数据,x表示无意义;P8为行效验位 REM_Buffer[11]= 数据格式:D90D91D92D93 P9xxx 三十二个数据,x表示无意义;P9为行效验位 REM_Buffer[12]= 数据格式:PC0PC1PC2PC3 0xxx 四个列效验位,x表示无意义;0为停止位 */ uchar code DispTab[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; uchar code Data[]={"Data: "};//数据 uchar code UserData[]={"User Data: "};//用户数据 uchar code Card_1[]={"Methods 1 Decimal Card Number: "};//方法1:掐头留尾法提取10位十进制卡号: uchar code Card_2[]={"Methods 2 Decimal Card Number: "};////方法2:前两位+后4位的微根格式,段间以小数点或豆号隔开 uchar code DispTab_2[]={' ','H',','}; void init()// { TMOD=0x21; TH1=0xfd;//11.0592MHz 波特率: 9600 TL1=0xfd; PCON&=0x80; SCON=0x40; //AUXR=0x40;//波特率倍增 //11.0592MHz 115200 TH0=0x00;// TL0=0x00;// EA=1; ET0=1; TR0=0; TR1=1; ES=0; REN=1; PT0=1; //PT0H=1;//定时器0中断优先级最高:第三 //PT0H是 stc单片机特有的寄存器 REM=1; CLK=1; SPP=1; LED=1; REM_BIT=1; } void delay1(uint z)// delay(10); 10次为1ms { uchar x; for(;z>0;z--) { for(x=0;x<160;x++) { } } } /* void delay()// { _nop_(); _nop_(); _nop_(); } */ void Time_interrupt(void) interrupt 1 //定时器0中断 { TR0=0; //关闭定时器0,为曼彻斯提取数据定时器 } void RS232_in(void) interrupt 4//串口中断 { EA=0; if(RI==1)//接收 { RI=0; //SBUF_RI_Buffer[0]=SBUF;//RS2323接收缓冲区 } ////////////////// else //if(TI==1)//发送 TI=0; EA=1; } void RS232()//通信转输数据,发给 PC { uchar i; ulong mm; //ES=0; if((REM_Buffer[0]==0xff)&&(REM_Buffer[1]==0x80))//同步头9个1的判断,同步头正确,进入数据发送,否则退出 { for(i=0;i<6;i++) { SBUF=Data[i];//" " while(TI==0); TI=0; } for(i=0;i<13;i++) { SBUF=DispTab[(REM_Buffer[i]/16)]; //SBUF=REM_Buffer[i];//给 PC 发送REM_Buffer[0~13]个数据 while(TI==0);//TI=1,表示数据发送完毕, TI=0;//TI清零,并把余下的数据继续发送,直到13个数据全部发送完。 SBUF=DispTab[(REM_Buffer[i]%16)]; while(TI==0); TI=0; SBUF=DispTab_2[1];//'H' while(TI==0); TI=0; SBUF=DispTab_2[0];//' ' while(TI==0); TI=0; } for(i=0;i<94;i++) { SBUF=DispTab_2[0];//" " while(TI==0); TI=0; } //U_D_Buffer[5];//User_Data//用户数据缓存, for(i=0;i<11;i++) { SBUF=UserData[i];//" " while(TI==0); TI=0; } for(i=0;i<5;i++) { SBUF=DispTab[(U_D_Buffer[i]/16)]; while(TI==0); TI=0; SBUF=DispTab[(U_D_Buffer[i]%16)]; while(TI==0); TI=0; SBUF=DispTab_2[1];//'H' while(TI==0); TI=0; SBUF=DispTab_2[0];//' ' while(TI==0); TI=0; } for(i=0;i<120;i++) { SBUF=DispTab_2[0];//" " while(TI==0); TI=0; } for(i=0;i<31;i++) { SBUF=Card_1[i];//" " while(TI==0); TI=0; } //10位十进制卡号 Card_1 SBUF=DispTab[long_D/1000000000];//10 while(TI==0); TI=0; mm=long_D%1000000000; SBUF=DispTab[mm/100000000];//9 while(TI==0); TI=0; mm=long_D%100000000; SBUF=DispTab[mm/10000000];//8 while(TI==0); TI=0; mm=long_D%10000000; SBUF=DispTab[mm/1000000];//7 while(TI==0); TI=0; mm=long_D%1000000; SBUF=DispTab[mm/100000];//6 while(TI==0); TI=0; mm=mm%100000; SBUF=DispTab[mm/10000];//5 while(TI==0); TI=0; mm=long_D%10000; SBUF=DispTab[mm/1000];//4 while(TI==0); TI=0; mm=long_D%1000; SBUF=DispTab[mm/100];//3 while(TI==0); TI=0; mm=long_D%100; SBUF=DispTab[mm/10];//2 while(TI==0); TI=0; SBUF=DispTab[mm%10];//1 while(TI==0); TI=0; //////////////////////////////////Card_2 for(i=0;i<106;i++) { SBUF=DispTab_2[0];//" " while(TI==0); TI=0; } for(i=0;i<31;i++) { SBUF=Card_2[i];//" " while(TI==0); TI=0; } SBUF=DispTab[char_D/100];// while(TI==0); TI=0; char_D=char_D%100; SBUF=DispTab[char_D/10];// while(TI==0); TI=0; SBUF=DispTab[char_D%10];// while(TI==0); TI=0; SBUF=DispTab_2[2];////////////////////// while(TI==0); TI=0; SBUF=DispTab[int_D/10000];// while(TI==0); TI=0; int_D=int_D%10000; SBUF=DispTab[int_D/1000];// while(TI==0); TI=0; int_D=int_D%1000; SBUF=DispTab[int_D/100];// while(TI==0); TI=0; int_D=int_D%100; SBUF=DispTab[int_D/10];// while(TI==0); TI=0; SBUF=DispTab[int_D%10];// while(TI==0); TI=0; for(i=0;i<109;i++) { SBUF=DispTab_2[0];//" " while(TI==0); TI=0; } //} } //ES=0; } void REM_init()//射频接口初始化 { CLK=0;//为74HC4060 提供+5V电源,74HC4060得电后输出125KHZ信号 } void REM_Processing()//曼彻斯数据提取 { uchar i,ii; loop: TR0=0; volue=0; for(i=0;i<9;i++)//曼彻斯同步头检测,9个1采用逐个前移检测法 //逐个前移检测法,即每检测到一个数据,如果是"1并向数据库写入1, //如果是"0就放弃当前检测的数据,并向当前数据流方向移动一位, //这样一来,就保证了不管数据流是在何种状态下,都能正确无误地抓取9个1, //同步头9个1的提取成功,曼彻斯译码器即和当前的数据流保持了同步, //并把余下的55位数据全部译完。 { while(REM==1) { if(TR0==0) { goto loop; //break; } } TR0=0; TH0=TH0_H;//开启400us定时器, TL0=TL0_L; TR0=1; while(TR0==1); TH0=TH0_H;//开启400us定时器,同步头逐个前移检测 TL0=TL0_L; TR0=1; if(REM==0) { goto loop; } if(i<8) { volue<<=1; volue|=0x01; if(i==7) { REM_Buffer[0]=volue; } } } REM_Buffer[1]=0x80; TR0=0; REM_BIT=0; volue=0x00; TH0=TH0_H;//400us TL0=TL0_L; //下降 TR0=1; for(i=2;i<13;i++)//曼彻斯解码 { for(ii=0;ii<5;ii++)//曼彻斯解码 { while(TR0==1); if(REM==1) { if(REM_BIT==0) { while(REM==1);//曼彻斯跳变为高电平 _nop_(); _nop_(); _nop_(); _nop_();//抗抖动 while(REM==1);// _nop_(); _nop_(); _nop_(); _nop_();//抗抖动 while(REM==1);// volue<<=1;//用左移指令把"1"移入volue volue|=0x08;//跳变的瞬间提取数据, TH0=TH0_H;//开启400us定时器,为下次提取数据提供参考 TL0=TL0_L; TR0=1; REM_BIT=0;//曼彻斯标志位置"0" } else //if(REM_BIT==1) { while(REM==1);//曼彻斯跳变为高电平 _nop_(); _nop_(); _nop_(); _nop_();//抗抖动 while(REM==1); _nop_(); _nop_(); _nop_(); _nop_();//抗抖动 while(REM==1); volue<<=1;//用左移指令把"1"移入volue volue|=0x08;//跳变的瞬间提取数据, TH0=TH0_H;//开启400us定时器,为下次提取数据提供参考 TL0=TL0_L; TR0=1; REM_BIT=0;//曼彻斯标志位置"0" } } else //if(REM==0) { if(REM_BIT==0) { while(REM==0);//曼彻斯跳变为下降沿 _nop_(); _nop_(); _nop_(); _nop_();//抗抖动 while(REM==0); _nop_(); _nop_(); _nop_(); _nop_();//抗抖动 while(REM==0); volue<<=1;//用左移指令把"0"移入volue TH0=TH0_H;//开启400us定时器,为下次提取数据提供参考 TL0=TL0_L; TR0=1; REM_BIT=1;//曼彻斯标志位置"1" } else //if(REM_BIT==1) { while(REM==0);//曼彻斯跳变为下降沿 _nop_(); _nop_(); _nop_(); _nop_();//抗抖动 while(REM==0); _nop_(); _nop_(); _nop_(); _nop_();//抗抖动 while(REM==0); volue<<=1;//用左移指令把"0"移入volue TH0=TH0_H;//开启400us定时器,为下次提取数据提供参考 TL0=TL0_L; TR0=1; REM_BIT=1;//曼彻斯标志位置"1" } } } REM_Buffer[i]=volue; volue=0x00; } } void Efficacy()//数据效验 { uchar i,ii,cache,cache_1,counter; //counter=0; for(i=2;i<12;i++)//行效验 { counter=0; cache=REM_Buffer[i]; cache_1=REM_Buffer[i]; for(ii=0;ii<4;ii++) { cache&=0x80; if(cache==0x80) { counter++; } cache_1<<=1; cache=cache_1; } if((counter==0)||(counter==2)||(counter==4)) { Efficacy_BIT=0; } else if((counter==1)||(counter==3)) { Efficacy_BIT=1; } cache=REM_Buffer[i]; cache&=0x08; if(cache==0x08) { P_PC_BIT=1; } else { P_PC_BIT=0; } if(Efficacy_BIT==P_PC_BIT) { YES_NO_BIT=1; //表示效验正确 } else { YES_NO_BIT=0; //表示效验错误 } if(YES_NO_BIT==0)//效验错误,无条件返回 { return; } } cache_1=0x80; for(i=0;i<4;i++)//列效验 { counter=0; for(ii=2;ii<12;ii++) { cache=REM_Buffer[i]; cache&=cache_1; if(cache==cache_1) { counter+=1; } } if((counter==0)||(counter==2)||(counter==4)||(counter==6)||(counter==8)||(counter==10)) { Efficacy_BIT=0; } else if((counter==1)||(counter==3)||(counter==5)||(counter==7)||(counter==9)) { Efficacy_BIT=1; } cache=REM_Buffer[13]; cache&=cache_1; if(cache==cache_1) { P_PC_BIT=1; } else { P_PC_BIT=0; } if(Efficacy_BIT==P_PC_BIT) { YES_NO_BIT=1; //表示效验正确 } else { YES_NO_BIT=0; //表示效验错误 } if(YES_NO_BIT==0)//效验错误,无条件返回 { return; } cache_1>>=1; } } void User_Data()//提取用户数据,//U_D_Buffer[5] { uchar i,ii,cache_2,cache_3; ii=0; for(i=2;i<12;i++) { cache_2=REM_Buffer[i]; cache_2&=0xf0; i++; cache_3=REM_Buffer[i]; cache_3&=0xf0; cache_3>>=4; U_D_Buffer[ii]=cache_2|cache_3; ii++; } } void Card_Conversion_1()////在用户数据中提取卡号信息,10位十进制卡号 { //方法1:掐头留尾法 long_D=0x00000000; long_D=U_D_Buffer[2]; long_D<<=8; long_D|=U_D_Buffer[3]; long_D<<=8; long_D|=U_D_Buffer[4];//方法1,卡号在 long_D 中 } void Card_Conversion_2()////在用户数据中提取卡号信息,10位十进制卡号 { //方法2:前两位+后4位的微根格式,段间以小数点或豆号隔开 int_D=0x0000; char_D=U_D_Buffer[2]; int_D|=U_D_Buffer[3]; int_D<<=8; int_D|=U_D_Buffer[4]; } void main() { init();//单片机(寄存器)硬件资源初始化 REM_init();//射频接口初始化 //delay1(2000);//初次上电,作短延时,使电源稳定 //delay(); while(1) { REM_Processing();//曼彻斯数据提取 if((REM_Buffer[0]==0xff)&&(REM_Buffer[1]==0x80))//同步头9个1的判断,同步头正确,进入数据发送,否则推退出 { Efficacy();//数据效验 if(YES_NO_BIT==1)//效验正确后,继续提取有用信息 { User_Data();//提取用户数据, Card_Conversion_1();//在用户数据中提取卡号信息,10位十进制卡号。 Card_Conversion_2();//在用户数据中提取卡号信息,10位十进制卡号。 RS232();//通信传输数据,发给 PC 显示。 LED=~LED;//LED闪烁,表示数据有效且发出数据。 //SPP=~SPP; delay1(600); SPP=1; LED=1; SPP=1; } } } }
