当前位置:首页 > 单片机 > 单片机
[导读]这篇文章是谈谈关于1937的定时器的,刚开始被晶振频率、时钟频率、振荡周期、振荡频率、指令周期、指令频率等等的名词绕晕了。先来解决这个问题。晶振频率是代表振荡器的频率,说的是晶振这个器件的频率,因为一个单

这篇文章是谈谈关于1937的定时器的,刚开始被晶振频率、时钟频率、振荡周期、振荡频率、指令周期、指令频率等等的名词绕晕了。先来解决这个问题。


晶振频率是代表振荡器的频率,说的是晶振这个器件的频率,因为一个单片机有内部外部晶振,比如你选择了内部晶振,那么这个晶振的频率就是你单片机的时钟频率,


振荡频率和晶振频率说的是一回事。振荡周期是1/(晶振频率),T = 1/f 嘛。指令周期这个根据单片机的不同会不同,8位的PIC单片机(PIC10/12/16/18系列)是4个时钟周期为一个指令周期。16位的PIC24单片机和dsPIC数字处理芯片和32位PIC32处理器是2个时钟周期为一个指令周期。(以上关于指令周期的内容是百度到的,内容较可靠http://zhidao.baidu.com/link?url=uEnsn0C-bb-xdDNG_qEI0HmhIpoDNVc4d2lheztGKsQMpflMcpbnlWAGdXyeMz05fJAhXardxSrQDLHEdDrCx_)


理清上面的内容,就开始我们的正题。


TIMER0


/*

* TIMER0是一个8位定时器/计数器,有8位预分频器(1:2-1:256),是所有定时器中预分频最大的(可以这么说吧。。)

* 可编程的内外部时钟源,可编程的外部时钟边沿选择。

* 溢出时中断

* TMR0可用于门控Timer1(还没试过。。)

* 休眠模式中无法工作

* 此时选择内部晶振8mhz,预分频1:16,每2.04s灯状态改变一次。TMR0从0计数到255

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

*/


这些是我写在单片机程序开头的内容,大致描述了TIMER0模块,接下来告诉你们怎么使用它吧。(只写关于初始化TIMER0的,CPU的初始化之类的略过)


1.先初始化时钟源,在OSSCON寄存器中设置SCS位来选择内部振荡模块,IRCF设置内部频率


2.现在初始化TIMER0,还是一样,先选择时钟源,TMR0CS = 0;表示内部指令周期(注意是指令周期,fosc/4)


3.选择预分频,PSA位来选择需不需要预分频,PS<2:0>来设置预分频


4.时钟都和中断有关,所以这里要允许有效中断,GIE = 1;


5.然后允许TIM0IE中断,TIM0IE = 1;


6.最后是溢出中断标志位,TMR0IF = 0;表示未溢出,当定时器开启的时候TMRO就会开始计数,一个指令周期加一,从0-255.当加到255后再加一使TMR0IF = 1;计数会跳到0继续。


7.TMR0可以不用使能,自动计数,但因为执行时会延迟2个指令周期,所以TMR0的初值需要设置,来抵消这个延迟。


还是上代码吧


1 void InitTime();

2 void Init_fosc(); //设置内部振荡器,不过好像没用。。

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 = 内部指令周期时钟(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; 下面的设置为设置内部振荡器频率的

37 SCS0 = 1;

38 SCS1 = 0; //1x内部振荡器模块

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是不用使能的,其他的时候也许不用管他,就算它在计数,没有允许它中断(TMR0IE位),也是没啥用的啊,残念ね。。


接下来是TIMER1模块,TIMER1模块的特殊的地方是带门控,是16位的定时计数器,有专用32kHz的振荡器电路。


这次先上代码吧,感觉会更有条理些


1 void InitTime();

2 void Init_fosc(); //设置内部振荡器,不过好像没用。。

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 = 内部指令周期时钟(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; 下面的设置为设置内部振荡器频率的

37 SCS0 = 1;

38 SCS1 = 0; //1x内部振荡器模块

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 }



再来写下总结的步骤


1.初始时钟源


2.在Timer1的初始中先选择时钟源


3.设置预分频


4.允许中断和溢出位清零


5.使能Timer1


虽然看起来简单,但是Timer1的功能比Timer0多,好些自己也没有用到过,有一个注意的地方,TMR1H和TMR1L的初值设定最好刚刚把延时拿回来就行了。使能也应该放最后,刚好需要起振时间



最后最后,1937里面最多的定时器,数量超过我的想象,竟然多达,,竟然拥有3个!!何等的数量啊。。。。。好了,不装怪了,他是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() //时钟是系统指令时钟 Fosc/4,沿边沿递增计数。

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是无法自己选择内外部时钟的,系统选什么他就得选什么,作为对比,TIMER0和TIMER1是可以自己选的,素晴らしい!



所有的时钟设置总结来说,必须考虑的要素有以下几条


1.设置时钟,系统时钟和定时器要用的时钟(TIMER0和TIMER1是可以选的)

2.预分频及后分频,所有时钟里TIMER0的预分频最大(1:2-1:256),TIMER2/4/6既有预分频又有后分频

3.TMRxIE、PEIE、GIE(允许TIMERx中断、允许外设中断、允许所有有效中断),这三个的赋值。除PEIE在TIMER0中没有也可以运作外,其他两个在每个定时器中必须有

4.TMRxIF,溢出的标志位,一般会在中断程序里面清零,所以在初始化里面可有可无。

5.计数的设置TIMER0中的TMRO(0-255),TIMER1中的TMR1H和TMR1L,TIMER2/4/6中的TMRx(0-PRx),PRx(0-255)


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