Decodificación de forma de onda 0-SIM

El formato de datos de envío y respuesta de la tarjeta SIM se especifica, comenzando con un nivel bajo y terminando con un nivel alto, tomando EUT como el ancho de pulso básico y 8 bits como un byte, lo cual es consistente con el protocolo del puerto serie.

Formato de datos.png

Primero observe una forma de onda capturada por un analizador lógico, de la siguiente manera:
Analizador lógico data.png

Se puede observar que el ancho de pulso mínimo es 77.54us, por lo que la velocidad en baudios es 1 / 77.5 = 12903, y la configuración es la siguiente: 8
bits, 2 bits de parada, incluso paridad

Analizador lógico configuration.png

Es más fácil escribir datos SIM, solo siga la secuencia, de la siguiente manera:

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();
}

La decodificación de datos SIM no es más que una decodificación de muestreo, por lo que comenzamos con un nivel bajo y esperamos que el nivel bajo comience a decodificar, de la siguiente manera:

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; 
}

Después de la prueba, dado que lo anterior es equivalente a muestrear un punto de 1 bit, incluso si se agrega el pequeño desplazamiento, se producirán errores de decodificación, y es necesario optimizar el aumento del punto de muestreo.

Se muestrean 10 puntos en un bit y se muestrean 100 puntos en un dato.

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 artículos originales publicados · 76 elogiados · 130,000 visitas +

Supongo que te gusta

Origin blog.csdn.net/Creator_Ly/article/details/105673800
Recomendado
Clasificación