📄 lib.c
字号:
/*------------------------------------------------------------------*/
/*模块名称:lib.c */
/*模块功能:串口驱动及各种校验库函数 */
/*编写日期:2005年9月 */
/*编写者: */
/*------------------------------------------------------------------*/
#include "includes.h"
INT16U crccode[0x100]={
0X0 , 0Xc0c1, 0Xc181, 0X140, 0Xc301, 0X3c0, 0X280, 0Xc241,
0Xc601, 0X6c0, 0X780, 0Xc741, 0X500, 0Xc5c1, 0Xc481, 0X440,
0Xcc01, 0Xcc0, 0Xd80, 0Xcd41, 0Xf00, 0Xcfc1, 0Xce81, 0Xe40,
0Xa00 , 0Xcac1, 0Xcb81, 0Xb40 , 0Xc901, 0X9c0, 0X880 , 0Xc841,
0Xd801, 0X18c0, 0X1980, 0Xd941, 0X1b00, 0Xdbc1, 0Xda81, 0X1a40,
0X1e00, 0Xdec1, 0Xdf81, 0X1f40, 0Xdd01, 0X1dc0, 0X1c80, 0Xdc41,
0X1400, 0Xd4c1, 0Xd581, 0X1540, 0Xd701, 0X17c0, 0X1680, 0Xd641,
0Xd201, 0X12c0, 0X1380, 0Xd341, 0X1100, 0Xd1c1, 0Xd081, 0X1040,
0Xf001, 0X30c0, 0X3180, 0Xf141, 0X3300, 0Xf3c1, 0Xf281, 0X3240,
0X3600, 0Xf6c1, 0Xf781, 0X3740, 0Xf501, 0X35c0, 0X3480, 0Xf441,
0X3c00, 0Xfcc1, 0Xfd81, 0X3d40, 0Xff01, 0X3fc0, 0X3e80, 0Xfe41,
0Xfa01, 0X3ac0, 0X3b80, 0Xfb41, 0X3900, 0Xf9c1, 0Xf881, 0X3840,
0X2800, 0Xe8c1, 0Xe981, 0X2940, 0Xeb01, 0X2bc0, 0X2a80, 0Xea41,
0Xee01, 0X2ec0, 0X2f80, 0Xef41, 0X2d00, 0Xedc1, 0Xec81, 0X2c40,
0Xe401, 0X24c0, 0X2580, 0Xe541, 0X2700, 0Xe7c1, 0Xe681, 0X2640,
0X2200, 0Xe2c1, 0Xe381, 0X2340, 0Xe101, 0X21c0, 0X2080, 0Xe041,
0Xa001, 0X60c0, 0X6180, 0Xa141, 0X6300, 0Xa3c1, 0Xa281, 0X6240,
0X6600, 0Xa6c1, 0Xa781, 0X6740, 0Xa501, 0X65c0, 0X6480, 0Xa441,
0X6c00, 0Xacc1, 0Xad81, 0X6d40, 0Xaf01, 0X6fc0, 0X6e80, 0Xae41,
0Xaa01, 0X6ac0, 0X6b80, 0Xab41, 0X6900, 0Xa9c1, 0Xa881, 0X6840,
0X7800, 0Xb8c1, 0Xb981, 0X7940, 0Xbb01, 0X7bc0, 0X7a80, 0Xba41,
0Xbe01, 0X7ec0, 0X7f80, 0Xbf41, 0X7d00, 0Xbdc1, 0Xbc81, 0X7c40,
0Xb401, 0X74c0, 0X7580, 0Xb541, 0X7700, 0Xb7c1, 0Xb681, 0X7640,
0X7200, 0Xb2c1, 0Xb381, 0X7340, 0Xb101, 0X71c0, 0X7080, 0Xb041,
0X5000, 0X90c1, 0X9181, 0X5140, 0X9301, 0X53c0, 0X5280, 0X9241,
0X9601, 0X56c0, 0X5780, 0X9741, 0X5500, 0X95c1, 0X9481, 0X5440,
0X9c01, 0X5cc0, 0X5d80, 0X9d41, 0X5f00, 0X9fc1, 0X9e81, 0X5e40,
0X5a00, 0X9ac1, 0X9b81, 0X5b40, 0X9901, 0X59c0, 0X5880, 0X9841,
0X8801, 0X48c0, 0X4980, 0X8941, 0X4b00, 0X8bc1, 0X8a81, 0X4a40,
0X4e00, 0X8ec1, 0X8f81, 0X4f40, 0X8d01, 0X4dc0, 0X4c80, 0X8c41,
0X4400, 0X84c1, 0X8581, 0X4540, 0X8701, 0X47c0, 0X4680, 0X8641,
0X8201, 0X42c0, 0X4380, 0X8341, 0X4100, 0X81c1, 0X8081, 0X4040,
};
extern struct PortAppInfo PortInfo[2];
/*-------------------------------------------------------------------------
Purpose: 用LPC计算8位校验码.
Input: lpbyBuf缓存指针;byNum:缓存字节数.
Output: 8位CRC码.
Errors:
------------------------------------------------------------------------*/
INT8U SendVerifyHead(INT8U* lpbyBuf,INT16U byNum)
{
INT8U byLPC = 0;
INT16U i;
for (i = 0; i < byNum; i++)
byLPC = (byLPC ^ lpbyBuf[i]);
return byLPC;
}
INT16U WHCRC16(INT8U *p,INT32U l)
{
INT16U crc=0;
INT16U index;
INT32U i;
for(i=0;i<l;i++)
{
index=((crc^p[i])&0x00FF);
crc=((crc>>8)&0x00FF)^crccode[index];
}
return(crc);
}
INT16U WHCRC(INT8U *p,INT32U l)
{
INT32U crc, i;
crc = 0;
for (i=0; i<l; i++)
{
crc += p[l-i-1];
if (crc & 0xFFFF0000)
{
crc++;
crc &= 0xFFFF;
}
}
return ((INT16U)crc);
}
/*------------------------------------------------------------------------
Procedure: fdkcrc ID:1
Purpose: 用(x^16+x^15+x^2+1)计算16位CRC码.
Input: ptr:缓存指针;count:缓存字节数.
Output: 16位CRC码.
Errors:
------------------------------------------------------------------------*/
/*
INT16U fdkcrc(INT8U* ptr, short count)
{
INT16U CRC16,test;
INT8U i;
CRC16 = 0;
while(--count >= 0)
//for(j=0;j<count;j++)
{
//CRC16 = ( CRC16^(((INT16U)*ptr++)<<8) );
memcpy(&test, (void *)ptr, 1);
CRC16 = CRC16^(test<<8);
ptr++;
for (i=0; i<8; i++)
if (CRC16 & 0x8000 ) CRC16 = ( (CRC16 << 1)^0x1021 );
else CRC16 = CRC16 << 1;
}
return CRC16;
}
*/
/*------------------------------------------------------------------------
Procedure: dnpcrc ID:1
Purpose: 用DNP多项式计算16位CRC码[结果取反].
Input: ptr:缓存指针;count:缓存字节数.
Output: 16位CRC码.
Errors:
------------------------------------------------------------------------*/
INT16U dnpcrc(const INT8U *ptr, short count)
{
INT16U CRC16; INT8U i;
CRC16 = 0;
while(--count >= 0) {
CRC16 = ( CRC16^((INT16U)*ptr++) );
for (i=0; i<8; i++)
if (CRC16 & 0x0001 ) CRC16 = ( (CRC16 >> 1)^0xA6BC );
else CRC16 = CRC16 >> 1;
}
return ~CRC16;
}
/*------------------------------------------------------------------------
目的:为网络器件的4字节转换为INT32U
输入:INT8U ×
输出:INT32U
------------------------------------------------------------------------*/
INT32U INT8UToINT32U(INT8U * b)
{
INT32U i=0,a;
a = *b; a <<=24; b++;
i += a;
a = *b; a<<=16; b++;
i +=a;
a = *b; a<<=8; b++;
i +=a;
a = *b; b++;
i +=a;
return i;
}
/*------------------------------------------------------------------------
目的:为网络器件的2字节转换为INT16U
输入:INT8U ×
输出:INT16U
------------------------------------------------------------------------*/
INT16U INT8UToINT16U(INT8U * b)
{
INT16U i=0,a;
a = *b; b++;
i += a;
a = *b; a<<=8; b++;
i +=a;
return i;
}
/*------------------------------------------------------------------------
目的:将INT32U转换为4个INT8U
输入:INT32U a
输出:INT8U ×b
------------------------------------------------------------------------*/
void INT32UToINT8U(INT32U a,INT8U *b)
{
*b = (INT8U)(a>>24); b++;
*b = (INT8U)(a>>16); b++;
*b = (INT8U)(a>>8); b++;
*b = (INT8U)a; b++;
}
/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
void INT16UToINT8U(INT16U a,INT8U *b)
{
*b = (INT8U)a; b++;
*b = (INT8U)(a>>8); b++;
}
/*------------------------------------------------------------------------
目的:为网络器件的子网掩码计算输入值
输入:INT32U
输出:转换结果
------------------------------------------------------------------------*/
INT8U NetMaskToConfig(INT32U u)
{
INT8U i,k=0x0001;
for(i = 0;i < 32;i++)
{
if(u&(k<<i)) break;
}
return i;
}
/*------------------------------------------------------------------------
目的:输入值转换网络器件的子网掩码
输入:INT8U
输出:转换结果
------------------------------------------------------------------------*/
INT32U ConfigToNetMask(INT8U u)
{
INT32U a = 0xffffffff;
a <<= u;
return a;
}
/*------------------------------------------------------------------------
Procedure: complement ID:1
Purpose: 取补码[与FDK的遥测格式(原码)相容]
Input: v:值.
Output: 转换结果.
Errors:
------------------------------------------------------------------------*/
/*
INT16U complement(INT16U v)
{
if( (v&0x8000) != 0 ) { // 负数
v ^= 0xffff;v += 1; // 取反加1
v |= 0x8000;
}
return(v);
}
*/
/*------------------------------------------------------------------------
Procedure: complement32 ID:1
Purpose: 取补码[与FDK的遥测格式(原码)相容]
Input: v:值.
Output: 转换结果.
Errors:
------------------------------------------------------------------------*/
/*
INT32U complement32(INT32U v)
{
if( v&0x80000000 ) { // 负数
v ^= 0xffffffff; v += 1; // 取反加1
v |= 0x80000000;
}
return(v);
}
*/
/*------------------------------------------------------------------------
Procedure: reverseb ID:1
Purpose: 按位颠倒字节.
Input: b:字节值.
Output: 转换结果.
Errors:
------------------------------------------------------------------------*/
/*
INT8U reverseb(INT8U b)
{
register INT8U i,temp;
for (temp=0,i=0; i<8; i++)
if ( (b&(1<<i)) != 0 ) temp += (0x80>>i);
return temp;
}
*/
/*------------------------------------------------------------------------
Procedure: reversebyte
Purpose: 高低字节颠倒.
Input:
Output: 转换结果.
Errors:
------------------------------------------------------------------------*/
INT16U reversebyte(INT16U word)
{
INT16U temp = 0;
temp += (word>>8)&0x00FF;
temp += (word<<8)&0xFF00;
return temp;
}
/*------------------------------------------------------------------------
Procedure: reversebyte_32 ID:1
Purpose: 高低字节颠倒.
Input:
Output: 转换结果.
Errors:
------------------------------------------------------------------------*/
INT32U reversebyte_32(INT32U dword)
{
INT32U temp =0;
temp += (dword>>24)&0x000000FF;
temp += (dword>> 8)&0x0000FF00;
temp += (dword<< 8)&0x00FF0000;
temp += (dword<<24)&0xFF000000;
return temp;
}
/*------------------------------------------------------------------------
Procedure: sumcrc ID:1
Purpose: 求和取反计算16位CRC码.
Input: ptr:字型缓存指针;count:缓存字数.
Output: 16位CRC码.
Errors:
------------------------------------------------------------------------*/
/*
INT16U sumcrc(void *ptr, short count)
{
register INT16U i, sum;
register INT16U *p = (INT16U *)ptr;
for(sum=0,i=0; i<count; i++) //求和
sum = sum + *(p+i);
return ~sum; //取反
}
*/
/*------------------------------------------------------------------------
Procedure: sumcrc ID:1
Purpose: 按字节求和取反计算16位CRC码.用于累计,整点数据缓存校验
Input: ptr:字节型缓存指针;count:缓存字节数.
Output: 16位CRC码.
Errors:
------------------------------------------------------------------------*/
/*
INT16U sumcrc_b(void *ptr, int count)
{
register INT16U i, sum;
register INT8U *p = (INT8U *)ptr;
for(sum=0,i=0; i<count; i++) //求和
{
sum = sum + *(p+i);
}
return ~sum; //取反
}
*/
/*------------------------------------------------------------------------
Procedure: cscrc ID:1
Purpose: 求和计算校验码.
Input: pbuf:字型缓存指针;count:缓存字数.
Output: 8 byte 校验和.
Errors:
------------------------------------------------------------------------*/
INT16U cscrc(void *pbuf, short count)
{
register INT8U i, sum;
register INT8U *p = (INT8U *)pbuf;
for(sum=0,i=0; i<count; i++) /*求和*/
sum = sum + *(p+i);
return sum;
}
/*------------------------------------------------------------------------
Procedure: bcd2bin ID:1
Purpose: 转换BCD码为二进制.
Input: BCD码.
Output: 转换结果.
Errors:
------------------------------------------------------------------------*/
/*
INT8U bcd2bin(INT8U v)
{
return ((v >> 4)*10 + (v & 0x0F));
}
*/
/*------------------------------------------------------------------------
Procedure: bin2bcd ID:1
Purpose: 转换二进制为BCD码.
Input: 二进制值.
Output: 转换结果.
Errors: 输入值过大.
------------------------------------------------------------------------*/
/*
INT8U bin2bcd(INT8U v)
{
register INT8U temp;
if(v>99) { return 0; }
temp = v/10; temp <<= 4; temp += v%10;
return(temp);
}
*/
/*------------------------------------------------------------------------
Procedure: bin2bcd16 ID:1
Purpose: 转换二进制为BCD码,用于两个字节.
Input: 二进制值.
Output: 转换结果.
Errors: 输入值过大.
------------------------------------------------------------------------*/
/*
INT16U bin2bcd16(INT16U v)
{
register INT16U temp=0,i,j;
if(v>9999) { return 0; }
for(i=1000,j=12;i>=1;i=i/10,j=j-4)
{
temp+=(v/i)<<j;
v-=(v/i)*i;
}
return (temp);
// if(v>9999) { return 0; }
// i= v/1000; temp += i<<12;
// v-=i*1000;
// i= (v/100); temp+=i<<8;
// v-=i*100;
// i = (v/10); temp+=i<<4;
// temp += ((v-i*10)%10);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -