ARM驅(qū)動(dòng)蜂鳴器的方式有兩種:一種是PWM輸出口直接驅(qū)動(dòng),另一種是利用IO定時(shí)翻轉(zhuǎn)電平產(chǎn)生驅(qū)動(dòng)波形對(duì)蜂鳴器進(jìn)行驅(qū)動(dòng)。PWM輸出口直接驅(qū)動(dòng)是利用PWM輸出口本身可以輸出一定的方波來進(jìn)行驅(qū)動(dòng)。在ARM中可以用幾個(gè)特殊功能寄存器對(duì)占空比和周期進(jìn)行設(shè)置。通過設(shè)置這些寄存器產(chǎn)生符合蜂鳴器要求的方波后,這個(gè)時(shí)候利用這個(gè)方波就可以對(duì)蜂鳴器進(jìn)行驅(qū)動(dòng)了。使用PWM時(shí),通過TCMPn可以決定脈寬,TCNTn決定頻率,TCMPn/TCNTn決定占空比。使用IO口電平翻轉(zhuǎn)時(shí),需要使用定時(shí)器來做定時(shí),通過定時(shí)翻轉(zhuǎn)產(chǎn)生符合要求頻率的波形。由于蜂鳴器一般的工作電流比較大,以至于IO口無法驅(qū)動(dòng),一般使用放大電路來驅(qū)動(dòng),一般使用三極管來放大電流就可以了。 使用PWM控制蜂鳴器: rTCFG0用來設(shè)置預(yù)分頻值,rTCFG1用來設(shè)置多路選擇器MUX的分頻值,TCNTB0也起到分頻作用。使用PWM控制蜂鳴器注意設(shè)置GPB0為TOUT0。這里設(shè)置PWM頻率為1HZ,占空比50%,也就是半秒響一次。S3C2440定時(shí)器中有雙緩沖rTCNTBn,rTCMPBn,他們是可以通過編程訪問的,他們會(huì)將數(shù)據(jù)自動(dòng)裝入rTCNTn,rTCMPn,這兩個(gè)16位計(jì)數(shù)器對(duì)程序員來說是透明的。 一般啟動(dòng)定時(shí)器的步驟如下:
#define rGPBCON (*(volatile unsigned *)0x56000010) #define rGPBDAT (*(volatile unsigned *)0x56000014) #define rGPBUP (*(volatile unsigned *)0x56000018) #define rTCFG0 (*(volatile unsigned *)0x51000000) #define rTCFG1 (*(volatile unsigned *)0x51000004) #define rTCNTB0 (*(volatile unsigned *)0x5100000C) #define rTCMPB0 (*(volatile unsigned *)0x51000010) #define rTCON (*(volatile unsigned *)0x51000008) int Main(){ rGPBCON &= 0xfffffc; rGPBCON |= 0x2; rTCFG0 &= "0xff; rTCFG0 |= 0x64; rTCFG1 &= "0xf; rTCFG1 |= 0x3; rTCNTB0 = 0x7530; rTCMPB0 = rTCNTB0>>1; rTCON &= "0x1f; rTCON |= (0x1)|(0x1<<1)|(0x1<<3); rTCON &= "2; while(1); return 0; } 使用定時(shí)器產(chǎn)生中斷使IO電平翻轉(zhuǎn),控制蜂鳴器: 定時(shí)器注意設(shè)置rINTMSK開中斷,并在中斷處理程序中清除中斷請(qǐng)求位。rSRCPND |= 0x1<<10;rINTPND |= 0x1<<10;清除rINTPND通過設(shè)置相應(yīng)為1進(jìn)行清除。rSTCPND是向相應(yīng)位寫數(shù)據(jù)清除。如果不清除,會(huì)一直響應(yīng)這個(gè)中斷。在Main函數(shù)中清一下是為了防止以前這個(gè)位申請(qǐng)中斷,所以清一下,以防萬一。定時(shí)器接在APB總線上,所以用PCLK時(shí)鐘。在這里我設(shè)預(yù)分頻為0x64,除法器為16,rTCNTB0為0x7a12,所以 50M/0x64/16/0x7a12為1HZ,所以中斷周期為1s,所以每一秒蜂鳴器響一下,然后隔一秒,然后再響。 #define rGPBCON (*(volatile unsigned *)0x56000010) #define rGPBDAT (*(volatile unsigned *)0x56000014) #define rGPBUP (*(volatile unsigned *)0x56000018) #define rSRCPND (*(volatile unsigned *)0x4A000000) #define rINTPND (*(volatile unsigned *)0x4A000010) #define rTCFG0 (*(volatile unsigned *)0x51000000) #define rTCFG1 (*(volatile unsigned *)0x51000004) #define rTCNTB0 (*(volatile unsigned *)0x5100000C) #define rTCON (*(volatile unsigned *)0x51000008) #define rINTMSK (*(volatile unsigned *)0x4A000008) #define U32 unsigned int #define _ISR_STARTADDRESS 0x33ffff00 #define pISR_TIMER0 (*(unsigned *)(_ISR_STARTADDRESS+0x48)) int count; void __irq Timer0_ISR(void){ rSRCPND |= 0x1<<10; rINTPND |= 0x1<<10; count++; if(count %2 == 1) rGPBDAT |= 0x01; else rGPBDAT &= 0xfe; if(count == 1000) count = 0; } int Main(){ count = 0; rGPBCON &= 0xfffffc; rGPBCON |= 0x1; rGPBDAT &= 0xffe; rGPBUP &= 0xfe; pISR_TIMER0 = (U32)Timer0_ISR; rSRCPND |= 0x1<<10; rINTPND |= 0x1<<10; rINTMSK &= "(0x1<<10); rTCFG0 &= "0xff; rTCFG0 |= 0x64; rTCFG1 &= "0xf; rTCFG1 |= 0x3; rTCNTB0 = 0x7a12; rTCON &= "0x1f; rTCON |= 0xb; rTCON &= "0x2; while(1); return 0; } 李萬鵬 |