TimerA定时器
连续计数模式:
/******************************************************************************
题目:如果SMCLK=80KHZ,要产生频率为16HZ的方波,那么CCR取80k/16=50000
******************************************************************************/
#include <msp430x42x0.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0x01; // P1.0 output
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 50000; // interrupt 50000 times /every SMCLK periods
TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
}
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
P1OUT ^= 0x01; // Toggle P1.0
CCR0 += 50000; // Add offset to CCR0
}
/***********************************************************************
总结:连续计数模式:在65536个时钟周期的定时应用场合常用,定时器从当前值计数到0FFFFH后,又从0开始重新计数。
而增计数模式是TAR增计数到CCRx后,定时器复位重新计数,增/减计数模式则是先从0增计数到CCRx再减计数到0,计数周期仍有CCRx决定。
连续计数模式的一个典型应用是:产生多个定时信号,通过中断处理程序在相应的比较寄存器CCRx上加上一个时间差来实现,这个时间差(CCRx的值)是当前时刻到下一次中断发生时刻所经历的时间。
***************************************************************************/
增计数模式:
/*************************************************
题目:如果ACLK=32768,SMCLK=32*32768,产生个方波
****************************************************/
#include <msp430x42x0.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0x01; // P1.0 output
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 20000; //方波频率f=32*32768/20000/2=13.1072hz
TACTL = TASSEL_2 + MC_1; // SMCLK, up mode
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
}
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR
}
/******************************************************
PS:CCRx是增计数模式的周期寄存器,增计数模式适用于定时周期小于65536的连续计数情况。
通过改变CCRx的值可以改变计数周期,每达到时钟源半个周期的时候刚好的达到TAR与CCRx的值相等的时候,CCRx为多少就有多少个方波周期。
****************************************************************/
溢出模式:
/**************************************************************
溢出模式有关乎一个专业性的词汇,中断向量寄存器(TAIV)
在多源的中断中,Timer——A的中断请求寄存器TAIV用来确定中断请求的中断源。各位定义如下:
优先级 |
中断源 |
TAIV内容 |
最高
最低 |
捕获比较器1(CCIFG1) |
2 |
捕获比较器2(CCIFG2) |
4 |
|
…… |
|
|
定时器溢出 |
10 |
|
没有中断将挂起 |
0 |
*************************************************************/
#include <msp430x42x0.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
FLL_CTL0 |= XCAP14PF; // Configure load caps
P1DIR |= 0x01; // Set P1.0 to output direction
TACTL = TASSEL_2 + MC_2 + TAIE; // SMCLK, continual mode,enable interrupt
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
}
// Timer_A3 Interrupt Vector (TAIV) handler
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A(void)
{
switch( TAIV )
{
case 2: break; // CCR1 not used
case 4: break; // CCR2 not used
case 10: P1OUT ^= 0x01; // overflow 发生溢出
break;
}
}
/******************************************************************
PS:其实溢出也可以理解为增计数模式,将CCR0当成为0FFFFH就是了。
上述程序可理解为这样的题目:
假设ACLK=32768HZ,SMCLK=1.048576MHZ,因为选择的是SMCLK模式,所以产生频率为
F=1.048576/65536/2=8HZ 的方波。
***************************************************************/
PWM输出:
/****************************************************************
题目:假设ACLK=32768HZ,SMCLK=32*32768HZ.利用TimerA输出周期(CCR0设置)为512*1/32768ms
占空比(CCR1~4设置)为75%,25%。
***********************************************************************/
#include <msp430x42x0.h>
void main(void)
{
WDTCTL = WDTPW +WDTHOLD; // Stop WDT
FLL_CTL0 |= XCAP14PF; // Configure load caps
P1DIR |= 0x0C; // P1.2,3 output
P1SEL |= 0x0C; // P1.2,3 TA1 option
CCR0 = 512-1; // PWM Period
CCTL1 = OUTMOD_7; // CCR1 reset/set PWM复位/置位
CCR1 = 384; // CCR1 PWM duty cycle
CCTL2 = OUTMOD_7; // CCR2 reset/set
CCR2 = 128; // CCR2 PWM duty cycle
TACTL = TASSEL_1 + MC_1; // ACLK, up mode
_BIS_SR(LPM3_bits); // Enter LPM3
}
/********************************************************************
PS:如果TimerA定时器的计数器工作在增计数方式,输出,采用模式7(复位/置位模式),则可以利用寄存器CCR0控制PWM波形的周期(T=(CCR0+1)*时钟源的周期),用某个寄存器CCR1~4控制占空比(占空比a=CCRx/CCR0),这样TimerA就可以产生出任意占空比的PWM波形了。
***********************************************************************/
至于异步串行通信,下次写,^_^
2010-11-26
11:07:25