历史上的今天

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

正在发生

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

发布者:Haifeeng 来源: 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; /* 累加各位数值 */

[1] [2]
关键字:数值  相互转换 引用地址:组合BCD码,非组合BCD码,及数值三者之间的相互转换和关系

上一篇:51单片机实现在在定时中断里动态扫描数码管的程序
下一篇:数码管与中断系统知识笔记

推荐阅读

配天机器人2018年Q3之后的持续爆发,下半年业绩依然相当可观。10月27日在合肥国际机电产品交易会现场,安徽省配天机器人技术有限公司与安徽技龙机器人科技有限公司共同签署战略合作协议即100台工业机器人采购项目,双方旨在以本次合作为契机,打开业务,共同开拓市场,实现共赢。继9月工博会与上海机气林的200台采购项目后,今天又签100台!发现今年配天百...
全球知名半导体制造商ROHM集团旗下的Kionix, Inc.,(总部位于美国纽约州伊萨卡)开发出两款加速度传感器“KX132-1211”和“KX134-1211”,非常适用于工业设备和可穿戴式设备等需要高精度且低功耗地进行运动感应的应用。 近年来,由于许多工厂都在努力节省人力并提高效率,因此在工业设备出现故障之前能够检测出异常的预测性维护理念越来越普及。与此同时...
康宁公司(纽约证券交易所代码:GLW)今日公布了截止至 2020 年 9 月 30 日第三季度的强劲财务业绩。 GAAP 销售额以及核心销售额均为 30 亿美元 核心销售额环比增长 16%,其中环境科技部和特殊材料部的环比增长分别达到 68%和 37%。 核心销售额同比增长 1%,其中特殊材料部和显示科技部的同比增长分别为 23%和 4%。 GAAP 每股收益为 0.48...
一、仪器型号安捷伦E8363A网络分析仪二、故障现象客户反馈仪器目前开机异常,开机后总会出现跳闸现象。三、故障检测遇到仪器开机总跳闸现象切记一定不能再次上电以免仪器故障扩大化,经检测,仪器控制板损坏,造成不开机;先处理开机故障,开机后端口1输出电平超差大,低20-30dB,微波开关损坏。四、维修与处理更换控制板组件,更换微波开关组件,调整检测...

史海拾趣

问答坊 | AI 解惑

求助:可变高频脉冲输出!

0~10V输入对应0~342016Hz脉冲输出大家有没有好的建议啊??…

查看全部问答∨

单片机或者嵌入式系统的开发规范化问题

随着人才流动的加快和研发周期的缩短,我们个人需要快速高效的完成自己的设计,维护和升级,公司需要人走不影响项目进度、新员工很快就能接手。这就需要:一个系统设计完成以后,它不应该仅仅是一些源代码,还应该包括各种各样的开发文档。(这对以 ...…

查看全部问答∨

学习linux嵌入式迷茫

学习到现在有半年时间拉,已经看完了arm体系结构和编程、深入理解计算机系统、linux简单的命令、linux shell、嵌入式linux开发完全手册(看到驱动部分), 到现在也没什么动手的能力,现在也就是看c 代码不是很吃力,但是,自己写的话好像有点困难 ...…

查看全部问答∨

Linux应用程序如何向设备发数据?

        本周,我的一个学生给我发了一个邮件,询问如何Linux下如何往外设写数据. 邮件如下.老大:        现在我有个紧急问题请教,希望你讲明白点,我想知道数据是怎么从用 ...…

查看全部问答∨

用tornado编译工程文件不产生.o文件

用tornado软件,创建“create downloadable application modules for vxworks...”的工程文件,编译时不产生.o文件。在编译完之后,直接down是怎么回事。…

查看全部问答∨

求中文版书籍<数字信号处理的fpga实现 >第三版

请问《数字信号处理的fpga实现 第三版》的中文版出来没有啊?英文太难看了…

查看全部问答∨

开源基于STM32F103系列 MINI板实验例程

蓝色Mini STM32 开发板 带CAN 485接口 基于STM32F103VET6 红色Mini STM32 开发板 带CAN 485接口 基于STM32F103RBT6 黄色Mini STM32 开发板 带CAN 485接口 基于STM32F103C8T6 高级例程将后续在本帖为大家提供!请关注!…

查看全部问答∨

本人刚刚从事微波射频行业,有没有什么入门的书求推荐

本人刚刚从事微波射频行业,有没有什么入门的书求推荐…

查看全部问答∨

msp430f2012 下载

刚学这个,然后要用到430f2012,可是只知道147的下载连接,不知道2012的下载电路,同样想要BSL下载(以前做好的模块),不知道怎么连接啊,大神教一下…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved