我的乐趣在于分享,分享我的小经验,也分享我的淘宝店铺~~“梯控之家”,有需要电梯刷卡管理软硬件系统的朋友,或者朋友的朋友,请以光临本店的方式为我的知识分享点赞,嘻嘻
主文件为"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_*/