全部博文(321)
分类: 嵌入式
2014-05-14 23:15:46
定时器:
1.五个16位定时器:定时器4单纯作为定时使用(无反转TCMPB),其他四个:单纯定时使用,控制外围设备。
2.定时器0,死区:主要用在控制大电流的开关上。
3.定时器值写入定时器计数缓冲寄存器(TCNTBn),即是放次数,我们要数多少次。可自动加载。是个递减计数器。
4.每个定时器有个输出引脚,若TCNTBn数到与TCMPB的值相等的话(不是数TCMPB的次数。假设100,tcmpb=40,则需要数60次才到40),电平反转。
5.频率由预分频器(共两个)来决定,8(0-255)位预分频器,使频率减低。新频率=旧频率/预分频器+1;TCLK分频器则分配比例固定。而真正的频率是要经过预分频器和分频器的分频。P285
6.作为DMA来使用,则不会产生中断。
7.从定时器计数监视器寄存器 (TCNTOn)读取当前定时器的值
8.TCNTBn(50+110),110为TCMPBn,,比较寄存器,电平反转。
9.这边的DMA请求为专用的DMA
10.rTCFG0==(0xFF<<8); 预分频器 //256=255+1;因为我们要用一个整数倍比较好算,所 以用2^8
11.rTCFG1=(0x0<<20)|(1<<16)除法器;选通输入1/2^2.刚好与上凑成2^10;
12.rTCON=(0<<22)|(1<<21)|(0<<20);其中:记得先写入rTCFG0,rTCFG1,再手动加载, 顺序最好不要乱。12,一定要在10.11后面
msec=(msec == 0)?1:msec;//msec为毫秒级。//1ms产生一次中
rTCNTB4 = msec*0.001*(50000000>>10);次数=T/一次的周期//*0.001,因为hz的倒数秒
总的时间T=一次的周期tf*次数n=1/f*次数=1/(50000000>>50)*次数
13.中断。。挂起。。中断函数
14.rTCON=(1<<22)|(0<<21)|(1<<20);。这个时候才打开。如果前面就打开,定时器就开 始工作了。所以要等全部准备完毕再打开。
11.定时器4,开启计时,时间一到则产生中断,则跳到中断处理函数
(
rTCNTB4 = msec*0.001*(50000000>>10);//1ms产生一次中断
rSRCPND |= BIT_TIMER4;写1清0
rINTPND |= BIT_TIMER4;
之后还要把手动加载改为自动加载,同理time0)
12.pISR_TIMER4 = (unsigned int)Timer4_sev;中断处理函数
{
rSRCPND |= BIT_TIMER4;写1清0
rINTPND |= BIT_TIMER4;
if(timer1mscnt)
timer1mscnt--;//static volatile unsigned int timer1mscnt
}
13.delay1s,通过timer1mscnt控制 注意:timer1mscnt更新很快,所以一定要用volatile,否则很容易出错。。
14.定时器原理:当配置完所有寄存器时,rTCON才开启,此时定时器就开始在工作了,至于多久产生一次中断,参数由我们之前写进去,1ms。所以1ms的时候就会进入中断函数处理。而我们外部调用定时器void delay1ms(unsigned int wait)的时候有传一个timer1mscnt的volatile全局变量,同时这个timer1mscnt也传给中断处理函数,通过中断处理函数来对他减减,两个函数同步,delay1s用while(1)记录,当在中断处理函数里面的timer1mscnt减到0的时候,delay1ms()函数中的while(1)也break.。