第五節:蜂鳴器的驅動程序

2021-01-07 電子產品世界
開場白:

上一節講了利用累計定時中斷次數實現LED燈閃爍,這個例子同時也第一次展示了我最完整的實戰程序框架:用switch語句實現狀態機,外加定時中斷。這個框架看似簡單,實際上就是那麼簡單。我做的所有開發項目都是基於這個簡單框架,但是非常好用。上一節只有一個單任務的LED燈在閃爍,這節開始,我們多增加一個蜂鳴器報警的任務,要教會大家四個知識點:

本文引用地址:http://www.eepw.com.cn/article/201611/319803.htm

第一點:蜂鳴器的驅動程序框架編寫。

第二點:多任務處理的程序框架。

第三點:如何控制蜂鳴器聲音的長叫和短叫。

第四點:如何知道1秒鐘需要多少個定時中斷,也就是如何按比例修正時間精度。

具體內容,請看原始碼講解。

(1)硬體平臺:基於朱兆祺51單片機學習板

(2)實現功能:同時跑兩個任務,第一個任務讓一個LED燈1秒鐘閃爍一次。第二個任務讓蜂鳴器在前面3秒發生一次短叫報警,在後面6秒發生一次長叫報警,反覆循環。

(3)原始碼講解如下:

#include "REG52.H"

/* 注釋一:

* 如何知道1秒鐘需要多少個定時中斷?

* 這個需要編寫一段小程序測試,得到測試的結果後再按比例修正。

* 步驟:

* 第一步:在程序代碼上先寫入1秒鐘大概需要200個定時中斷。

* 第二步:基於以上1秒鐘的基準,編寫一個60秒的簡單測試程序(如果編寫超過

* 60秒的時間,這個精度還會更高)。比如,編寫一個用蜂鳴器的聲音來識別計時的

* 起始和終止的測試程序。

* 第三步:把程序燒錄進單片機後,上電開始測試,手上同步打開手機裡的秒表。

* 如果單片機僅僅跑了27秒。

* 第四步:那麼最終得出1秒鐘需要的定時中斷次數是:const_time_1s=(200*60)/27=444

*/

#define const_time_05s 222 //0.5秒鐘的時間需要的定時中斷次數

#define const_time_1s 444 //1秒鐘的時間需要的定時中斷次數

#define const_time_3s 1332 //3秒鐘的時間需要的定時中斷次數

#define const_time_6s 2664 //6秒鐘的時間需要的定時中斷次數

#define const_voice_short 40 //蜂鳴器短叫的持續時間

#define const_voice_long 200 //蜂鳴器長叫的持續時間

void initial_myself();

void initial_peripheral();

void delay_long(unsigned int uiDelaylong);

void led_flicker();

void alarm_run();

void T0_time(); //定時中斷函數

sbit beep_dr=P2^7; //蜂鳴器的驅動IO口

sbit led_dr=P3^5; //LED燈的驅動IO口

unsigned char ucLedStep=0; //LED燈的步驟變量

unsigned int uiTimeLedCnt=0; //LED燈統計定時中斷次數的延時計數器

unsigned char ucAlarmStep=0; //報警的步驟變量

unsigned int uiTimeAlarmCnt=0; //報警統計定時中斷次數的延時計數器

unsigned int uiVoiceCnt=0; //蜂鳴器鳴叫的持續時間計數器

void main()

{

initial_myself();

delay_long(100);

initial_peripheral();

while(1)

{

led_flicker(); //第一個任務LED燈閃爍

alarm_run(); //第二個任務報警器定時報警

}

}

void led_flicker() //第三區 LED閃爍應用程式

{

switch(ucLedStep)

{

case 0:

if(uiTimeLedCnt>=const_time_05s) //時間到

{

uiTimeLedCnt=0; //時間計數器清零

led_dr=1; //讓LED亮

ucLedStep=1; //切換到下一個步驟

}

break;

case 1:

if(uiTimeLedCnt>=const_time_05s) //時間到

{

uiTimeLedCnt=0; //時間計數器清零

led_dr=0; //讓LED滅

ucLedStep=0; //返回到上一個步驟

}

break;

}

}

void alarm_run() //第三區 報警器的應用程式

{

switch(ucAlarmStep)

{

case 0:

if(uiTimeAlarmCnt>=const_time_3s) //時間到

{

uiTimeAlarmCnt=0; //時間計數器清零

/* 注釋二:

* 只要變量uiVoiceCnt不為0,蜂鳴器就會在定時中斷函數裡啟動鳴叫,並且自減uiVoiceCnt

* 直到uiVoiceCnt為0時才停止鳴叫。因此控制uiVoiceCnt變量的大小就是控制聲音的長短。

*/

uiVoiceCnt=const_voice_short; //蜂鳴器短叫

ucAlarmStep=1; //切換到下一個步驟

}

break;

case 1:

if(uiTimeAlarmCnt>=const_time_6s) //時間到

{

uiTimeAlarmCnt=0; //時間計數器清零

uiVoiceCnt=const_voice_long; //蜂鳴器長叫

ucAlarmStep=0; //返回到上一個步驟

}

break;

}

}

void T0_time() interrupt 1

{

TF0=0; //清除中斷標誌

TR0=0; //關中斷

if(uiTimeLedCnt<0xffff) //設定這個條件,防止uiTimeLedCnt超範圍。

{

uiTimeLedCnt++; //LED燈的時間計數器,累加定時中斷的次數,

}

if(uiTimeAlarmCnt<0xffff) //設定這個條件,防止uiTimeAlarmCnt超範圍。

{

uiTimeAlarmCnt++; //報警的時間計數器,累加定時中斷的次數,

}

/* 注釋三:

* 為什麼不把驅動蜂鳴器這段代碼放到main函數的循環裡去?

* 因為放在定時中斷裡,能保證蜂鳴器的聲音長度是一致的,

* 如果放在main循環裡,聲音的長度就有可能受到某些必須

* 一氣呵成的任務幹擾,得不到及時響應,影響聲音長度的一致性。

*/

if(uiVoiceCnt!=0)

{

uiVoiceCnt--; //每次進入定時中斷都自減1,直到等於零為止。才停止鳴叫

beep_dr=0; //蜂鳴器是PNP三極體控制,低電平就開始鳴叫。

}

else

{

; //此處多加一個空指令,想維持跟if括號語句的數量對稱,都是兩條指令。不加也可以。

beep_dr=1; //蜂鳴器是PNP三極體控制,高電平就停止鳴叫。

}

TH0=0xf8; //重裝初始值(65535-2000)=63535=0xf82f

TL0=0x2f;

TR0=1; //開中斷

}

void delay_long(unsigned int uiDelayLong)

