單片機驅動蜂鳴器的設計詳解
單片機驅動蜂鳴器的設計詳解
在單片機應用的設計上,很多方案都會用到蜂鳴器,大部分都是使用蜂鳴器來做提示或報警,比如按鍵按下、開始工作、工作結束或是故障等等。
1.驅動方式
由于自激蜂鳴器(有源蜂鳴器)是直流電壓驅動的,不需要利用交流信號進行驅動,只需對驅動口輸出驅動電平并通過三極管放大驅動電流就能使蜂鳴器發出聲音,很簡單,這里就不對自激蜂鳴器進行說明了。這里只對必須用1/2duty的方波信號進行驅動的他激蜂鳴器進行說明。
單片機驅動他激蜂鳴器(無源蜂鳴器)的方式有兩種:一種是PWM輸出口直接驅動,另一種是利用I/O定時翻轉電平產生驅動波形對蜂鳴器進行驅動。
PWM輸出口直接驅動是利用PWM輸出口本身可以輸出一定的方波來直接驅動蜂鳴器。在單片機的軟體設置中有幾個系統寄存器是用來設置PWM口的輸出的,可以設置占空比、周期等等,通過設置這些寄存器產生符合蜂鳴器要求的頻率的
波形之后,只要打開PWM輸出,PWM輸出口就能輸出該頻率的方波,這個時候利用這個波形就可以驅動蜂鳴器了。比如頻率為2000Hz的蜂鳴器的驅動,可以知道周期為500μs,這樣只需要把PWM的周期設置為500μs,占空比電平設置為
250μs,就能產生一個頻率為2000Hz的方波,通過這個方波再利用三極管就可以去驅動這個蜂鳴器了。而利用I/O定時翻轉電平來產生驅動波形的方式會比較麻煩一點,必須利用計時器來做定時,通過定時翻轉電平產生符合蜂鳴器要求的頻率的波形,這個波形就可以用來驅動蜂鳴器了。比如為2500Hz的蜂鳴器的驅動,可以知道周期為400μs,這樣只需要驅動蜂鳴器的I/O口每200μs翻轉一次電平就可以產生一個頻率為2500Hz,占空比為1/2duty的方波,再通過三極管放大就可以驅動這個蜂鳴器了。
2.蜂鳴器驅動電路
由于蜂鳴器的工作電流一般比較大,以致于單片機的I/O口是無法直接驅動的,所以要利用放大電路來驅動,一般使用三極管來放大電流就可以了。
3.蜂鳴器驅動設計
由于這里要介紹兩種驅動方式的方法,所以在設計模組系統中將兩種驅動方式做到一塊,即程式里邊不僅介紹了PWM輸出口驅動蜂鳴器的方法,還要介紹I/O口驅動蜂鳴器的方法。所以,我們將設計如下的一個系統來說明單片機對蜂
鳴器的驅動:系統有兩個他激蜂鳴器,頻率都為2000Hz,一個由I/O口進行控制,另一個由PWM輸出口進行控制;系統還有兩個按鍵,一個按鍵為PORT按鍵,I/O口控制的蜂鳴器不鳴叫時按一次按鍵I/O口控制的蜂鳴器鳴叫,再按一次停
止鳴叫,另一個按鍵為PWM按鍵,PWM口控制的蜂鳴器不鳴叫時按一次按鍵PWM輸出口控制的蜂鳴器鳴叫,再按一次停止鳴叫。
PORTC.3/T0作為I/O口通過三極管Q2來驅動蜂鳴器LS1,而PORTC.2/PWM0則作
為PWM輸出口通過三極管Q1來驅動蜂鳴器LS2。另外在PORTA.3和PORTA.2分
別接了兩個按鍵,一個是PWM按鍵,是用來控制PWM輸出口驅動蜂鳴器使用的;
另一個是PORT按鍵,是用來控制I/O口驅動蜂鳴器使用的。連接按鍵的I/O口
開內部上拉電阻。
軟體設計方法
先分析一下蜂鳴器。所使用的蜂鳴器的工作頻率是2000Hz,也就是說蜂鳴器的驅動信號波形周期是500μs,由于是1/2duty的信號,所以一個周期內的高電平和低電平的時間寬度都為250μs。軟體設計上,我們將根據兩種驅動方式來進行說明。
a) PWM輸出口直接驅動蜂鳴器方式
由于PWM只控制固定頻率的蜂鳴器,所以可以在程式的系統初始化時就對PWM的輸出波形進行設置。首先根據SH69P43的PWM輸出的周期寬度是10位元資料來選擇PWM時鐘。系統使用4MHz的晶振作為主振蕩器,一個tosc的時間就是0.25μs,若是將PWM的時鐘設置為tosc的話,則蜂鳴器要求的波形周期500μs的計數值為500μs/0.25μs=(2000)10=(7D0)16,7D0H為11位元的資料,而SH69P43的PWM輸出周期寬度只是10位元資料,所以選擇PWM的時鐘為tosc是不能實現蜂鳴器所要的驅動波形的。這里我們將PWM的時鐘設置為4tosc,這樣一個PWM的時鐘周期就是1μs了,由此可以算出500μs對應的計數值為500μs/1μs=(500)10=(1F4)16,即分在周期寄存器的高2位、中4位和低4位三個寄存器中填入1、F和4,就完成了對輸出周期的設置。再來設置占空比寄存器,在PWM輸出中占空比的實現是
通過設定一個周期內電平的寬度來實現的。當輸出模式選擇為普通模式時,占空比寄存器是用來設置高電平的寬度。 250μs的寬度計數值為250μs/1μs=(250)10=(0FA)16。只需要在占空比寄存器的高2位、中4位和低4位中分別填入0、F和A就可以完成對占空比的設置了,設置占空比為1/2duty。以后只需要打開PWM輸出,PWM輸出口自然就能輸出頻率為2000Hz、占空比為1/2duty的方波。
b) I/O口定時翻轉電平驅動蜂鳴器方式
使用I/O口定時翻轉電平驅動蜂鳴器方式的設置比較簡單,只需要對波形分析一下。由于驅動的信號剛好為周期500μs,占空比為1/2duty的方波,只需要每250μs進行一次電平翻轉,就可以得到驅動蜂鳴器的方波信號。在程式上,可以使用TIMER0來定時,將TIMER0的預分頻設置為/1,選擇TIMER0的始終為系統時鐘(主振蕩器時鐘/4),在TIMER0的載入/計數寄存器的高4位和低4位分別寫入00H和06H,就能將TIMER0的中斷設置為250μs。當需要I/O口驅動的蜂鳴器鳴叫時,只需要在進入TIMER0中斷的時候對該I/O口的電平進行翻轉一次,直到蜂鳴器不需要鳴叫的時候,將I/O口的電平設
置為低電平即可。不鳴叫時將I/O口的輸出電平設置為低電平是為了防止漏電。
程式
以下是帶有兩種驅動方式的蜂鳴器驅動模組程式,其中黃色背景的內容是關于I/O口定時翻轉電平驅動方式的,綠色背景的內容則是關于PWM輸出口直接驅動方式的:
例:
LIST P=69P43
ROMSIZE=3072
;************************************************
;系統寄存器
;************************************************
IE EQU 00H ;中斷使能標志
IRQ EQU 01H ;中斷請求標志
TM0 EQU 02H ;Timer0模式寄存器
TL0 EQU 04H ;Timer0裝入/記數寄存器低四位
TH0 EQU 05H ;Timer0裝入/記數寄存器高四位
PORTA EQU 08H ;Port A資料寄存器
PORTC EQU 0AH ;Port C資料寄存器
TBR EQU 0EH ;查表寄存器
INX EQU 0FH ;間接定址偽索引寄存器
DPL EQU 10H ;INX數據指標低四位元
DPM EQU 11H ;INX數據指標中三位元
DPH EQU 12H ;INX數據指標高三位元
PACR EQU 18H ;PortA輸入/輸出控制寄存器
PCCR EQU 1AH ;PortC輸入/輸出控制寄存器
PWM0 EQU 20H ;位0:選擇PWM輸出,位2-1:設置PWM0時鐘,位元3:設置PWM0占空比輸出
模式
PP0L EQU 22H ;PWM0周期低四位
PP0M EQU 23H ;PWM0周期中四位
PP0H EQU 24H ;PWM0周期高二位
PD0L EQU 25H ;PWM0占空比低四位
PD0M EQU 26H ;PWM0占空比中四位
PD0H EQU 27H ;PWM0占空比高二位
;************************************************
;用戶定義寄存器(Bank0)
;************************************************
AC_BAK EQU 30H ;AC值備份寄存器
PA_BAK EQU 31H ;PortA緩沖寄存器
PC_BAK EQU 32H ;PortC 緩衝寄存器
TMP_T0 EQU 33H ;臨時寄存器用于TIMER0
;————————————–
F_TIMER EQU 34H
;位0=1, 5ms到
FLAG1 EQU 35H
;位元0=1,按鍵未松開
;位3=1,需使用I/O口驅動蜂鳴器
;————————————–
KCODE_NEW EQU 36H ;舊的按鍵碼
KCODE_OLD EQU 37H ;新的按鍵碼
KEYS_CT EQU 38H ;按鍵掃描次數
;————————————–
T5MS_CT1 EQU 39H ;5ms計數器低位
T5MS_CT2 EQU 3AH ;5ms計數器高位
;************************************************
;程式
;************************************************
ORG 0000H
JMP RESET
RTNI
JMP TIMER0_ISP
RTNI
RTNI
;*******************************************
;副程式: TIMER0中斷服務程式(250us中斷)
;*******************************************
TIMER0_ISP:
STA AC_BAK,00H ;備份AC值
ANDIM IRQ,1011B ;清TIMER0中斷請求標志
;****************************
;模組: I/O口驅動蜂鳴器模組
;****************************
PORT_BUZ:
ADI FLAG1,1000B
BA3 PORT_BUZ_NO ;不需要I/O口驅動蜂鳴器,跳轉
EORIM PC_BAK,1000B
STA PORTC,00H ;PORTC.3翻轉電平
JMP PORT_BUZ_END
PORT_BUZ_NO:
ANDIM PC_BAK,0111B
STA PORTC,00H ;PORTC.3口驅動的蜂鳴器未鳴叫時,輸出低電平以保證不漏電
PORT_BUZ_END:
;****************************
J5MS: ;判斷5ms到
SBIM T5MS_CT1,01H
LDI TMP_T0,00H
SBCM T5MS_CT2,00H
OR T5MS_CT1,00H
BNZ TIMER0_ISP_END ;5ms未到,跳轉
LDI T5MS_CT1,04H
LDI T5MS_CT2,01H ;重新載入5ms計數值
ORIM F_TIMER,0001B ;設置”5ms到”標志
TIMER0_ISP_END:
LDI IE,0100B ;開TIMER0中斷
LDA AC_BAK,00H ;恢復AC值
RTNI ;返回
;*******************************************
;上電程式
;*******************************************
RESET:
NOP
;————————————–
;清用戶寄存器
POWER_RESET:
LDI DPL,00H
LDI DPM,02H
LDI DPH,00H
POWER_RESET_1:
LDI INX,00H
ADIM DPL,01H
LDI TBR,00H
ADCM DPM,00H
BA3 POWER_RESET_2
JMP POWER_RESET_3
POWER_RESET_2:
ADIM DPH,01H
POWER_RESET_3:
SBI DPH,01H
BNZ POWER_RESET_1
SBI DPM,04H
BNZ POWER_RESET_1
;————————————–
;初始化系統寄存器
SYSTEM_INITIAL:
;TIMER0初始化
LDI TM0,07H ;設置TIMER0預分頻為/1
LDI TL0,06H
LDI TH0,00H ;設置中斷時間為250us
LDI T5MS_CT1,04H
LDI T5MS_CT2,01H
;I/O口初始化
LDI PORTC,0011B
LDI PCCR,1100B ;設置PORTC.2和PORTC.3為輸出口
LDI PORTA,0FH ;打開PORTA上拉電阻
;PWM初始化
LDI PWM0,04H ;設置PWM0時鐘為4tosc,占空比輸出模式為正常模式
LDI PP0H,01H
LDI PP0M,0FH
LDI PP0L,04H ;設置周期為500us
LDI PD0H,00H
LDI PD0M,0FH
LDI PD0L,0AH ;設置占空比電平為250us,得頻率為2KHz,占空比為
1/2duty的
;信號
;————————————–
MAIN_PRE:
LDI IRQ,00H
LDI IE,0100B ;打開Timer0中斷
;************************************************
MAIN:
ADI F_TIMER,0001B
BA0 HALTMODE ;未到5ms,跳轉
ANDIM F_TIMER,1110B ;清”5ms到”標志
;**************************************
;按鍵掃描
;**************************************
KEYSCAN:
LDA PORTA,00H
STA TBR,00H
SBI TBR,0FH
BAZ NO_KEY ;沒有掃描到按鍵按下,跳轉
LDA FLAG1,00H
BA0 KEYSCAN_END ;之前的按鍵未松開,不再掃描按鍵,跳轉
SBI TBR,0111B
BAZ KS_PORT ;PORT鍵按下,跳轉
SBI TBR,1011B
BAZ KS_PWM ;PWM鍵按下,跳轉
JMP KEYSCAN_END
KS_PORT:
LDI KCODE_NEW,0001B ;設置PORT鍵的鍵碼為01H
JMP KEYSCAN_1
KS_PWM:
LDI KCODE_NEW,0010B ;設置PWM鍵的鍵碼為02H
KEYSCAN_1:
ADIM KEYS_CT,01H ;掃描次數加一
SBI KEYS_CT,01H
BAZ KEYSCAN_2 ;第一次掃描到該按鍵,無需與舊按鍵進行比較,跳轉
LDA KCODE_OLD,00H
SUB KCODE_NEW,00H ;新掃描的按鍵碼與上次掃描的按鍵碼比較
BAZ KEYSCAN_2 ;同一個按鍵,跳轉
LDI KEYS_CT,01H ;不是同一按鍵,將掃描次數置為1,為新按鍵
KEYSCAN_2:
LDA KCODE_NEW,00H
STA KCODE_OLD,00H ;將新的按鍵碼賦值給舊的按鍵碼
SBI KEYS_CT,0AH
BNC KEYSCAN_END ;掃描未到10次(50ms),跳轉
;已掃描到該按鍵10次
LDI KEYS_CT,00H ;清按鍵掃描次數
ORIM FLAG1,0001B ;設置”按鍵未松開”標志
LDA KCODE_OLD,00H
BA0 KEY_PORT
KEY_PWM: ;PWM鍵
EORIM PWM0,0001B ;PWM輸出開啟或關閉,PWM口驅動的蜂鳴器鳴叫或停止
JMP KEYSCAN_END
KEY_PORT: ;PORT鍵
EORIM FLAG1,1000B ;I/O定時翻轉電平開啟或停止翻轉
;I/O口驅動的蜂鳴器鳴叫或停止
JMP KEYSCAN_END
NO_KEY:
ANDIM FLAG1,1110B ;清”按鍵未松開”標志
LDI KEYS_CT,00H ;清按鍵掃描次數
KEYSCAN_END:
;*************************************
HALTMODE:
NOP
HALT ;進入HALT模式
NOP
NOP
JMP MAIN
END