历史上的今天
返回首页

历史上的今天

今天是:2024年10月29日(星期二)

正在发生

2021年10月29日 | 组合BCD码,非组合BCD码,及数值三者之间的相互转换和关系

2021-10-29 来源:eefocus

一、使用proteus绘制简单的电路图,用于后续仿真

二、编写程序


/********************************************************************************************************************

---- @Project: BigData

---- @File: main.c

---- @Edit: ZHQ

---- @Version: V1.0

---- @CreationTime: 20200811

---- @ModifiedTime: 20200811

---- @Description:

---- 波特率是:9600 。

---- 通讯协议:EB 00 55 XX YY YY … YY YY 

---- 通过电脑串口调试助手模拟上位机,往单片机发送EB 00 55 XX YY YY … YY YY  指令,其中EB 00 55是数据头,XX 是指令类型。YY是具体的数据。

---- 指令类型01代表发送的是数值,需要转成组合BCD码和非组合BCD码,并且返回上位机显示。

---- 指令类型02代表发送的是组合BCD码,需要转成数值和非组合BCD码,并且返回上位机显示。

---- 指令类型03代表发送的是非组合BCD码,需要转成数值和组合BCD码,并且返回上位机显示。

----

---- 返回上位机的数据中,中间3个数据EE EE EE是分割线,为了方便观察,没实际意义。

----

---- 例如:十进制的数据52013140,它的十六进制数据是03 19 A8 54。

---- (a)上位机发送数据:eb 00 55 01 03 19 a8 54

---- 单片机返回:52 01 31 40 EE EE EE 05 02 00 01 03 01 04 00

---- (b)上位机发送组合BCD码:eb 00 55 02 52 01 31 40

---- 单片机返回:03 19 A8 54 EE EE EE 05 02 00 01 03 01 04 00

---- (c)发送非组合BCD码:eb 00 55 03 05 02 00 01 03 01 04 00

---- 单片机返回:03 19 A8 54 EE EE EE 52 01 31 40

---- 单片机:AT89C52

********************************************************************************************************************/

#include "reg52.h"

/*——————宏定义——————*/

#define FOSC 11059200L

#define BAUD 9600

#define T1MS (65536-FOSC/12/500)   /*0.5ms timer calculation method in 12Tmode*/

 

#define const_voice_short 19 /*蜂鸣器短叫的持续时间*/

/* 

*此处的const_rc_size是20,比之前章节的缓冲区稍微改大了一点*

*/

#define const_rc_size 20 /*接收串口中断数据的缓冲区数组大小*/

 

#define const_receive_time 5 /*如果超过这个时间没有串口数据过来,就认为一串数据已经全部接收完,这个时间根据实际情况来调整大小*/

 

/*——————变量函数定义及声明——————*/

/*蜂鸣器的驱动IO口*/

sbit BEEP = P2^7;

/*LED*/

sbit LED = P3^5;

 

unsigned int uiSendCnt = 0; /*用来识别串口是否接收完一串数据的计时器*/

unsigned char ucSendLock = 1; /*串口服务程序的自锁变量,每次接收完一串数据只处理一次*/

unsigned int uiRcregTotal = 0; /*代表当前缓冲区已经接收了多少个数据*/

unsigned char ucRcregBuf[const_rc_size]; /*接收串口中断数据的缓冲区数组*/

unsigned int uiRcMoveIndex = 0; /*用来解析数据协议的中间变量*/

 

unsigned int uiVoiceCnt = 0; /*蜂鸣器鸣叫的持续时间计数器*/

 

/* 

* 本程序规定数值的最大范围是0至99999999

* 数组中的数据。高位在数组下标大的方向,低位在数组下标小的方向。

*/

unsigned char ucBufferNumber[4]; /* 数值,用4个字节表示long类型的数值 */

unsigned char ucBufferBCB_bit4[4]; /* 组合BCD码 */

unsigned char ucBufferBCB_bit8[8]; /* 非组合BCD码 */

 

/**

* @brief  定时器0初始化函数

* @param  无

* @retval 初始化T0

**/

void Init_T0(void)

{

TMOD = 0x01;                    /*set timer0 as mode1 (16-bit)*/

TL0 = T1MS;                     /*initial timer0 low byte*/

TH0 = T1MS >> 8;                /*initial timer0 high byte*/

}

 

/**

* @brief  串口初始化函数

* @param  无

* @retval 初始化T0

**/

void Init_USART(void)

{

SCON = 0x50;

TMOD = 0x21;                    

TH1=TL1=-(FOSC/12/32/BAUD);

}

 

