控制/MCU
AVR有三个定时计数器,其中定时计数器0和定时计数器2是8位的,定时计数器1是16位。
在学习AVR定时计数器时,刚开始被一大堆的寄存器搞的有点晕了,后来认真的把Datasheet中的有关寄存器先看了一遍,再重新看定时计数器的内容才理清了。这里做个总结吧,加深自己的印象。
定时计数器0和定时计数器2基本上是相同的。以定时计数器0来总结它的几种工作模式的不同。
普通模式:不做介绍,和51里面是一模一样的。
CTC模式:当寄存器TCNT0与OCR0相等时(即匹配),OC0按照COM0[1:0]的值相应的改变(置位,清零或取反)。同时TCNT0清零,TCNT0从0x00重新开始计数,当计数结果和下一个OCR0寄存器中值相等时又发生匹配。发生匹配时,匹配比较标志OCF0置位,即OCF0=1,可申请匹配比较中断。
快速PWM模式:当寄存器TCNT0与OCR0匹配相等时,OC0按照COM0[1:0]的值相应的置位或清零。与CTC模式不同的是TCNT0不会清零,而是继续计数,直到计数为0XFF,此时OC0会发生清零或置位。同时TCNT0从0x00重新开始计数,当计数结果和下一个OCR0寄存器中值相等时又发生匹配。与CTC模式不同发生匹配时,OCF0不会置位。TCNT0计数到0XFF时,计数溢出标志TOV0置位,即TOV0=1,此时可申请溢出中断。
相位可调PWM模式:此模式下,定时计数器是双向计数器(可加可减),,从0x00一直加到0xff,在下一个计数脉冲到来时从0xff一直减到0x00。当COM0[1:0]=2时,在加的过程中,若发生匹配,清零OC0;在减的过程中,若发生匹配,置位OC0。(当COM0[1:0]=3时,和COM0[1:0]=2的情况相反)。与快速PWM模式不同的是,当TCNT0计数到0xff时不会影响到OC0的输出,而是当从0xff减到0x00的过程中与下一个OCR0寄存器的值匹配时,OC0发生改变(加的过程是清零,那这时应该是置位)。当定时计数器计数到0x00时,计数溢出标志TOV0置位,即TOV0=1,此时可申请溢出中断。
以上几种工作模式同时适合定时计数器0,1,2。只是定时计数器1的功能有所增强。下面将会讨论。
星期二我看一个程序时候,那个程序是工作在快速PWM模式,选择计数溢出中断。当时我还想为什么不选择匹配中断而要去等到计数溢出才中断岂不是占用时间了,还去问老师了,现在看来是多么的愚蠢!快速PWM模式根本就没有匹配中断!
定时计数器0和2,在CTC模式下,频率和相位可调。PWM模式下,频率不可调。由频率计数公司就可以看出。不论是CTC还是PWM都可以通过调节OCRn的值去调节占空比。(关于产生PWM波频率的计算公式将会在后文给出的,关于定时计数器的各种寄存器可自己去查看Datasheet)
下面是定时计数器1比0和2的增强功能总结:
1)定时计数器1比0和2有许多增强功能。在PWM模式时,可产生频率和相位都可调的PWM波,这时8位定时计时器0和2所做不到的,因为定时计数器1具备输入捕获功能,即具备输入捕获寄存器ICR1,在PWM模式下,ICR1中可存放一个top值,就是这个top值可以改变PWM波的频率。这点可在频率计算公司看出。
2)定时计数器1有两个输出比较单元和两个输出比较寄存器OCR1A和OCR1B,因此可同时产生2路频率相同,占空比不同的PWM波形。占空比的调整当然由OCR1A和OCR1B来确定。波形在OC1A和OC1B引脚输出。
3)定时计数器1具有输入捕获单元。可以精确的记录外部事件发生的时间。捕获外部事件的信号由引脚ICP1输入。当输入捕获信号产生,TCNT1中的计数值将被写入输入捕获寄存器ICR1(ICR1H,ICR1L)中去。输入捕获信号也可由模拟比较器的AC0单元的输出信号来触发。关于触发的方式有两种,当定时计数器1的控制寄存器B(即TCCR1B)中的第六位ICESE=0,下降沿触发;ICESE=1,上升沿触发。当满足触发条件时,输入捕获单元开始捕获该事件的发生。利用该功能可以来对输入波形频率的测量。如果我没有记错的话在51里面定时计数器也有这个功能的,可以有GATE门控位的设置来达到这个目的。51里面,把GATE置位,那么此时定时计数器的启动由INTX(X=0或1)引脚和TRX(X=0或1)来决定。可先把TRX置位,让定时计数的启动条件还欠缺INTX为高电平(即先让INTX处于低电平),等待INTX变为高电平,那么此时定时计数器启动了,等到INTX变为低电平时定时计数器又被关闭了,那么此时定时计数器计数值即为一个PWM脉宽了。
说到这里突然想到了在AVR里面,定时计数器都有自己的分频器,这里也可以先设置定时计数器的启动条件都满足,但设置为无分频,此时相当于人没有了心脏,定时计数器此时是不工作的。可以在其他什么条件(如一个外部中断里面)满足时,给定时计数器分频,此时定时计数器才工作!
刚才说到中断,与51不同的是,AVR对中断标志位清“0”的操作时向该位写“1”。即AVR清除中断标志位是软件写“1”。值得提醒的是在设置中断寄存器的时候,最好先清除中断标志位,然后马上将相应的中断允许控制位值“1”。
这里还需要说明的是上文提及到的定时计数器波形输出引脚和输入捕获引脚,在使用之前,必须要先设置好它的方向寄存器是输出还是输入。如果是输入的话还需要考虑是否需要上拉电阻。
说了这么多,差点忘记了个人觉得比较重要的一点。定时计数器1是16位的,它的每一个16位的寄存器分别配备了一个8位的TEMP寄存器,用来临时性的保留寄存器的高8位数据。MCU从16位寄存器读数据时时,低8位被送到MCU的同时,高8位被送到TEMP,当MCU读高8位时取的是TEMP中的数据。从MCU写数据16位数据寄存器时,高8位写到TEMP,写低8位的时候,低8位与TEMP中的高8位组成16位数据写到16位寄存器中。即读的时候是先读低8位,再读高8位;写的时候是先写高8位,再写低8位。
最后给出定时计数器常用3种工作模式的设置方法(以定时计数器1为例):
普通模式:
1,根据需要设置时钟源,即设置控制寄存器TCCR1B。
2,根据定时时间和时钟源确定定时器的初值写入到数据寄存器TCNT1H和TCNT1B。
3,设置中断时能位。
4,选择中断号,编写中断服务程序。注意需要在中断服务程序中重载初值写入到TCNT1H和TCNT1B(和51一样的)!
CTC模式:
1,若输出波形,设置端口OC1A或OC1B为输出方式。
2,设置波形发生模式,选择需要的时钟源,即TCCR1B。
3,设置输出模式,即TCCR1A。
4,根据需要设置上限值top(前面提到过的)写入到输出比较寄存器OCR1A。
5,根据公式计算频率。
快速PWM模式:
1,若输出波形,设置端口OC1A或OC1B为输出方式。
2,设置PWM波形模式,选择需要的时钟源,即TCCR1A和TCCR1B。
3,设置波形的频率,即OCR1A。
4,设置波形占空比,即OCCR1B。
6,根据频率公式计算频率。
全部0条评论
快来发表一下你的评论吧 !