0-SIM波形解码

SIM卡发送和应答的数据格式都是有规定的,以低电平为起始,高电平结束,以EUT为基本脉宽,8bit为一字节,与串口的协议一致。

数据格式.png

先看一段有逻辑分析仪抓出来的波形,如下:


逻辑分析仪数据.png

可以观察到最小脉宽为77.54us, 所以波特率为1/77.5=12903,进行如下配置:
8Bit、2位停止位,偶校验

逻辑分析仪配置.png

SIM数据的写比较容易,按着时序走即可,如下:

void Sim_Write_Byte(uint8_t ChannelID, uint8_t senddata) 
{
    uint8_t i; 
    bool parity_bit = 0;
    
    Set_Sim_Io(ChannelID, SIM_DATA, 0);
    Delay_One_ETU();
    for(i=0; i<8; i++) 
    {
        if(1 == (senddata & 0x01))
        {
            Set_Sim_Io(ChannelID, SIM_DATA, 1);
        }
        else
        {
            Set_Sim_Io(ChannelID, SIM_DATA, 0);        
        }
        parity_bit ^= senddata & 0x01;
        senddata >>= 1;
        Delay_One_ETU();
    }
    Set_Sim_Io(ChannelID, SIM_DATA, parity_bit);
    Delay_One_ETU();
    Set_Sim_Io(ChannelID, SIM_DATA, 1);
    Delay_One_ETU();
    Delay_One_ETU();
}

对于SIM数据的解码无非就是采样解码,所以我们以低电平为起始,等到低电平就开始解码,如下:

uint8_t Sim_Read_Byte(uint8_t ChannelID, uint32_t WaitTime) 
{
    uint32_t count = 0; 
    uint8_t i = 0;
    uint8_t recvdata = 0x00;
    bool parity_bit = 0;

    while(Get_Sim_Io(ChannelID, SIM_DATA))
    {
        if(0 == Get_Sim_Io(ChannelID, SIM_DATA)) 
        {
            break;
        }
        count++;
        if(count >= WaitTime)
        {
            pSimChannelCtl->bReadTimeOut = 1;
            return YFI_FAIL; 
        }
        Delay_Us(10);
    }
    Delay_One_ETU();
    Delay_Half_ETU();  //偏移1/2,使采样位于中间
    
    for(i=0; i<8; i++) 
    {
        recvdata >>= 1;
        if(Get_Sim_Io(ChannelID, SIM_DATA))
        {
            recvdata |= 0x80;
        }
        parity_bit ^= Get_Sim_Io(ChannelID, SIM_DATA); 
        Delay_One_ETU();
    }
    
    parity_bit ^= Get_Sim_Io(ChannelID, SIM_DATA);
    Delay_One_ETU();
    if (!parity_bit)
    {
        recvdata = recvdata;
    }
    else
    {
        recvdata = '\xbb';  //parity error
    }
    
    return recvdata; 
}

经测试,由于上面的采用相当于是1bit采样一个点,就算加了Little的偏移还是会出现解码错误,需要优化增加采样点。

一个bit里面采样10个点,一个数据采样100个点。

uint8_t Sim_Read_Byte(uint8_t ChannelID, uint32_t WaitTime) 
{
    uint32_t count = 0; 
    uint8_t i = 0, first = 0;
    uint8_t lnum = 0, hnum = 0;
    uint8_t recvdata = 0x00;
    uint32_t recvpoint = 0;
    bool parity_bit = 0;

    PSIMROOTST     pSimRootSt;
    PSIMCHANNELST  pSimChannelCtl;
    
    pSimRootSt     = (PSIMROOTST)&stSimRootSt;    
    pSimChannelCtl = &pSimRootSt->stChannelSt[ChannelID];

    while(Get_Sim_Io(ChannelID, SIM_DATA))
    {
        if(0 == Get_Sim_Io(ChannelID, SIM_DATA))  //检测到低电平,即起始位,开始解码
        {
            break;
        }
        count++;
        if(count >= WaitTime)                     //未检测到低电平,到达超时时间退出
        {
            pSimChannelCtl->bReadTimeOut = 1;
            return YFI_FAIL; 
        }
        Delay_Us(10);
    }
    //32point
    for(i=0; i<32; i++) 
    {
        recvpoint >>= 1;
        if(Get_Sim_Io(ChannelID, SIM_DATA))
        {
            recvpoint |= 0x80000000;
        }
        Delay_Us(31);
    } 

    lnum = 0;
    hnum = 0;
    first = 0;
    for(i=0; i<32; i++) 
    {
        if(1 == (recvpoint & 0x00000001))
        {
            if(0 == lnum)
            {
                hnum++;
            }
            else
            {
                if(0 == first)
                {
                    first = 1;
                    lnum = lnum - 2;
                }
                if((lnum > 0)&&(lnum <= 4))
                {
                    recvdata |= 0x00;
                    recvdata >>= 1;
                }
                else if((lnum > 4)&&(lnum <= 7))
                {
                    recvdata |= 0x00;
                    recvdata >>= 2;
                }
                else if((lnum > 7)&&(lnum <= 10))
                {
                    recvdata |= 0x00;
                    recvdata >>= 3;
                }
                else if((lnum > 10)&&(lnum <= 13))
                {
                    recvdata |= 0x00;
                    recvdata >>= 4;
                }
                else if((lnum > 13)&&(lnum <= 16))
                {
                    recvdata |= 0x00;
                    recvdata >>= 5;
                }
                else if((lnum > 16)&&(lnum <= 19))
                {
                    recvdata |= 0x00;
                    recvdata >>= 6;
                }
                else if((lnum > 18)&&(lnum <= 22))
                {
                    recvdata |= 0x00;
                    recvdata >>= 7;
                }
                else if((lnum > 22)&&(lnum <= 25))
                {
                    recvdata |= 0x00;
                    recvdata >>= 8;
                }
                else if((lnum > 25)&&(lnum <= 28))
                {
                    recvdata = 0x00;
                }
                else if((lnum > 28)&&(lnum <= 31))
                {
                    recvdata = 0x00;
                }
                lnum = 0;
                hnum = 1;
            }
        }
        else
        {
            if(0 == hnum)
            {
                lnum++;
            }
            else
            {
                if((hnum > 0)&&(hnum <= 4))
                {
                    recvdata &= 0x80;
                    recvdata >>= 1;
                }
                else if((hnum > 4)&&(hnum <= 7))
                {
                    recvdata &= 0xC0;
                    recvdata >>= 2;
                }
                else if((hnum > 7)&&(hnum <= 10))
                {
                    recvdata &= 0xE0;
                    recvdata >>= 3;
                }
                else if((hnum > 10)&&(hnum <= 13))
                {
                    recvdata &= 0xF0;
                    recvdata >>= 4;
                }
                else if((hnum > 13)&&(hnum <= 16))
                {
                    recvdata &= 0xF8;
                    recvdata >>= 5;
                }
                else if((hnum > 16)&&(hnum <= 19))
                {
                    recvdata &= 0xFC;
                    recvdata >>= 6;
                }
                else if((hnum > 18)&&(hnum <= 22))
                {
                    recvdata &= 0xFE;
                    recvdata >>= 7;
                }
                else if((hnum > 22)&&(hnum <= 25))
                {
                    recvdata &= 0xFF;
                    recvdata >>= 8;
                }
                else if((hnum > 25)&&(hnum <= 28))
                {
                    recvdata = 0xFF;
                }
                else if((hnum > 28)&&(hnum <= 31))
                {
                    recvdata = 0xFF;
                }
                hnum = 0;
                lnum = 1;
            }
        }
        recvpoint >>= 1;
    }
    
    /*if (!parity_bit)
    {
        recvdata = recvdata;
    }
    else
    {
        recvdata = '\xbb';  //parity error
    }*/
    return recvdata; 
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容