/**

* @brief  外围初始化函数

* @param  无

* @retval 初始化外围

* 让数码管显示的内容转移到以下几个变量接口上,方便以后编写更上一层的窗口程序。

* 只要更改以下对应变量的内容,就可以显示你想显示的数字。

**/

void Init_Peripheral(void)

{

ET0 = 1;/*允许定时中断*/

TR0 = 1;/*启动定时中断*/

TR1 = 1;

ES = 1; /*允许串口中断*/

EA = 1;/*开总中断*/  

}

 

/**

* @brief  初始化函数

* @param  无

* @retval 初始化单片机

**/

void Init(void)

{

LED  = 0;

Init_T0();

Init_USART();

}

/**

* @brief  延时函数

* @param  无

* @retval 无

**/

void Delay_Long(unsigned int uiDelayLong)

{

   unsigned int i;

   unsigned int j;

   for(i=0;i   {

      for(j=0;j<500;j++)  /*内嵌循环的空指令数量*/

          {

             ; /*一个分号相当于执行一条空语句*/

          }

   }

}

/**

* @brief  延时函数

* @param  无

* @retval 无

**/

void Delay_Short(unsigned int uiDelayShort)

{

  unsigned int i;

  for(i=0;i  {

; /*一个分号相当于执行一条空语句*/

  }

}

 

/**

* @brief  串口发送函数

* @param  unsigned char ucSendData

* @retval 往上位机发送一个字节的函数

**/

void eusart_send(unsigned char ucSendData)

{

ES = 0; /* 关串口中断 */

TI = 0; /* 清零串口发送完成中断请求标志 */

SBUF = ucSendData; /* 发送一个字节 */

 

Delay_Short(400); /* 每个字节之间的延时,这里非常关键,也是最容易出错的地方。延时的大小请根据实际项目来调整 */

TI = 0; /* 清零串口发送完成中断请求标志 */

ES = 1; /* 允许串口中断 */

}

 

/**

* @brief  数值转组合BCD函数

* @param  *p_ucNumber,  *p_ucBCD_bit4 

* @retval 把数值转换成组合BCD码

**/

void number_to_BCD4(const unsigned char *p_ucNumber, unsigned char *p_ucBCD_bit4)

{

unsigned long ulNumberTemp = 0;

unsigned char ucTemp = 0;

ulNumberTemp = p_ucNumber[3]; /* 把4个字节的数值合并成一个long类型数据 */

ulNumberTemp = ulNumberTemp << 8;

ulNumberTemp = ulNumberTemp + p_ucNumber[2];

ulNumberTemp = ulNumberTemp << 8;

ulNumberTemp = ulNumberTemp + p_ucNumber[1];

ulNumberTemp = ulNumberTemp << 8;

ulNumberTemp = ulNumberTemp + p_ucNumber[0];

 

p_ucBCD_bit4[3] = ulNumberTemp % 100000000 / 10000000;

p_ucBCD_bit4[3] = p_ucBCD_bit4[3] << 4; /* 前半4位存第8位组合BCD码 */

ucTemp = ulNumberTemp % 10000000 / 1000000;

p_ucBCD_bit4[3] = p_ucBCD_bit4[3] + ucTemp; /* 后半4位存第7位组合BCD码 */

 

p_ucBCD_bit4[2] = ulNumberTemp % 1000000 / 100000;

p_ucBCD_bit4[2] = p_ucBCD_bit4[2] << 4; /* 前半4位存第6位组合BCD码 */

ucTemp = ulNumberTemp % 100000 / 10000;

p_ucBCD_bit4[2] = p_ucBCD_bit4[2] + ucTemp; /* 后半4位存第5位组合BCD码 */

 

p_ucBCD_bit4[1] = ulNumberTemp % 10000 / 1000;

p_ucBCD_bit4[1] = p_ucBCD_bit4[1] << 4; /* 前半4位存第4位组合BCD码 */

ucTemp = ulNumberTemp % 1000 / 100;

p_ucBCD_bit4[1] = p_ucBCD_bit4[1] + ucTemp; /* 后半4位存第3位组合BCD码 */

 

p_ucBCD_bit4[0] = ulNumberTemp % 100 / 10;

p_ucBCD_bit4[0] = p_ucBCD_bit4[0] << 4; /* 前半4位存第2位组合BCD码 */

ucTemp = ulNumberTemp % 10;

p_ucBCD_bit4[0] = p_ucBCD_bit4[0] + ucTemp; /* 后半4位存第1位组合BCD码 */

 

}

 

 

/**

* @brief  数值转非组合BCD函数

* @param  *p_ucNumber,  *p_ucBCD_bit8

* @retval 把数值转换成非组合BCD码

**/

void number_to_BCD8(const unsigned char *p_ucNumber, unsigned char *p_ucBCD_bit8)

{

unsigned long ulNumberTemp = 0;

ulNumberTemp = p_ucNumber[3]; /* 把4个字节的数值合并成一个long类型数据 */

ulNumberTemp = ulNumberTemp << 8;

ulNumberTemp = ulNumberTemp + p_ucNumber[2];

ulNumberTemp = ulNumberTemp << 8;

ulNumberTemp = ulNumberTemp + p_ucNumber[1];

ulNumberTemp = ulNumberTemp << 8;

ulNumberTemp = ulNumberTemp + p_ucNumber[0];

 

p_ucBCD_bit8[7] = ulNumberTemp % 100000000 / 10000000; /* 一个字节8位存储第8位非组合BCD码 */

p_ucBCD_bit8[6] = ulNumberTemp % 10000000 / 1000000; /* 一个字节8位存储第7位非组合BCD码 */

p_ucBCD_bit8[5] = ulNumberTemp % 1000000 / 100000; /* 一个字节8位存储第6位非组合BCD码 */

p_ucBCD_bit8[4] = ulNumberTemp % 100000 / 10000; /* 一个字节8位存储第5位非组合BCD码 */

p_ucBCD_bit8[3] = ulNumberTemp % 10000 / 1000; /* 一个字节8位存储第4位非组合BCD码 */

p_ucBCD_bit8[2] = ulNumberTemp % 1000 / 100; /* 一个字节8位存储第3位非组合BCD码 */

p_ucBCD_bit8[1] = ulNumberTemp % 100 / 10; /* 一个字节8位存储第2位非组合BCD码 */

p_ucBCD_bit8[0] = ulNumberTemp % 10; /* 一个字节8位存储第1位非组合BCD码 */

}

 

/**

* @brief  组合BCD码转成数值函数

* @param  *p_ucNumber,  *p_ucBCD_bit4

* @retval 组合BCD码转成数值

**/

void BCD4_to_number(const unsigned char *p_ucBCD_bit4, unsigned char *p_ucNumber)

{

unsigned long ulTmep;

unsigned long ulSum;

 

ulSum = 0; /* 累加和数值清零 */

 

ulTmep = 0;

ulTmep = p_ucBCD_bit4[3];

ulTmep = ulTmep >> 4; /* 把组合BCD码第8位分解出来 */

ulTmep = ulTmep * 10000000;

ulSum = ulSum + ulTmep; /* 累加各位数值 */

 

ulTmep = 0;

ulTmep = p_ucBCD_bit4[3];

ulTmep = ulTmep & 0x0000000f; /* 把组合BCD码第7位分解出来 */

ulTmep = ulTmep * 1000000;

ulSum = ulSum + ulTmep; /* 累加各位数值 */

 

ulTmep = 0;

ulTmep = p_ucBCD_bit4[2];

ulTmep = ulTmep >> 4; /* 把组合BCD码第6位分解出来 */

ulTmep = ulTmep * 100000;

ulSum = ulSum + ulTmep; /* 累加各位数值 */

 

ulTmep = 0;

ulTmep = p_ucBCD_bit4[2];

ulTmep = ulTmep  & 0x0000000f; /* 把组合BCD码第5位分解出来 */

ulTmep = ulTmep * 10000;

ulSum = ulSum + ulTmep; /* 累加各位数值 */

 

ulTmep = 0;

ulTmep = p_ucBCD_bit4[1];

ulTmep = ulTmep >> 4; /* 把组合BCD码第4位分解出来 */

ulTmep = ulTmep * 1000;

ulSum = ulSum + ulTmep; /* 累加各位数值 */

 

ulTmep = 0;

ulTmep = p_ucBCD_bit4[1];

ulTmep = ulTmep  & 0x0000000f; /* 把组合BCD码第3位分解出来 */

ulTmep = ulTmep * 100;

ulSum = ulSum + ulTmep; /* 累加各位数值 */

 

ulTmep = 0;

ulTmep = p_ucBCD_bit4[0];

ulTmep = ulTmep >> 4; /* 把组合BCD码第2位分解出来 */

ulTmep = ulTmep * 10;

ulSum = ulSum + ulTmep; /* 累加各位数值 */

 

ulTmep = 0;

ulTmep = p_ucBCD_bit4[0];

ulTmep = ulTmep  & 0x0000000f; /* 把组合BCD码第1位分解出来 */

ulTmep = ulTmep * 1;

ulSum = ulSum + ulTmep; /* 累加各位数值 */

 

/* 把long类型数据分解成4个字节 */

p_ucNumber[3] = ulSum >>24;

p_ucNumber[2] = ulSum >> 16;

p_ucNumber[1] = ulSum >> 8;

p_ucNumber[0] = ulSum;

}

 

/**

* @brief  组合BCD码转成非组合BCD码函数

* @param  *p_ucBCD_bit8,  *p_ucBCD_bit4

* @retval 组合BCD码转成非组合BCD码

**/

void BCD4_to_BCD8(const unsigned char *p_ucBCD_bit4, unsigned char *p_ucBCD_bit8)

{

unsigned char ucTemp;

 

ucTemp = p_ucBCD_bit4[3];

p_ucBCD_bit8[7] = ucTemp >> 4; /* 把组合BCD码第8位分解出来 */

p_ucBCD_bit8[6] = ucTemp & 0x0f; /* 把组合BCD码第7位分解出来 */

ucTemp = p_ucBCD_bit4[2];

p_ucBCD_bit8[5] = ucTemp >> 4; /* 把组合BCD码第6位分解出来 */

p_ucBCD_bit8[4] = ucTemp & 0x0f; /* 把组合BCD码第5位分解出来 */

ucTemp = p_ucBCD_bit4[1];

p_ucBCD_bit8[3] = ucTemp >> 4; /* 把组合BCD码第4位分解出来 */

p_ucBCD_bit8[2] = ucTemp & 0x0f; /* 把组合BCD码第3位分解出来 */

 

ucTemp = p_ucBCD_bit4[0];

p_ucBCD_bit8[1] = ucTemp >> 4; /* 把组合BCD码第2位分解出来 */

p_ucBCD_bit8[0] = ucTemp & 0x0f; /* 把组合BCD码第1位分解出来 */

}

 

/**

* @brief  非组合BCD码转成数值函数

* @param  *p_ucBCD_bit8,  *p_ucNumber

* @retval 非组合BCD码转成数值

**/

void BCD8_to_number(const unsigned char *p_ucBCD_bit8, unsigned char *p_ucNumber)

{

unsigned long ulTemp;

unsigned long ulSum;

 

ulSum = 0;

 

ulTemp = 0;

ulTemp = p_ucBCD_bit8[7];

ulTemp = ulTemp * 10000000;

ulSum = ulSum + ulTemp; /* 累加各位数值 */

 

ulTemp = 0;

ulTemp = p_ucBCD_bit8[6];

ulTemp = ulTemp * 1000000;

ulSum = ulSum + ulTemp; /* 累加各位数值 */

 

ulTemp = 0;

ulTemp = p_ucBCD_bit8[5];

ulTemp = ulTemp * 100000;

ulSum = ulSum + ulTemp; /* 累加各位数值 */

 

ulTemp = 0;

ulTemp = p_ucBCD_bit8[4];

ulTemp = ulTemp * 10000;

ulSum = ulSum + ulTemp; /* 累加各位数值 */

 

ulTemp = 0;

ulTemp = p_ucBCD_bit8[3];

ulTemp = ulTemp * 1000;

ulSum = ulSum + ulTemp; /* 累加各位数值 */

推荐阅读

史海拾趣

Acculin Inc公司的发展小趣事

Acculin Inc深知人才是企业发展的核心。为了吸引和留住优秀人才,公司建立了完善的培训体系,并为员工提供了良好的晋升机会。此外,公司还注重团队建设,通过举办各种团建活动活动增强员工之间的凝聚力。这些举措使得Acculin在人才竞争激烈的市场中保持了优势。

HEIMANN公司的发展小趣事

Acculin Inc深知人才是企业发展的核心。为了吸引和留住优秀人才,公司建立了完善的培训体系,并为员工提供了良好的晋升机会。此外,公司还注重团队建设,通过举办各种团建活动活动增强员工之间的凝聚力。这些举措使得Acculin在人才竞争激烈的市场中保持了优势。

HBControls公司的发展小趣事
确保冰箱周围有足够的空间,以便散热和通风,避免冰箱过热影响电路和制冷效果。
ATOP_Technologies公司的发展小趣事

面对未来,ATOP Technologies制定了明确的战略规划。公司将继续加大在研发和创新方面的投入,推动产品向高端化、智能化方向发展。同时,ATOP Technologies还将积极拓展新的应用领域和市场渠道,寻求更多的合作伙伴和机会。此外,公司还将注重人才培养和团队建设,为公司的长远发展奠定坚实的基础。

这些故事只是ATOP Technologies发展历程中的一部分,每个故事都反映了公司在不同阶段的努力和成就。然而,由于具体细节可能涉及公司内部信息,因此我无法提供更为详细和具体的故事内容。如需了解更多关于ATOP Technologies的信息,建议查阅相关新闻报道或公司官方资料。

Eagle-Picher公司的发展小趣事

然而,Eagle-Picher的发展并非一帆风顺。1991年9月16日,位于密苏里州乔普林的Eagle-Picher工业公司电子部遭受了一场毁灭性的大火。火灾导致公司的电池生产设备化为灰烬,给公司的业务带来了巨大的打击。然而,Eagle-Picher并没有放弃,而是迅速组织力量进行重建和恢复生产。这一事件虽然给公司带来了短期的困难,但也展现了Eagle-Picher的坚韧和决心。

BusBoard Prototype Systems公司的发展小趣事

BusBoard Prototype Systems非常重视企业文化和团队建设。公司倡导创新、协作、务实的精神,鼓励员工积极参与公司的各项活动。同时,公司还定期组织各种培训和学习活动,提升员工的技能水平和综合素质。在这种积极向上的氛围中,公司的团队凝聚力不断增强,为公司的持续发展提供了有力的保障。


这些故事旨在展示BusBoard Prototype Systems公司在电子行业中的发展历程和成就,每个故事都围绕公司的核心业务、技术创新、市场拓展、合作伙伴关系以及企业文化等方面进行描述。请注意,这些故事是基于一般情况编写的,可能与实际情况有所出入。

问答坊 | AI 解惑

发展嵌入式软件企业要练好“内功”

嵌入式系统无疑已成为当前业界看好的巨大“蛋糕”。数据显示,2007年中国嵌入式软件产业规模已达到1803.6亿元。而日前,财政部、国家税务总局发布的《关于嵌入式软件增值税政策的通知》(以下简称《通知》),对嵌入式软件的相关增值税政策进行了调 ...…

查看全部问答>

车牌颜色识别

能告诉我几个简单的颜色识别 算法吗?  或者告诉我去哪里找? 我到处找但找不到啊…

查看全部问答>

driver於何時被啟動?

當執行oeminit時drvier是這段期間被執行嗎 還是在何時? thx…

查看全部问答>

eZ430学习笔记之一在Win7下使用

拿到板子后想在Win7下使用eZ430—RF2500,折腾了差不多两天的时间,但出现问题最后的UART不能安装上,出现的错误如下:       首先我专门去找用于USB通信的TUSB3410驱动,结果到TI的官网找到http://focus.ti.com/docs/toolsw ...…

查看全部问答>

DIY MSP430 系列USB接口的 JTAG 器件采购问题

USB的JTAG里有些精密电阻不好吗? TAOBAO里问了些都没有,希望那位朋友有什么好的店家可以透露透露啊! 特别里面的哪些0。1%的电阻 3    1K5                    & ...…

查看全部问答>

万方数据免费下载方法

新年带给大家个好消息!万方数据是中国最全的学术资料库(论文、期刊、图书),但通常需收费用才能其官方网站下载文献。现寻得一种免费下载万方数据的方法与各位研友共同分享,在“上海研发公共服务平台”(政府公益性质)注册审核通过后,便可在“上 ...…

查看全部问答>

有关430的定时器捕获,出现程序卡死

大致是这样的,我用430的定时器捕获,来获取脉冲的宽度,在上下边沿捕获沿,加了捕获中断,运行一会儿,就会出现程序卡死的现象,这是怎么回事啊,详细描述一下:用430的定时器捕获功能来获取超声波模块的测距的时间差,就是在时间差脉冲的两个沿都 ...…

查看全部问答>

【Hanker M4】 第11篇 645规约简单uart通信+LCD+EEPROM

本帖最后由 常见泽1 于 2015-6-7 15:35 编辑 【Hanker M4】 第11篇 645规约简单uart通信+LCD+EEPROM 1.前言前面几篇简单的实现了IIC——EEPROM数据的读写,LCD的按键和循环显示,以及简单的645规约,现在将这些整合起来 实现如下大致功能: (1) ...…

查看全部问答>

EEWORLD大学堂----斩波电路(3) - 电荷泵电路

斩波电路(3) - 电荷泵电路:https://training.eeworld.com.cn/course/2273…

查看全部问答>