C经典算法 基础算法 算法工具 数据处理

8 篇文章 0 订阅

       我的乐趣在于分享,分享我的小经验,也分享我的淘宝店铺~~“梯控之家”,有需要电梯刷卡管理软硬件系统的朋友,或者朋友的朋友,请以光临本店的方式为我的知识分享点赞,嘻嘻

        主文件为"dataoperate.c",其头文件"dataoperate.h"贴在主文件后面:

#include "dataoperate.h"
//#include	"config.h"

//------------------------------------------------------------------//
//描述: 单个按键键值获取
//参数: pt             按键结构体
//      GPIOx GPIO_Pin 按键输入IO脚
//      PRESStim       设置 长按最少时长
//      RELSEtim       设置 连按/双击最短时间间隔
//返回: 空
//注意: 10ms定时中断服务中调用  
//------------------------------------------------------------------//
void GetKeyValue(StuKEY *pt, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, u16 PRESStim, u8 RELSEtim) 
{    
	u8 key;
	PressTYPE  EDGEtyp = (pt->presstyp==Press_L)?Press_H:Press_L;
		
    key = checkPin(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin), &(pt->keyLine), 3);//30ms防抖延时
    switch(pt->status)
    {
    	case STATUS0:
		{
			if(pt->presstyp == key) //检测按键按下时的跳变沿
			{
			  pt->status =STATUS1;
			  pt->time   =0;			  
			}
			break;
		}
    	case STATUS1:
		{
			if(++(pt->time) > PRESStim)
			{
			  pt->value  =KEY_LONG; //确认"长按"
			  pt->status =STATUS0;
			}
			else
			{
			  if(EDGEtyp == key) //检测按键抬起时的跳变沿
			  {
			    pt->time =0;
				pt->status =STATUS2;
			  }
			}
			break;
		}
    	case STATUS2:
		{
			if(++(pt->time) > RELSEtim)
			{
			  pt->value  =KEY_CLICK; //确认"单击-短按"
			  pt->status =STATUS0;
			}
			else
			{
			  if(pt->presstyp == key) //短时间内再次检测到按键按下时的跳变沿
			  {			    
				pt->value  =KEY_DOUBLE; //确认"双击-连按"
				pt->status =STATUS0;
			  }
			}
			break;
		}
		
    	default: break;
    }
}

//------------------------------------------------------------------//
//描述: 单脉冲输出方法
//参数: pt 单脉冲结构体 
//    
//返回: 个数
//------------------------------------------------------------------//
void  PulseExport(StuPulse *pt)
{
    if(pt->time > 0)
    {
        pt->time--;
		if(pt->time != 0)
		{
	        if(PULSE_H==pt->outlevel)
				GPIO_SetBits(pt->GPIOx,pt->GPIO_Pin);
			else
				GPIO_ResetBits(pt->GPIOx,pt->GPIO_Pin);
		}
		else
		{
	        if(PULSE_H==pt->outlevel)
				GPIO_ResetBits(pt->GPIOx,pt->GPIO_Pin);
			else
				GPIO_SetBits(pt->GPIOx,pt->GPIO_Pin);		
		}
    }	
}

//------------------------------------------------------------------//
//描述: 查找字节中1的数量 
//参数: p_data:内容
//      plen :字节数
//返回: 个数
//------------------------------------------------------------------//
u8  BitsISSet(u8 *p_data, u8 plen)
{
    u8 i,j,count =0;

    for(j=0; j<plen; j++)
    {
        for(i=0; i<8; i++)
        {
            if( ((p_data[j]<<i)&0x80)!=0 ) { count++; }
        }
    }
    
    return count;
}

//------------------------------------------------------------------//
//描述: 字节倒序
//参数: p_data:内容
//      plen :要实现倒序的连续字节数
//返回: 无
//------------------------------------------------------------------//
//方法一: 
void ReverseByte(u8 *p_data, u8 plen)
{
	u8 i,j,temp;
	for(j=0;j<plen;j++)
	{
	  for(i=0;i<8;i++)
	  {
	    temp>>=1;
		if(p_data[j]>=0x80) //从最高位开始取值
			temp|=0x80;
		p_data[j]<<=1;      //源数据向左移位
	  }
	  p_data[j]=temp;
	}
}
//方法二:
void ReverseByte2(u8 *p_data, u8 plen)
{
	u8 bit,j,temp;
	for(j=0;j<plen;j++)
	{
	    bit = 8;		
	  while(bit)
	  {
		  bit--;
		  temp |= ((p_data[j] & 0x01) << bit); //从最低位开始取值
		  p_data[j] >>=1;                 //源数据向右移位
	  }
	    p_data[j]=temp;
	}
}

//------------------------------------------------------------------//
//描述: 字符串倒序
//参数: 
//      
//返回: 无
//------------------------------------------------------------------//
//方法一: 相对较优
void inverted_order1(u8 *p)
{
   u8 *s1,*s2,tem;
   
   s1=p;               //第一个字符的位置
   s2=s1+strlen(p)-1;  //最后一个非'\0'字符的位置
   while(s1<s2)
   {
    tem=*s1;
    *s1=*s2;
    *s2=tem;
    s1++;
    s2--;
   }
}
//方法二:相对较劣
void inverted_order2(char *src)
{
   int len = strlen(src);
   char *des = (char *)malloc(len + 1);
   char *s = &src[len-1]; //末位置
   char *d = des;         //首位置
   
   while(len-- != 0)
       *d++ = *s--;
   len = strlen(src);
   Mem_cpy(src, des, len);//结果拷贝回原字符串
//   *d = 0;
   free(des);//malloc 不能返回动态内存,不能将des指针地址复制给src
}

//------------------------------------------------------------------//
//描述: 字符串倒序 大小端转换
//参数: 
//      
//返回: 无
//------------------------------------------------------------------//
void BigEndianConvert_UINT16(uint16_t *pData, uint16_t dData)
{
	*pData = 0;

	*pData |= (dData&0xFF)<<8;
	*pData |= ((dData>>8)&0xFF);
}
void BigEndianConvert_UINT32(uint32_t *pData, uint32_t dData)
{
	*pData = 0;

	*pData |= (dData&0xFF)<<24;
	*pData |= ((dData>>8)&0xFF)<<16;
	*pData |= ((dData>>16)&0xFF)<<8;
	*pData |= ((dData>>24)&0xFF);
}

//------------------------------------------------------------------//
//描述: 数值区域判断
//参数: 
//返回: 查找成功或是失败
//------------------------------------------------------------------//
ErrorStatus BetweenValue(u32 q1, u32 q2, u32 value)
{
    if( (value>=q1)&&(value<=q2) )
    { return SUCCESS; }
    else
    { return ERROR;   }
}



//------------------------------------------------------------------//
//描述: 在指定字符串内查找字符出现指定次数的起始位置
//参数: source  原字符串
//		   sLen    原字符串长度
//             dest    要查找的字符
//             dcnt    出现的次数    
//
//             begin   目标字符串在原字符串的起始位置
//返回: 查找成功或是失败
//------------------------------------------------------------------//
ErrorStatus FindChar(const u8 *source, u16 sLen, u8 dest, u8 dcnt, u16 *begin)
{
	u16   jval;
	if( (sLen==0)||(dcnt==0) ){ return ERROR; }
	
	for(jval =0; jval< sLen; jval++)
	{
	    if(source[jval]==dest)
	    {
            if( (--dcnt)==0 )
            {
                *begin = jval;  
                return SUCCESS;
            }
	    }
	}	
	return ERROR;
}



