S3C2440A有5個16位定時器。其中定時器0、1、2和3具有脈寬調(diào)制(PWM)功能。定時器4是一個無輸出引腳的內(nèi)部定時器。定時器0還包含用于大電流驅(qū)動的死區(qū)發(fā)生器
定時器0和1共用一個8位預(yù)分頻器,定時器2、3和4共用另外的8位預(yù)分頻器。每個定時器都有一個可以生成5種不同分頻信號(1/2,1/4,1/8,1/16和TCLK)的時鐘分頻器。每個定時器模塊從相應(yīng)8位預(yù)分頻器得到時鐘的時鐘分頻器中得到其自己的時鐘信號。8位預(yù)分頻器是可編程的,并且按存儲在TCFG0和TCFG1寄存器中的加載值來分頻PCLK
每個定時器有它自己的由定時器時鐘驅(qū)動的16位遞減計數(shù)器。當(dāng)遞減計數(shù)器到達零時,產(chǎn)生定時器中斷請求通知CPU定時器操作已經(jīng)完成。當(dāng)定時器計數(shù)器到達零時,相應(yīng)的TCNTBn的值將自動被加載到遞減計數(shù)器以繼續(xù)下一次操作
對于定時器的使用有兩種模式,第一是普通定時第二是PWM輸出
先說普通定時,一般定時器的使用流程都會包含這幾步
1.在低功耗寄存器里面啟用相應(yīng)的定時器外設(shè)
2.設(shè)置時鐘分頻比,獲取定時器的計數(shù)時鐘
3.設(shè)置定時器的定時值(重載值),配置中端,啟動定時器
4.等待中斷發(fā)生,中斷處理函數(shù)中清除中斷
依靠這幾步,有以下寄存器我們需要注意
首先,設(shè)置PCLK到定時器的分頻比例,有兩種時鐘,分別是01定時器和234定時器
然后進行第二次分頻
可選擇1/2%201/4%201/8%201/16幾種時鐘,時鐘源是從上一個寄存器分頻來的
設(shè)置定時器的自動重載和啟動定時器,注意在這個寄存器中,請用手動更新了之后必須再次清零,否則定時器無法運行
我之前就遇到過這個問題
設(shè)置定時器自動重載的值
再然后按照之前的設(shè)置中斷的方式設(shè)置中斷,定時器沒有次級源,以time0為例
1.源掛起srcpend
2.中斷模式intmode
3.中斷屏蔽intmask
4.中斷掛起intpend
使能中斷之后定時器就可以正常使用了
具體代碼如下:
Timer.c
#include"timer.h"u8timer0Up=0;void__irqtimer0(){rSRCPND"=(1<<10);//清除源掛起rINTPND|=(1<<10);//清除中斷掛起timer0Up=1;}//定時器初始化//prescaler8為分頻器值,0-255//mux定時器的選通輸入01/211/421/831/16//定時器的重載值voidInitTimer0(u8prescaler,u8mux,u16count){rCLKCON|=(1<<8);//打開timer時鐘rTCFG0&=~0xff;//清零分頻器rTCFG0|=prescaler;//設(shè)置預(yù)分頻器rTCFG1&=~(0x0f<<0);rTCFG1|=(mux<<0);//設(shè)置選通輸入//設(shè)置定時器的計數(shù)值rTCMPB0=0x0;rTCNTB0=count;//設(shè)定初值//啟動定時器rTCON|=(1<<1);//更新TCNTB0和TCMPB0rTCON|=(1<<3);//啟動自動重載rTCON&=~(1<<1);//清零手動更新rSRCPND|=(1<<10);//清除源掛起rINTPND|=(1<<10);//清除中斷掛起rINTMOD&=~(1<<10);//設(shè)置中斷模式為IRQ模式rINTMSK&=~(1<<10);//使能定時器中斷pISR_TIMER0=(unsigned)timer0;//設(shè)置中斷地址rTCON|=(1<<0);//啟動定時器0}
Timer.h
#ifndef__TIMER_H#define__TIMER_H#include"2440addr.h"#include"led.h"#include"uart0.h"externu8timer0Up;voidInitTimer0(u8prescaler,u8mux,u16count);#endif
PWM波形輸出時需要注意幾個別的寄存器
第一:PWM輸出不需要開啟中斷,但是要設(shè)置相應(yīng)的引腳復(fù)用功能為pwm功能,如圖,TCLK
第二,使用pwm功能必須要使能比較寄存器,也就是
第三,根據(jù)需要看是否需要反向,何為反向呢
就是TCNT Pwm.c Pwm.h#include"pwm.h"http://compare比較寄存器的值voidTomer0PwmInit(u8prescaler,u8mux,u16count,u16compare){rGPBCON&=~3;rGPBCON"=2;//設(shè)置GPB0為OUT0rGPBUP=0x0;//使能上拉rCLKCON|=(1<<8);//打開timer時鐘rTCFG0&=~0xff;//清零分頻器rTCFG0|=prescaler;//設(shè)置預(yù)分頻器rTCFG1&=~(0x0f<<0);rTCFG1|=(mux<<0);//設(shè)置選通輸入//設(shè)置定時器的計數(shù)值rTCMPB0=compare;//比較寄存器的值rTCNTB0=count;//設(shè)定初值//啟動定時器rTCON|=(1<<1);//更新TCNTB0和TCMPB0rTCON|=(1<<3);//啟動自動重載rTCON&=~(1<<1);//清零手動更新rTCON|=(1<<0);//啟動定時器0}
#ifndef__PWM_H_#define__PWM_H_#include"2440addr.h"#include"def.h"http://compare比較寄存器的值voidTomer0PwmInit(u8prescaler,u8mux,u16count,u16compare);#endif