历史上的今天

今天是:2024年11月08日(星期五)

正在发生

2021年11月08日 | 51单片机实现通过串口用delay延时方式发送一串数据

发布者:masphia 来源: eefocus关键字:51单片机  串口  delay  延时方式  数据 手机看文章 扫描二维码
随时随地手机看文章

一、使用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单片机  串口  delay  延时方式  数据 引用地址:51单片机实现通过串口用delay延时方式发送一串数据

上一篇:51单片机实现通过串口用计数延时方式发送一串数据
下一篇:51单片机实现在串口接收中断里即时解析数据头的特殊程序框架

推荐阅读

集微网信息,美光(Micron)推出旗下首款单片容量12Gb(1.5GB)的LPDDR4X低电压内存芯片,该款内存芯片速度为4266Mbps,即4266MHz。        现代人几乎难以摆脱对智能移动终端的依赖,随着系统和应用程序的不断升级优化,对内存的要求将会逐步提高,因此高频率、大容量的LPDDR4X内存将成为主流。今年10月公布的海思麒麟980芯片就非常具有前瞻性地...
面对全球液晶显示器(LCD)市场的长期低迷,中国面板制造商正考虑转向有 OLED 面板。如果中国的面板厂商进入 OLED 市场,那么全球电视市场的"迭代"速度将加快。 业内观察人士表示,由于液晶面板供过于求和低价竞争,中国面板制造商正遭受盈利能力恶化的影响,他们正在考虑提高 OLED 面板产品的比例。事实上,进入 OLED 电视市场的中国公司数量从 20...
近年在 HMD Global 的领导下,诺基亚凭借几款智能手机和专注于软件安全性的业务重新崛起。该品牌目前拥有大量智能手机,从入门到中端到旗舰机型均有涉猎。去年发布的诺基亚 9 PureView 旗舰机型配备了一个后置五摄系统,配备 ToF 传感器。但这款机型似乎并未成功,为诺基亚提供相机模组的厂商 Light 也宣布全面撤离手机市场。近日国内一位网友在...
看门狗定时器看门狗定时器由独立的1 Mhz 片内振荡器驱动。这是VCC = 5V 时的典型值。请参见特性 数据以了解其他VCC 电平下的典型值。通过设置看门狗定时器的预分频器可以调节看门狗 复位的时间间隔,如 P 53Table 22 所示。看门狗复位指令WDR 用来复位看门狗定时器。 此外,禁止看门狗定时器或发生复位时定时器也被复位。复位时间有8 个选项...

史海拾趣

问答坊 | AI 解惑

ST---STVD7

各位大虾们: 我刚学ST单片机 在用编译器STVD7的时候 ,程序运行的时候老是出现Program received signal SIGTRAP, Trace/breakpoint trap. 0xe000 in __stext () 希望各位能指点一二,怎样解决这个问题啊,谢谢了~~…

查看全部问答∨

FPGA LED

本帖最后由 paulhyde 于 2014-9-15 09:29 编辑 FPGA 与fpga很有价值的27  …

查看全部问答∨

智能卡优胜的地方

与传统的数据传输设备相比, 智能卡具有更高的安全性, 更为方便, 并带来了更大的经济效益。另外, 基于智能卡的系统还具有高度的可调整性, 以适应不同人、不同会员卡制作公司的需要。智能卡的具体优点为:1)包括的加密和验证技术满足了发行者和用户 ...…

查看全部问答∨

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 ...…

查看全部问答∨

wince下如何使用看门狗

三星2440的板子,wince5.0, 现在想加个看门狗,具体如何实现呢?是写个流驱动吗,加个中断,定时中断,定时喂狗,如果长时间没有喂狗,系统重启,请问重启的代码加在哪里,哪位高手给个详细的思路,多谢了…

查看全部问答∨

【求助】关于449的flash存储问题!!!

请问各位大侠,我现在用的是449的片子,在程序中我有一个大小为1000的数组,而且是变量数组,如果存在RAM里面,再加上我其他的程序,大小就会超出2K的范围,请问变量数组能否存到flash 里面? 怎样存储呢?谢谢!!!…

查看全部问答∨

cary334002同学 请不要恶意灌水行么

本帖最后由 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 ...…

查看全部问答∨

串口接收消息并返回

最近实验PC通过串口与单片机通信,要求如下代码开头所说,但是通信过程中在按键的同时lcd与PC的串口助手同时出现了多余信息,请高手指教。   另外,我想在单片机接收到8个字符后自动发送8个字符,请问程序能如何设计呢?/************** ...…

查看全部问答∨

【你问我答】发了一笔2-3K的横财,只充许买一样东东,雕刻机或者3D打印机,二先一...

【你问我答】发了一笔2-3K的横财,只充许买一样东东,雕刻机或者3D打印机,二先一,你选哪?…

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

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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