搜索
bottom↓
回复: 2

t5557这段代码谁用过讲讲思路

[复制链接]

出0入0汤圆

发表于 2010-11-25 23:46:29 | 显示全部楼层 |阅读模式
我正在搞T5557卡的读写,发现读卡不对.曼码输出.输出管脚一直有跳变,放卡和不放卡一样有.只是解码出来的数据不一样.不
放卡时测得的是05,放卡是07,解码程序如下:
解码部分按网上一位仁兄的取奇数位来读码.大虾,代码如下,小弟恳请指
教./****************temic*********t5557***********************************/
#include   "at892051.h"
#include   "string.h"
#include   "intrins.h"
#include   "stdio.h"
#define    uchar    unsigned char
#define    uint     unsigned int
#define    ulong    unsigned long
//STC12C2051AD的SFR定义
sfr  WDT_CONTR = 0xe1;//stc2051的看门狗??????
/**********全局常量************/
//写卡的命令
#define    write_command0       0//写密码
#define    write_command1       1//写配置字
#define    write_command2       2//密码写数据
#define    write_command3       3//唤醒
#define    write_command4       4//停止命令
#define    TRUE       1
#define    FALSE      0
#define    OK         0
#define    ERROR      255
//读卡的时间参数us
#define ts_min                250//270*11.0592/12=249//取近似的整数
#define ts_max                304//330*11.0592/12=304
#define t1_min                73//90*11.0592/12=83:-10调整
#define t1_max                156//180*11.0592/12=166
#define t2_min                184//210*11.0592/12=194
#define t2_max                267//300*11.0592/12=276

///***********不采用中断处理:采用查询的方法读卡时关所有中断****************/
sbit p_U2270B_Standby = P3^5;//p_U2270B_Standby BIT P3.5;AT89C2051:T1;
sbit p_U2270B_CFE     = P3^3;//p_U2270B_CFE     BIT p3.3;AT89C2051:INT1
sbit p_U2270B_OutPut  = P3^7;//p_U2270B_OutPut  BIT p3.7;AT89C2051:
sbit wtd_sck      = P1^7;//SPI总线
sbit wtd_si       = P1^3;
sbit wtd_so       = P1^2;

sbit   iic_data   = P1^2;//lcd IIC
sbit   iic_clk    = P1^7;

sbit   led_light  = P1^6;//测试绿灯
sbit   led_light1 = P1^5;//测试红灯
sbit   led_light_ok  = P1^1;//读卡成功标志
sbit   fengmingqi = P1^5;
/***********全局变量************************************/
/////////////////////////////////////////////////////////
        uchar data Nkey_a[4]    =  {0xA0, 0xA1, 0xA2, 0xA3};//初始密码        
        //uchar idata card_snr[4];   //配置字
        uchar data bankdata[28]={1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7};     //存储卡上用户
数据(1-7)7*4=28
        uchar data comsendbuff[9];   //串口数组被分配在直接寻址ram?
                uchar data cominceptbuff[6]={1,2,3,4,5,6};//串口接收数组ram
//uchar cominceptoldbuff[3]={0,0,0};        //串口接收记忆
//uchar cominceptbuff[8]={0,0,0,0,0,0,0,0};                //串口接收缓冲
///////////////////quan ju bian liang/////////////////////////////////////////
//uint T1_int_time;                        //quan ju bian liang:T1 initial
//uint T0_int_time=0;                        //quan ju bian liang:T0 initial
//uchar read_count;
uchar jieshoujishu=0;
uchar sendjishu=0;
uchar command; //第一个命令
uchar command1;//
//uint  temp;
uchar j,i;
uchar myaddr=8;
//uchar ywqz_count,time_count;             //ywqz jishu:
uchar bdata DATA;
sbit BIT0=DATA^0;
sbit BIT1=DATA^1;
sbit BIT2=DATA^2;
sbit BIT3=DATA^3;
sbit BIT4=DATA^4;
sbit BIT5=DATA^5;
sbit BIT6=DATA^6;
sbit BIT7=DATA^7;

