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.
Primero observe una forma de onda capturada por un analizador lógico, de la siguiente manera:
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
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;
}