日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀]這篇文章是談談關(guān)于1937的定時器的,剛開始被晶振頻率、時鐘頻率、振蕩周期、振蕩頻率、指令周期、指令頻率等等的名詞繞暈了。先來解決這個問題。晶振頻率是代表振蕩器的頻率,說的是晶振這個器件的頻率,因為一個單

這篇文章是談談關(guān)于1937的定時器的,剛開始被晶振頻率、時鐘頻率、振蕩周期、振蕩頻率、指令周期、指令頻率等等的名詞繞暈了。先來解決這個問題。


晶振頻率是代表振蕩器的頻率,說的是晶振這個器件的頻率,因為一個單片機有內(nèi)部外部晶振,比如你選擇了內(nèi)部晶振,那么這個晶振的頻率就是你單片機的時鐘頻率,


振蕩頻率和晶振頻率說的是一回事。振蕩周期是1/(晶振頻率),T = 1/f 嘛。指令周期這個根據(jù)單片機的不同會不同,8位的PIC單片機(PIC10/12/16/18系列)是4個時鐘周期為一個指令周期。16位的PIC24單片機和dsPIC數(shù)字處理芯片和32位PIC32處理器是2個時鐘周期為一個指令周期。(以上關(guān)于指令周期的內(nèi)容是百度到的,內(nèi)容較可靠http://zhidao.baidu.com/link?url=uEnsn0C-bb-xdDNG_qEI0HmhIpoDNVc4d2lheztGKsQMpflMcpbnlWAGdXyeMz05fJAhXardxSrQDLHEdDrCx_)


理清上面的內(nèi)容,就開始我們的正題。


TIMER0


/*

* TIMER0是一個8位定時器/計數(shù)器,有8位預分頻器(1:2-1:256),是所有定時器中預分頻最大的(可以這么說吧。。)

* 可編程的內(nèi)外部時鐘源,可編程的外部時鐘邊沿選擇。

* 溢出時中斷

* TMR0可用于門控Timer1(還沒試過。。)

* 休眠模式中無法工作

* 此時選擇內(nèi)部晶振8mhz,預分頻1:16,每2.04s燈狀態(tài)改變一次。TMR0從0計數(shù)到255

* 所以是255*16*1000/(Fosc(晶振頻率)/4) = 2.04

*/


這些是我寫在單片機程序開頭的內(nèi)容,大致描述了TIMER0模塊,接下來告訴你們怎么使用它吧。(只寫關(guān)于初始化TIMER0的,CPU的初始化之類的略過)


1.先初始化時鐘源,在OSSCON寄存器中設置SCS位來選擇內(nèi)部振蕩模塊,IRCF設置內(nèi)部頻率


2.現(xiàn)在初始化TIMER0,還是一樣,先選擇時鐘源,TMR0CS = 0;表示內(nèi)部指令周期(注意是指令周期,fosc/4)


3.選擇預分頻,PSA位來選擇需不需要預分頻,PS<2:0>來設置預分頻


4.時鐘都和中斷有關(guān),所以這里要允許有效中斷,GIE = 1;


5.然后允許TIM0IE中斷,TIM0IE = 1;


6.最后是溢出中斷標志位,TMR0IF = 0;表示未溢出,當定時器開啟的時候TMRO就會開始計數(shù),一個指令周期加一,從0-255.當加到255后再加一使TMR0IF = 1;計數(shù)會跳到0繼續(xù)。


7.TMR0可以不用使能,自動計數(shù),但因為執(zhí)行時會延遲2個指令周期,所以TMR0的初值需要設置,來抵消這個延遲。


還是上代碼吧


1 void InitTime();

2 void Init_fosc(); //設置內(nèi)部振蕩器,不過好像沒用。。

3

4 unsigned int count = 0;

5

6 int main(int argc, char** argv)

7 {

8 InitCPU();

9 Init_fosc();

10 InitTime();

11 TRISC = 0x00;

12 // LATC = 0x00;

13 while(1);

14 return (EXIT_SUCCESS);

15 }

16

17 void InitTime()

18 {

19 // INTEDG = 0; //bit6 中斷邊沿選擇位,1 = 上升沿,0 = 下降沿

20 TMR0CS = 0; //bit5 Timer0時鐘源選擇位,0 = 內(nèi)部指令周期時鐘(Fosc/4)

21 TMR0SE = 0; //bit4 Timer0時鐘源邊沿選擇位,1 = 在T0CKI引腳電平下降沿時遞增,0 = 上升沿時遞增

22 PSA = 0; //bit3 預分頻器分配位,1 = 不分給Timer0,0 = 預分頻器分給Timer0

23 PS0 = 1;

24 PS1 = 1;

25 PS2 = 0; //1:16

26 //PS<2:0>,預分頻器分頻比選擇位

27 GIE = 1; //允許所有有效中斷

28 PEIE = 0; //禁止所有外設中斷,有待考慮

29 TMR0IE = 1; //允許TMR0中斷

30 TMR0IF = 0; //溢出中斷標志位,未溢出

31 TMR0 = 1;

32 }

33

34 void Init_fosc()

35 {

36 // OSCCON = 0x6a; 下面的設置為設置內(nèi)部振蕩器頻率的

37 SCS0 = 1;

38 SCS1 = 0; //1x內(nèi)部振蕩器模塊

39 IRCF0 = 0;

40 IRCF1 = 1;

41 IRCF2 = 1;

42 IRCF3 = 0; //1101 = 250kHz

43

44 }

45

46 void interrupt ISR()

47 {

48 TMR0 = 1;

49 count++;

50 if(count ==10)

51 {

52 LATC = ~LATC;

53 count = 0;

54 }

55 TMR0IF = 0;

56 }


TMR0是不用使能的,其他的時候也許不用管他,就算它在計數(shù),沒有允許它中斷(TMR0IE位),也是沒啥用的啊,殘念ね。。


接下來是TIMER1模塊,TIMER1模塊的特殊的地方是帶門控,是16位的定時計數(shù)器,有專用32kHz的振蕩器電路。


這次先上代碼吧,感覺會更有條理些


1 void InitTime();

2 void Init_fosc(); //設置內(nèi)部振蕩器,不過好像沒用。。

3

4 unsigned int count = 0;

5

6 int main(int argc, char** argv)

7 {

8 InitCPU();

9 Init_fosc();

10 InitTime();

11 TRISC = 0x00;

12 // LATC = 0x00;

13 while(1);

14 return (EXIT_SUCCESS);

15 }

16

17 void InitTime()

18 {

19 // INTEDG = 0; //bit6 中斷邊沿選擇位,1 = 上升沿,0 = 下降沿

20 TMR0CS = 0; //bit5 Timer0時鐘源選擇位,0 = 內(nèi)部指令周期時鐘(Fosc/4)

21 TMR0SE = 0; //bit4 Timer0時鐘源邊沿選擇位,1 = 在T0CKI引腳電平下降沿時遞增,0 = 上升沿時遞增

22 PSA = 0; //bit3 預分頻器分配位,1 = 不分給Timer0,0 = 預分頻器分給Timer0

23 PS0 = 1;

24 PS1 = 1;

25 PS2 = 0; //1:16

26 //PS<2:0>,預分頻器分頻比選擇位

27 GIE = 1; //允許所有有效中斷

28 PEIE = 0; //禁止所有外設中斷,有待考慮

29 TMR0IE = 1; //允許TMR0中斷

30 TMR0IF = 0; //溢出中斷標志位,未溢出

31 TMR0 = 1;

32 }

33

34 void Init_fosc()

35 {

36 // OSCCON = 0x6a; 下面的設置為設置內(nèi)部振蕩器頻率的

37 SCS0 = 1;

38 SCS1 = 0; //1x內(nèi)部振蕩器模塊

39 IRCF0 = 0;

40 IRCF1 = 1;

41 IRCF2 = 1;

42 IRCF3 = 0; //1101 = 250kHz

43

44 }

45

46 void interrupt ISR()

47 {

48 TMR0 = 1;

49 count++;

50 if(count ==10)

51 {

52 LATC = ~LATC;

53 count = 0;

54 }

55 TMR0IF = 0;

56 }



再來寫下總結(jié)的步驟


1.初始時鐘源


2.在Timer1的初始中先選擇時鐘源


3.設置預分頻


4.允許中斷和溢出位清零


5.使能Timer1


雖然看起來簡單,但是Timer1的功能比Timer0多,好些自己也沒有用到過,有一個注意的地方,TMR1H和TMR1L的初值設定最好剛剛把延時拿回來就行了。使能也應該放最后,剛好需要起振時間



最后最后,1937里面最多的定時器,數(shù)量超過我的想象,竟然多達,,竟然擁有3個??!何等的數(shù)量啊。。。。。好了,不裝怪了,他是TIMER2/4/6葫蘆三兄弟。


/*1937共含有3個相同的Timer2模塊,分別為Timer2、Timer4、Timer6

* 8位定時器和周期寄存器(TMRx和PRx)

* 可讀寫、預分頻(1:1:4:16:64)后分頻(1:1至1:16)

* TMRx與相應的PRx分別匹配時中斷、可選擇作為MSSP模塊的移位時鐘(僅Timer2)

*/


看到了嗎,這里是TMRx與相應的PRx分別匹配時中斷,不像前面兩個あほ(TIMER0與TIMER1)是溢出中斷


還是先上代碼吧,,,這里直接上初始化Timer2/4/6的程序了,



1 void Init_Timer2() //時鐘是系統(tǒng)指令時鐘 Fosc/4,沿邊沿遞增計數(shù)。

2 {

3 T2CON = 0x0d; //設置后分頻,使能Timer2,設置預分頻

4 TMR2 = 0;

5 PR2 = 100; //TMR2與PR2的值越相近,進入中斷越快

6 GIE = 1; //允許所有有效中斷,?。。?!實驗無此語句能否運作

7 PEIE = 1;

8 TMR2IE = 1; //允許Timer2中斷

9 TMR2IF = 0; //溢出標志位,未溢出

10 }


TIMER2/4/6是無法自己選擇內(nèi)外部時鐘的,系統(tǒng)選什么他就得選什么,作為對比,TIMER0和TIMER1是可以自己選的,素晴らしい!



所有的時鐘設置總結(jié)來說,必須考慮的要素有以下幾條


1.設置時鐘,系統(tǒng)時鐘和定時器要用的時鐘(TIMER0和TIMER1是可以選的)

2.預分頻及后分頻,所有時鐘里TIMER0的預分頻最大(1:2-1:256),TIMER2/4/6既有預分頻又有后分頻

3.TMRxIE、PEIE、GIE(允許TIMERx中斷、允許外設中斷、允許所有有效中斷),這三個的賦值。除PEIE在TIMER0中沒有也可以運作外,其他兩個在每個定時器中必須有

4.TMRxIF,溢出的標志位,一般會在中斷程序里面清零,所以在初始化里面可有可無。

5.計數(shù)的設置TIMER0中的TMRO(0-255),TIMER1中的TMR1H和TMR1L,TIMER2/4/6中的TMRx(0-PRx),PRx(0-255)


本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