一行代码说清楚进制转换--转来转去

一行代码如下:

int comm_bcd_to_bin(unsigned char bcd)
{
	return (bcd>>4)*10 + (bcd&0x0F);
}

可以测试下:

#include<stdio.h>

int main()
{
	char data=0x78;
	printf("%d\n",data );//120
	data=comm_bcd_to_bin(data);
	printf("%d\n",data );//78
}    

思路就是:暴力把数据分成两部分,一部分是高4位 A,一部分是低4位 B。

此后的事情就是 :

你要16进制的 我就给你A*16 +B   此时数据依旧客观正确

你要10进制的 我就给你A*10 +B   此时数据变化了0X78其实是120,数据转换后变成78

用以前的风格写一下:(不要在意函数的名字)

#include<stdio.h>

#define GetHBits(val_8)     ((val_8>>4)&0x0F)
#define GetLBits(val_8)     (val_8     &0x0F)

#define HEX2BCD(HEX)        ( GetHBits(HEX)*10 + GetLBits(HEX) )

int main()
{
	short data=0x12;
	printf("%d\n",data );//18
	printf("%d\n",HEX2BCD(data) );//12
} 

现在就是十六进制的0X12变成十进制的12,如果你希望十六进制变十六进制就定义为:

 #define HEX2BCD(HEX)        ( GetHBits(HEX)*16 + GetLBits(HEX) )

 

再看看u16的 :----其实完全没有意义了 u8才是绝配的0X12这样的数据就是u8的8个位置4个一捏4个一捏的。

#include<stdio.h>

#define GetHBits(val_8)     ((val_8>>8)&0xFF)
#define GetLBits(val_8)     (val_8     &0xFF)

#define HEX2BCD(HEX)        ( GetHBits(HEX)*16*16 + GetLBits(HEX) )

int main()
{
	short data=0x1234;
	printf("%d\n",data );//4660
	printf("%d\n",HEX2BCD(data) );//4660
}    
   

 

1此时十六进制转十六进制。用法上是没有意义的,我们是希望十进制转化成十六进制才有意义。

2#define HEX2BCD(HEX)     (GetHBits(HEX)<<8 | GetLBits(HEX))  可以!

3#define HEX2BCD(HEX)     (GetHBits(HEX)*10*10 | GetLBits(HEX))  不可以!

 

再看一个u8的二分的例子,按键开门,点击确认#以后的函数:

《充电桩用的记录密码的是arr[6]其实用arr[3]就可以了 因为你都是1 2 3 4 5 6 7 8 9 0呀所以你是0X01 0X02这样你可以挤一挤》

uint8_t *userPwd , *pairPwd;
uint8_t pwd[3];//6位的密码 用arr[3]即可
     
log(DEBUG,"校验固定密码\n");

pwd[0] = touchKey.buffer[0]<<4|touchKey.buffer[1];
pwd[1] = touchKey.buffer[2]<<4|touchKey.buffer[3];
pwd[2] = touchKey.buffer[4]<<4|touchKey.buffer[5];
config.read(CFG_PAIR_PWD , (void **)&pairPwd );
config.read(CFG_USER_PWD , (void **)&userPwd );

