0-SIM波形解码
2020-04-22 本文已影响0人
Creator_Ly
数据格式.pngSIM卡发送和应答的数据格式都是有规定的,以低电平为起始,高电平结束,以EUT为基本脉宽,8bit为一字节,与串口的协议一致。
先看一段有逻辑分析仪抓出来的波形,如下:
逻辑分析仪数据.png
可以观察到最小脉宽为77.54us, 所以波特率为1/77.5=12903,进行如下配置:
8Bit、2位停止位,偶校验
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;
}