历史上的今天
返回首页

历史上的今天

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

正在发生

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

2021-11-08 来源:eefocus

一、使用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(); /*按键服务的应用程序*/

}

}

 

三、仿真实现


推荐阅读

史海拾趣

Harwin公司的发展小趣事

进入20世纪80年代和90年代,Harbour Industries继续深化其在电缆领域的研发。为了满足军事和国防部门对电缆的特殊需求,公司开始研发并生产Mil-Spec(军用规格)电缆。这些电缆不仅具备高度的耐用性和可靠性,还符合严格的军事标准。Harbour凭借其在技术上的不断创新和产品质量的持续提升,成功地将Mil-Spec电缆推向市场,并赢得了众多军事客户和合作伙伴的信赖。

Eby Electro Inc公司的发展小趣事

Eby Electro Inc在发展壮大的同时,始终关注社会责任的履行。公司积极参与环保和公益活动,推广绿色电子产品,减少生产过程中的环境污染。此外,公司还设立了奖学金和助学金,支持教育事业的发展。这些举措不仅提升了公司的社会形象,也为公司赢得了更多的社会支持和认可。

高通(GENITOP)公司的发展小趣事

70年代,全球电子产品热潮兴起,金山工业决定进军这一领域。公司推出了碱性和氧化的银钮型电池,这些产品广泛应用于电子手表、计算机等小型电子设备中。这一战略转型不仅丰富了超霸电池的产品线,也进一步提升了其在电子行业的知名度。随着技术的不断积累,超霸电池逐渐在市场中占据了一席之地。

AMSCO [Austria micro systems AG]公司的发展小趣事

1964年,超霸电池的前身——金山工业集团在中国香港地区成立,最初专注于生产9伏干电池,以满足当时收音机等电子产品的需求。这一时期的超霸电池以其稳定的质量和可靠的性能迅速在市场上站稳脚跟。随着电子产品的普及,金山工业敏锐地捕捉到市场机遇,逐步扩大生产规模,为后续的发展奠定了坚实基础。

CW Industries公司的发展小趣事

CW Industries公司的前身Wirt Company由爱迪生的助手查尔斯·沃尔特于1904年创立。在公司初创时期,沃特率先发展了线绕电位器、固定线绕电阻器、汽车火花抑制器和滑动开关等产品。这些创新为公司的初步发展奠定了坚实的基础。随着电子行业的快速发展,CW Industries逐渐在多个电子领域开发出专利产品和工艺,如滑动、摇臂和按钮开关,以及绝缘穿刺连接器等。公司凭借其独特的设计和专利功能,逐渐在市场上占据了一席之地。

ARCOL公司的发展小趣事

随着电子技术的飞速发展,ARCOL公司意识到只有不断创新才能在激烈的市场竞争中立于不败之地。因此,公司加大了对研发的投入,积极引进先进的生产设备和技术,不断推出创新性的产品。通过不断优化生产工艺和提升产品质量,ARCOL的产品在市场上逐渐占据了领先地位。

问答坊 | AI 解惑

MCGS组态软件设计及其应用

一、引言     过去工业控制计算机系统的软件功能都靠软件人员编程实现。工作量大,软件通用性差,且易产生错误。随着工业控制要求的不断提高,专门用于工业控制的组态软件应运而生,它是一套功能齐全的组态生成工具软件,通用性强,而 ...…

查看全部问答>

ARM c程序的问题

_irqHandler PROC    1. STMFD   sp!,{r0-r4,r12,lr}    2. mov     r4,#0x80000000  //中断控制寄存器首地址(假设的)    3. ldr     r0,[r4,#0] ...…

查看全部问答>

给论坛的建议

我希望论坛能够在下载扣金币方面可以放松点,比如每次只扣一个或者在某个贴上下载只扣若干个就好了,因为有些文件确实比较大,要下好几个压缩文件才能行的,而每下一个就扣好几,很多人都有些不舍得,毕竟金币有比较难得,特别是新手就更麻烦了,我 ...…

查看全部问答>

wince 桌面快捷方式

请问: wince中的文件夹有没有后缀名? 我想把一个名为NandFlash的文件夹,放到桌面快捷方式, 我在WINCE500\\PLATFORM\\SMDK2440\\FILES创建了一个NandFlash.LNK文件,里面写上22#\\windows\\NandFlash 我又在Project.bib 里面加上 NandFlash ...…

查看全部问答>

PCI设备识别不正常

首先我的程序在某些主板上是可以正常工作的(具体型号我也搞不懂),设置的是从设备,内部只有从设备状态机。没有接入奇偶检验,仲裁和热插拔。 问题是在一些主板上发现设置为从设备时无法找到设备,设置为主设备可以找到,但是通过软件读取配置信 ...…

查看全部问答>

0

居然要全部下完才能都打开?这个有点不厚道…

查看全部问答>

LM3S程序求教

//————————————————头文件————————————————————#include \"inc/hw_ints.h\"//硬件中断#include \"inc/hw_memmap.h\"#include \"inc/hw_types.h\"//硬件类型#include \"driverlib/gpio.h\"//GPIO#include \"dri ...…

查看全部问答>

中断究竟是个怎么回事?

今天听单片机老师讲课讲中断,说分了好几种,被他弄得一头雾水,还是没明白他说的中断都有什么,怎么配置,查了查2553手册,愣是没找到讲解终端的地方,球大神指点123!不胜感激。…

查看全部问答>

DCDC电源中的电流检测

文章介绍了7中电流检测的办法,可以作为电流检测的入门读物 …

查看全部问答>