if((aiot_strcmp(pwd , pairPwd , 3) == TRUE )||(aiot_strcmp(pwd , userPwd , 3) == TRUE ))
{
   open_door();
..




/* 
 *  设备默认配对密码
 */
-DDEFAULT_PAIR_PWD="{0X12,0x34,0x56}"


/* 
 *  设备默认开门密码
 */
-DDEFAULT_OPEN_PWD="{0X12,0x34,0x56}"

 

 

 

模块函数



//压缩一半

//方法1
//完成'4'-->4  ‘A’-->10
//传入参数不是ASCII的 就返回-1
unsigned char ASCII2INT(unsigned char dData)
{
	unsigned char rst=0;
	if((dData >= '0')&& (dData <= '9'))
				rst = dData-'0';
	else if((dData >= 'A')&&(dData <= 'F'))
				rst =  dData+10-'A';
	else if((dData >= 'a')&&(dData <= 'f'))
				rst =  dData+10-'a';
	else rst = -1;
			
	return rst;
}


//完成"10"--->0x10  "1234"--->0X12,0X34 
//len标识传入的strlen(strings)
//返回值是len的一半
char G_strsTobytes(void* Strings,void* Bytes,char len)
{
	unsigned char* strings=(unsigned char *)Strings;
	unsigned char* bytes  =(unsigned char *)Bytes;
	unsigned char i = 0,j=0,lowbits=0,highbits=0;
	if(len%2)return 0;//禁止奇数
	for (i = 0; i < len; i+=2)
	{           
		highbits = ASCII2INT(strings[i]  );
		lowbits  = ASCII2INT(strings[i+1]);
		bytes[j++] =( highbits << 4)|lowbits;//可以自己切换十进制 十六进制
	}
	return j;
}




//方法2
//完成"10"--->0x10  "1234"--->0X12,0X34 
//功能和上面一样 这个是机智云源码
void G_strsTohexs(char *pbSrc,char *pbDest,int32_t nLen)
{
    char h1,h2;
    char s1,s2;
    int32_t i;

    for (i=0; i<nLen; i++)
    {
        h1 = pbSrc[2*i];
        h2 = pbSrc[2*i+1];

        s1 = toupper(h1) - 0x30;//技巧1 直接减去0X30也就是减去‘0’
        if (s1 > 9)             //技巧2 toupper直接把char变成大写 也就避免了小写的case 
            s1 -= 7;            //技巧3 如果是ABC字符的话在-0x30的基础上再-7 7怎么来的?ASCII表A--65 9--57

        s2 = toupper(h2) - 0x30;
        if (s2 > 9)
            s2 -= 7;

        pbDest[i] = s1*16 + s2;//不如前面的思路写为s1<<4 | s2 //可以自己切换十进制 十六进制
    }
}


//方法3
//"1234"--->0X12,0X34 
void BAIDUhex_to_decimal(const char *hex_string, unsigned char *arr, size_t arr_len)
{
    const char *pos = hex_string;
    int count;

    for (count = 0; count < arr_len; count++) {
        sscanf(pos, "%2hhx", &arr[count]);//可以自己切换十进制 十六进制
        pos += 2;
    }
}





//0XAB-->"AB" 0XABCD-->"ABCD"  长度会扩大一倍!注意:没有结束符\0
void G_1byteTo2str(unsigned char* strings,unsigned char* bytes,unsigned char len)
{
    unsigned char const StrRefer[]="0123456789abcdef";//"0123456789ABCDEF";
    #define GET_MSB_STR(x) (StrRefer[((x>>4)&0x0f)])
    #define GET_LSB_STR(x) (StrRefer[(x&0x0f)])
    for(char i=0,j=0;i<len;i++,j+=2)
    {
        strings[j]  =GET_MSB_STR(bytes[i]);
        strings[j+1]=GET_LSB_STR(bytes[i]);
    }

}

//方法2是机智云版本:
//最后出来的Str的长度是进去的hex的2倍+1 注意:有结束符\0
void  G_hex2Str(unsigned char *pbDest, unsigned char *pbSrc, int32_t nLen)
{
    char    ddl,ddh;
    int32_t i;

    for (i=0; i<nLen; i++) 
	{
        ddh = 0x30 + pbSrc[i] / 16;
        ddl = 0x30 + pbSrc[i] % 16;
        if (ddh > 0x39) ddh = ddh + 7;
        if (ddl > 0x39) ddl = ddl + 7;
        pbDest[i*2]   = ddh;
        pbDest[i*2+1] = ddl;
    }

    pbDest[nLen*2] = '\0';
}




//0XABCD1234-->AB CD 12 34 保证正确!CSDN
void u32toArr4(uint32_t U,uint8_t *Arr)
{
	Arr[0] = (U&0XFF000000)>>24;
	Arr[1] = (U&0X00FF0000)>>16;
	Arr[2] = (U&0X0000FF00)>>8;
	Arr[3] = (U&0X000000FF)>>0; 
}






/**
 * htons unsigned short -> Network byte order
 * ntohs Network byte order -> unsigned short
 */
 //0XABCD-->0XCDAB CSDN
//为什么需要这个?你看0906 ble_Analysis_Rxdata 过来【0X00】【0X1B】
//如果直接读的话你是拿到了0X1B00 因为我们STM32的读是XX字节序 和读内存一样
//所以要反一下
uint16_t  exchangeBytes(uint16_t value)
{

    uint16_t tmp_value = 0;
    uint8_t *index_1, *index_2;

    index_1 = (uint8_t *)&tmp_value;
    index_2 = (uint8_t *)&value;

    *index_1     = *(index_2+1);
    *(index_1+1) = *index_2;

    return tmp_value;

}

 //0XABCD1234-->0X3412CDAB CSDN
uint32_t exchangeWord(uint32_t value)
{
	uint32_t tmp_value = 0;
    uint8_t *index_1, *index_2;

    index_1 = (uint8_t *)&tmp_value;
    index_2 = (uint8_t *)&value;

    *(index_1+0) = *(index_2+3);
    *(index_1+1) = *(index_2+2);
    *(index_1+2) = *(index_2+1);
    *(index_1+3) = *(index_2+0);
    return tmp_value;

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值