C常用函数

 

//数据共用体结构体
typedef union DATA_UnionTypeDef
{
    unsigned char     char_data[4];
    unsigned short     short_data[2];
    unsigned int      int_data;
    float             float_data;
}DATA_UnionTypeDef;





unsigned char crc_check_8(const unsigned char *p_data_buf, unsigned int data_len);
unsigned short crc_check_16(const unsigned char *p_data_buf, unsigned int data_len);
unsigned int crc_check_32(const unsigned char *p_data_buf, unsigned int data_len);


unsigned char c2d(unsigned char c);
unsigned short stoi16(unsigned char* p_str);
unsigned int stoi32(unsigned char* p_str);
float stof(unsigned char *p_str);
void itos(unsigned int data, unsigned char *p_str);
void ftos(float data, unsigned char *p_str);


void char_replace(unsigned char *p_str, char old_char, char new_char);


unsigned short swap_bytes_16(unsigned short data);
unsigned int swap_bytes_32(unsigned int data);
unsigned long swap_bytes_64(unsigned long data) ;



void inet_stoi(unsigned char* p_ipaddr_str, unsigned char *p_ip_num);
void inet_itos(unsigned int ip_addr, unsigned char *p_ipaddr_str);


unsigned short htons(unsigned short hostshort);
unsigned long htonl(unsigned long hostlong);
unsigned short ntohs(unsigned short netshort);
unsigned long ntohl(unsigned long netlong);

 

 

/************************************************************************************************
  * @ 函 数 名:crc_check_8
  * @ 功能说明:CRC-8 (多项式: 0x07)
  * @ 参    数:p_data_buf:要校验的数据        data_len:要校验的数据长度(字节)  
  * @ 返 回 值:校验码
************************************************************************************************/
unsigned char crc_check_8(const unsigned char *p_data_buf, unsigned int data_len) 
{
    unsigned char crc = 0x00;
    unsigned char poly = 0x07;
    
    for (unsigned int i=0;i<data_len;i++) 
    {
        crc ^= p_data_buf[i];
        for (unsigned char bit=0;bit<8;bit++) 
        {
            if (crc & 0x80) 
            {
                crc = (crc << 1) ^ poly;
            } 
            else 
            {
                crc <<= 1;
            }
        }
    }
    
    return crc;
}




/************************************************************************************************
  * @ 函 数 名:crc_check_16
  * @ 功能说明:CRC-16 (Modbus, 多项式: 0x8005)
  * @ 参    数:p_data_buf:要校验的数据        data_len:要校验的数据长度(字节)  
  * @ 返 回 值:校验码
************************************************************************************************/
unsigned short crc_check_16(const unsigned char *p_data_buf, unsigned int data_len) 
{
    unsigned short crc = 0xFFFF;
    unsigned short poly = 0xA001; // 0x8005的反转
    
    for (unsigned int i=0;i<data_len;i++) 
    {
        crc ^= p_data_buf[i];
        for (unsigned char bit=0;bit<8;bit++) 
        {
            if (crc & 0x0001) 
            {
                crc = (crc >> 1) ^ poly;
            } 
            else 
            {
                crc >>= 1;
            }
        }
    }
    
    return crc;
}



/************************************************************************************************
  * @ 函 数 名:crc_check_32
  * @ 功能说明:CRC-32 (多项式: 0x04C11DB7)
  * @ 参    数:p_data_buf:要校验的数据        data_len:要校验的数据长度(字节)  
  * @ 返 回 值:校验码
************************************************************************************************/
unsigned int crc_check_32(const unsigned char *p_data_buf, unsigned int data_len) 
{
    unsigned int crc = 0xFFFFFFFF;
    unsigned int poly = 0xEDB88320; // 0x04C11DB7的反转
    
    for (unsigned int i=0;i<data_len;i++) 
    {
        crc ^= p_data_buf[i];
        for (unsigned char bit=0;bit<8;bit++) 
        {
            if (crc & 0x00000001) 
            {
                crc = (crc >> 1) ^ poly;
            } 
            else 
            {
                crc >>= 1;
            }
        }
    }
    
    return ~crc;
}










/************************************************************************************************
  * @ 函 数 名:c2d
  * @ 功能说明:把字符数字转换成十进制数字
  * @ 参    数:c:要转化数字字符
  * @ 返 回 值:返回一个字符型数据
************************************************************************************************/
unsigned char c2d(unsigned char c)
{
    if (c >= '0' && c <= '9')
    {
        return c - '0';
    }
    
    if (c >= 'a' && c <= 'f')
    {
        return 10 + c -'a';
    }
    
    if (c >= 'A' && c <= 'F')
    {
        return 10 + c -'A';
    }

    return c;
}