//------------------------------------------------------------------//
//描述: 在指定字符串内查找相应字符串
//参数: source  原字符串
//		   sLen    原字符串长度
//             dest     查找字符串
//             dLen    查找字符串长度
//
//             begin   目标字符串在原字符串的起始位置
//返回: 查找成功或是失败
//------------------------------------------------------------------//
ErrorStatus InString(const u8 *source, u16 sLen, const u8 *dest, u16 dLen, u16 *begin)
{
	u16   jval,idx;
	bool  result =false;

	for(jval =0; jval< sLen; jval++)
	{
        if( (jval+dLen)>sLen )
        {
            return ERROR;
        }
        result =true;
        for(idx=0; idx<dLen; idx++)
        {
            if(source[jval+idx] != dest[idx])
            {
                result =false;
                break;
            }
        }
        if(result ==true)
        {
            *begin = jval;  
            return SUCCESS;
        }
	}	

	return ERROR;
}

//功能与 InString 一样, 这个是从后面开始寻找
ErrorStatus InStringLast(const u8 *source, u16 sLen, const u8 *dest, u16 dLen, u16 *begin)
{
	u16   jval,idx;
	bool  result =false;

	for(jval =sLen; jval>0; jval--)
	{
        if( jval < dLen )
        {
            return ERROR;
        }
        result =true;
        for(idx=0; idx < dLen; idx++)
        {
            if(source[jval-dLen+idx] != dest[idx])
            {
                result =false;
                break;
            }
        }
        if(result ==true)
        {
            *begin = jval-dLen;  
            return SUCCESS;
        }
	}	
	return ERROR;
}



//------------------------------------------------------------------//
//描述: 在指定字符串内查找数字串返回起始位置和长度
//参数: source  原字符串
//		   sLen    原字符串长度
//             begin   数字起始位置
//             dLen    数字长度
//
//返回: 查找成功或是失败
//------------------------------------------------------------------//
ErrorStatus SearchNumb(const u8 *source, u16 sLen, u16 *begin, u16 *dLen)
{
    u8    flag=0;
	u16   i,j,len=0;

	for(i=0; i<sLen; i++)
	{
	    if( (source[i]>='0')&&(source[i]<='9') )
        {  
            if(flag==0) {j=i; len=1; flag=1;}
            else        {len++;}
        }
        else
        {
            if(flag==1) {break;}
        }  
	}
	
    if(len >0)
    {*begin =j;*dLen =len; return SUCCESS;}
    else
    {return ERROR;}
}



//------------------------------------------------------------------//
//描述: 字符串转整形值
//参数:  source 待转换的字符串
//		    size    待转换字符串长度
//              mode  转换模式'D' : "12345" -> 12345       'H':"123AB" -> 0x123AB
//
//              changedata 转换后的数据
//返回: 转换成功或是失败
//------------------------------------------------------------------//
ErrorStatus AscToLong(const u8 *source, u8 size, u8 mode, u32 *changedata)
{
    u8 loop, dh =10;
    u32 k,j,temp;

    if(mode =='H')
    {
        if( (size==0)||(size>8) )
        {
            return ERROR;
        }
        
        for(loop =0; loop < size; loop++)
        {
            if( !IS_HEX(source[loop]) )
            {
                return ERROR;
            }
        }
        
        dh =0x10;
    }
    else if(mode =='D')
    {
        if( (size==0)||(size>10) )
        {
            return ERROR;
        }
        
        for(loop =0; loop < size; loop++)
        {
            if( !IS_DIGIT_NUM(source[loop]) )
            {
                return ERROR;
            }
        }
        
        dh =10;
    }

    k =1;
    for(loop =0; loop<(size-1); loop++)
    {
        k *= dh;
    }
    j =0;
    for(loop =0; loop<size; loop++)
    {
        temp = j;
        //j += CharToHex(source[loop])*k;
        j += CharToHex(source[loop])*k;
        if(temp > j)
        {
            return ERROR;   //出现溢出
        }
        k /= dh;
    }

    *changedata =j;
    
    return SUCCESS;
}



//------------------------------------------------------------------//
//描述:  整形值转字符串
//参数:  sourcedata 要转换的数值
//		    cgdata 转换后存储的字符
//              cglen  转换后字符长度
//              cgtype 转换类型
//                      DEC_CODE:    12345 -> "12345"
//                      HEX_CODE: 0x12345 -> "12345"
//              delzero 
//                      DEC_CODE 格式下结束字符
//                      1:  12345 -> "12345"
//                      0:  12345 -> "12345\0"
//                      HEX_CODE 格式下前导0
//                      1:  0x089ABCDE  -> "89ABCDE"
//                      0:  0x089ABCDE  -> "089ABCDE"
//
//返回: 转换成功或是失败
//------------------------------------------------------------------//
ErrorStatus LongToAsc(u32 sourcedata, u8 *cgdata, u8 *cglen, CODE_TYPE cgtype, u8 delzero)
{
    u8 i,j,k,r;
    u32 mask;
    
    if(cgtype == HEX_CODE)
    {
        k =0;
        j =28;
        mask =0xffffffff;
        
        for(i=0; i<8; i++)
        {
            r = (u8)(sourcedata>>j);
            if( (r==0)&&(k==0)&&(delzero==1) )
            {
                
            }
            else
            {
                //cgdata[k++] = HexToChar(r);
                cgdata[k++] = HexToChar(r);
            }

            mask >>= 4;
            sourcedata &= mask;
            j -=4;
        }

        if( k == 0)
        {
            cgdata[0] = '0';
            k =1;
        }

        *cglen =k;
        return  SUCCESS;
        
    }
    else if(cgtype == DEC_CODE)
    {
        j =0;
        mask = 1000000000;
        
        for(i=0; i<10; i++)
        {
            r = sourcedata/mask;
            if( (j>0)||(r!=0) )
            {
                cgdata[j++] = r+'0';
            }

            //sourcedata = sourcedata - r*mask;
            sourcedata %= mask;
            mask /= 10;
        }

        if( j==0 )
        {
            cgdata[j++] = '0';
        }

        if(delzero !=1)
        {
            cgdata[j] = '\0';  //结束符
        }
        
        *cglen =j;
        return  SUCCESS;
    }

    return  ERROR;
}



//------------------------------------------------------------------//
//描述: 内存比较函数
//参数:  dst 目的地址
//       sor 源地址
//       len 长度
//返回: 成功或失败
//------------------------------------------------------------------//
ErrorStatus Mem_cmp(const u8 *dst, const u8 *sor, u32 len)
{
    u32 i;
    for(i=0; i<len; i++)
    {
        if( dst[i] != sor[i] )
        { return ERROR;}
    }
    return SUCCESS;
}


//------------------------------------------------------------------//
//描述: 内存拷贝程序
//参数:  dst 目的地址
//       sor 源地址
//       len 长度
//返回: 成功或失败
//------------------------------------------------------------------//
ErrorStatus Mem_cpy(u8 *dst, const u8 *sor, u32 len)
{
    u32 i;
    
    for(i=0; i<len; i++)
    {
        *(dst+i) = *(sor+i);
    }
    
    return SUCCESS;
}


//------------------------------------------------------------------//
//描述: 内存初始化
//参数:  dst 目的地址
//              _data 填充数
//              len 长度
//返回: 成功或失败
//------------------------------------------------------------------//
ErrorStatus Mem_set(u8 *mem, u8 _data, u32 len)
{
    u32 i;
    
    for(i=0; i<len; i++)
    {
        *(mem+i) = _data;
    }
    
    return SUCCESS;
}



//------------------------------------------------------------------//
//描述: 十进制转BCD码
//参数:  _data 待转换的数
//返回: 转换后的数据
//------------------------------------------------------------------//
u8  DTOBCD(u8 _data)
{
    return ((_data/10)<<4) | (_data%10);
    //return ( ((_data/16)<<4) | (_data&0x0f) );
}



//------------------------------------------------------------------//
//描述: BCD码转十进制
//参数:  _data 待转换的数
//返回: 转换后的数据
//------------------------------------------------------------------//
u8  BCDTOD(u8 _data)
{
    return ( (_data>>4)*10 + (_data&0x0f) );
}


//------------------------------------------------------------------//
//描述: 将字符转成16进制数值 // '0' -> 0; 'a' -> 0x0a; 'A' -> 0x0a
//参数: x 要转换的字符
//返回: 转换后的HEX字符
//------------------------------------------------------------------//
u8 CharToHex(u8 X)
{
    u8 rByte;
    if( (X>='0') && (X<='9') )
    {
        return X - '0';
    }
    else if( (X>='A') && (X<='F') )   //( (_data>='A')&&(_data<='Z') )
    {
        return X - 'A' + 10;
    }
    else if( (X>='a') && (X<='f') )
    {
        return X - 'a' + 10;
    }
	else
	{
		return 0;
	}
}


//------------------------------------------------------------------//
//描述: 将16进制数值转成字符 // 0 -> '0'; 0x0a -> 'a'; 0x0a -> 'A'
//参数: x 要转换的HEX字符
//返回: 转换后的字符
//------------------------------------------------------------------//
u8 HexToChar(u8 X)
{
    u8 rByte;
    if( X<=9 )
    {
        return X + '0';
    }
    else if( X<=0x0f ) //( (X>=0x0a)&&(X<=0x0f) )
    {
        return X - 0x0a + 'A';
    }
    else
    {
        return 'x';
    }
}


//------------------------------------------------------------------//
//描述: HEX数组 转 ASC 字符串 // 0x12  => {0x31,0x32}   0x1210 => {0x31,0x32,0x31,0x30} 
//参数:                      // 0x12  => {'1' ,'2'}    0x1210 => {'1' ,'2' ,'1' ,'0'}
//返回: 转换后的字符长度
//------------------------------------------------------------------//
u32 HexToAscArray(u8 *asc, u8 *hex, u32 len)
{
    u32 retlen=0,i;
    
    for(i=0; i<len; i++)
    {
        asc[retlen++] = HexToChar(hex[i]>>4);
        asc[retlen++] = HexToChar(hex[i]&0x0f);
        #ifdef 0
		asc[retlen++] = ' ';	//改行代码仅供调试使用,不调试时,删除
        #endif		
    }
	asc[retlen] = '\0';
    
    return  retlen;
}


//------------------------------------------------------------------//
//描述: ASC 字符串 转 HEX数组 
// 0x12  <= {0x31,0x32}   0x1210 <= {0x31,0x32,0x31}   0x1210 <= {0x31,0x32,0x31,0x30}
//参数: 
//返回: 转换后额字符长度
//------------------------------------------------------------------//
u32 AscToHexArray(u8 *hex, u8 *asc, u32 len)
{
    u32 retlen=0,i;
    
    for(i=0; i<len/2; i++)
    {
        hex[retlen++] = (CharToHex(asc[i*2])<<4)|(CharToHex(asc[i*2+1]));
    }
    if(len%2)
    {
        hex[retlen++] = CharToHex(asc[i*2])<<4;
    }
    
    return  retlen;
}

/**----------------------------------------------*
// * funct: BCD码转字符 效果等同于 HexToAscArray()
//描述: HEX数组 转 ASC 字符串 // 0x12  => {0x31,0x32}   0x1210 => {0x31,0x32,0x31,0x30} 
//参数:                      // 0x12  => {'1' ,'2'}    0x1210 => {'1' ,'2' ,'1' ,'0'}
 * param:
 	入参:
 		*BCD:待转变的BCD码串
 		bytes:BCD码串长度
 	出参:
 		*dest:字符串返回地址
 * retur:
 		生成字符串的返回地址
 **----------------------------------------------*/
char *BCDToString(char *dest, unsigned char *BCD, int bytes)
{
    char  temp[] = "0123456789ABCDEF";
    int index = 0;
    int length = 0;
    if (BCD == NULL || bytes <= 0)
        return NULL;

    for (index = 0; index < bytes; index++) {
        dest[length++] = temp[(BCD[index] >> 4) & 0x0F];
        dest[length++] = temp[BCD[index] & 0x0F];
    }
    dest[length] = '\0';
    return dest;
}

/**----------------------------------------------*
// * funct: 字符转BCD码 效果等同于 AscToHexArray()
// 0x12  <= {0x31,0x32}   0x1210 <= {0x31,0x32,0x31}   0x1210 <= {0x31,0x32,0x31,0x30}
 * param:
 	入参:
 		*str:字符串地址
 	出参:
 		*BCD:转变生成的BCD码串
 * retur:
 		生成BCD串的长度
 **----------------------------------------------*/
int StringToBCD(unsigned char *BCD, const char *str)
{
    unsigned char chh, chl;
    int length = strlen(str);
    int index = 0;

    for (index = 0; index < length; index += 2) {
        chh = CharToHex(str[index]);
        if(index + 1 == length)//字符串长度为奇数
        	chl = 0;
        else                   //字符串长度为偶数
        	chl = CharToHex(str[index + 1]);
        BCD[index / 2] = (chh << 4) | chl;
    }
    return (length / 2);
}



//------------------------------------------------------------------//
//描述: 2~4 字节数组转 32 位整形
//参数: _data count
//返回: 转换后的数据
//------------------------------------------------------------------//
u32 ArrayToInt(u8 *_data, u8 count)
{
    if(count ==4)
    {
        return ( ((u32)_data[0]<<24) | ((u32)_data[1]<<16) | ((u32)_data[2]<<8) | _data[3]) ;
    }
    else if(count ==3)
    {
        return ( ((u32)_data[0]<<16) | ((u32)_data[1]<<8) |  _data[2]) ;
    }
    else if(count ==2)
    {
        return ( ((u32)_data[0]<<8) |  _data[1]) ;
    }

    return 0;
}


//------------------------------------------------------------------//
//描述: 32 位整形 转 2~4字节数组
//参数: inda count
//返回: _data
//------------------------------------------------------------------//
void IntToArray(u8 *_data , u32 inda, u8 count)
{
    if(count ==4)
    {
        _data[0]   = inda>>24;
        _data[1]   = inda>>16;
        _data[2]   = inda>>8;
        _data[3]   = inda&0xff;
    }
    else if(count ==3)
    {
        _data[0]   = inda>>16;
        _data[1]   = inda>>8;
        _data[2]   = inda&0xff;
    }
    else if(count ==2)
    {
        _data[0]   = inda>>8;
        _data[1]   = inda&0xff;
    }
}


//------------------------------------------------------------------//
//描述: 字符串长度判断
//参数: 
//返回: 
//------------------------------------------------------------------//
u32 Strlen(u8 *_data, u32 maxlen)
{
    u32 len =0;

    for(len =0; len<maxlen; len++)
    {
        if(_data[len]=='\0')
        { break; }
    }
    
    return len;
}

//------------------------------------------------------------------//
//描述: 路径头拼接另外一个路径
//参数: 
//返回: 成功或是失败
//------------------------------------------------------------------//
u8 GetPath(u8 *head, u8 *fname, u8 *getname)
{
    u16 begin, len;

    begin =Strlen(head, 100);
    len   =Strlen(fname,100);
    Mem_cpy(&getname[0], head, begin);
    if(getname[begin-1]!='/')  
    { getname[begin++]='/'; }
    Mem_cpy(&getname[begin], fname, len);
    getname[begin+len] ='\0';
    
    return SUCCESS;
}

//------------------------------------------------------------------//
//描述: 在原始路径上添加一级目录
//参数: 
//返回: 成功/失败
//------------------------------------------------------------------//
ErrorStatus PathAdd(u8 *basepath, u8 *addpath)
{
    u16 begin, len;

    begin =Strlen(basepath, 100);
    len   =Strlen(addpath,100);

    if(basepath[begin-1]!='/')  //上级目录后面加'/'
    { basepath[begin++]='/'; }

    Mem_cpy(&basepath[begin], addpath, len);
    basepath[begin+len] ='\0';

    return SUCCESS;
}

