计时器的寄存器组
T1SC,T2SC:TIM状态寄存器
 
| PS2 | PS1 | PS0 | 计时器时钟 | PS2 | PS1 | PS0 | 计时器时钟 | 
| 0 | 0 | 0 | 内部总线时钟/1 | 1 | 0 | 0 | 内部总线时钟/16 | 
| 0 | 0 | 1 | 内部总线时钟/2 | 1 | 0 | 1 | 内部总线时钟/32 | 
| 0 | 1 | 0 | 内部总线时钟/4 | 1 | 1 | 0 | 内部总线时钟/64 | 
| 0 | 1 | 1 | 内部总线时钟/8 | 1 | 1 | 1 | 无效 | 
TMODH,TMODL:终止值预置寄存器
TMODH和TMODL和在一起组成一个四位十六进制数,如$9600,计数器复位后从
锁相环是什么?是一种倍频器,它将时钟基频(CGMXCLK)进行分频,产生PLL倍频信号(CGMVCLK),然而,由于它基础理论抽象,很难懂。本文以尽量简明的原则,帮大家学好锁相环初始值的设定
寄存器:
PCTL:锁相环控制寄存器 所在地址 $036
 
通过PRE预分频值查此表可计算出第三位,第二位值以及PRE值
| PRE1 | PRE2 | PRE值 | 预分频系数 | 
| 0 | 0 | 0 | 1 | 
| 0 | 1 | 1 | 2 | 
| 1 | 0 | 2 | 4 | 
| 1 | 1 | 3 | 8 | 
通过VCD电源系数查此表可计算出第一位,第零位以及VPR系数
| VPR1 | VPR0 | VPR值 | VCD电源系数 | 
| 0 | 0 | 0 | 1 | 
| 0 | 1 | 1 | 2 | 
| 1 | 0 | 2 | 4 | 
| 1 | 1 | 3 | 8 | 
其中PRE和VCD由fbus(内部时钟速率)确定,输出时钟为4*fbus,确定方式见下表
| Fbus | PMSH值 | PMSL值 | PMRS值 | PRE值 | VPR值 | 
| 2 | 0 | F5 | D1 | 0 | 0 | 
| 2.4576 | 1 | 2c | 80 | 0 | 1 | 
| 2.5 | 1 | 32 | 83 | 0 | 1 | 
| 4.0 | 1 | E9 | D1 | 0 | 1 | 
| 4.9152 | 2 | 58 | 80 | 0 | 2 | 
| 5.0 | 2 | 63 | 82 | 0 | 2 | 
| 7.3728 | 3 | 84 | C0 | 0 | 2 | 
| 8.0 | 3 | D1 | D0 | 0 | 2 | 
典型应用:
PCTL=0x00;//禁止PLL
PCTL=0x22;//00100010,开启PLL,选择PRE=0,VPR=1
PCTL_PLLON=1;//使能PLL
PCTL_BCS=1;//输出时钟分频选择
PBWC:PLL控制寄存器 所在地址 $037
| 地址 | 7 | 6 | 5 | |
| AUTO 带宽控制方式 | LOCK 带宽是否已稳定(只读) | |||
| 置1 | 自动 | 锁定 | ||
| 置0 | 手动 | 不锁定 | ||
| 默认 | 0 | 0 | 
还有几个寄存器,一般保持复位的值不变,知道即可
PMSH,PMSL:PLL倍率选择器 所在地址$038,$039
PMSH低四位有效,PMSL全部有效。复位后都为0
PMRS:电源范围系数 复位后为0
PMDS:PLL基时钟分频选择器 所在地址$3B
锁相环设置七步走:
(1) 禁止PLL:PCTL=0;
(2) 选择自动控制方式 PBWC=0x80;
(3) 设置分频系至PMSH和PMSL
(4) 设置输出范围系数至PMRS
(5) 根据典型参数表设置PCTL,其中包括PRE值(由Vpr1,Vpr0联合确定),VPR值(由PRE1,PRE0联合确定)和
锁相环使能PCTL_PLLON=1,等待稳定,稳定后,设PBWC_LOCK=0;
(6) 设置输出时钟为CGMVCLK的二分频PCTL_BCS=1
实例:
PCTL=0x00;//step1
PBWC=0x80;//step2
PMSH=0x02;//step3
PMSL=0x58;
PMRS=0x80; //step4
PCTL=0x22; //step5
PCTL_PLLON=1; //step6
PBWC_LOCK=0;
PCTL_BCS=1; //step7
注意锁相环要经过两次使能,如上所示PCTL=0x22; (第一次) PCTL_PLLON=1;(第二次)
其实作为初学,可以直接把典型的代码复制过来,如果想DIY的话,就通过“常用PLL系数表”进行设置即可。
开始工作,当工作到这个数值时产生中断,如果没有设置这个数,则按默认$ffff处理。TSC0,TSC1 :定时器通道状态和控制寄存器
有一些输入捕捉和输出比较等用的设置。暂时不提。
典型例子:
这个例子实现了一个以秒计时的秒表,每隔一秒钟产生一个定时器中断,在七段显示屏上显示出当前的秒数。并有LED灯相映闪烁,非常好看。
#include 
#include 
int counter=0;
int b1,b2,b3,b4,b5,b1r,b2r,b3r,b4r,b;
void main(void) {
CONFIG2=0x01;
CONFIG1=0x09;
T1SC=0b01000110; //溢出中断使能,总线分频/64
T1MODH=0x96;//9600是一秒钟的对应值。比如除以2可以得到0.5秒,以此类推
T1MODL=0x00;
b=0;
SPCR=0x3a;//七段数码管芯片通信初始化
SPSCR=0x01;
DDRD=0xff;//端口方向
DDRE=0xff;
EnableInterrupts;//开中断
for(;;){}//死循环
}
void delay(int k){//延时子程序
int i;
for (i=0;i<=k;i++);
}
void printLED(void){//显示到C口的LED上
counter++;
switch (counter) {
case 0:PTC=0b11111111;break;
case 1:PTC=0b11111110;break;
case 2:PTC=0b11111100;break;
case 3:PTC=0b11111000;break;
case 4:PTC=0b11110000;break;
case 5:PTC=0b11100000;
}
if (counter==5) counter=-1;
}
void printNum(void){//显示到数码管上
b++;
b1=(int)b/10000;b1r=(int)b%10000;
b2=(int)b1r/1000;b2r=(int)b%1000;
b3=(int)b2r/100;b3r=(int)b%100;
b4=(int)b3r/10;b4r=(int)b%10;
b5=(int)b4r;
PTE_PTE1=0;
SPDR=b1;
delay(5);
SPDR=b2*16+b3;
delay(5);
SPDR=b4*16+b5;
delay(5);
PTE_PTE1=1;
PTE_PTE1=0;
SPDR=0x01;
delay(5);
PTE_PTE1=1;
}
interrupt 6 void OverFlow(){//计时器中断,中断向量6
T1SC_TOIE=0;//计时器中断禁止
T1SC_TOF=0;//复位溢出标志
printLED();//显示到LED
printNum();//显示到数码管
T1SC_TOIE=1;//允许计时中断
}
//下载完毕请将PC0,PC1,PC3三个开关置于左侧