/************************************************************************************************
  * @ 函 数 名:stoi16
  * @ 功能说明:字符串转化为16位整型函数
  * @ 参    数:p_str:要转化字符串
  * @ 返 回 值:返回转换后的整型数
************************************************************************************************/
unsigned short stoi16(unsigned char* p_str)
{
    unsigned short num = 0;
    
    while (*p_str != 0)
    {
        num = num*10 + c2d(*p_str++);
    }
    
    return num;
}



/************************************************************************************************
  * @ 函 数 名:stoi32
  * @ 功能说明:字符串转化为32位整型函数
  * @ 参    数:p_str:要转化字符串
  * @ 返 回 值:返回转换后的整型数
************************************************************************************************/
unsigned int stoi32(unsigned char* p_str)
{
    unsigned int num = 0;
    
    while (*p_str !=0)
    {
        num = num*10 + c2d(*p_str++);
    }
    return num;
}



/************************************************************************************************
  * @ 函 数 名:stof
  * @ 功能说明:字符串转化为浮点数
  * @ 参    数:p_str:要转换的字符串
  * @ 返 回 值:返回转换后的浮点数
************************************************************************************************/
float stof(unsigned char *p_str)
{
    unsigned int data_bits = 0;        //数据的位数
    unsigned int i = 0;
    float float_value = 0.0f;
    
    data_bits = strlen((const char *)p_str);//数据位数
    
    for (i=0;i<20;i++)//最多20位数
    {
        if (p_str[i] == '.')//小数点的位置
        {
            break;
        }
    }
    
    if (i >= 20)//没有找到小数点
    {
        i = data_bits;
    }
    
    for (unsigned int j=0;j<i;j++)//整数部分
    {
        float_value = float_value + (p_str[j] - 0x30)*pow(10,i-j-1);
    }

    for (unsigned int j=0;j<data_bits-i-1;j++)//小数部分
    {
        float_value = float_value + (p_str[j+i+1] - 0x30)*pow(0.1,(data_bits-i-1)-((data_bits-i-1)-j-1));
    }

    return float_value;
}



/************************************************************************************************
  * @ 函 数 名:itos
  * @ 功能说明:整型数转化为字符串函数
  * @ 参    数:data:要转化的整数, p_str:存放转化后的字符串
  * @ 返 回 值:无
************************************************************************************************/
void itos(unsigned int data, unsigned char *p_str)
{
    sprintf((char *)p_str,"%d",data);

    return;
}




/************************************************************************************************
  * @ 函 数 名:ftos
  * @ 功能说明:浮点数转化为字符串函数
  * @ 参    数:data:要转化的浮点数, p_str:存放转化后的字符串
  * @ 返 回 值:无
************************************************************************************************/
void ftos(float data, unsigned char *p_str)
{
    sprintf((char *)p_str,"\"%f\"",data);

    return;
}










/************************************************************************************************
  * @ 函 数 名:char_replace
  * @ 功能说明:用新的字符去替换字符串中指定的字符
  * @ 参    数:str:要替换的字符串,old_char:指定的字符,new_char:新的字符    
  * @ 返 回 值:无
************************************************************************************************/
void char_replace(unsigned char *p_str, char old_char, char new_char)
{
    unsigned int i = 0;
    
    while (*p_str != '\0')
    {
        if (p_str[i] == old_char) 
        {
            p_str[i] = new_char;    
        }
        
        i++;
    }
    
    return ;
}





/************************************************************************************************
  * @ 函 数 名:swap_bytes_16
  * @ 功能说明:16位高低字节交换
  * @ 参    数:data:要转换的数据
  * @ 返 回 值:转换后的数据
************************************************************************************************/
unsigned short swap_bytes_16(unsigned short data) 
{
    return (data >> 8) | (data << 8);
}



/************************************************************************************************
  * @ 函 数 名:swap_bytes_32
  * @ 功能说明:32位高低字节交换
  * @ 参    数:data:要转换的数据
  * @ 返 回 值:转换后的数据
************************************************************************************************/
unsigned int swap_bytes_32(unsigned int data) 
{
    return ((data >> 24) & 0x000000FF) |
           ((data >> 8)  & 0x0000FF00) |
           ((data << 8)  & 0x00FF0000) |
           ((data << 24) & 0xFF000000);
}



