您的位置 首页 电子

根据MCU单片机在蜂鸣器体系中的使用规划

初学者在编写单片机程序时经常会用到延时函数,但是当系统逐步复杂以后(没有复杂到使用操作系统)延时会因为延时降低MCU的利用率,更严重的会影响系统中的“并行”操作例如一个既有按键又有蜂鸣器的系统中,

  初学者在编写单片机程序时经常会用到延时函数,可是当体系逐渐杂乱今后(没有杂乱到运用操作体系)延时会由于延时下降MCU的利用率,更严峻的会影响体系中的“并行”操作例如一个既有按键又有蜂鸣器的体系中,假如要求按下按键宣布不同的声响,每次发声时间在1秒-2秒之间, 假如用延时来做代码很简单:

  //蜂鸣器宣布“哔-哔-哔”声响时间约1s

  void BeepFuction(void)

  {

  unsigned char i;

  for(i=0;i《3;i=++)

  {

  BeepEn(); //敞开蜂鸣器

  Delayms(220);//延时220ms

  BeepDis();//封闭蜂鸣器

  Delayms(110);//延时110ms

  }

  }

  当这段代码履行时MCU不可能一起处理按键查看程序由于它大部分时间在履行Delayms()函数中的nop指令,这样就不可能去履行查看按键了(不运用中止时),假如把程序改成流程方式的写规律成果会大为不同,下面先介绍一下基本原理。

  咱们都知道一般的定时器为16位或8位循环计数,例如关于16位的计数器当计数器数值从0增加到65535时再加一就会回到0那么咱们来比较下面两种状况(不考虑计数器在记载当时时间T后再次回到或超越T这种状况我暂时称它为“压圈”):

  状况1:

  T1时间计数器数值为300

  T2时间计数器数值为400

  则T1时间到T2为100个计数单位。

  这段时间差也为100个计数单位。

  状况2:

  T1时间计数器数值为65535

  T2时间计数器数值为99

  则T1到T2 能够算出为65535到0的1个计数单位再加上 0到99的99个计数单位总共为100个计数单位。

  所以时间差仍是100个计数单位。

  在C语言中假如运用两个无符号数作减法会得到如下成果:99-65535=100,这个很好了解就和10进制的借位相同只不过借位后不必管高位了也就相当于99+65536-65535成果是100了,当然这些前提条件都是计数器不会呈现“压圈”。

  有了上面临定时器的了解就能够重新写这个Beep函数了

  //蜂鸣器宣布“哔-哔-哔”声响时间约1s

  bit BeepFlag = 0;//蜂鸣流程忙标志位

  bit BeepCtrl = 0;//蜂鸣器流程操控标志位

  void BeepProc(void)

  {

  staTIc unsigned int BeepTImer;

  staTIc unsigned char BeepStatus = 0;

  staTIc unsigned char i;

  switch(BeepStatus)

  {

  case 0://

  if(BeepCtrl)

  {

  i = 3;//蜂鸣次数

  BeepFlag = 1;//置位忙标志位

  BeepCtrl = 0;//铲除操控标志位

  BeepTimer = TIMER;//这儿TIMER为体系定时器计数时钟为1ms

  BeepEn(); //敞开蜂鸣器

  BeepStatus = 1;//进入下一个状况

  }

  break;

  case 1://蜂鸣状况

  if(TIMER-BeepTimer》220)//220ms

  {

  BeepDis(); //封闭蜂鸣器

  BeepTimer = TIMER;//记载时间

  BeepStatus = 2;//进入下一个状况

  }

  break;

  case 2://中止蜂鸣状况

  if(TIMER-BeepTimer》110)//110ms

  {

  if(i!=0)

  {

  i–;

  BeepTimer = TIMER;//记载时间

  BeepEn(); //敞开蜂鸣器

  BeepStatus = 2;//回到蜂鸣状况

  }

  else

  {

  BeepStatus = 0;//回到初始状况

  BeepFlag = 0;//铲除忙标志位

  }

  }

  break;

  default:

  BeepFlag = 0;//铲除忙标志位

  BeepStatus = 0;//回到初始状况

  break;

  }

  }

  用这样的办法完成的蜂鸣程序在运用时也有不同的当地,由于运用的switch状况一切在主循环中要一向调用:

  void main()

  {

  SystemInitial();//体系初始化

  。..。..。..。..。..

  //主循环

  while(1)

  {

  Fun1Proc();//功用1流程

  Fun2Proc();//功用2流程

  。..。

  BeepProc();//蜂鸣流程

  。..。

  }

  }

  在其他函数中需求使蜂鸣器作业时只需求下面代码即可:

  if(!BeepFlag)//查看是否忙

  BeepCtrl = 1;//发动蜂鸣器

  用这种办法能充分利用MCU,在蜂鸣器发声或发声距离的等待时间MCU能够处理其他函数,可是还要有几点需求留意

  榜首,主循环while(1)的循环周期最好小于定时器计数时钟周期

  第二,主循环中尽量不要运用硬延时Delayms

  第三,代码中假如存在多个当地需求操控一个流程时一定要先读取标志位再操控

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/dianzi/131462.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部