计时器的寄存器组
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三个开关置于左侧