?? ds2401a.c
字號:
#include "Global.h"
BYTE cMachineType; //
DWORD dwTimeLimit; //
BYTE cLimitTime[10]; //
BYTE CheckResult; //
void Delayus( WORD wTimeLong )
{
WORD i,j;
for( i=0; i<wTimeLong; i++ )
for( j=0; j<10; j++ );
}//Delayus
//*******************ReadOneBit**************************
//從2401讀1bit,2401的數據在通信線的上升沿輸出
BYTE ReadOneBit(void)
{
BYTE bResult;
OutputEN();//輸出使能
Delayus(1);
//產生上升沿
Clr2401();
Delayus(5);
Set2401();
InputEN();//讀使能
Delayus(10);
bResult = Read2401();
Delayus(50);
return( bResult );
}//ReadOneBit
//*******************ReadOneBit**************************
//*******************ReadSN2401**************************
//從2401讀出串行碼:先發復位信號,再發寫命令0x33,然后讀,在整個過程關閉中斷
void ReadSN2401( BYTE *cpDst )
{
WORD i,j,bOptBit;
DisableInt();
OutputEN();//輸出使能
Delayus(1);
//發復位信號
Clr2401();
Delayus(500);
Set2401();
InputEN();//讀使能,放棄總線占有權
//這一句必須有,否則讀不到結果
Delayus(450);
//發寫命令0x33
OutputEN();//輸出使能
i = 0x33;
bOptBit = 1;
for( j=0; j<8; j++ )
{
if( i & bOptBit )
{
Clr2401();
Delayus(8);
Set2401();
Delayus(70);
}
else
{
Clr2401();
Delayus(65);
Set2401();
Delayus(12);
}
bOptBit <<= 1;
}
for( i=0; i<8; i++ ) //共8個字節
{
bOptBit = 1;
for( j=0; j<8; j++ ) //讀1個字節
{
if( ReadOneBit() )
*(cpDst+i) |= bOptBit;
else
*(cpDst+i) &= ~bOptBit;
bOptBit <<= 1;
}
}
OutputEN();//輸出使能
Set2401(); //讀完之后把通信線拉高
EnableInt();
}//ReadSN2401
//*******************ReadSN2401**************************
//*******************WriteSN2401**************************
//SN2401的數據存放在0x00007100開始的地址空間上
BYTE WriteSN2401(void)
{
DWORD *add;
DWORD data32[3];
BYTE data8[8];//存放從DS2401讀出的8字節數據
//rWDMOD = 0;//禁止WDT
//先把狀態讀出來
add = (DWORD *)0x00007000;
data32[0] = *add;
//讀DS2401
ReadSN2401(data8);
//CRC校驗讀出的數據
if(CheckDS2401CRC(data8)==FALSE)
return CRC_ERROR;//不正確則退出函數
else
{
//加密2401數據
EncryptSN(data8);
//把數據轉存進雙字變量
data32[1] = 0;
data32[2] = 0;
data32[1] = ((DWORD)data8[3]<<24) | ((DWORD)data8[2]<<16) | ((DWORD)data8[1]<<8) | data8[0];
data32[2] = ((DWORD)data8[7]<<24) | ((DWORD)data8[6]<<16) | ((DWORD)data8[5]<<8) | data8[4];
//向FLASH寫入數據(狀態字和2401處理后的數據)
DisableInt();
SelSector(7,7);
EraseSector(7,7);
SelSector(7,7);
RamToFlash(0x00007000, (DWORD)data32, 256);
EnableInt();
return TRUE;
}
//InitWDT();//啟動WDT
}//void WriteSN2401(void)
//*******************WriteSN2401**************************
//*******************CRC**************************
//CRC校驗,最后的結果在B中
void CRC( BYTE A, BYTE *B )
{
BYTE C,i,tempA = A;
for( i=0; i<8; i++ )
{
A ^= *B;
C = A & 0x01;
A = *B;
if( C ==1 )
A ^= 0x18;
A /= 2;
A += (C<<7);
*B = A;
tempA /= 2;
A = tempA;
}
}//CRC
//*******************CRC**************************
//*******************CheckDS2401CRC*********************
//校驗讀到的串行碼是否正確
//從2401讀到的串行碼第一字節是廠商碼,所有2401都相同
//然后是6字節的串行碼,最后一個是CRC校驗碼
//前面7個字節做CRC校驗之后應該等于第8個字節
BYTE CheckDS2401CRC( BYTE *cpSrc )
{
BYTE i,B=0;
for( i=0; i<7; i++ )
CRC( *(cpSrc+i) , &B );
if( *(cpSrc+7) == B )
return TRUE;
else
return FALSE;
}//CheckDS2401CRC
//*******************CheckDS2401CRC*********************
//*******************MUL*********************
//6字節×6字節,按字符串的形式相乘
void MUL( BYTE *cpSrc )
{
BYTE i,j;
DWORD Mul[] = { 0xA7, 0x5B, 0xC9, 0x26, 0x0D, 0xA5 };
DWORD c,Temp,Result[12];
//結果緩沖區清零
for( i=0; i<12; i++ )
Result[i] = 0;
for( j=0; j<6; j++ ) //考察乘數的每一個字節
{
c=0; //進位清零
for( i=0; i<6; i++ ) //對于乘數的每一個字節,都掃描一遍被乘數
{
Temp = *(cpSrc+i) * Mul[j] + c; //乘數和被乘數各自一個字節相乘,再加上進位
Result[i+j] += (Temp % 256); //上面的結果MOD256,再加進結果的相應字節
c = Temp / 256; //求進位
}
}
//對結果進行調整,只取8個字節,故多出的字節沒必要調整
for( i=0; i<8; i++ )
{
*(cpSrc+i) = Result[i] % 256;
c = Result[i] / 256;
Result[i+1] += c;
}
}//MUL
//*******************MUL*********************
//*******************Exchange****************
//把字節順序倒亂
void Exchange( BYTE *pcSrc )
{
BYTE i,cTemp[8];
cTemp[0] = *(pcSrc+3);
cTemp[1] = *(pcSrc+5);
cTemp[2] = *(pcSrc+0);
cTemp[3] = *(pcSrc+7);
cTemp[4] = *(pcSrc+2);
cTemp[5] = *(pcSrc+6);
cTemp[6] = *(pcSrc+1);
cTemp[7] = *(pcSrc+4);
for( i=0; i<8; i++ )
*(pcSrc+i) = cTemp[i];
}//Exchange
//*******************Exchange****************
//*******************RLC*********************
//把輸入的字節 cSrc 左循環移 cBits 位
BYTE RLC( BYTE cSrc , BYTE cBits )
{
WORD wTemp;
BYTE i,cTemp;
wTemp = cSrc;
for( i=0; i<cBits; i++ )
wTemp *=2;
cTemp = (wTemp>>8)&0x00FF;
wTemp += cTemp;
wTemp &= 0x00FF;
return( (BYTE)wTemp );
}//RLC
//*******************RLC*********************
//*******************RRC*********************
//把輸入的字節 cSrc 右循環移 cBits 位
BYTE RRC( BYTE cSrc , BYTE cBits )
{
WORD wTemp;
BYTE i,cTemp;
wTemp = cSrc<<8;
for( i=0; i<cBits; i++ )
wTemp /=2;
cTemp = (wTemp>>8)&0x00FF;
wTemp += cTemp;
wTemp &= 0x00FF;
return( (BYTE)wTemp );
}//RRC
//*******************RRC*********************
//*******************EncryptSN*********************
//對讀到的2401SN碼進行加密
void EncryptSN( BYTE *cpSrc )
{
BYTE i;
//只取SN碼中間6個字節
for( i=0; i<6; i++ )
*(cpSrc+i) = *(cpSrc+i+1);
//其它字節清零
for( i=6; i<8; i++ )
*(cpSrc+i) = 0;
//乘上一個6字節的常數
MUL( cpSrc );
//倒亂結果的字節位置
Exchange( cpSrc );
//對不同的字節分別進行不同的循環左移或者循環右移
for( i=0; i<8; i++ )
if( i%2 == 0 )
{
*(cpSrc+i) = RLC( *(cpSrc+i), ((i/2+6)%4)+1 ); //偶字節進行不同的循環左移
*(cpSrc+i) ^= 0xB4; //結果再異或 0xB4
}
else
{
*(cpSrc+i) = RRC( *(cpSrc+i), (i%3)+1 ); //奇字節進行不同的循環右移
*(cpSrc+i) ^= 0x69; //結果再異或 0x69
}
//對第四個字節進行特殊處理
for( i=0; i<8; i++ )
*(cpSrc+3) += *(cpSrc+i);
*(cpSrc+3) %= 256;
//對第六個字節進行特殊處理
for( i=2; i<7; i++ )
*(cpSrc+5) += *(cpSrc+i);
*(cpSrc+5) %= 256;
}//EncryptSN
//*******************EncryptSN*********************
//*******************CheckSN*********************
//判斷從2401讀出并加密后的SN碼跟從FLASH中讀出的SN碼是否一致
BYTE CheckSN(void)
{
BYTE data8[8];
DWORD data32[2];
DWORD *add;
DWORD temp0,temp1;
//先讀出DS2401的數據并處理好
//讀DS2401
ReadSN2401(data8);
//CRC校驗讀出的數據
if(!CheckDS2401CRC(data8))
return CRC_ERROR;//不正確則退出函數
else
{
//加密2401數據
EncryptSN(data8);
//把數據轉存進雙字變量
data32[0] = 0;
data32[1] = 0;
data32[0] = ((DWORD)data8[3]<<24) | ((DWORD)data8[2]<<16) | ((DWORD)data8[1]<<8) | data8[0];
data32[1] = ((DWORD)data8[7]<<24) | ((DWORD)data8[6]<<16) | ((DWORD)data8[5]<<8) | data8[4];
//讀出FLASH中的DS2401數據
add = (DWORD *)0x00007004;
temp0 = *add;
add = (DWORD *)0x00007008;
temp1 = *add;
//比較
if((temp0==data32[0])&&(temp1==data32[1]))
return( SN_OK );
else
return( SN_ERROR );
}
}//CheckSN
//*******************CheckSN*********************
//*******************Noise2401*********************
//平時不讀取2401時不斷向它發干擾脈沖
void Noise2401( void )
{
BYTE i,j,bOptBit;
BYTE cTime; //脈沖波之間的隨機延時時間
BYTE cWave; //隨機產生的脈沖波形
cWave = ((DWORD)LedTimeCount*19)%251 + 3; //產生隨機脈沖波形
bOptBit = 1;
for( i=0; i<8; i++ )
{
if( cWave & bOptBit ) //輸出cWave中相應于bOptBit的位
Set2401();
else
Clr2401();
cTime = ((DWORD)LedTimeCount*13)%191 + 57; //產生隨機的延時時間
for( j=0; j<cTime; j++ ); //延時
bOptBit <<= 1; //移向下一位
}
Set2401(); //最后都對2401保持高電平,避免2401不必要的復位
}//Noise2401
//*******************Noise2401*********************
//密碼錯誤執行的程序
void WrongPassword(void)
{
DWORD i;
ColorSelect = 2;
AllOn();
for(i=0;i<1500000;i++);
ClrDisplay();
for(i=0;i<1500000;i++);
}//void WrongPassword(void)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -