SIM卡發(fā)送和應(yīng)答的數(shù)據(jù)格式都是有規(guī)定的,以低電平為起始琐旁,高電平結(jié)束,以EUT為基本脈寬猜绣,8bit為一字節(jié)灰殴,與串口的協(xié)議一致。
數(shù)據(jù)格式.png
先看一段有邏輯分析儀抓出來(lái)的波形掰邢,如下:
邏輯分析儀數(shù)據(jù).png
可以觀察到最小脈寬為77.54us牺陶, 所以波特率為1/77.5=12903,進(jìn)行如下配置:
8Bit辣之、2位停止位掰伸,偶校驗(yàn)
邏輯分析儀配置.png
SIM數(shù)據(jù)的寫比較容易,按著時(shí)序走即可怀估,如下:
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();
}
對(duì)于SIM數(shù)據(jù)的解碼無(wú)非就是采樣解碼狮鸭,所以我們以低電平為起始,等到低電平就開始解碼多搀,如下:
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;
}
經(jīng)測(cè)試,由于上面的采用相當(dāng)于是1bit采樣一個(gè)點(diǎn)康铭,就算加了Little的偏移還是會(huì)出現(xiàn)解碼錯(cuò)誤惯退,需要優(yōu)化增加采樣點(diǎn)。
一個(gè)bit里面采樣10個(gè)點(diǎn)从藤,一個(gè)數(shù)據(jù)采樣100個(gè)點(diǎn)催跪。
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)) //檢測(cè)到低電平,即起始位呛哟,開始解碼
{
break;
}
count++;
if(count >= WaitTime) //未檢測(cè)到低電平叠荠,到達(dá)超時(shí)時(shí)間退出
{
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;
}