uchar bdata DATA1;
sbit BIT10=DATA1^0;
sbit BIT11=DATA1^1;
sbit BIT12=DATA1^2;
sbit BIT13=DATA1^3;
sbit BIT14=DATA1^4;
sbit BIT15=DATA1^5;
sbit BIT16=DATA1^6;
sbit BIT17=DATA1^7;

bit i_CurrentLevel;//i_CurrentLevel  BIT 00H(Saves current level of OutPut pin of U2270B)
bit timer1_end;
bit com_ov=0;
bit com_send;
bit read_ok=0;
//缓存定时值,因用同一个定时器
union HLint{uint W;
            struct{uchar H;uchar L;}B;};//union HLint idata a
union HLint data a;
//缓存定时值,因用同一个定时器
union HLint0{uint W;
            struct{uchar H;uchar L;}B;};//union HLint idata a
union HLint0 data b;
/**********************函数原型*****************/
//读写操作
void f_readcard(void);//全部读出1~7 AOR唤醒
void f_writecard(uchar x);//根据命令写不同的内容和操作
void f_clearpassword(void);//清除密码
void f_changepassword(void);//修改密码
//串口处理
void process_data(void);//接收数据处理
void com_readsend(void);//发送数据处理
//功能子函数
void write_password(uchar data *data p);//写初始密码或数据
void write_block(uchar x,uchar data *data p);//不能用通用指针
void write_bit(bit x);//写位
//中断函数
void timer1(void);//波特率产生
void com(void);//串口中断

/*子函数区*****************************************************/
void delay_2(uint x)        //延时,时间x*10us@12MHz,最小20us@12MHz
{
        x--;x--;
        while(x)
        {
                _nop_();
                _nop_();
                x--;
        }
        _nop_();//WDT_CONTR=0X3C;不能频繁的复位
        _nop_();
}
/*用来产生延时的过程函数即无返回参数*/
/*void delay(uint i)                          
{
   while(i--)     //为了得到延时时间但要防止看门狗复位(very good值得借鉴)
   {
       WDT_CONTR=0X3C;//stc12c2051ad:WDT_CONTR喂狗
           WDT_CONTR=0X3C;
           _nop_();
           _nop_();
                       //89c55:WDREG=0x1e;
                   //WDREG=0xe1;//复位看门狗即喂狗
   }
}
*/
/////////////////////////////////////////////////////////////////////
void initial(void)
{
   
        SCON = 0x50; //串口方式1,允许接收
    //SCON  =0x50;
    //01010000B:10位异步收发,波特率可变,SM2=0不用接收到有效停止位才RI=1,
    //REN=1允许接收
        TMOD = 0x21; //定时器1 定时方式2(8位),定时器0 定时方式1(16位)

        TCON = 0x40; //设定时器1 允许开始计时(IT1=1)

        TH1 = 0xfD;  //FB 18.432MHz 9600 波特率

        TL1 = 0xfD;  //fd 11.0592 9600

        IE=0X90;     //EA=ES=1
   
        TR1 = 1;     //启动定时器
      
    WDT_CONTR=0x3c;//使能看门狗

    p_U2270B_Standby=0;//单电源
   
    PCON  =0x00;

    IP    =0x10;//uart you xian XXXPS PT1 PX1 PT0 PX0
   
        led_light1 =1;
        led_light =0;
        p_U2270B_OutPut=1;
}
////////////////////////////////////////////
void main()
{
    initial();
    TI=RI=0;
    ES=1;
    EA=1;
    //f_readcard();
    while(1)
    {
            WDT_CONTR=0X3C;//delay_2(2);//dog               
        if (com_ov)//接收溢出,处理数据
                {
                    process_data();
            WDT_CONTR=0x3c;//喂狗1.13s
            if(com_send)//串口需返回数据
            {
                                com_readsend();
                        com_send=0;
                    }
            com_ov=0;
                }               
                //led_light_ok=1;//成功
        WDT_CONTR=0X3C;
                delay_2(20000);
                //WDT_CONTR=0X3C;
        delay_2(20000);        
        delay_2(20000);
        WDT_CONTR=0X3C;
                led_light=!led_light;             
    }
}
////////////////////功能函数///////////////////////////////////////////////////