//------------------------------------------------------------------//
//描述:原路径上减去一层路径(现在最多30层)
//参数: 
//返回: 成功/失败
//------------------------------------------------------------------//
ErrorStatus PathSub(u8 *basepath)
{//"SD:/一次就好.mp3"
    ErrorStatus ret =ERROR;
    u16 begin, end, len;
    u8 maxpath =30;     //最大30级目录 
    u8 pathcnt =0;

    len =Strlen(basepath, 100);
    if(InString((const u8 *)basepath, len, ":/", 2, &begin) ==SUCCESS)
    {
        begin +=2;
        while(maxpath--)
        {
            if( InString((const u8 *)&basepath[begin], len-begin, "/", 1, &end)==ERROR)
            {
                if(pathcnt ==0)
                {   
                    if(len==begin) { break; }
                    Mem_set(&basepath[begin], '\0', len-begin); //清除/xxxxx 
                }
                else
                {
                    Mem_set(&basepath[begin-1], '\0', len-begin+1); //清除/xxxxx 
                }
                ret =SUCCESS;
                break;
            }
            begin += end+1;
            pathcnt++;
        }
    }
    return ret;   
}


#if 0
//------------------------------------------------------------------//
//描述:unicode 转GB2312码
//参数:  way: 0,UNICODE to GBK      1,GBK to UNICODE
//返回: 成功/失败
//------------------------------------------------------------------//
WCHAR   UnicodeGBChange(WCHAR sor, u8 way)
{
    WCHAR c;
    int i, n, li, hi;
    DWORD gbk2uni_offset=0;
    WCHAR t[2];
    
    if(W25QXX_Info.ZKFlag==1)   //有字库
    {
        if(way) { gbk2uni_offset=W25QXX_Info.ZKunicLen/2; } //GBK 2 UNICODE
        else    { gbk2uni_offset=0; }                       //UNICODE 2 GBK    
        
        /* Unicode to OEMCP */
        hi=W25QXX_Info.ZKunicLen/2;//对半开.
        hi =hi / 4 - 1;
        li = 0;
        for (n = 16; n; n--)
        {
            i = li + (hi - li) / 2; 
            W25QXX_Read((BYTE*)&t,W25QXX_Info.ZKunicAddr+i*4+gbk2uni_offset,4);//读出4个字节  
            if (sor == t[0]) break;
            if (sor > t[0])li = i;  
            else hi = i;    
        }
        c = n ? t[1] : 'x';     
    }
    else
    {
        c ='x';
    }

    return c;
}
#endif

//------------------------------------------------------------------//
//描述: strUctoGb unicode 转GB2312码
//参数:
//返回: 成功/失败
//------------------------------------------------------------------//
u16 strUctoGb(u8 *pDst, const u8*pSrc, u16 pSlen)
{
    u16 i,nDst;
    WCHAR Sordata,CGdata;

    nDst =0;
    for(i=0; i<pSlen; i++)
    {
        if(pSrc[i]==0x00)
        {
            pDst[nDst++] =pSrc[++i];
        }
        else
        {
            Sordata = ((WCHAR)pSrc[i]<<8) | pSrc[i+1]; i++;
            CGdata =UnicodeGBChange(Sordata,0); 
            pDst[nDst++] = (u8)(CGdata>>8);
            pDst[nDst++] = (u8)(CGdata&0xff);
        }
    }

    return nDst;
}

//------------------------------------------------------------------//
//描述: strGbtoUc unicode 转GB2312码 
//参数:
//返回: 成功/失败
//------------------------------------------------------------------//
u16 strGbtoUc(u8 *pDst, const u8*pSrc, u16 pSlen)
{
    u16 i,nDst;
    WCHAR Sordata,CGdata;

    nDst =0;
    for(i=0; i<pSlen; i++)
    {
        if(pSrc[i] <=0x7F)
        {
            pDst[nDst++] =0x00;
            pDst[nDst++] =pSrc[i];
        }
        else
        {
            Sordata = ((WCHAR)pSrc[i]<<8) | pSrc[i+1]; i++;
            CGdata =UnicodeGBChange(Sordata,1); 
            pDst[nDst++] = (u8)(CGdata>>8);
            pDst[nDst++] = (u8)(CGdata&0xff);
        }
    }

    return nDst;
}

/**----------------------------------------------*
// * funct: IO脚电平状态和跳变沿检测
 * param:
 	入参:
 		*gpio:GPIO检测结构体
 		timeout:IO电平状态检测过滤时长 - 一般设置100ms
 	出参:
 * retur:
 		空
 * 备注:
 	使用范例--
		void lockGpio_Changed(uint8_t state) // 门锁状态发生变化 回调
		{
			printf("lock status change:%d",state);
		}
 		Gpio_Singal lock_state;	//柜门状态0-打开  1-关闭 --定义
 		lock_state.callback = lockGpio_Changed; //回调函数注册
 	  
 		lock_state.tempState = gpio_input_bit_get(GPIOB,GPIO_PIN_13); --每20ms更新tempState
		GpioEvent_Loop(&GlobalInfo.lock_state,100);//100ms过滤    每20ms调用
 **----------------------------------------------*/
void GpioEvent_Loop(Gpio_Singal *gpio,uint16_t timeout) //每20ms轮询一次
{
	if(gpio->preState != gpio->tempState)
	{
		gpio->preState = gpio->tempState;
		gpio->timer = 0;
	}
	if(gpio->timer < timeout)
	{
		gpio->timer += 20; //每20ms轮询一次
		if(gpio->timer >= timeout && gpio->tempState != gpio->curState)
		{
			gpio->curState = gpio->tempState;
			if(gpio->callback) gpio->callback(gpio->curState);
		}
	}
}


//-----检测IO脚电平状态 消抖延时 结构化计时 按键检测----------------------------//
/*
申明 定义:
typedef struct
{
    u16 Time1; //对低电平状态计时
    u16 Time2; //对高电平状态计时
    u8 state;  //记录检测引脚的最终状态
} xchrTime; 
xchrTime    keys2;
#define PinSWITCH_S2IN      GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)

调用举例:
    IO_status = checkPin(PinSWITCH_S2IN, &keys2, 10);    //100ms检测后确认
	//程序的调用是在每10ms一次的定时中断里

函数参数:
  Level   电平状态,    形参例子: PinSWITCH_S2IN  
  pt      全局变量,    记录检测引脚状态
  keepTim 消抖延时时长,若定时器中断每10ms产生一次,那么消抖延时总时长为 10* keepTim 
                        这段时间内,要求每次检测都是一样的结果才正确
*/
u8 checkPin(u8 Level, xchrTime *pt, u16 keepTim)
{
    if((Level==0)&&(pt->state!='L'))
    {
        pt->Time1++;
        if(pt->Time1>=keepTim) 
        {
            pt->state='L';
            return 'L';
        }
    }
    else if((Level==1)&&(pt->state!='H'))
    {
        pt->Time2++;
        if(pt->Time2>=keepTim)
        {
            pt->state='H';
            return 'H';
        }
    }
    else 
    {
        pt->Time1=pt->Time2=0;
    }
    
    return 0;  // 0
}
//-------------------------END of 消抖延时-----------------------------------------------//	

//获取 IP
// "192.168.1.1"
ErrorStatus Findipaddress(u8 *pstr, u16 plen, u8 *ip)
{
    u16 begin=0, end=0;
    u8 i;
    u8 vip[4];

    for(i=0; i<3; i++)  //查找IP
    {  
        if(FindChar( &pstr[begin], plen, '.', 1, &end)==SUCCESS)
        {
            if( (end>0)&&(end<=3) )
            {
                if( AscToLong(&pstr[begin], end, 'D', (u32 *)&vip[i])==SUCCESS )
                {
                    begin += (end+1);
                    plen  -= (end+1);
                }
                else
                { return ERROR; }
            }
            else
            { return ERROR; }
        }
        else
        { return ERROR; }
    }

    if( (plen>0)&&(plen<=3) )
    {
        if(AscToLong(&pstr[begin], plen, 'D', (u32 *)&vip[3])==ERROR)
        { return ERROR; }
    }
    else
    { return ERROR; }

    Mem_cpy( (u8 *)ip, (const u8 *)vip, 4 );
    return  SUCCESS;
}


//获取 IP与端口
// "192.168.1.1,8866"
ErrorStatus Findfullipaddress(u8 *pstr, u16 plen, IPv4Type *ip)
{
    u16 begin=0, end=0, len=0;
    u8 i, chr;
    IPv4Type vip;

    for(i=0; i<4; i++)  //查找IP
    {
        if(i<3) { chr = '.'; }
        else    { chr = ','; }
        
        if(FindChar( &pstr[begin], plen, chr, 1, &end)==SUCCESS)
        {
            if( (end>0)&&(end<=3) )
            {
                if( AscToLong(&pstr[begin], end, 'D', (u32 *)&(vip.IP[i]))==SUCCESS )
                {
                    begin += (end+1);
                    plen  -= (end+1);
                }
                else
                { return ERROR; }
            }
            else
            { return ERROR; }
        }
        else
        { return ERROR; }
    }

    if( SearchNumb((const u8 *)&pstr[begin], plen, &end, &len)==SUCCESS )
    {
        if( (len>0)&&(len<=5) )
        {
            if(AscToLong((const u8 *)&pstr[begin+end], len, 'D', (u32 *)&(vip.PORT))==ERROR)
            { return ERROR; }
        }
        else
        { return ERROR; }
    }
    else
    { return ERROR; }
    
    Mem_cpy( (u8 *)ip, (const u8 *)&vip, sizeof(vip) );
    return  SUCCESS;
}


//IP地址 格式化成字符串
//192 168 1 1 -->   "192.168.1.1"
void    IPAddrToAsc(u8 *ip, u8 *out, u8 *outlen)
{
    u8  len =0;

    *outlen =0;
    LongToAsc( (u32)ip[0], &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
    out[*outlen] ='.'; *outlen += 1;

    LongToAsc( (u32)ip[1], &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
    out[*outlen] ='.'; *outlen += 1;

    LongToAsc( (u32)ip[2], &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
    out[*outlen] ='.'; *outlen += 1;

    LongToAsc( (u32)ip[3], &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
    
}


//IP地址 格式化成字符串
//192 168 1 1 8800 -->   "192.168.1.1,8800"
void    IPAddrToFullAsc(IPv4Type ip, u8 *out, u8 *outlen)
{
    u8  len =0;

    *outlen =0;
    LongToAsc( (u32)ip.IP[0], &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
    out[*outlen] ='.'; *outlen += 1;

    LongToAsc( (u32)ip.IP[1], &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
    out[*outlen] ='.'; *outlen += 1;

    LongToAsc( (u32)ip.IP[2], &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
    out[*outlen] ='.'; *outlen += 1;

    LongToAsc( (u32)ip.IP[3], &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
    out[*outlen] =','; *outlen += 1;

    LongToAsc( (u32)ip.PORT,  &out[*outlen], &len, DEC_CODE, 1);  *outlen += len;
}



//------------------------------------------------------------------//
//描述:CRC校验算法 未经验证 added by ypl 20170922
//参数: 
//返回: 
//------------------------------------------------------------------//
//-----------------高低位倒置----------------
//描述: 单字节数据倒序
u8 invert_byte( u8 U8B )
{
U8B = (u8)((u8)( U8B << 4 ) & 0x0F0U ) | (u8)((u8)( U8B >> 4 ) & 0x00FU );
U8B = (u8)((u8)( U8B << 2 ) & 0x0CCU ) | (u8)((u8)( U8B >> 2 ) & 0x033U );
U8B = (u8)((u8)( U8B << 1 ) & 0x0AAU ) | (u8)((u8)( U8B >> 1 ) & 0x055U );
return U8B;
}

//描述: 单字数据倒序
u16 invert_word( u16 U8B )
{
 U8B = (u16)((u16)( U8B & 0x000FFU ) << 8 ) | (u16)((u16)( U8B & 0x0FF00U ) >> 8 );
 U8B = (u16)((u16)( U8B & 0x00F0FU ) << 4 ) | (u16)((u16)( U8B & 0x0F0F0U ) >> 4 );
 U8B = (u16)((u16)( U8B & 0x03333U ) << 2 ) | (u16)((u16)( U8B & 0x0CCCCU ) >> 2 );
 U8B = (u16)((u16)( U8B & 0x05555U ) << 1 ) | (u16)((u16)( U8B & 0x0AAAAU ) >> 1 );
 return U8B;
}

//描述: 双字数据倒序
u32 invert_dword( u32 U8B )
{
 U8B = (u32)((u32)( U8B & 0x055555555U ) << 1 ) | (u32)((u32)( U8B & 0x0AAAAaaaaU ) >> 1 );
 U8B = (u32)((u32)( U8B & 0x033333333U ) << 2 ) | (u32)((u32)( U8B & 0x0CCCCccccU ) >> 2 );
 U8B = (u32)((u32)( U8B & 0x00f0f0F0FU ) << 4 ) | (u32)((u32)( U8B & 0x0F0F0f0f0U ) >> 4 );
 U8B = (u32)((u32)( U8B & 0x000FF00FFU ) << 8 ) | (u32)((u32)( U8B & 0x0FF00FF00U ) >> 8 );
 U8B = (u32)((u32)( U8B & 0x00000FFFFU ) << 16 )| (u32)((u32)( U8B & 0x0FFFF0000U ) >> 16 );
 return U8B;
}


//------------------CRC16 多种算法---------------
u16 CRC16_CCITT(u8 *puchMsg, u32 usDataLen)  
{  
  u16 wCRCin = 0x0000;  
  u16 wCPoly = 0x1021;  
  u8 wChar = 0;
  u8 i;  
    
  while (usDataLen--)     
  {  
        wChar = *(puchMsg++);  
        wChar = invert_byte(wChar);  
        wCRCin ^= (wChar << 8);  
        for(i=0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
  }  
  wCRCin = invert_word(wCRCin);  
  return (wCRCin) ;  
}  
u16 CRC16_CCITT_FALSE(u8 *puchMsg, u32 usDataLen)  
{  
  u16 wCRCin = 0xFFFF;  
  u16 wCPoly = 0x1021;  
  u8 wChar = 0;  
  u8 i;
    
  while (usDataLen--)     
  {  
        wChar = *(puchMsg++);  
        wCRCin ^= (wChar << 8);  
        for(i = 0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
  }  
  return (wCRCin) ;  
}  
u16 CRC16_XMODEM(u8 *puchMsg, u32 usDataLen)  
{  
  u16 wCRCin = 0x0000;  
  u16 wCPoly = 0x1021;  
  u8 wChar = 0;  
  u8 i;  
    
  while (usDataLen--)     
  {  
        wChar = *(puchMsg++);  
        wCRCin ^= (wChar << 8);  
        for(i = 0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
  }  
  return (wCRCin) ;  
}  
  
u16 CRC16_X25(u8 *puchMsg, u32 usDataLen)  
{  
  u16 wCRCin = 0xFFFF;  
  u16 wCPoly = 0x1021;  
  u8 wChar = 0;  
  u8 i;  
    
  while (usDataLen--)     
  {  
        wChar = *(puchMsg++);  
        wChar = invert_byte(wChar);  
        wCRCin ^= (wChar << 8);  
        for(i = 0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
  }  
  wCRCin = invert_word(wCRCin);  
  return (wCRCin^0xFFFF) ;  
}  
  
u16 CRC16_MODBUS(u8 *puchMsg, u32 usDataLen)  
{  
  u16 wCRCin = 0xFFFF;  
  u16 wCPoly = 0x8005;  
  u8 wChar = 0;  
  u8 i;  
    
  while (usDataLen--)     
  {  
        wChar = *(puchMsg++);  
        wChar = invert_byte(wChar);  
        wCRCin ^= (wChar << 8);  
        for(i = 0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
  }  
  wCRCin = invert_word(wCRCin);  
  return (wCRCin) ;  
}  
u16 CRC16_IBM(u8 *puchMsg, u32 usDataLen)  
{  
  u16 wCRCin = 0x0000;  
  u16 wCPoly = 0x8005;  
  u8 wChar = 0;  
  u8 i;  
    
  while (usDataLen--)     
  {  
        wChar = *(puchMsg++);  
        wChar = invert_byte(wChar);  
        wCRCin ^= (wChar << 8);  
        for(i = 0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
  }  
  wCRCin = invert_word(wCRCin);  
  return (wCRCin) ;  
}  
u16 CRC16_MAXIM(u8 *puchMsg, u32 usDataLen)  
{  
  u16 wCRCin = 0x0000;  
  u16 wCPoly = 0x8005;  
  u8 wChar = 0;  
  u8 i;  
    
  while (usDataLen--)     
  {  
        wChar = *(puchMsg++);  
        wChar = invert_byte(wChar);  
        wCRCin ^= (wChar << 8);  
        for(i = 0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
  }  
  wCRCin = invert_word(wCRCin);  
  return (wCRCin^0xFFFF) ;  
}  
u16 CRC16_USB(u8 *puchMsg, u32 usDataLen)  
{  
  u16 wCRCin = 0xFFFF;  
  u16 wCPoly = 0x8005;  
  u8 wChar = 0;  
  u8 i;  
    
  while (usDataLen--)     
  {  
        wChar = *(puchMsg++);  
        wChar = invert_byte(wChar);  
        wCRCin ^= (wChar << 8);  
        for(i = 0;i < 8;i++)  
        {  
          if(wCRCin & 0x8000)  
            wCRCin = (wCRCin << 1) ^ wCPoly;  
          else  
            wCRCin = wCRCin << 1;  
        }  
  }  
  wCRCin = invert_word(wCRCin);  
  return (wCRCin^0xFFFF) ;  
}



 // * funct: CRC校验数组
 const uint16_t CRC_TAB[] =
	 {
		 0x0000, 0x0C1C0, 0x81C1, 0x4001, 0x01C3, 0x0C003, 0x8002, 0x41C2,
		 0x01C6, 0x0C006, 0x8007, 0x41C7, 0x0005, 0x0C1C5, 0x81C4, 0x4004,
		 0x01CC, 0x0C00C, 0x800D, 0x41CD, 0x000F, 0x0C1CF, 0x81CE, 0x400E,
		 0x000A, 0x0C1CA, 0x81CB, 0x400B, 0x01C9, 0x0C009, 0x8008, 0x41C8,
		 0x01D8, 0x0C018, 0x8019, 0x41D9, 0x001B, 0x0C1DB, 0x81DA, 0x401A,
		 0x001E, 0x0C1DE, 0x81DF, 0x401F, 0x01DD, 0x0C01D, 0x801C, 0x41DC,
		 0x0014, 0x0C1D4, 0x81D5, 0x4015, 0x01D7, 0x0C017, 0x8016, 0x41D6,
		 0x01D2, 0x0C012, 0x8013, 0x41D3, 0x0011, 0x0C1D1, 0x81D0, 0x4010,
		 0x01F0, 0x0C030, 0x8031, 0x41F1, 0x0033, 0x0C1F3, 0x81F2, 0x4032,
		 0x0036, 0x0C1F6, 0x81F7, 0x4037, 0x01F5, 0x0C035, 0x8034, 0x41F4,
		 0x003C, 0x0C1FC, 0x81FD, 0x403D, 0x01FF, 0x0C03F, 0x803E, 0x41FE,
		 0x01FA, 0x0C03A, 0x803B, 0x41FB, 0x0039, 0x0C1F9, 0x81F8, 0x4038,
		 0x0028, 0x0C1E8, 0x81E9, 0x4029, 0x01EB, 0x0C02B, 0x802A, 0x41EA,
		 0x01EE, 0x0C02E, 0x802F, 0x41EF, 0x002D, 0x0C1ED, 0x81EC, 0x402C,
		 0x01E4, 0x0C024, 0x8025, 0x41E5, 0x0027, 0x0C1E7, 0x81E6, 0x4026,
		 0x0022, 0x0C1E2, 0x81E3, 0x4023, 0x01E1, 0x0C021, 0x8020, 0x41E0,
		 0x01A0, 0x0C060, 0x8061, 0x41A1, 0x0063, 0x0C1A3, 0x81A2, 0x4062,
		 0x0066, 0x0C1A6, 0x81A7, 0x4067, 0x01A5, 0x0C065, 0x8064, 0x41A4,
		 0x006C, 0x0C1AC, 0x81AD, 0x406D, 0x01AF, 0x0C06F, 0x806E, 0x41AE,
		 0x01AA, 0x0C06A, 0x806B, 0x41AB, 0x0069, 0x0C1A9, 0x81A8, 0x4068,
		 0x0078, 0x0C1B8, 0x81B9, 0x4079, 0x01BB, 0x0C07B, 0x807A, 0x41BA,
		 0x01BE, 0x0C07E, 0x807F, 0x41BF, 0x007D, 0x0C1BD, 0x81BC, 0x407C,
		 0x01B4, 0x0C074, 0x8075, 0x41B5, 0x0077, 0x0C1B7, 0x81B6, 0x4076,
		 0x0072, 0x0C1B2, 0x81B3, 0x4073, 0x01B1, 0x0C071, 0x8070, 0x41B0,
		 0x0050, 0x0C190, 0x8191, 0x4051, 0x0193, 0x0C053, 0x8052, 0x4192,
		 0x0196, 0x0C056, 0x8057, 0x4197, 0x0055, 0x0C195, 0x8194, 0x4054,
		 0x019C, 0x0C05C, 0x805D, 0x419D, 0x005F, 0x0C19F, 0x819E, 0x405E,
		 0x005A, 0x0C19A, 0x819B, 0x405B, 0x0199, 0x0C059, 0x8058, 0x4198,
		 0x0188, 0x0C048, 0x8049, 0x4189, 0x004B, 0x0C18B, 0x818A, 0x404A,
		 0x004E, 0x0C18E, 0x818F, 0x404F, 0x018D, 0x0C04D, 0x804C, 0x418C,
		 0x0044, 0x0C184, 0x8185, 0x4045, 0x0187, 0x0C047, 0x8046, 0x4186,
		 0x0182, 0x0C042, 0x8043, 0x4183, 0x0041, 0x0C181, 0x8180, 0x4040};

/**----------------------------------------------*
// * funct: CRC校验
* param:
 入参:
	 *dat:校验数据
	 data_len:校验数据的长度
 出参:
	 *crc:
* retur:
	 空
* 备注:
 使用范例--
	 typedef struct
	 {
		 uint8_t head;
		 uint8_t status;
		 uint8_t len;
		 uint8_t dat[256];
	 } FrameType_t;
	 void DnDataDeal(FrameType_t *frame,uint8_t len)
	 {
		 tCrc crcDnData;
		 CrcCal((uint8_t *)&frame->head, 3+frame->len, &crcDnData);
		 if (frame->dat[frame->len] == crcDnData.C1.C0.Low)//这里只使用了CRC结果的低位
		 {}
	 }
**----------------------------------------------*/
 void CrcCal(uint8_t *dat, uint16_t data_len, tCrc *crc)
 {
	 uint16_t temp1, temp2;
	 uint8_t *ptr = dat;
	 crc->C1.C0.High = crc->C1.C0.Low = 0xff;
	 do
	 {
		 crc->Index = ((*ptr++) ^ crc->C1.C0.Low) & 0xff;
		 temp1 = CRC_TAB[crc->Index];
		 temp2 = temp1 >> 8;
		 crc->C1.C0.Low = (crc->C1.C0.High ^ temp2) & 0xff;
		 crc->C1.C0.High = temp1 & 0xff;
	 } while (--data_len);
 }


 /**----------------------------------------------*
// * funct: 获取芯片唯一id, 12个字节 96位
 * param:
 	入参:
 	出参:
 		HWId:MCU唯一ID
 * retur:CL_OK
 **----------------------------------------------*/
int BswSrv_GetHWId(char HWId[])
{
	if(HWId == NULL) return CL_FAIL;

	uint8_t id[10];

    //获取MCU唯一ID
    uint32_t Unique_ID1 = *(uint32_t *)(0x1FFFF7E8);        //UNIQUE_ID[31: 0] //各类芯片MCU唯一ID的地址可能不同
    uint32_t Unique_ID2 = *(uint32_t *)(0x1FFFF7EC);        //UNIQUE_ID[63:32]
    uint32_t Unique_ID3 = *(uint32_t *)(0x1FFFF7F0);        //UNIQUE_ID[95:63]

	id[0] = (Unique_ID1 >> 24) & 0xFF;
	id[1] = (Unique_ID1 >> 16) & 0xFF;
	id[2] = (Unique_ID1 >> 8) & 0xFF;
	id[3] = (Unique_ID1) & 0xFF;

	id[4] = (Unique_ID2 >> 24) & 0xFF;
	id[5] = (Unique_ID2 >> 16) & 0xFF;
	id[6] = (Unique_ID2 >> 8) & 0xFF;
	id[7] = (Unique_ID2) & 0xFF;

	id[8] = (Unique_ID3 >> 24) & 0xFF;
	id[9] = (Unique_ID3 >> 16) & 0xFF;
//	id[10] = (Unique_ID3 >> 8) & 0xFF;
//	id[11] = (Unique_ID3) & 0xFF;

	BCDToString(HWId,id,10);
	return CL_OK;
}


/**----------------------------------------------*
// * funct: 累加和校验
 * param:
 	入参:
 		*dat:8位数据串地址
 		len: 参与检验的数据字节数
 	出参:
 * retur:累加和
 **----------------------------------------------*/
uint8_t ACC_CheckSum(uint8_t *dat,uint16_t len)
{
    uint8_t sum = 0;

    for(uint8_t i = 0; i < len; i++)
    {
        sum += dat[i];
    }

    return sum;
}

/**----------------------------------------------*
// * funct:异或和校验
 * param:
 	入参:
 		*dat:8位数据串地址
 		len: 参与检验的数据字节数
 	出参:
 * retur:异或和
 **----------------------------------------------*/
uint8_t XOR_CheckSum(uint8_t *dat,uint16_t len)
{
    uint8_t sum = 0;

    for(uint16_t i = 0; i < len; i++)
    {
        sum ^= dat[i];
    }

    return sum;
}

/**----------------------------------------------*
// * funct:数组查空,判断数组数据是否全部为空
 * param:
 	入参:
 		*array:数据串地址
 		len: 数据字节数
 	出参:
 * retur:
 		为空:CL_OK
 		不为空:CL_FAIL
 **----------------------------------------------*/
int isArraryEmpty(uint8_t *array,int len)
{
	for(int i = 0;i<len ; i++){
		if(array[i] != 0x00)
        {
			return CL_FAIL;
		}
	}
	return CL_OK;
}

/**----------------------------------------------*
// * funct: 交换变量
 * param:
 	入参:
 		*a:int变量a的地址
 		*b:int变量b的地址
 	出参:
 * retur:
 		空
 **----------------------------------------------*/
void SwapInt(int *a, int *b)
{
    int temp;

    temp = *a;
    *a = *b;
    *b = temp;

    return ;
}

/**----------------------------------------------*
// * funct: 快速排序
 * param:
 	入参:
 		array:int数组
 		begin:排序数组的起始偏移
 		end:  排序数组的结束偏移
 	出参:
 		array:排序完成的数组
 * retur:
 		空
 **----------------------------------------------*/
void Quicksort(int array[], int begin, int end)
{
    int i, j;

    if(begin < end)
    {
        i = begin + 1;
        j = end;

        while(i < j)
        {
            if(array[i] > array[begin])
            {
                SwapInt(&array[i], &array[j]);
                j--;
            }
            else
            {
                i++;
            }
        }
        if(array[i] >= array[begin])
        {
            i--;
        }
        SwapInt(&array[begin], &array[i]);

        Quicksort(array, begin, i);
        Quicksort(array, j, end);
    }
}






头文件"dataoperate.h"如下:

#ifndef	_DATA_OPERATE_H_
#define	_DATA_OPERATE_H_

#include	"config.h"
#include    "integer.h"
#include    <stdbool.h>

//typedef unsigned char u8;
//typedef unsigned int  u16;
//typedef unsigned short long int u24;
//typedef unsigned long int u32;

#define CL_OK                           0
#define CL_FAIL                         (-1)
#define CL_TRUE                         1
#define CL_FALSE                        0


#define IS_DIGIT_NUM(C)     ( ((C)>='0') && ((C)<='9') )
#define IS_UPPER_CHAR(C)       ( ((C)>='A') && ((C)<='Z') )
#define IS_LOWER_CHAR(C)       ( ((C)>='a') && ((C)<='z') )
#define IS_CHAR(C)         ( ( ((C)>='A') && ((C)<='Z') ) || ( ((C)>='a') && ((C)<='z') ) )
#define IS_HEX(C)          ( ( ((C)>='0') && ((C)<='9') ) || ( ((C)>='a') && ((C)<='f') ) || ( ((C)>='A') && ((C)<='F') ) )

#define  MAXvalue(a,b)  ((a)>(b)?(a):(b))

typedef enum{ DEC_CODE =1, HEX_CODE, BCD_CODE} CODE_TYPE;

//typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;

typedef struct
{
    u16 Time1;
    u16 Time2;
    u8 state;
} xchrTime; 

typedef struct
{
    u8  IP[4];  //1P
    u16 PORT;   //端口
    
}IPv4Type;

typedef enum{
	PULSE_H=0, //单脉冲输出极性
	PULSE_L
}LEVELType; 
typedef struct{
	GPIO_TypeDef* GPIOx;    //IO口
	uint16_t      GPIO_Pin; //pin
	u8            time;     //设置单脉冲输出时长
	LEVELType     outlevel; //设置单脉冲输出极性
}StuPulse;

typedef struct 
{
	uint8_t curState;	//记录多次采集测定的IO状态---跳变沿
	uint8_t preState;	//记录前一次采集IO的状态
	uint8_t tempState;	//记录本次。。。
	uint16_t timer;		//记录采集次数
	void (*callback)(uint8_t);
}Gpio_Singal;


typedef enum{
	KEY_NONE=0,  //初始化键值 读取键值后,清空值
	KEY_CLICK,   //单击
	KEY_DOUBLE,  //双击
	KEY_LONG     //长按
}KeyVALUE;
typedef enum{
	Press_L='L',   //定义按下电平类型为低
	Press_H='H',
}PressTYPE;
typedef enum{
	STATUS0, //初始化状态 按键未按下状态
	STATUS1, //长按 待确定状态
	STATUS2, //单击、双击 待确定状态
}keySTATUS;
typedef struct{
	PressTYPE     presstyp;     //检测按下电平类型           init need
	KeyVALUE      value;        //键值                 	     init need
	keySTATUS     status;       //状态                       init need
	u16           time;         //按钮释放时长/按钮按下时长	 init need
	xchrTime      keyLine;      //IO检测结构化计             init noneed
}StuKEY;

//CrcCal() CRC检验函数相关数据结构体
typedef struct
{
	union {
		struct
		{
			uint8_t Low;  //CRC校验结果的低位
			uint8_t High; //CRC校验结果的高位
		} C0;
		uint16_t Value;
	} C1;
	uint16_t Index;
} tCrc;



void        GetKeyValue(StuKEY *pt, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, u16 PRESStim, u8 RELSEtim);//描述: 单个按键键值获取
void        PulseExport(StuPulse *pt);//描述: 单脉冲输出方法

u8          BitsISSet(u8 *p_data, u8 plen);//描述: 查找字节中1的数量

void        ReverseByte(u8 *pdata, u8 plen); //描述: 字节倒序 方式1
void        ReverseByte2(u8 *pdata, u8 plen);//描述: 字节倒序 方式2
void        inverted_order1(u8 *p); //字符串倒序 方式1
void        inverted_order2(u8 *p); //字符串倒序 方式2
void BigEndianConvert_UINT16(uint16_t *pData, uint16_t dData); //字符串倒序 半字数据大小端转换
void BigEndianConvert_UINT32(uint32_t *pData, uint32_t dData); //字符串倒序 单字数据大小端转换

ErrorStatus BetweenValue(u32 q1, u32 q2, u32 value); //描述: 数值区域判断

ErrorStatus FindChar(const u8 *source, u16 sLen, u8 dest, u8 dcnt, u16 *begin); //描述: 在指定字符串内查找字符出现指定次数的起始位置
ErrorStatus InString(const u8 *source, u16 sLen, const u8 *dest, u16 dLen, u16 *begin); //描述: 在指定字符串内查找相应字符串
ErrorStatus InStringLast(const u8 *source, u16 sLen, const u8 *dest, u16 dLen, u16 *begin); //功能与 InString 一样, 这个是从后面开始寻找
ErrorStatus SearchNumb(const u8 *source, u16 sLen, u16 *begin, u16 *dLen); //描述: 在指定字符串内查找数字串返回起始位置和长度

ErrorStatus AscToLong(const u8 *source, u8 size, u8 mode, u32 *changedata); //描述: 字符串转整形值
ErrorStatus LongToAsc(u32 sourcedata, u8 *cgdata, u8 *cglen, CODE_TYPE cgtype, u8 delzero); //描述:  整形值转字符串

ErrorStatus Mem_cmp(const u8 *dst, const u8 *sor, u32 len); //描述: 内存比较函数
ErrorStatus Mem_cpy(u8 *dst, const u8 *sor, u32 len); //描述: 内存拷贝程序
ErrorStatus Mem_set(u8 *mem, u8 _data, u32 len);  //描述: 内存初始化

u8          DTOBCD(u8 _data); //描述: 十进制转BCD码
u8          BCDTOD(u8 _data); //描述: BCD码转十进制
u8          CharToHex(u8 X); //描述: 将字符转成16进制数值 // '0' -> 0; 'a' -> 0x0a; 'A' -> 0x0a
u8          HexToChar(u8 X); //描述: 将16进制数值转成字符 // 0 -> '0'; 0x0a -> 'a'; 0x0a -> 'A'
u32         HexToAscArray(u8 *asc, u8 *hex, u32 len); //描述: HEX数组 转 ASC 字符串
u32         AscToHexArray(u8 *hex, u8 *asc, u32 len); //描述: ASC 字符串 转 HEX数组 // 0x12  <= {0x31,0x32}   0x1210 <= {0x31,0x32,0x31}   0x1210 <= {0x31,0x32,0x31,0x30}
char *      BCDToString(char *dest, unsigned char *BCD, int bytes); // * funct: BCD码转字符 效果等同于 HexToAscArray()
int         StringToBCD(unsigned char *BCD, const char *str); // * funct: 字符转BCD码 效果等同于 AscToHexArray()

u32         ArrayToInt(u8 *_data, u8 count); //描述: 2~4 字节数组转 32 位整形
void        IntToArray(u8 *_data , u32 inda, u8 count); //描述: 32 位整形 转 2~4字节数组

u32         Strlen(u8 *_data, u32 maxlen); //描述: 字符串长度判断
u8          GetPath(u8 *head, u8 *fname, u8 *getname); //描述: 路径头拼接另外一个路径
ErrorStatus PathAdd(u8 *basepath, u8 *addpath); //描述: 在原始路径上添加一级目录
ErrorStatus PathSub(u8 *basepath); //描述:原路径上减去一层路径(现在最多30层)

WCHAR       UnicodeGBChange(WCHAR sor, u8 way); //描述:unicode 转GB2312码
u16         strUctoGb(u8 *pDst, const u8*pSrc, u16 pSlen); //描述: strUctoGb unicode 转GB2312码
u16         strGbtoUc(u8 *pDst, const u8*pSrc, u16 pSlen); //描述: strGbtoUc unicode 转GB2312码 

void        GpioEvent_Loop(Gpio_Singal *gpio,uint16_t timeout); // * funct: IO脚电平状态和跳变沿检测
u8          checkPin(u8 Level, xchrTime *pt, u16 keepTim); //-----检测IO脚电平状态 消抖延时 结构化计时

ErrorStatus Findipaddress(u8 *pstr, u16 plen, u8 *ip); //获取 IP
ErrorStatus Findfullipaddress(u8 *pstr, u16 plen, IPv4Type *ip); //获取 IP与端口
void        IPAddrToAsc(u8 *ip, u8 *out, u8 *outlen); //IP地址 格式化成字符串
void        IPAddrToFullAsc(IPv4Type ip, u8 *out, u8 *outlen); //IP地址与端口 格式化成字符串

u8  invert_byte( u8 U8B ); //描述: 单字节数据倒序
u16 invert_word( u16 U8B ); //描述: 单字数据倒序
u32 invert_dword( u32 U8B ); //描述: 双字数据倒序
//------------------CRC16 多种算法---------------
u16 CRC16_CCITT(u8 *puchMsg, u32 usDataLen);
u16 CRC16_CCITT_FALSE(u8 *puchMsg, u32 usDataLen);
u16 CRC16_XMODEM(u8 *puchMsg, u32 usDataLen);
u16 CRC16_X25(u8 *puchMsg, u32 usDataLen);
u16 CRC16_MODBUS(u8 *puchMsg, u32 usDataLen);
u16 CRC16_IBM(u8 *puchMsg, u32 usDataLen);
u16 CRC16_MAXIM(u8 *puchMsg, u32 usDataLen);
u16 CRC16_USB(u8 *puchMsg, u32 usDataLen);


int    BswSrv_GetHWId(char HWId[]); // * funct: 获取芯片唯一id, 12个字节 96位

uint8_t ACC_CheckSum(uint8_t *dat,uint16_t len); // * funct: 累加和校验
uint8_t XOR_CheckSum(uint8_t *dat,uint16_t len); // * funct:异或和校验
int     isArraryEmpty(uint8_t *array,int len); // * funct:数组查空,判断数组数据是否全部为空

void    SwapInt(int *a, int *b); // * funct: 交换变量
void    Quicksort(int array[], int begin, int end); // * funct: 快速排序


#endif	/*_DATA_OPERATE_H_*/

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值