您现在的位置是:首页 > 数字电源 > 技术解析

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

时间:2018-10-09 来源:

初学者在编写单片机程序时经常会用到延时函数,但是当系统逐步复杂以后(没有复杂到使用操作系统)延时会因为延时降低MCU的利用率,更严重的会影响系统中的“并行”操作例如一个既有按键又有蜂鸣器的系统中,如果要求按下按键发出不同的声音,每次发声时间在1秒-2秒之间, 如果用延时来做代码很简单:

本文引用地址: http://power.21ic.com//digi/technical/201810/76666.html

 

基于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();//蜂鸣流程

。..。

}

}

16

在别的函数中需要使蜂鸣器工作时只需要下面代码即可:

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

BeepCtrl = 1;//启动蜂鸣器

用这种方法能充分利用MCU,在蜂鸣器发声或发声间隔的等待时间MCU可以处理别的函数,但是还要有几点需要注意

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

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

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

换一批

延伸阅读

[资讯] 一种新型光伏控制器PWM精确控制的解决方案

一种新型光伏控制器PWM精确控制的解决方案

摘 要: 本文针对现有光伏控制器控制模式的不足,提出一种精粗调组合的新型PWM精确控制的解决方案,将太阳能电池分成N个独立的太阳能子阵,只令一路子阵采用PWM控制作为精调......

关键字:控制器 精确 光伏

[资讯] 智能灵活的大电流 DC/DC 控制器简化电信和数据通信系统中的电源

智能灵活的大电流 DC/DC 控制器简化电信和数据通信系统中的电源

电信和数据通信系统中常见的下一代路由器和交换机的复杂性和可扩展性不断提高,这给电源制造带来了压力,因为人们需要提供智能灵活、可横跨多种平台扩展的高效率电源解决方案。系统设计师经常会需要几种基础架构变体,以能够提供高、中、低端系统,且每种系统......

关键字:DC/DC 控制器 电源

[资讯] “跨界智能化”将有望为未来照明带来新的火花?

“跨界智能化”将有望为未来照明带来新的火花?

伏波,广东省高级工业设计师、副教授,现任广东轻工职业技术学院艺术设计学院工业设计系主任、全国机械行指委工业设计教指委委员、国家高职教育艺术设计(工业设计)专业教学资源库建设工作子项目负责人、广东省第一批省级高职教育重点专业建设项目负责人;拥......

关键字:LED照明 智能照明 智能化控制

[资讯] 100W真做到了:USB充电大跃进

100W真做到了:USB充电大跃进

台湾钰创科技(Etron)今天宣布推出新款USB供电芯片“EJ888”,全球第一个符合“USB Power Delivery Rev. 1.0”供电规范,最大功率达到了惊人的100W,是......

关键字:USB充电 供电芯片 闪存控制器

[资讯] 德州仪器推出业界首款支持动态温度补偿电感器电流传感的模拟 DC/DC 控制器

德州仪器推出业界首款支持动态温度补偿电感器电流传感的模拟 DC/DC 控制器

20V DC/DC 同步降压控制器以最小电感器尺寸实现超过 95% 的效率21ic讯 日前,德州仪器 (TI) 宣布推出首款支持远程双极结晶体管 (BJT) 温度补偿电感器电流传感的模拟 DC/DC......

关键字:DC-DC控制器 温度补偿 电感器 电流传感
发表评论 共有条评论
用户名: 验证码:

精确稳定 让平均电流法帮你实现模块电源并联

精确稳定 让平均电流法帮你实现模块电源并联

今天要为大家介绍的是平均电流法,这种方法能够精确稳定的帮助工程师实现电源模块的并……

九款最简单的电子镇流器电路图原理图分析

九款最简单的电子镇流器电路图原理图分析

从工作原理而言,电子镇流器是一个电源变换电路,它将交流输入市电电源的波形、频率和……

干货|交流接触器常用接线电路图和实物图

干货|交流接触器常用接线电路图和实物图

今天分享一些电气知识中的交流接触器常用接线电路图和实物图,从简单到复杂。

……

项目外包