天天看點

mini2440裸機試煉之——PWM定時器按鍵更改頻率

資料:《s3c2440中文資料手冊(完整版)》 

第九章:輸入輸出端口  ;

第十章:PWM蜂鳴器

//按按鍵k1蜂鳴器頻率降低,
//按按鍵k2蜂鳴器頻率升高,
//按按鍵k3退出蜂鳴器測試
//按按鍵k4開啟蜂鳴器測試

#define GPBCON    (*(volatile unsigned long*)0x56000010)  //rGPBCON是指向0x56000010這個位址空間的一個宏
#define GPBDAT    (*(volatile unsigned long*)0x56000014)  //led GPIO

#define GPGCON    (*(volatile unsigned long*)0x56000060)  //KEY GPIO
#define GPGDAT    (*(volatile unsigned long*)0x56000064)

#define TCFG0     (*(volatile unsigned long*)0x51000000)  //PWM定時器
#define TCFG1     (*(volatile unsigned long*)0x51000004)
#define TCON      (*(volatile unsigned long*)0x51000008)
#define TCNTB0    (*(volatile unsigned long*)0x5100000C)
#define TCMPB0    (*(volatile unsigned long*)0x51000010)

#define PWM_out   (0x01)                      //開啟PWM為輸出
#define PWM_TOUT0 (10)                        //開啟PWM為TOUT0功能,LED輸出功能
#define LED1_out  (1<<(5*2))
#define LED2_out  (1<<(6*2))
#define LED3_out  (1<<(7*2))
#define LED4_out  (1<<(8*2))

#define BEEP_OFF  (0)        //蜂鳴器來說1代表發出聲音,而0則代表不出聲音
#define BEEP_ON   (1)

#define LED_OFF   (0x0F<<5)  //LED                 OFF
#define LED1_ON   (0x0E<<5)  //LED1                ON
#define LED2_ON   (0x0E<<6)  //LED1+LED2           ON
#define LED3_ON   (0x0E<<7)  //LED1+LED2+LED3      ON
#define LED4_ON   (0x0E<<8)  //LED1+LED2+LED3+LED4 ON

#define U8        unsigned char
#define U32       unsigned int


void daly()               //時間延遲函數
{
    U32 t;
    U32 i;
    for(t=888;t>0;t--)
    for(i=0;i<10000;i++);

}

void led_key_init()            //初始化LED和KEY
{
    GPBCON=LED1_out|LED2_out|LED3_out|LED4_out|PWM_TOUT0;                                  //led PWM 設定為輸出
    GPGCON= ~( (3<<(2*0))|(3<<(2*3))|(3<<(2*5))|(3<<(2*6)) );                              //GPG0 3 5  6輸入  開啟按鍵1 2 3 4功能
    GPBDAT=LED_OFF|BEEP_ON;
}

void PWM_init()                //初始化PWM定時器函數
{
    TCFG0 &= 0xFFFF00;         //初始化預分頻值
    TCFG0 |= 0x31;             //prescal=49
    TCFG1 &= ~0xF;             //mux=1/2    ,PCLK為50MHz,定時器輸入時鐘頻率 = PCLK / {預分頻值+1} / {分頻值};是以50MHz/(49+1)/2=500kHz
    TCNTB0 = 5000;             //初始化雙緩沖器TCNTB0和TCMPB0
    TCMPB0 = 2500;
    TCON &= ~0x1F;             //TCON置零
    TCON |= 0xf;               //死區無效,自動裝載,電平反轉,手動更新,定時器開啟
    TCON &= ~0x2 ;             //手動更新位清零,PWM開始工作
}

void ESC_PWM()
{
    GPBCON = ~0x3;             //關閉GPB0的TOUT0功能,
    GPBCON = PWM_out;          //設定GPB0為01輸出功能
    GPBDAT = BEEP_OFF;         //設定GPB0資料寄存器為0,對蜂鳴器來說1代表發出聲音,而0則代表不出聲音
}

void OPEN_PWM()
{
    GPBCON=LED1_out|LED2_out|LED3_out|LED4_out|PWM_TOUT0;  //重置GPB控制器和資料寄存器
    GPBDAT=LED_OFF|BEEP_ON;
}


void led2_1_on()                              //LED1 2;1點亮
{
    GPBDAT=LED2_ON; daly();
    GPBDAT=LED_OFF; daly();
    GPBDAT=LED1_ON; daly();
    GPBDAT=LED_OFF;
}

void led3_4_on()                              //LED3 ; 3 4點亮
{
    GPBDAT=LED3_ON; daly();
    GPBDAT=LED_OFF; daly();
    GPBDAT=LED4_ON; daly();
    GPBDAT=LED_OFF;
}

int Main()
{
    U32  freq=2500;
    led_key_init();         //初始化LED和KEY
    PWM_init();             //初始化PWM定時器

    while(1)
    {
        if( !(GPGDAT &( 1<<0 )) ){      // K1  PWM值降低
            freq =freq+300;
            if(freq>5000) freq=2500;

            TCMPB0 = freq;             //資料手冊裡說:PWM功能可以通過使用TCMPBn實作。PWM頻率由TCNTBn決定。
                                       //這裡通過改變TCMPB0來改變PWM的值。
                                       //減小TCMPBn可以提高PWM值。增大TCMPBn可以降低PWM值。
            led2_1_on();
            } else

        if(!(GPGDAT &( 1<<3 )) ){      // K2   PWM值增加
            freq =freq-300;
            if(freq<1000) freq=2500;
            TCMPB0 = freq;
            led3_4_on();
            } else

        if(!(GPGDAT &( 1<<5 )) ){      // K3   關閉蜂鳴器輸出
            ESC_PWM();
            } else

        if(!(GPGDAT &( 1<<6 )) ){      // K4   打開蜂鳴器輸出
            OPEN_PWM();
            }
    }
    return 0;
}