历史上的今天
今天是: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; /* 累加各位数值 */
下一篇:数码管与中断系统知识笔记
史海拾趣
|
嵌入式系统无疑已成为当前业界看好的巨大“蛋糕”。数据显示,2007年中国嵌入式软件产业规模已达到1803.6亿元。而日前,财政部、国家税务总局发布的《关于嵌入式软件增值税政策的通知》(以下简称《通知》),对嵌入式软件的相关增值税政策进行了调 ...… 查看全部问答> |
|
拿到板子后想在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的定时器捕获功能来获取超声波模块的测距的时间差,就是在时间差脉冲的两个沿都 ...… 查看全部问答> |
|
【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) ...… 查看全部问答> |




