网站首页
IC库存
IC展台
电子资讯
技术资料
PDF文档
我的博客
IC72论坛
ic72 logo
资料首页最新产品 技术参数 电路图 设计应用 解决方案 代理商查询 IC替换 IC厂商 电子辞典
关键字: 技术文章 PDF资料 IC价格 电路图 代理商查询 IC替换 IC厂商 电子辞典

基于MCU单片机在蜂鸣器系统中的应用设计

  //蜂鸣器发出“哔-哔-哔”声音时间约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

  第三,代码中如果存在多个地方需要控制一个流程时一定要先读取标志位再控制

热门搜索:BT-M515RD RS1215-20 LED12-C2 N060-002 01B5001JF 2882828 2920120 BQ25895MRTWR ADS1013IDGSR TLP810NET 2818135 2839211 01C5001JF SBBSM2106-1 UL24RA-15 2838322 LCR2400 2856087 02M0500JF B3429D 02T5000JF 02M5000JF TLP808 01M2251SFC3 LC2400
COPYRIGHT:(1998-2010) IC72 达普IC芯片交易网
客户服务:service@IC72.com 库存上载:IC72@IC72.com
(北京)联系方式: 在线QQ咨询:点击这里给我发消息 联系电话:010-82614113 传真:010-82614123
京ICP备06008810号-21 京公网安备 11010802032910 号 企业资质