void com_readsend(void)
{
        uchar i;
        uchar a;
        comsendbuff[0]=myaddr;                                //本机地址        返回数据
        comsendbuff[1]=command;             //命令1
        comsendbuff[2]=command1;                //命令2
        switch(command1)
        {
                case 1:{comsendbuff[3]=bankdata[0];comsendbuff[4]=bankdata[1];
                        comsendbuff[5]=bankdata[2];comsendbuff[6]=bankdata[3];}break;//数据区1;
            case 2:{comsendbuff[3]=bankdata[4];comsendbuff[4]=bankdata[5];
                        comsendbuff[5]=bankdata[6];comsendbuff[6]=bankdata[7];}break;//数据区2;      
            
                case 3:{comsendbuff[3]=bankdata[8];comsendbuff[4]=bankdata[9];
                        comsendbuff[5]=bankdata[10];comsendbuff[6]=bankdata[11];}break;//数据区3;        
       
                case 4:{comsendbuff[3]=bankdata[12];comsendbuff[4]=bankdata[13];
                        comsendbuff[5]=bankdata[14];comsendbuff[6]=bankdata[15];}break;//数据区4;
                case 5:{comsendbuff[3]=bankdata[16];comsendbuff[4]=bankdata[17];
                        comsendbuff[5]=bankdata[18];comsendbuff[6]=bankdata[19];}break;//数据区5;          
          
                case 6:{comsendbuff[3]=bankdata[20];comsendbuff[4]=bankdata[21];
                        comsendbuff[5]=bankdata[22];comsendbuff[6]=bankdata[23];}break;//数据区6;
                case 7:{comsendbuff[3]=bankdata[24];comsendbuff[4]=bankdata[25];
                        comsendbuff[5]=bankdata[26];comsendbuff[6]=bankdata[27];}break;//数据区7;
                default:{comsendbuff[3]=cominceptbuff[0];comsendbuff[4]=cominceptbuff[1];
                        comsendbuff[5]=cominceptbuff[2];comsendbuff[6]=cominceptbuff[3];}break;//数据区
7;
        }
    comsendbuff[7]=command1;
        a=0;
        for (i=3;i<8;i++)
        {
                a^=comsendbuff;
        }
        comsendbuff[8]=a;                                        //校验
        SBUF=comsendbuff[0];
        sendjishu=0;
        REN=0;                                                        //发送时不能接收
        //SM2=1;
        //TB8=0;
       
}


///////////////////////////////////////
void process_data(void)
{
    uchar i,a=0;
        for(i=0;i<5;i++)
        {
                a^=cominceptbuff;
        }
        if(cominceptbuff[5]==a)//
        {
                if(command==0x00)      {f_readcard();read_ok=0;com_send=1;}//读卡   
                else if(command==0x01) {f_writecard(command1);com_send=1;} //写卡
            else if(command==0x02) {f_clearpassword();com_send=1;}     //清除密码
            else if(command==0x03) {f_changepassword();com_send=1;}    //改密码
            else com_send=0;REN=1; //命令不对不回传
        }
        else com_send=0;REN=1;//校验无效不回传
}
/************************************************/
void f_readcard()//读卡
{
    EA=0;//全关,防止影响跳变的定时器计时
        WDT_CONTR=0X3C;//喂狗
    p_U2270B_CFE=1;//
    delay_2(232);  //>2.5ms      
    /*
        //   aor    用唤醒功能来防碰撞
    p_U2270B_CFE=0;delay_2(18);//start gap>150us
    write_bit(1);//10=操作码读0页
    write_bit(0);   
    write_password(&bankdata[24]);//密码block7
    p_U2270B_CFE=1;//
    delay_2(516);//编程及确认时间5.6ms
        */
        WDT_CONTR=0X3C;//喂狗
        led_light=0;
        b.W=0;
    while(!(read_ok==1))
    {              
                //while(p_U2270B_OutPut);//等一个稳定的低电平?超时判断?      
            while(!p_U2270B_OutPut);//等待上升沿的到来同步信号检测1
                TR0=1;
            //deng xia jiang
                while(p_U2270B_OutPut);//等待下降沿
                TR0=0;a.B.H=TH0;a.B.L=TL0;TH0=TL0=0;TR0=1;//定时器晚启动10个周期
                        //同步头
            if((324 < a.W)&&(a.W < 353)) ;//检测同步信号1               
            else {TR0=0;TH0=TL0=0;goto read_error;}
            //等待上升沿
            while(!p_U2270B_OutPut);TR0=0;a.B.H=TH0;a.B.L=TL0;TH0=TL0=0;TR0=1;//b.N1<<=8;            
            if(a.B.L < 195);//0.5p
            else {TR0=0;TH0=TL0=0;goto read_error;}
               
            //读0~7块的数据
            for(j=0;j<28;j++)
            {
                        //uchar i;                       
                    for(i=0;i<16;i++)//8个位
                    {
                            //等待下降沿的到来
                        while(p_U2270B_OutPut);              
                        TR0=0;a.B.H=TH0;a.B.L=TL0;TH0=TL0=0;TR0=1;          
                       
                                if(t2_max < a.W/*)&&(a.W < t2_max)*/)//1P
                        {
                        b.W>>=2;//先左移再赋值
                        b.B.L+=0xc0;                       
                        i++;
                    }
                        else if(t1_min < a.B.L/*)&&(a.B.L < t1_max)*/)//0.5p
                        {
                            b.W>>=1;
                            b.B.L+=0x80;                          
                        }
                        else {TR0=0;TH0=TL0=0;goto read_error;}
                               i++;
                                while(!p_U2270B_OutPut);//上升              
                        TR0=0;a.B.H=TH0;a.B.L=TL0;TH0=TL0=0;TR0=1;                       
                        if(t2_min < a.W/*)&&(a.W < t2_max)*/)//1P
                        {
                            b.W>>=2;
                           
                            i++;
                        }
                        else if(t1_min < a.B.L/*a.W)&&(a.B.L < t1_max)*/)//0.5P
                                //else if(!(a.W==0))
                        {
                                b.W>>=1;
                                //temp+=0x00;
                                //led_light1=0;led_light=1;delay_2(40000);
                        }
                        else {TR0=0;TH0=TL0=0;goto read_error;}
                        i++;
                }
            //取出奇位
                DATA=b.B.L;
                BIT13=BIT7;BIT12=BIT5;BIT11=BIT3;BIT10=BIT1;
                DATA=b.B.H;
                BIT17=BIT7;BIT16=BIT5;BIT15=BIT3;BIT14=BIT1;
        bankdata[j]=DATA1;
        }        
    read_ok=1;EA=ES=1;//读卡完成了
    read_error:_nop_();
    }       
}
/***************************************************/

void f_writecard(uchar x)//写卡
{
    p_U2270B_CFE=1;
        delay_2(232);  //>2.5ms      
        //psw=0 standard write
    if (x==write_command0)//写密码:初始化密码
    {
            uchar i;
                uchar data *data p;
                p=cominceptbuff;
                p_U2270B_CFE=0;delay_2(31);//start gap>330us
            write_bit(1);//写操作码1:10
            write_bit(0);//写操作码0
            write_bit(0);//写锁定位0
                for(i=0;i<35;i++)
                {
            write_bit(1);//写数据位1
                }
                p_U2270B_CFE=1;
        led_light1=0;led_light=1;delay_2(40000);//测试使用



              //write_block(cominceptbuff[4],p);
                p_U2270B_CFE=1;
                bankdata[20]=cominceptbuff[0];//密码存入
                bankdata[21]=cominceptbuff[1];
                bankdata[22]=cominceptbuff[2];
                bankdata[23]=cominceptbuff[3];
    }
    else if (x==write_command1)//配置卡参数:初始化
    {
            uchar data *data p;
                p=cominceptbuff;
            write_bit(1);//写操作码1:10
            write_bit(0);//写操作码0
            write_bit(0);//写锁定位0           
              write_block(cominceptbuff[4],p);
              p_U2270B_CFE=1;
    }
    //psw=1  pssword mode
    else if(x==write_command2)//
    {
            uchar data*data p;
                p=bankdata[24];
                write_bit(1);//写操作码1:10
            write_bit(0);//写操作码0
            write_password(p);//发口令
            write_bit(0);//写锁定位0
            p=cominceptbuff;
              write_block(cominceptbuff[4],p);//写数据               
    }
    else if(x==write_command3)//aor
    {
        //cominceptbuff[1]操作码10 X xxxxxB
                uchar data *data p;
                p=cominceptbuff;
                write_bit(1);//10
        write_bit(0);           
              write_password(p);//密码
              p_U2270B_CFE=1;//此时数据不停的循环传出
    }
    else //停止操作码
    {
            write_bit(1);//11
        write_bit(1);           
            p_U2270B_CFE=1;           
    }
        p_U2270B_CFE=1;
    delay_2(560);//5.6ms
}

/************************************/
void f_clearpassword()//清除密码
{
                uchar data *data p;
                uchar i,x;               
            p=&bankdata[24];//原密码
        p_U2270B_CFE=0;delay_2(18);//start gap>150us
            //操作码10:10xxxxxxB
            write_bit(1);
                write_bit(0);              
        for(x=0;x<4;x++)//发原密码
            {             
            DATA=*(p++);
                  for(i=0;i<8;i++)
                {
                    write_bit(BIT0);
                        DATA>>=1;
                  }
        }
        write_bit(0);//锁定位0:0
        p=&cominceptbuff[0];
        write_block(0x00,p);//写新配置参数:pwd=0        
            //密码无效:即清除密码
            DATA=0x00;//停止操作码00000000B
            for(i=0;i<2;i++)
            {
                write_bit(BIT7);
                DATA<<=1;
              }
            p_U2270B_CFE=1;   
        delay_2(560);//5.6ms
}
/********************************
*/
void f_changepassword()//修改密码                 
{       
            uchar data *data p;
                uchar i,x,addr;
            addr=0x07;//block7
            p=&Nkey_a[0];//原密码
            DATA=0x80;//操作码10:10xxxxxxB
            for(i=0;i<2;i++)
            {
                write_bit(BIT7);
                DATA<<=1;
              }
        for(x=0;x<4;x++)//发原密码
            {             
            DATA=*(p++);
                  for(i=0;i<8;i++)
                {
                    write_bit(BIT7);
                        DATA>>=1;
                  }
        }
        write_bit(0);//锁定位0:0
        p=&cominceptbuff[0];
        write_block(0x07,p);//写新密码
        p_U2270B_CFE=1;
                bankdata[24]=cominceptbuff[0];//密码存入
                bankdata[25]=cominceptbuff[1];
                bankdata[26]=cominceptbuff[2];
                bankdata[27]=cominceptbuff[3];
                //
            DATA=0x00;//停止操作码00000000B
            for(i=0;i<2;i++)
            {
                write_bit(BIT7);
                DATA<<=1;
              }
            p_U2270B_CFE=1;   
        delay_2(560);//5.6ms
}
/************T0***************/

/***************************子函数**********************************
*/
void write_bit(bit x)//写一位
{
    if(x)
    {
            p_U2270B_CFE=1;delay_2(32);//448*11.0592/120=42延时448us
            p_U2270B_CFE=0;delay_2(28);//280*11.0592/120=26写1
    }
    else
    {
            p_U2270B_CFE=1;delay_2(92);//192*11.0592/120=18
            p_U2270B_CFE=0;delay_2(28);//280*11.0592/120=26写0
    }
}
/*******************写一个block*******************/
void write_block(uchar addr,uchar data *data p)
{
    uchar i,j;   
        for(i=0;i<4;i++)//block0数据
    {             
        DATA=*(p++);
              for(j=0;j<8;j++)
            {
                write_bit(BIT0);
                DATA>>=1;
              }
    }
    DATA=addr<<=5;//0地址
    for(i=0;i<3;i++)
    {
            write_bit(BIT7);
            DATA<<=1;
    }                      
}
/************************************************
*/
void write_password(uchar data *data p)
{
    uchar i,j;   
        for(i=0;i<4;i++)//
    {             
        DATA=*(p++);
              for(j=0;j<8;j++)
            {
                write_bit(BIT0);
                DATA>>=1;
              }
    }   
}
/*************************中断函数**********************************
*/
void com (void) interrupt 4 using 1//串口中断,才用中断方式通讯向量地址 0x23h
{
    uchar buff;
    if (TI)
    {
                TI=0;              //发送中断标志位        
        //sendjishu++;
                if (++sendjishu==9)//使用sendjishu之前改变sendjishu
                {
                    sendjishu=0;  //
                    REN=1;//允许接收   
                }
                else
                {            
                    SBUF=comsendbuff[sendjishu];        
                }
    }
    else if(RI)
    {
                buff=SBUF;
                RI=0;       
                switch (jieshoujishu)
                {
                    case 0: if (buff!=0xff) jieshoujishu=0;
                        else jieshoujishu=1;break;                               
                    case 1: if (buff!=0xff) jieshoujishu=0;
                    else jieshoujishu=2;break;          
                    case 2: if (buff==0xff) jieshoujishu=0;
                    else jieshoujishu=3;command=buff;break;                                   
                        case 3: if (buff==0xff) jieshoujishu=0;
                    else jieshoujishu=4;command1=buff;break;                                   
                    default: if(jieshoujishu<10)
                              {
                                 cominceptbuff[jieshoujishu-4]=buff;
                         jieshoujishu++;
                                        if(jieshoujishu==10) goto
com;                                   
                             }   
                             else
                             {   
                       com:          com_ov=1;
                                          jieshoujishu=0;                               
       
                                          REN=0;//不允许收,发使能               
                                }break;               
                }
    }
    RI=TI=0;   
    EA=1;          //kai zhongduan
}

/*外中断0******************************************************/
void int0()  interrupt 0 using 1
{
}
/*外中断1-----------------------------------------------------*/
void int1()  interrupt 2 using 1
{
}
/*定时器0----------25ms---------------------------------------*/
void time0() interrupt 1 using 1
{
       
}
/*定时器1----------波特率-------------------------------------*/
void time1() interrupt 3 using 1
{
}
/*******************end***********************************************/

我测了一下,读出的数据不太对,没改配置字,出厂一致,我的卡里第1快存的是11111111,第2块是22222222,以此类推到7

我读出来的
03 07 01 03 07 07 01      03 07 01 07 01 03 07    02 07 01 03 07 04 04    04 04 01 03 07 01 03

感觉是读出来的,好像是错位,不太理解作者取奇位的意思,我用的京振12m,作者110592,相关的延时我业改了,读数很稳定就是不对

移植没进展,大家帮忙看看,我用的是51+2270,都是普通i/o接的,没接到51的外部中断上,我是在中断程序里读的数据,一次全读出来1-7

是不是在读操作前要写一下配置字?

而作者注释0-7,不理解

我没对配置字进行操作,数据是从标准读卡器读的,我原想读出配置字,来判断时序是否正确,

程序里通用同一个定时器是啥意思?


希望各路英雄拔刀相助

我理解程序应该是f/32,man码,我用这个读头读出了4100,说明硬件ok

出0入12汤圆

发表于 2010-11-26 08:42:35 | 显示全部楼层
兄弟,你用的是章其波大侠的那个程序吗?貌似我测试过,章大侠那个程序好像会误码噢

出0入0汤圆

发表于 2011-2-26 18:22:12 | 显示全部楼层
楼主说的没错,f/32,曼彻斯特编码,取奇数位是他解码的方式
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-4 10:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表