一、使用proteus绘制简单的电路图,用于后续仿真
二、编写程序
/********************************************************************************************************************
---- @Project: USART
---- @File: main.c
---- @Edit: ZHQ
---- @Version: V1.0
---- @CreationTime: 20200713
---- @ModifiedTime: 20200713
---- @Description:
---- 波特率是:9600 。
---- 按一次按键S1,单片机就往上位机发送以下一串数据:eb 00 55 01 00 00 00 00 41
---- 单片机: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_send_size 20 /*串口发送数据的缓冲区数组大小*/
#define const_voice_short 40 /*蜂鸣器短叫的持续时间*/
#define const_key_time1 20 /*按键去抖动延时的时间*/
/*——————变量函数定义及声明——————*/
/*蜂鸣器的驱动IO口*/
sbit BEEP = P2^7;
/*LED*/
sbit LED = P3^5;
/*按键*/
sbit Key_S1 = P0^0;
sbit Key_Gnd = P0^4;
unsigned char ucSendregBuf[const_send_size]; /*接收串口中断数据的缓冲区数组*/
/*为串口计时器多增加一个原子锁,作为中断与主函数共享数据的保护*/
unsigned char ucVoiceLock = 0; /*蜂鸣器鸣叫的原子锁*/
unsigned int uiVoiceCnt = 0; /*蜂鸣器鸣叫的持续时间计数器*/
unsigned char ucKeySec = 0; /*被触发的按键编号*/
unsigned int uiKeyTimeCnt1 = 0; /*按键去抖动延时计数器*/
unsigned char ucKeyLock1 = 0; /*按键触发后自锁的变量标志*/
/**
* @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;
BEEP = 1;
Key_Gnd = 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 ucSendData * @retval 在发送一串数据中,每个字节之间必须添加一个延时,用来等待串口发送完成。 * 不增加延时,单单靠发送完成标志位来判断还是容易出错,在51,PIC单片机中都是这么做。 * 在stm32单片机中,可以不增加延时,直接靠单片机自带的标志位来判断就很可靠。 **/ void eusart_send(unsigned char ucSendData) { ES = 0; /*关串口中断*/ TI = 0; /*清零串口发送完成中断请求标志*/ SBUF = ucSendData; /*发送一个字节*/ Delay_Short(400); /*每个字节之间的延时。延时的大小请根据实际项目来调整*/ TI = 0; /*清零串口发送完成中断请求标志*/ ES = 1; /*允许串口中断*/ } /** * @brief 按键扫描函数 * @param 无 * @retval 放在定时中断里 **/ void key_scan(void) { if(Key_S1 == 1) /*IO是高电平,说明按键没有被按下,这时要及时清零一些标志位*/ { ucKeyLock1 = 0; /*按键自锁标志清零*/ uiKeyTimeCnt1 = 0; /*按键去抖动延时计数器清零*/ } else if(ucKeyLock1 == 0) /*有按键按下,且是第一次被按下*/ { uiKeyTimeCnt1 ++; /*累加定时中断次数*/ if(uiKeyTimeCnt1 > const_key_time1) { uiKeyTimeCnt1 = 0; ucKeyLock1 = 1; /*自锁按键置位,避免一直触发*/ ucKeySec = 1; } } } /** * @brief 按键服务的应用程序 * @param 无 * @retval 无 **/ void key_service(void) { unsigned int i; switch(ucKeySec) /*按键服务状态切换*/ { case 1: ucSendregBuf[0] = 0xeb; /*把准备发送的数据放入发送缓冲区*/ ucSendregBuf[1] = 0x00; ucSendregBuf[2] = 0x55; ucSendregBuf[3] = 0x01; ucSendregBuf[4] = 0x00; ucSendregBuf[5] = 0x00; ucSendregBuf[6] = 0x00; ucSendregBuf[7] = 0x00; ucSendregBuf[8] = 0x41; for(i = 0; i <= 8; i ++) { eusart_send(ucSendregBuf[i]); /*发送一串数据给上位机*/ } ucVoiceLock = 1; /*原子锁加锁,保护中断与主函数的共享数据*/ uiVoiceCnt = const_voice_short; /*按键声音触发,滴一声就停。*/ ucVoiceLock = 0; /*原子锁解锁*/ ucKeySec = 0; /*响应按键服务处理程序后,按键编号清零,避免一致触发*/ break; } } /** * @brief 定时器0中断函数 * @param 无 * @retval 无 **/ void ISR_T0(void) interrupt 1 { TF0 = 0; /*清除中断标志*/ TR0 = 0; /*关中断*/ /* * 此处多增加一个原子锁,作为中断与主函数共享数据的保护 */ if(ucVoiceLock == 0) /*原子锁判断*/ { if(uiVoiceCnt != 0) { uiVoiceCnt --; BEEP = 0; } else { ; BEEP = 1; } } key_scan(); TL0 = T1MS; /*initial timer0 low byte*/ TH0 = T1MS >> 8; /*initial timer0 high byte*/ TR0 = 1; /*开中断*/ } /** * @brief 串口接收数据中断 * @param 无 * @retval 无 **/ void usart_receive(void) interrupt 4 { if(RI == 1) { RI = 0; } else { TI = 0; } } /*————————————主函数————————————*/ /** * @brief 主函数 * @param 无 * @retval 实现LED灯闪烁 **/ void main() { /*单片机初始化*/ Init(); /*延时,延时时间一般是0.3秒到2秒之间,等待外围芯片和模块上电稳定*/ Delay_Long(100); /*单片机外围初始化*/ Init_Peripheral(); while(1) { key_service(); /*按键服务的应用程序*/ } } 三、仿真实现
上一篇:51单片机实现通过串口用计数延时方式发送一串数据
下一篇:51单片机实现在串口接收中断里即时解析数据头的特殊程序框架
推荐阅读
史海拾趣
随着全球化进程的加速推进,ABECO开始实施全球化战略。公司积极开拓国际市场,参加各类国际展会和论坛,与全球客户建立联系。同时,公司还加强与国际同行的交流与合作,引进先进的技术和管理经验。通过不断的努力,ABECO逐渐在全球电子行业中树立起了自己的品牌形象,成为了一家具有影响力的跨国公司。
请注意,上述故事是基于已知信息进行的虚构创作,并不代表ABECO公司的真实发展历程。如果您需要更详细和准确的信息,建议直接联系ABECO公司或查阅相关文献资料。
随着国内市场的逐渐饱和,联捷(Elinker)开始寻求海外市场的拓展。公司积极参加国际电子展会,与国外的电子企业建立了广泛的合作关系。同时,公司还通过引进国外先进的技术和管理经验,不断提升自身的竞争力。在国际市场的竞争中,联捷(Elinker)凭借其优质的产品和服务,赢得了越来越多客户的信任和认可。
品质控制一直是Emhiser Research非常重视的方面。公司建立了严格的质量管理体系和检测流程,确保每一件产品都符合高标准的质量要求。同时,公司还注重品牌建设,通过不断提升产品品质和服务水平来树立品牌形象。这些努力使得Emhiser Research在客户中赢得了良好的口碑和信任。
EVER-WAY公司成立于XX世纪初,当时电子行业正处于蓬勃发展的阶段。创始人李明看准了市场机遇,决定创立一家专注于电子元器件制造的公司。他带领一支由几名工程师组成的小团队,开始了艰苦的创业之路。初期,公司面临着资金短缺、技术落后和市场竞争激烈等多重挑战。然而,李明和他的团队凭借坚定的信念和不懈的努力,逐渐在市场中站稳脚跟。他们不断优化产品性能,提高生产效率,同时积极拓展国内外市场,逐步扩大了公司的知名度和影响力。
AZ Displays深知品质是企业生存的根本。因此,公司始终将质量控制放在首位,从原材料采购到生产工艺的每一个环节都进行严格把控。通过严格的质量管理体系和高效的供应链管理,AZ Displays的产品质量得到了客户的高度认可,逐渐在行业内建立了卓越的声誉。
近年来,电子行业面临着诸多市场挑战与机遇。在这场全球供应链的博弈中,AXTAL公司展现出了敏锐的市场洞察力和应变能力。面对中国发布的镓锗禁令,AXTAL巧妙地抓住了第一个漏洞,通过在中国设立的子公司申请出口镓锗的许可证,成功绕过了禁令的限制。这一睿智之举不仅为公司打开了新的市场窗口,也彰显了公司在应对市场挑战时的灵活性和创造力。
各位大虾们: 我刚学ST单片机 在用编译器STVD7的时候 ,程序运行的时候老是出现Program received signal SIGTRAP, Trace/breakpoint trap. 0xe000 in __stext () 希望各位能指点一二,怎样解决这个问题啊,谢谢了~~… 查看全部问答∨ |
|
Mismatched time stamp on .rel file 我在wince6下,移植5.0的bsp到6.0,最后make run-time image时,提示如下信息: Error: Mismatched time stamp on .rel file for module kernel.dll requesting kernel fixup. Valid .rel file is required for kernel fixups. makeim ...… 查看全部问答∨ |
|
三星2440的板子,wince5.0, 现在想加个看门狗,具体如何实现呢?是写个流驱动吗,加个中断,定时中断,定时喂狗,如果长时间没有喂狗,系统重启,请问重启的代码加在哪里,哪位高手给个详细的思路,多谢了… 查看全部问答∨ |
请问各位大侠,我现在用的是449的片子,在程序中我有一个大小为1000的数组,而且是变量数组,如果存在RAM里面,再加上我其他的程序,大小就会超出2K的范围,请问变量数组能否存到flash 里面? 怎样存储呢?谢谢!!!… 查看全部问答∨ |
本帖最后由 paulhyde 于 2014-9-15 09:00 编辑 如题~~~~~~~~~~~ 刷了一整页的帖子让别人怎么办,强烈鄙视这种不负责任的自私行为!! … 查看全部问答∨ |
RT-Thread在富士通Cortex M3 Easy Kit开发板上的移植 1、安装IAR Embedded Workbench® for ARM,这次我用的是最新从IAR官网下载的使用EWARM-EV-CD-6307.exe2、安装万利电子的驱动(支持IAR EWARM 6.30),安装完成后重启电脑。http://www.manley.com.cn/web/down.a ...… 查看全部问答∨ |
【你问我答】发了一笔2-3K的横财,只充许买一样东东,雕刻机或者3D打印机,二先一... 【你问我答】发了一笔2-3K的横财,只充许买一样东东,雕刻机或者3D打印机,二先一,你选哪?… 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- 【边分享,边成长,11月有奖】EEWORLD优秀主题/回复第16期活动开始拉
- 想要Get更好的服务?TE人工客服说:“我可以”
- Littelfuse【智能家居的电路保护方案】在线研讨会 11月22日10点 强势登场!预报名、参与研讨会赢好礼!
- 【开工大吉,抢楼有礼】聊一聊你感兴趣的技术和板子
- 安世半导体新能源应用探索站,闯关赢好礼!
- 知否知否 应是更多汽车方案
- 围读 《嵌入式软件的时间分析》——汽车行业领域的嵌入式软件理论、分析及实践
- Follow me第二季第1期来啦!与得捷一起解锁【Adafruit Circuit Playground Express】超能力!
- 2024年STM32巡回研讨会即将开启!(9月3日-9月13日)