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