一、使用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; /* 累加各位数值 */
上一篇:51单片机实现在在定时中断里动态扫描数码管的程序
下一篇:数码管与中断系统知识笔记
推荐阅读
史海拾趣
对于5G169节日彩灯集成电路,网友可能提出多种问题,以下是一些常见问题及其详细回答:
1. 5G169节日彩灯集成电路的基本工作原理是什么?
回答:
5G169节日彩灯集成电路通过交流电输入,经过VDI~VD4桥式整流输出全波脉动直流电,供四路彩灯用电。该电路还包含简单的稳压电路(由Rl、R2、VD5和VD6组成),经过Cl滤波后输出约6V直流电供集成块用电。VD6在这里起隔离作用,使得R2两端能获得6V全波脉动直流电压,其脉动频率为交流电的2倍(即100Hz)。此100Hz信号经R4注入集成块的8脚作为同步信号。电路中还包含正、反向控制开关SB,用于控制彩灯的正向或反向循环。
2. 如何调节5G169节日彩灯的亮灯周期?
回答:
5G169节日彩灯的亮灯周期是可调的,但具体调节方式可能因不同型号的集成电路或电路设计而异。通常,亮灯周期的调节可能涉及改变与集成电路相关的电阻、电容或其他元件的值。然而,对于5G169这样的具体型号,如果没有详细的电路设计图或说明书,很难给出确切的调节步骤。一般情况下,可以通过查阅产品手册或联系制造商获取具体的调节方法。
3. 5G169节日彩灯集成电路是否需要外接电源?
回答:
是的,5G169节日彩灯集成电路需要外接电源来提供工作所需的电能。通常,这种集成电路会设计为能够接受家庭常用的交流电源(如220V或110V,具体取决于所在地区的电压标准),并通过内部的整流和稳压电路转换为集成电路和彩灯所需的直流电压。
4. 5G169节日彩灯集成电路在使用过程中需要注意哪些事项?
回答:
在使用5G169节日彩灯集成电路时,需要注意以下事项:
- 确保电源电压与集成电路的额定电压相匹配,避免过电压或过电流导致的损坏。
- 遵循产品手册中的安装和接线指导,确保电路连接正确无误。
- 注意电路的散热问题,避免长时间在高温环境下使用导致集成电路过热。
- 定期检查电路连接和元件状态,及时发现并处理可能的问题。
- 避免在潮湿或腐蚀性环境中使用,以防电路受潮或腐蚀。
5. 5G169节日彩灯集成电路有哪些常见故障及解决方法?
回答:
5G169节日彩灯集成电路的常见故障可能包括灯不亮、亮度不均、闪烁异常等。针对这些故障,可以尝试以下解决方法:
- 检查电源电压是否正常,确保电路得到足够的电能供应。
- 检查电路连接是否牢固可靠,无短路或断路现象。
- 检查集成电路的引脚是否接触良好,无虚焊或断裂现象。
- 如果集成电路损坏,需要更换新的集成电路。
- 对于亮度不均或闪烁异常的问题,可以尝试调整与集成电路相关的电阻、电容等元件的值,或者检查彩灯本身是否存在问题。
请注意,以上回答基于一般性的集成电路知识和经验,具体情况可能因不同型号的集成电路或电路设计而异。在实际操作中,建议根据具体的产品手册或咨询专业人士进行故障排查和解决。
机顶盒,全称为数字视频变换盒,是连接电视机与外部信号源的重要设备,具有高度的专业性和广泛的应用性。它不仅能接收来自有线电缆、卫星天线、宽带网络及地面广播的数字电视信号,还能将这些信号转换成适合在电视机上播放的格式,极大地丰富了用户的观看体验。
机顶盒分为数字机顶盒和网络机顶盒两大类。数字机顶盒主要实现数模转换功能,使用户能用原有的模拟电视机观看数字电视,包括有线电视、卫星电视和地面广播电视的数字机顶盒。而网络机顶盒则进一步扩展了功能,能接入互联网,提供如IPTV、视频点播、在线游戏、网页浏览等多元化服务,使电视机转变为一个智能互动终端。
机顶盒的工作原理涵盖接收、解码和显示三个关键步骤。通过内置的调谐器接收信号,解调器将信号从载波中提取,解码器再将信号转换为电视可识别的视频和音频流,最终通过电视机呈现给用户。随着技术的不断进步,机顶盒的功能也在不断升级,如支持4K、8K超高清视频播放,搭载智能推荐算法提供个性化内容推荐,以及通过语音识别技术实现便捷操作等。
综上所述,机顶盒作为连接电视与互联网的重要桥梁,其专业性和科普性不言而喻。它不仅为用户提供了丰富多彩的电视节目和娱乐选择,还推动了电视产业的智能化发展,成为现代家庭不可或缺的一部分。
在激烈的市场竞争中,德崧电子始终坚持品质为先的经营理念。公司从原材料采购到生产加工,再到成品检验,每一个环节都严格把控,确保产品质量。这种对品质的坚守不仅赢得了客户的信任,也为公司赢得了良好的口碑。正是凭借着过硬的产品质量和优质的服务,德崧电子在电子开关行业中树立了良好的品牌形象。
Cal Crystal Lab Inc起初是一家专注于电子晶体管研发的小型实验室。在电子行业的早期,晶体管的性能直接决定了电子设备的质量和性能。创始人张先生凭借对电子技术的深厚理解,带领团队不断攻克技术难关,成功研发出性能更稳定、寿命更长的晶体管。这一创新不仅让Cal Crystal Lab Inc在业内崭露头角,还吸引了大批合作伙伴的青睐。随着市场需求的不断增长,公司逐渐扩大规模,从一个小型实验室成长为拥有多条生产线的大型企业。
在环保意识日益增强的今天,锋鸣电子(深圳分公司)积极响应国家号召,致力于绿色电子产品的研发与生产。公司投入大量资金引进环保设备和生产工艺,确保产品从原材料采购到生产制造的全过程都符合环保标准。同时,锋鸣电子还积极推广节能减排理念,为客户提供绿色、低碳的电子产品解决方案。凭借在绿色环保方面的突出表现,锋鸣电子赢得了业界的广泛赞誉。
随着人才流动的加快和研发周期的缩短,我们个人需要快速高效的完成自己的设计,维护和升级,公司需要人走不影响项目进度、新员工很快就能接手。这就需要:一个系统设计完成以后,它不应该仅仅是一些源代码,还应该包括各种各样的开发文档。(这对以 ...… 查看全部问答∨ |
|
学习到现在有半年时间拉,已经看完了arm体系结构和编程、深入理解计算机系统、linux简单的命令、linux shell、嵌入式linux开发完全手册(看到驱动部分), 到现在也没什么动手的能力,现在也就是看c 代码不是很吃力,但是,自己写的话好像有点困难 ...… 查看全部问答∨ |
|
本周,我的一个学生给我发了一个邮件,询问如何Linux下如何往外设写数据. 邮件如下.老大: 现在我有个紧急问题请教,希望你讲明白点,我想知道数据是怎么从用 ...… 查看全部问答∨ |
用tornado软件,创建“create downloadable application modules for vxworks...”的工程文件,编译时不产生.o文件。在编译完之后,直接down是怎么回事。… 查看全部问答∨ |
蓝色Mini STM32 开发板 带CAN 485接口 基于STM32F103VET6 红色Mini STM32 开发板 带CAN 485接口 基于STM32F103RBT6 黄色Mini STM32 开发板 带CAN 485接口 基于STM32F103C8T6 高级例程将后续在本帖为大家提供!请关注!… 查看全部问答∨ |
|
刚学这个,然后要用到430f2012,可是只知道147的下载连接,不知道2012的下载电路,同样想要BSL下载(以前做好的模块),不知道怎么连接啊,大神教一下… 查看全部问答∨ |