轉自:http://caiyh.blog.163.com/blog/static/18670512220115152564613/
//=========================================
// NAME: main.c
// DESC: TQ2440PWM測試程式
// 蜂鳴器頻率響 GPB0 設定為TOUT
// 設定為輸出低電平就關掉蜂鳴器
// 改變頻率通過改變時鐘頻率
//=========================================
/* 標頭檔包含 */
#include "def.h"
#include "option.h"
#include "2440addr.h"
void delay_ms(U32 time)
{
//定時器3輸入時鐘頻率 = PCLK / {預分頻值+1} / {分頻值}
//{預分頻值} = 0~255
//{分頻值} = 2, 4, 8, 16
//PCLK:50MHz 時鐘頻率:6250KHz 定時1ms 計數:時鐘頻率*定時時間-1
U32 val = 50000000/(4*2)/1000-1;
rTCFG0 = (rTCFG0 & ~(0xff<<8)) | (3<<8);//Prescaler1 = 3+1
rTCFG1 = (rTCFG1 & ~(0xf<<12)) | (0<<12);//mux = 1/2
rTCNTB3 = val;
rTCMPB3 = rTCNTB3/2; //占空比50%
rTCON = (rTCON & ~(0xf<<16)) | (0xb<<16);//自動重載、變相、手動更新、啟動定時器3
rTCON = (rTCON & ~(0x2<<16)); //禁止手動更新
while(time--) //等待一次定時結束
{
while(rTCNTO3 >= (val>>1));
while(rTCNTO3 < (val>>1));
}
}
void buzzer_freq_set(U32 freq)
{
//定時器1輸入時鐘頻率 = PCLK / {預分頻值+1} / {分頻值}
//{預分頻值} = 0~255
//{分頻值} = 2, 4, 8, 16
//PCLK:50MHz 時鐘頻率:6250KHz 定時1ms 計數:時鐘頻率*定時時間-1
// 50000000/(16*8) = 390625
rGPBCON = (rGPBCON & ~0x3) | 0x2;//GPB0口設定為TOUT PWM 0b10
rTCFG0 = (rTCFG0 & ~0xff) | 15; //Prescaler0 = 15+1
rTCFG1 = (rTCFG1 & ~0xf) | 0x2; //mux = 1/8 0b0010
rTCNTB0 = 50000000/(16*8)/freq;
rTCMPB0 = rTCNTB0/2; //占空比50%
rTCON = (rTCON & ~0x1f) | 0xb; //禁止死區、自動重載、變相、手動更新、啟動定時器3
rTCON = (rTCON & ~0x2); //禁止手動更新
}
void buzzer_stop(void)
{
rGPBCON = (rGPBCON & ~0x3) | 0x1;//GPB0口設定為輸出0b01
rGPBDAT = (rGPBDAT & ~0x1); //GPB0口輸出低電平關掉蜂鳴器
}
void beep(U32 freq,U32 time)
{
buzzer_freq_set(freq);
delay_ms(time);
buzzer_stop();
}
void Main(void)
{
beep(20000,100);
while(1);
}