{

unsigned int i;

unsigned int j;

for(i=0;i

{

for(j=0;j<500;j++) //內嵌循環的空指令數量

{

; //一個分號相當於執行一條空語句

}

}

}

void initial_myself() //第一區 初始化單片機

{

beep_dr=1; //用PNP三極體控制蜂鳴器,輸出高電平時不叫。

led_dr=0; //LED滅

TMOD=0x01; //設置定時器0為工作方式1

TH0=0xf8; //重裝初始值(65535-2000)=63535=0xf82f

TL0=0x2f;

}

void initial_peripheral() //第二區 初始化外圍

{

EA=1; //開總中斷

ET0=1; //允許定時中斷

TR0=1; //啟動定時中斷

}

總結陳詞:

本節程序已經展示了一個多任務處理的基本思路,假如要實現一個獨立按鍵檢測,能不能也按照這種思路來處理呢?欲知詳情,請聽下回分解在主函數中利用累計主循環次數來實現獨立按鍵的檢測。

相關焦點

  • 單片機驅動蜂鳴器C51程序
    uchar unsigned char#define uint unsigned intsbit k1=P1^4; //按鈕1sbit k2=P1^5; //按鈕2sbit beep=P3^7; //接蜂鳴器/*********************************************************本程序出自
  • 單片機蜂鳴器的控制程序與驅動電路圖
    蜂鳴器從結構區分分為壓電式蜂鳴器和電磁式蜂鳴器。壓電式為壓電陶瓷片發音,電流比較小一些,電磁式蜂鳴器為線圈通電震動發音,體積比較小。 按照驅動方式分為有源蜂鳴器和無源蜂鳴器。這裡的有源和無源不是指電源,而是振蕩源。
  • 51單片機學習14-蜂鳴器驅動
    這篇驅動蜂鳴器,單片機IO口通過開關三極體來驅動蜂鳴器,這裡用PNP的三極體,常用SS8550。三極體b極電阻一般選用1K。仿真圖:程序:源程序:#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit
  • PWM在ARM Linux中的原理和蜂鳴器驅動實例開發
    下面我們來通過一個蜂鳴器的實例來說明PWM功能的使用。三、蜂鳴器驅動實例1. 蜂鳴器的種類和工作原理 蜂鳴器主要分為壓電式蜂鳴器和電磁式蜂鳴器兩種類型。 壓電式蜂鳴器主要由多諧振蕩器、壓電蜂鳴片、阻抗匹配器及共鳴箱、外殼等組成。有的壓電式蜂鳴器外殼上還裝有發光二極體。
  • 蜂鳴器控制高級程序
    ;目的:掌握蜂鳴器的控制程序;程序名字:蜂鳴器;這是一個非常好的一個控制蜂鳴器的程序,用到了定時器中斷方式來定時,且弄能夠用程序狀態字中的CY標誌位來進行運算,;並且用到了CJNE中的比的不夠CY為1,比大的話
  • 單片機驅動蜂鳴器原理與設計
    蜂鳴器是一種一體化結構的電子訊響器,本文介紹如何用單片機驅動蜂鳴器,他廣泛應用於計算機、印表機、複印機、報警器、電話機等電子產品中作發聲器件。   蜂鳴器主要分為壓電式蜂鳴器和電磁式蜂鳴器兩種類型。
  • 簡單電子琴程序-用蜂鳴器發聲
    /*程序效果:數碼管顯示輸入,數碼管為遞增顯示,即像     手機打電話時輸入號碼一樣,同時蜂鳴器發出     不同的音律程序簡單緊湊理解相對困難,但     只要把上一程序弄懂,本程序即可理解*/#includereg52.h> //頭文件#includeintrins.h>
  • 蜂鳴器有沒有正負極_蜂鳴器正負極怎麼區分
    必須用2K~5K的方波去驅動它。   有源蜂鳴器往往比無源的貴,就是因為裡面多個震蕩電路。   無源蜂鳴器的優點是:1.便宜,2.聲音頻率可控,可以做出「多來米發索拉西」的效果。3.在一些特例中,可以和LED復用一個控制口 有源蜂鳴器的優點是:程序控制方便 。
  • 正點原子-戰艦V3第七章 蜂鳴器實驗
    前面我們已經對 STM32F1 的 IO 做了簡單介紹,上一章,我們就是利用 STM32 的 IO 口直接驅動 LED 的,本章的蜂鳴器,我們能否直接用 STM32 的 IO 口驅動呢?讓我們來分析下:STM32F1 的單個 IO 最大可以提供 25mA 電流(來自數據手冊),而蜂鳴器的驅動電流是 30mA左右,兩者十分相近,但是全盤考慮,STM32F1 整個晶片的電流,最大也就 150mA,如果用IO 口直接驅動蜂鳴器,其他地方用電就得省著點了…所以,我們不用
  • 蜂鳴器是什麼_蜂鳴器報警工作原理
    消耗電流: 電磁式的依電壓的不同,從幾十到上百毫安培都有,壓電式的就省電的多,幾毫安培就可以正常的動作, 且在蜂鳴器啟動時,瞬間需消耗約三倍的電流,驅動方式: 二種蜂鳴器都有自激式的,只要接上直流電(DC)即可發聲,因為已內建了驅動線路在蜂鳴器中了,因為動作原理的不同,電磁式蜂鳴器要用1/2方波來驅動,壓電的用方波,才能有較好的聲音輸出。
  • 蜂鳴器驅動電路圖解_有源蜂鳴器原理_有源蜂鳴器和無源蜂鳴器如何...
    打開APP 蜂鳴器驅動電路圖解_有源蜂鳴器原理_有源蜂鳴器和無源蜂鳴器如何區分 發表於 2017-08-25 09:12:49
  • 單片機基礎:燥起來吧,蜂鳴器
    導 讀蜂鳴器是電路設計中常用的器件,廣泛用於工業控制、機房監控、門禁、計算機等電子產品的預警發聲器件,驅動電路貌似很簡單,但隨意設計會引來蜂鳴器不發聲,輕微發聲或亂發聲等不良現象,本例來分享分享。,無法驅動或者聲音很小很小,注意兩個電壓表的值,下面個顯示2.01V,計算的不是1.8V嗎?
  • 蜂鳴器不響的原因_蜂鳴器故障分析
    3、焊接後蜂鳴器鳴叫過程中出小聲、無音或沙音變調,這種情形可能是啟動蜂鳴器的電流過小或過大(蜂鳴器正常工作電流20-30mA)導致蜂鳴器不能正常鳴叫。   4、蜂鳴器使用一段時間後出現變音或無音,這種情形可能是蜂鳴器的連續鳴叫時間過長(蜂鳴器連續鳴叫時間不能超過8-10小時,否則會變音或燒壞)或是蜂鳴器受環境影響。
  • 51單片機驅動無源蜂鳴器
    流水燈的程序相對我個人來說比較簡單,但是蜂鳴器有些難度,正常給I/0口一個信號,蜂鳴器既然不響,後經查證是無源蜂鳴器;無源的蜂鳴器,就要通過IO口輸出振蕩信號來驅動蜂鳴器本文引用地址:http://www.eepw.com.cn/article/201612/324157.htm
  • 怎樣用Arduino設置蜂鳴器
    打開APP 怎樣用Arduino設置蜂鳴器 發表於 2019-08-05 11:47:02 所需組件: - Arduino
  • 蜂鳴器的識別與檢測
    一、蜂鳴器的功能特點蜂鳴器從結構上分為壓電式和電磁式兩種。壓電式蜂鳴器是由陶瓷材料製成的。電磁式蜂鳴器是由電磁線圈構成的。從工作原理上說,蜂鳴器可以分為無源蜂鳴器和有源蜂鳴器。無源蜂鳴器內部無振蕩源,必須有驅動信號才能發聲。
  • 蜂鳴器原理
    導讀:本文主要介紹的是蜂鳴器的原理,感興趣的盆友們快來學習一下吧~~~很漲姿勢的哦~~~本文引用地址:http://www.eepw.com.cn/article/277228.htm1.蜂鳴器原理--簡介  蜂鳴器其實就是一種一體化結構的電子訊響器
  • 51單片機按鍵控制蜂鳴器啟停程序
    51單片機按鍵控制蜂鳴器啟停程序#include<reg52.h> #define uint unsigned int //宏定義sbit SPK=P3^5; //定義喇叭埠sbit key=
  • 蜂鳴器常見錯誤電路分析
    蜂鳴器在電路中電路圖形符號用字母「H」或「HA」(舊標準用「FM」、「LB」、「JD」等)表示。  下面我們介紹最常用的兩類蜂鳴器:有源蜂鳴器和無源蜂鳴器。  從驅動方式分類,有源驅動和無源驅動,有源蜂鳴器又稱為直流蜂鳴器,其內部已經包含了一個多諧振蕩器,只要在兩端施加額定直流電壓即可發聲,具有驅動、控制簡單的特點,但價格略高。
  • 單片機小白學步(22) IO口:蜂鳴器的使用/三極體的工作原理
    蜂鳴器和LED相比最主要的區別,就是蜂鳴器比LED需要的電流大很多,電壓一般也會高一些。為了讓單片機驅動蜂鳴器,也就是控制蜂鳴器工作,我們需要使用一些特別的電路。不知道大家是否了解繼電器,繼電器的特點就是用小電流低電壓,控制大電流高電壓電路。但是一般的繼電器控制端需要的電流,對於單片機來說還是太大了,而且繼電器價格比較高,能控制很大的電流,用在這裡大材小用了。