?? 串口收發短消息(上.txt
字號:
//用C實現7-bit編碼和解碼的算法如下:
// 7-bit編碼
// pSrc: 源字符串指針
// pDst: 目標編碼串指針
// nSrcLength: 源字符串長度
// 返回: 目標編碼串長度
int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
int nSrc; // 源字符串的計數值
int nDst; // 目標編碼串的計數值
int nChar; // 當前正在處理的組內字符字節的序號,范圍是0-7
unsigned char nLeft; // 上一字節殘余的數據
// 計數值初始化
nSrc = 0;
nDst = 0;
// 將源串每8個字節分為一組,壓縮成7個字節
// 循環該處理過程,直至源串被處理完
// 如果分組不到8字節,也能正確處理
while(nSrc<nSrcLength)
{
// 取源字符串的計數值的最低3位
nChar = nSrc & 7;
// 處理源串的每個字節
if(nChar == 0)
{
// 組內第一個字節,只是保存起來,待處理下一個字節時使用
nLeft = *pSrc;
}
else
{
// 組內其它字節,將其右邊部分與殘余數據相加,得到一個目標編碼字節
*pDst = (*pSrc << (8-nChar)) | nLeft;
// 將該字節剩下的左邊部分,作為殘余數據保存起來
nLeft = *pSrc >> nChar;
// 修改目標串的指針和計數值 pDst++;
nDst++;
}
// 修改源串的指針和計數值
pSrc++; nSrc++;
}
// 返回目標串長度
return nDst;
}
// 7-bit解碼
// pSrc: 源編碼串指針
// pDst: 目標字符串指針
// nSrcLength: 源編碼串長度
// 返回: 目標字符串長度
int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
int nSrc; // 源字符串的計數值
int nDst; // 目標解碼串的計數值
int nByte; // 當前正在處理的組內字節的序號,范圍是0-6
unsigned char nLeft; // 上一字節殘余的數據
// 計數值初始化
nSrc = 0;
nDst = 0;
// 組內字節序號和殘余數據初始化
nByte = 0;
nLeft = 0;
// 將源數據每7個字節分為一組,解壓縮成8個字節
// 循環該處理過程,直至源數據被處理完
// 如果分組不到7字節,也能正確處理
while(nSrc<nSrcLength)
{
// 將源字節右邊部分與殘余數據相加,去掉最高位,得到一個目標解碼字節
*pDst = ((*pSrc << nByte) | nLeft) & 0x7f;
// 將該字節剩下的左邊部分,作為殘余數據保存起來
nLeft = *pSrc >> (7-nByte);
// 修改目標串的指針和計數值
pDst++;
nDst++;
// 修改字節計數值
nByte++;
// 到了一組的最后一個字節
if(nByte == 7)
{
// 額外得到一個目標解碼字節
*pDst = nLeft;
// 修改目標串的指針和計數值
pDst++;
nDst++;
// 組內字節序號和殘余數據初始化
nByte = 0;
nLeft = 0;
}
// 修改源串的指針和計數值
pSrc++;
nSrc++;
}
*pDst = 0;
// 返回目標串長度
return nDst;
}
//需要指出的是,7-bit的字符集與ANSI標準字符集不完全一致,在0x20以下也排布了一些可打印字符,但英文字母、阿拉伯數字和常用符號的位置兩者是一樣的。用上面介紹的算法收發純英文短消息,一般情況應該是夠用了。如果是法語、德語、西班牙語等,含有 “?”、 “é”這一類字符,則要按上面編碼的輸出去查表,請參閱GSM 03.38的規定。
//8-bit編碼其實沒有規定什么具體的算法,不需要介紹。
//UCS2編碼是將每個字符(1-2個字節)按照ISO/IEC10646的規定,轉變為16位的Unicode寬字符。在Windows系統中,特別是在2000/XP中,可以簡單地調用API 函數實現編碼和解碼。如果沒有系統的支持,比如用單片機控制手機模塊收發短消息,只好用查表法解決了。
//Windows環境下,用C實現UCS2編碼和解碼的算法如下:
// UCS2編碼
// pSrc: 源字符串指針
// pDst: 目標編碼串指針
// nSrcLength: 源字符串長度
// 返回: 目標編碼串長度
int gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
int nDstLength; // UNICODE寬字符數目
WCHAR wchar[128]; // UNICODE串緩沖區
// 字符串-->UNICODE串
nDstLength = ::MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);
// 高低字節對調,輸出
for(int i=0; i<nDstLength; i++)
{
// 先輸出高位字節
*pDst++ = wchar[i] >> 8;
// 后輸出低位字節
*pDst++ = wchar[i] & 0xff;
}
// 返回目標編碼串長度
return nDstLength * 2;
}
// UCS2解碼
// pSrc: 源編碼串指針
// pDst: 目標字符串指針
// nSrcLength: 源編碼串長度
// 返回: 目標字符串長度
int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
int nDstLength; // UNICODE寬字符數目
WCHAR wchar[128]; // UNICODE串緩沖區
// 高低字節對調,拼成UNICODE
for(int i=0; i<nSrcLength/2; i++)
{
// 先高位字節
wchar[i] = *pSrc++ << 8;
// 后低位字節
wchar[i] |= *pSrc++;
}
// UNICODE串-->字符串
nDstLength = ::WideCharToMultiByte(CP_ACP, 0, wchar, nSrcLength/2, pDst, 160, NULL, NULL);
// 輸出字符串加個結束符
pDst[nDstLength] = '\0';
// 返回目標字符串長度
return nDstLength;
}
//用以上編碼和解碼模塊,還不能將短消息字符串編碼為PDU串需要的格式,也不能直接將PDU串中的用戶信息解碼為短消息字符串,因為還差一個在可打印字符串和字節數據之間相互轉換的環節。可以循環調用sscanf和sprintf函數實現這種變換。下面提供不用這些函數的算法,它們也適用于單片機、DSP編程環境。
// 可打印字符串轉換為字節數據
// 如:"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}
// pSrc: 源字符串指針
// pDst: 目標數據指針
// nSrcLength: 源字符串長度
// 返回: 目標數據長度
int gsmString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
for(int i=0; i<nSrcLength; i+=2)
{
// 輸出高4位
if(*pSrc>='0' && *pSrc<='9')
{
*pDst = (*pSrc - '0') << 4;
}
else
{
*pDst = (*pSrc - 'A' + 10) << 4;
}
pSrc++;
// 輸出低4位
if(*pSrc>='0' && *pSrc<='9')
{
*pDst |= *pSrc - '0';
}
else
{
*pDst |= *pSrc - 'A' + 10;
}
pSrc++;
pDst++;
}
// 返回目標數據長度
returnnSrcLength / 2;
}
// 字節數據轉換為可打印字符串
// 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01"
// pSrc: 源數據指針
// pDst: 目標字符串指針
// nSrcLength: 源數據長度
// 返回: 目標字符串長度
int gsmBytes2String(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
const char tab[]="0123456789ABCDEF"; // 0x0-0xf的字符查找表
for(int i=0; i<nSrcLength; i++)
{
// 輸出低4位
*pDst++ = tab[*pSrc >> 4];
// 輸出高4位
*pDst++ = tab[*pSrc & 0x0f];
pSrc++;
}
// 輸出字符串加個結束符
*pDst = '\0';
// 返回目標字符串長度
return nSrcLength * 2;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -