打印

新年快乐,各位大哥帮我看看这个问题啊,谢谢!

[复制链接]
1632|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
星星电灯|  楼主 | 2008-2-17 11:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教:
IC卡数据的读取

unsigned char ReadByte(void)   //读取一个字符
{
    unsigned char i,ch;
    ch = 0;
    for (i = 8; i > 0; i--)
    {
        CARD_CLK = 0;
        ch = ch >> 1;           //从低位读起 
        if((unsigned char)CARD_DATA)
            ch |= 0x80;
        Delay5us();
        CARD_CLK = 1;
        Delay5us();
    }
    return ch;
}


1:
为什么是 
ch |= 0x80

ch |= 0x20 
不可以啊?

2:
ch = ch >> 1;      

为什么就说从低位读起 ?
1000 0002
1 是最高位,还是最低位?

3:
CARD_DATA 的值没有变化啊
如果在循环里
for (i = 8; i > 0; i--)
    {
      if((unsigned char)CARD_DATA)
            ch |= 0x80;
    }
第一次 CARD_DATA 的值为 1
那么 
for (i = 8; i > 0; i--)
    {
      
    }
里,就一直为 1

那么不直接写

ch = 0xff 啊


void ReadMode(unsigned char *pt,unsigned char count) //读模式
{
    CARD_CLK=0;
    Delay5us();
    do
    {
        *pt = ReadByte();    //读入一个字节
        pt++;                //指针加一
    }while(--count);             //计数器减一,判断
}


谢谢!

相关帖子

沙发
NE5532| | 2008-2-17 11:37 | 只看该作者

答:

1.从ch = ch >> 1;和if((unsigned char)CARD_DATA) ch |= 0x80;看出看,这个IC卡是串行通讯的,并且低位在前,并且强制类型转换((unsigned char)CARD_DATA将“BIT”型变量转化为字节数据的最高位,所以必须用0x80,与编译器对强制类型转换的解释相关。

2.“1”是最高位“MSB”,中文意思就是“权重最大的位”(表示数值最大的位)

3.楼主的程序和原来的程序不相符,原程序是“每次读入一个位,并组装成字节”,从程序推测,CARD_DATA是一个定义在端口上的位变量。

使用特权

评论回复
板凳
救火车| | 2008-2-17 11:42 | 只看该作者

是什么卡

使用特权

评论回复
地板
NE5532| | 2008-2-17 11:49 | 只看该作者

估计是个同步传输的卡,不是ISO7816

使用特权

评论回复
5
xwj| | 2008-2-17 13:40 | 只看该作者

呵呵。LZ没理解移位操作的行为和用途(目的)

使用特权

评论回复
6
星星电灯|  楼主 | 2008-2-17 14:20 | 只看该作者

谢谢各位大哥,是 sle4442 逻辑卡啊

for (i = 8; i > 0; i--)
    {
      if((unsigned char)CARD_DATA)
            ch |= 0x80;
    }

CARD_DATA 的值变化吗?
谢谢!

使用特权

评论回复
7
NE5532| | 2008-2-17 14:22 | 只看该作者

呵呵,做到我们老本行上来了。

CARD_DATA的值随着卡的输出变化,简单说就是“单片机I/O上的电平值”

使用特权

评论回复
8
星星电灯|  楼主 | 2008-2-17 15:03 | 只看该作者

谢谢!NE5532 大哥再帮我看看这个,好吗?

#include <REG52.H>
#include <intrins.h>
#include <SLE4442.h>

void Delay5us(void)
{
    _nop_();
    _nop_();
    _nop_();
}

void Delay10us(void)
{
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
}

void WriteByte(unsigned char ch) //写一个字符
{
    unsigned char i;             
    for(i = 8; i > 0; i--)
    {
        CARD_CLK = 0;      //时钟信号为低        
        CARD_DATA = (bit)(ch & 0x01);  //得到写字符的最右边一位     
        Delay5us();                    //延时
        CARD_CLK = 1;                  //时钟信号为高 ,发出数据
        Delay10us();                   //延时
        ch = ch >> 1;                 //右移一位
    }
}

void StartComm(void)       //开始命令
{
    CARD_CLK = 0;          //时钟信号为低
    CARD_DATA  = 1;        //数据 1
    Delay5us();            //延时
    CARD_CLK = 1;          //时钟信号为高   
    Delay5us();            //延时
    CARD_DATA  = 0;        //数据 0  
    Delay5us();            //延时 
}

void StopComm(void)       //停止命令
{
    CARD_CLK = 0;         //时钟信号为低
    CARD_DATA  = 0;       //数据 0 
    Delay5us();           //延时 
    CARD_CLK = 1;         //CLK: H
    Delay5us();           //延时 
    CARD_DATA  = 1;       //IO : H
    Delay10us();          //延时 
}

void SendComm(unsigned char a,unsigned char b,unsigned char c)  //发送命令
{
    StartComm();          //开始发送命令
    WriteByte(a);          //a: 发命令字
    WriteByte(b);          //b: 发地址
    WriteByte(c);          //c: 发数据
    StopComm();           //结束发送命令
}

unsigned char ReadByte(void)   //读取一个字符
{
    unsigned char i,ch;
    ch = 0;
    for (i = 8; i > 0; i--)
    {
        CARD_CLK = 0;
        ch = ch >> 1;           //从低位读起 
        if((unsigned char)CARD_DATA)
            ch |= 0x80;
        Delay5us();
        CARD_CLK = 1;
        Delay5us();
    }
    return ch;
}


void ReadMode(unsigned char *pt,unsigned char count) //读模式
{
    CARD_CLK=0;
    Delay5us();
    do
    {
        *pt = ReadByte();    //读入一个字节
        pt++;                //指针加一
    }while(--count);             //计数器减一,判断
}

void BreakOperate(void)     //断开操作
{
     CARD_CLK = 0;          //时钟信号为低      
     CARD_RST = 0;          //卡复位信号
     CARD_DATA  = 0;        //数据
     Delay5us();            //延时
     CARD_RST = 1;          //卡复位信号
     CARD_DATA  = 1;        //数据
     Delay5us();            //延时
     CARD_RST = 0;          //卡复位信号  
     Delay5us();            //延时
}

void ReadMainMem(unsigned char addr,unsigned char *pt,unsigned char count)  //读IC卡主存
{

    SendComm(RMM_COMM,addr,0xff);   //发送命令
    ReadMode(pt,count);
    //Delay5us();
    BreakOperate();
    //IC_Read_LED = ON;
}



假设卡里存储的数据 为:
0x01 0x20 0x30 0x40

那么发读的命令后
CARD_DATA 的值是什么呢?

使用特权

评论回复
9
NE5532| | 2008-2-17 15:12 | 只看该作者

看清楚这句话

CARD_DATA  = 1;

CARD_DATA是单片机的端口(比如说P0.1),而不是内存的变量。

使用特权

评论回复
10
星星电灯|  楼主 | 2008-2-17 16:11 | 只看该作者

NE5532 大哥 ,那么 CARD_DATA 的值是根据什么来确定的啊?

使用特权

评论回复
11
NE5532| | 2008-2-17 16:26 | 只看该作者

卡片输出到端口上的电平

如果要读入一个端口上的电平,需要怎么做?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

74

主题

121

帖子

1

粉丝