msp430入门学习21--TA
MSP430的Timer_A是单片机中一个很重要的外设,结合官方文档和例程,因此做此文。
一、单片机的Timer_A我把它分为三个层次,硬件底层,应用抽象层,应用层,分别说明:
Timer_A硬件底层:
1、定时器/计时器,主要对选定的时钟计数
2、捕获器/比较器,完成对输入信号的处理
为什么这么设置:
0、ti的msp430单片机中Timer_A拥有中断;
1、DCO作为RC振荡器,主要通过对RSELx的配置实现频段的选择,而后通过DCOx实现频率的粗调,通过MODx的混频实现振荡频率的细调,通过DCOR实现配置电阻的内外选择,
2、DCO振荡器却不够精确,但是有比没有强很多的,主要就是在单片机工作中外接的时钟电路出了问题,可以及时用内部的振荡器电路,相当于对时钟电路做了个备份,单路更可靠;
3、为了解决DCO不够精确的问题,就允许用户外接时钟,引入了XT1震荡电路可以在800k~8MHz间的晶振,
1)为了监测外接晶振有问题,设置了中断标志:OFIFG位,当外接晶振有问题时,及时启用DCO;
2)为了省电设置了SCG0位,置位时,允许用户关闭DCO;
3)为了更进一步省电,设置了SCG1位,置位时,允许用户关闭CPU,这样当只用外设时,允许用户关闭CPU
4)为了进一步省电,将外设分为高速和低速外设,低速外设的晶振可以设置为32.768KHz,因此XT1可以在低频模式下,为了区分高频和低频的时钟晶振,将XT1标明为LFXT1,可以通过设置XTS为设置LFXT1工作在高频模式下
5)后来引入了XT2振荡电路,自然要加上2了,因为在原来XT1的基础上加的,只不过我们现在都习惯将XT1称为LFXT1,XT2主要用于高频晶振,XT2OFF置位时,不使用XT2振荡器;复位时才打开XT2振荡器
应用抽象层:LFXT1CLK、SMCLK和MCLK
4、LFXT1相关的寄存器位:
1)OSCOFF置位时,关闭LFXT1时钟电路
2)XTS置位时,LFXT1在高频模式,XTS复位时,LFXT1在低频模式
3)DIVAx有两位,
00时 分频系数为1,
01时 分频系数为2
10时 分频系数为4
11时 分频系数为8
5、SMCLK相关的寄存器位:
1)SELS选择SMCLK的时钟源,
SELS置位时,SMCLK选择的时钟源为外接振荡器,
当XT2振荡器存在时优先用XT2振荡器;
当XT2振荡器不存在时,就用LFXT1振荡器;
SELS复位时,SMCLK选择的时钟源为DCO振荡器
2)DIVSx有两位,配置SMCLK的分频系数
00时 分频系数为1,
01时 分频系数为2
10时 分频系数为4
11时 分频系数为8
5、MCLK相关的寄存器位:
1)SELMx有两位,选择MCLK的时钟源
00时 选择DCO振荡器为时钟源,
01时 选择DCO振荡器为时钟源,
10时 选择XT2振荡器,如果XT2振荡器不在时,选择LFXT1振荡器为时钟源,
11时 选择LFXT1振荡器为时钟源,
2)DIVMx有两位,配置MCLK的分频系数
00时 分频系数为1,
01时 分频系数为2
10时 分频系数为4
11时 分频系数为8
6、DCO相关的寄存器位:
图一 振荡频率示意图
1)RSELx有三位,选择DCO振荡器的输出频段
000时 如图一所示的RSEL=0的频段,
001时 如图一所示的RSEL=1的频段,
010时 如图一所示的RSEL=2的频段,
011时 如图一所示的RSEL=3的频段,
100时 如图一所示的RSEL=4的频段,
101时 如图一所示的RSEL=5的频段,
110时 如图一所示的RSEL=6的频段,
111时 如图一所示的RSEL=7的频段,
2)DCOx有三位,细分DCO的频率点
000时 如图一所示的DCO=0的频段,
001时 如图一所示的DCO=1的频段,
010时 如图一所示的DCO=2的频段,
011时 如图一所示的DCO=3的频段,
100时 如图一所示的DCO=4的频段,
101时 如图一所示的DCO=5的频段,
110时 如图一所示的DCO=6的频段,
111时 如图一所示的DCO=7的频段,
3)MODx有五位,进一步配置混频系数,公式为:
t = (32 - MODx)* tDCO + MODx * tDCO+1
公式说明:t表示混频后振荡信号的周期;
MODx就是MODx五位寄存器中对应的10进制数值;
tDCO就是混频中的低频信号的周期;
tDCO+1就是混频中的高频信号的周期;
Timer_A
1 #include <msp430f169.h> 2 3 int main(void) 4 { 5 WDTCTL = WDTPW + WDTHOLD; //停止看门狗 6 P6DIR |= 0x01; // P6.0设置为输出 7 P6OUT |= 0x01; // P6.0设置为高电平,灯灭 8 9 TACCTL0 = CCIE; // CCR0允许中断 10 TACCR0 = 30000; 11 //TACTL = TASSEL_2 + MC_2 + ID_2; //时钟选择SMCLK,4分频, 计数模式为连续计数 12 TACTL = TASSEL_1 + MC_2 + ID_3; //时钟选择ACLK,8分频, 计数模式为连续计数 13 P5DIR |= 0x70; //打开时钟输出接口,选择为输出 14 P5SEL |= 0x70; //打开时钟输出接口,选择为第二功能 15 16 //__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt 17 18 _EINT(); 19 LPM0; 20 } 21 22 // Timer A0 interrupt service routine 23 24 #pragma vector=TIMERA0_VECTOR 25 __interrupt void Timer_A(void) 26 { 27 P6OUT ^= 0x01; // Toggle P1.0 28 CCR0 += 30000; // Add Offset to CCR0 29 }
例如在上述代码:
当没有混频时,将第8行注释,DCOx=3, RSELx=4时,DCO的频率fDCO=816.32kHz
当没有混频时,将第8行注释,第9行用第10行代替,DCOx=4, RSELx=4时,DCO的频率fDCO=1.24MHz
当有混频时,DCOx=3, RSELx=4时,DCO的混频后的频率fDCO=810kHz、860kHz、890kHz等,可见的确混频了。
MODx=16,
3)DCOR配置DCO是否使用外置电阻,置位时使用外部电阻,复位时使用内部电阻,使用外部电阻时可以提高振荡器的输出频率,减少DCO振荡器受温度影响的情况,但是不能超过振荡器的振荡频率的最大值。
msp430的时钟设置说明:
程序非常简单,说明如下:
一、设置ACLK,没有代码,主要使用寄存器相应位的默认值:
XTS=0,使用LFXT1的低频模式,DIVAx=0,不分频,因此ACLK的波形为:fACKL=32KHz
二、设置SMCLK,没有代码,主要使用寄存器相应位的默认值:
SELS=0,默认时钟源为DCO振荡器
DIVx=0默认不分频
在PUC或POR后,
RSELx=4,选择频段为4
DCOx=3,选择频率点为3
MODx=0,默认不混频,也就是用低频
DCOR=0,默认使用内部电阻,因此fDCO=810KHz
三、设置MCLK,使用时钟源为XT2高频时钟,主要使用寄存器相应位为:
XT2OFF=0,打开XT2振荡器
SELMx=2,选择XT2时钟源,将时钟源由DCO切换到外部晶振时,必须确定清除了振荡错误标志位,具体就是必须使用9~15行货16~23行的代码,最后加上第24行的代码,进行再次清除振荡器振荡错误标记;
DIVMx=3,将MCLK8分频
在PUC或POR后,
RSELx=4,选择频段为4
DCOx=3,选择频率点为3
MODx=0,默认不混频,也就是用低频
SELMx=0,选择时钟源为DCO振荡器,或者OFIFG--振荡错误标志存在时也选择为DCO振荡器
DIVMx=0,MCLK不分频
好了,终于写完了。