/************************************************************************************************
  * @ 函 数 名:swap_bytes_64
  * @ 功能说明:64位高低字节交换
  * @ 参    数:data:要转换的数据
  * @ 返 回 值:转换后的数据
************************************************************************************************/
unsigned long swap_bytes_64(unsigned long data) 
{
    return ((data >> 56) & 0x00000000000000FF) |
           ((data >> 40) & 0x000000000000FF00) |
           ((data >> 24) & 0x0000000000FF0000) |
           ((data >> 8)  & 0x00000000FF000000) |
           ((data << 8)  & 0x000000FF00000000) |
           ((data << 24) & 0x0000FF0000000000) |
           ((data << 40) & 0x00FF000000000000) |
           ((data << 56) & 0xFF00000000000000);
}






/************************************************************************************************
  * @ 函 数 名:inet_stoi
  * @ 功能说明:ip网络地址字符串转换为数据
  * @ 参    数:p_ipaddr_str:地址字符串  p_ip_num:ip数据
  * @ 返 回 值:无
************************************************************************************************/
void inet_stoi(unsigned char* p_ipaddr_str, unsigned char *p_ip_num)
{
    unsigned char ip_addr[50] = {0};
    unsigned char * nexttok = NULL;
    unsigned char num = 0;
    
    
    strcpy((char *)ip_addr,(const char *)p_ipaddr_str);
    nexttok = ip_addr;
    
    for (unsigned char i=0;i<4;i++)
    {
        nexttok = strtok((char *)nexttok,(const char*)".");

        num = (unsigned char) stoi16(nexttok);

        p_ip_num[i] = num;
        nexttok = NULL;
    }
    
    return ;
}    
 



/************************************************************************************************
  * @ 函 数 名:inet_itos
  * @ 功能说明:将4字节地址转化为字符串格式
  * @ 参    数:ip_addr:  要转化地址
  * @ 返 回 值:无
************************************************************************************************/
void inet_itos(unsigned int ip_addr, unsigned char *p_ipaddr_str)
{
    memset((void *)p_ipaddr_str, 0, 32);
    sprintf(p_ipaddr_str,"%d.%d.%d.%d",(int)(ip_addr>>24 & 0xFF),(int)(ip_addr>>16 & 0xFF),(int)(ip_addr>>8 & 0xFF),(int)(ip_addr & 0xFF));
    
    return ;
}








/************************************************************************************************
  * @ 函 数 名:htons
  * @ 功能说明:将一个 主机模式的unsigned short型数据转换到大端模式的TCP/IP 网络字节格式的数据.
  * @ 参    数:要转换的数据
  * @ 返 回 值:大端模式的数据
************************************************************************************************/
unsigned short htons(unsigned short hostshort)
{
#if ( SYSTEM_ENDIAN == _ENDIAN_LITTLE_ )
    return swap_bytes_16(hostshort);
#else
    return hostshort;
#endif        
}





/************************************************************************************************
  * @ 函 数 名:htonl
  * @ 功能说明:将一个 主机模式的unsigned long型数据转换到大端模式的TCP/IP 网络字节格式的数据.
  * @ 参    数:hostlong:要转换的数据
  * @ 返 回 值:大端模式的数据
************************************************************************************************/
unsigned long htonl(unsigned long hostlong)    
{
#if ( SYSTEM_ENDIAN == _ENDIAN_LITTLE_ )
    return (unsigned long)(swap_bytes_64(hostlong));
#else
    return hostlong;
#endif    
}




/************************************************************************************************
  * @ 函 数 名:ntohs
  * @ 功能说明:将一个大端模式的TCP/IP 网络字节格式的数据转换到主机模式的unsigned short型数据
  * @ 参    数:netshort:要转换的数据
  * @ 返 回 值:unsigned short模式的数据
************************************************************************************************/
unsigned short ntohs(unsigned short netshort)
{
#if ( SYSTEM_ENDIAN == _ENDIAN_LITTLE_ )    
    return htons(netshort);
#else
    return netshort;
#endif        
}




/************************************************************************************************
  * @ 函 数 名:ntohl
  * @ 功能说明:将一个大端模式的TCP/IP 网络字节格式的数据转换到主机模式的unsigned long型数据
  * @ 参    数:netlong:要转换的数据
  * @ 返 回 值:unsigned long模式的数据
************************************************************************************************/
unsigned long ntohl(unsigned long netlong)
{
#if ( SYSTEM_ENDIAN == _ENDIAN_LITTLE_ )
    return htonl(netlong);
#else
    return netlong;
#endif        
}

 

posted @ 2025-08-15 16:53  孤情剑客  阅读(11)  评论(0)    收藏  举报