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; 
}
发布了106 篇原创文章 · 获赞 76 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/Creator_Ly/article/details/105673800
sim
今日推荐