51 匯編編程:使蜂鳴器發(fā)出“嘀、嘀。。。”報(bào)警聲
對蜂鳴器控制,使蜂鳴器發(fā)出“嘀、嘀。。?!眻?bào)警聲。
報(bào)警聲從 P1.3 端口輸出,產(chǎn)生頻率為 2.5KHz,聲長 1.1 秒,間隔 1 秒。
晶振暫定12MHz。使用匯編語言編寫。
要求發(fā)音頻率是 2.5KHz,其半周期就是 200us。
可令單片機(jī)每隔 200us 中斷一次。
每中斷一次,就對 P1.3 取一次反,這就發(fā)出了 2.5KHz 方波。
取反 55 000 次,就是發(fā)音 1.1s。
再中斷 50 000 次,不取反,就是發(fā)音間隔 1s。
中斷的次數(shù):50 000、55 000,可以用兩個(gè)寄存器來計(jì)數(shù)。
定時(shí) 200us,可以使用方式2。
用匯編語言編寫的程序如下:
? ? ORG ? 0000H
? ? JMP ? MAIN
? ? ORG ? 000BH
? ? JMP ? T0_INT ? ? ?;T0中斷入口
;------------------------------------
MAIN:
? ? MOV ? TMOD, #02H ?;T0定時(shí)方式2
? ? MOV ? TH0, #56 ? ?;200us @ 12MHz
? ? MOV ? TL0, #56
? ? SETB ?TR0 ? ? ? ? ;啟動T0
? ? MOV ? IE, #82H ? ?;允許T0中斷
? ? MOV ? R2, #100
? ? MOV ? R3, #50 ? ? ;中斷計(jì)數(shù)初始值
? ? SJMP ?$ ? ? ? ? ? ;等待中斷
;------------------------------------
T0_INT:
? ? JNB ? F0, NO
? ? CPL ? P1.3 ? ? ? ?;發(fā)音
? ? DJNZ ?R2, EXIT
? ? MOV ? R2, #100
? ? DJNZ ?R3, EXIT
? ? MOV ? R3, #50 ? ? ;中斷次數(shù)定為50000
? ? CPL ? F0 ? ? ? ? ?;下次中斷,將不發(fā)音1s
? ? RETI
NO:
? ? SETB ?P1.3 ? ? ? ?;不發(fā)音
? ? DJNZ ?R2, EXIT
? ? MOV ? R2, #100
? ? DJNZ ?R3, EXIT
? ? MOV ? R3, #55 ? ? ;中斷次數(shù)定為55000
? ? CPL ? F0 ? ? ? ? ?;下次中斷,將發(fā)音1.1s
EXIT:
? ? RETI
;------------------------------------
END
本程序,已經(jīng)經(jīng)過了測試。
發(fā)音的頻率,題目規(guī)定的是 2.5KHz,聽起來,稍稍有些尖銳刺耳。
定時(shí) 200us 和發(fā)音 1.1s、靜音 1s,做而論道僅僅使用了一個(gè)計(jì)數(shù)器T0,就解決了問題,這對于節(jié)省硬件資源,很有意義。
在回答這個(gè)題目的答案中,有人用上了兩個(gè)定時(shí)/計(jì)數(shù)器,程序還長了許多,也沒有滿足題目的要求。
當(dāng)然,把程序修改一下,還是可以的,但是,使用兩個(gè)定時(shí)/計(jì)數(shù)器,這可不是正確的思路。
如果晶振頻率改成 8MHz,分析如下:
輸出的頻率,題目要求是 2.5KHz,其半周期是 200us,必須定時(shí) 200us。
上面是用 12MHz 的晶振,機(jī)器周期是 1us,需要定時(shí) 200us,初值就是 256 - 200 = 56。
如果使用 8MHz 的晶振,機(jī)器周期是 1.5us,仍然定時(shí) 200us,初值就是 256 - 200/1.5 = 256 - 133 = 123。
把上面的程序中,有 56 的地方,改成 123,其它的,都不用改動。
這么改動之后,在 8MHz 的頻率下,仍然是每隔 200us 中斷一次。