msp430学习

jdk1024   2011-11-18 18:10 楼主
430F2xxx的TA是一个16位的定时器/计数器,有3个"捕获/比较寄存器",定时器(TA)与"捕获/比较寄存器"(CCRx)工作是相对独立的.

计数器TAR三种模式(增计数,连续计数,增减计数)。分设置MC1、MC0位,设置后,TA就开始计数了。上电默认为MC1=0,MC0=0为停止。
那么欲定时一段时间周期的话,可以有两种方法:一是TA计数,计到一定值产生TA中断;二是用CCRx和计数值比较,一致的话产生CCRx中断.(比较模式,也是上电默认模式)中断。每当一定的时间间隔都会产生中断请求,那么,需将下一事件发生的时间在当前的中断程序中加到CCRx中。见程序:

#include "msp430x22x4.h"
int main( void )
{
WDTCTL=WDTPW+WDTHOLD;
BCSCTL1=CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
TACTL=TASSEL1+TACLR;//SMCLK=VLOCLK=12KHZ,清楚TAR
CCTL0=CCIE;//中断允许
CCR0=50000;//方波频率:1m/50000
P1DIR|=BIT0;
TACTL|=MC1;//连续计数
_EINT();
_BIS_SR(LPM0_bits);
return 0;
}

#pragma vector=TIMERA0_VECTOR
__interrupt void TIMER_A(void)
{
P1OUT^=BIT0;
CCR0+=50000;
}

捕获模式: 位于控制字CCTLX中的模式位CAPX的置位将选择捕获模式。 捕获模式用于时间的精确定位,她可以用在速度计算或时间测量中.若在选定的输入引脚上发生选定脉冲触发沿.则定时器计数的值将被复制到捕获寄存器CCRX中.完成捕获后。控制字CCTLX中的中断标志CCIFGX置位。如果通用中断允许位GIE和相应的中断标志位CCIEX置位,则产生中断请求.复位表示在下一次捕获完成前捕获数据已被读取.如果捕获数据还未读取时第二次捕获数据已锁存,则寄存器CCTLX中的溢出位COVX置位,检查这一位可以使程序从失去同步状态中恢复.需要用软件来复位COVX.

定时器暂停时捕获应该停止.顺序应是先停止捕获功能,再停止定时器计数.捕获功能重新开始时,顺序应先开始捕获功能,再开始定时器计数.
附程序:

#include "msp430x22x4.h"
volatile unsigned int cap_value; //存两次捕值之差
int main( void )
{
volatile unsigned int first_value,second_value,n,max=10;
WDTCTL=WDTPW+WDTHOLD; //关看门狗
BCSCTL1 =CALBC1_8MHZ; //设定DCO为1MHZ
// DCOCTL =CALBC1_8MHZ;
DCOCTL = CALDCO_8MHZ;
BCSCTL1 |=DIVA_3; //ACLK输入八分频
do //等待晶振稳定
{
IFG1 &=~OFIFG;
for(n=5;n>0;n--,max--);
if(max<=0)
{
BCSCTL3|=LFXT1S1;//aclk来源于VLO
break;
}
} while(OFIFG&IFG1);

TACCTL2=CM1+CCIS_1+CAP; //捕获模式,捕获上升沿,捕获内部ACLK
TACTL=TASSEL_2+MC_2+TACLR; //定时器时钟源为SMCLK,启动连续计数,清TAR
TACCTL2 &=~CCIFG; //清CCR2的标志位
while(!(CCIFG&TACCTL2)); //查CCR2标志位
first_value=TACCR2; //第一个捕获值存入first_value
TACCTL2 &=~CCIFG; //清CCR2的标志位
while(!(CCIFG&TACCTL2)); //查CCR2标志位
second_value=TACCR2; //第二个捕获值存入second_value
TACCTL2 &=~CCIFG; //清CCR2的标志位
TACCTL2 &=~MC1; //关定时器A
cap_value=(second_value-first_value);
return 0;
}

通过比较模式,输出得到PWM波形( 脉宽调制,PWM是一种对模拟信号电平进行数字编码的方法,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。)TimerA可以得到两路,分别以CCR0位计数周期。设置CCR1,CCR2的值(小于CCR0)形成一定的占空比。输出时候将IO口设置为外部模块输出。

附程序:

int main( void )
{
WDTCTL=WDTPW+WDTHOLD; //关看门狗
BCSCTL1 =CALBC1_1MHZ; //设定DCO为1MHZ
DCOCTL = CALDCO_1MHZ;
TACTL=TASSEL1+TAR; //SMCLK为时钟源,清TAR
CCR0=512; //设定PWM周期
CCTL1 |=OUTMOD_7; //CCR1输出为reset/set模式
CCR1=384; //CCR1的PWM占空比设定
CCTL2 |=OUTMOD_7; //CCR2输出为reset/set模式
CCR2=128; //CCR2的PWM占空比设定
P1SEL |=BIT2+BIT3; //TA1,TA2输出功能
P1DIR |=BIT2+BIT3;
TACTL |=MC0; //启动定时器A增计数模式
_BIS_SR(CPUOFF);
return 0;
}

中断:

Two interrupt vectors are associated with the 16-bit Timer_A module:
TACCR0 interrupt vector for TACCR0 CCIFG
TAIV interrupt vector for all other CCIFG flags and TAIFG
In capture mode any CCIFG flag is set when a timer value is captured in the
associated TACCRx register. In compare mode, any CCIFG flag is set if TAR
counts to the associated TACCRx value. Software may also set or clear any
CCIFG flag. All CCIFG flags request an interrupt when their corresponding
CCIE bit and the GIE bit are set.

The TACCR1 CCIFG, TACCR2 CCIFG, and TAIFG flags are prioritized and
combined to source a single interrupt vector. The interrupt vector register TAIV
is used to determine which flag requested an interrupt.

For example:
//******************************************************************************
// MSP430F22x4 Demo - Timer_A, Toggle P1.0-3, Cont. Mode ISR, 32kHz ACLK
//
// Description: Use Timer_A CCRx units and overflow to generate four
// independent timing intervals. For demonstration, TACCR0, TACCR1 and TACCR2
// output units are optionally selected with port pins P1.1, P1.2 and P1.3
// in toggle mode. As such, these pins will toggle when respective TACCRx
// registers match the TAR counter. Interrupts are also enabled with all
// TACCRx units, software loads offset to next interval only - as long as the
// interval offset is added to TACCRx, toggle rate is generated in hardware.
// Timer_A overflow ISR is used to toggle P1.0 with software. Proper use
// of the TAIV interrupt vector generator is demonstrated.
// ACLK = TACLK = 32kHz, MCLK = SMCLK = default DCO ~1.2MHz
// //* An external watch crystal on XIN XOUT is required for ACLK *//
//
// As coded and with TACLK = 32768Hz, toggle rates are:
// P1.1 = TACCR0 = 32768/(2*4) = 4096Hz
// P1.2 = TACCR1 = 32768/(2*16) = 1024Hz
// P1.3 = TACCR2 = 32768/(2*100) = 163.84Hz
// P1.0 = overflow = 32768/(2*65536) = 0.25Hz
//
// MSP430F22x4
// -----------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// | P1.1/TA0|--> TACCR0
// | P1.2/TA1|--> TACCR1
// | P1.3/TA2|--> TACCR2
// | P1.0|--> Overflow/software
//
// A. Dannenberg
// Texas Instruments Inc.
// April 2006
// Built with IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include "msp430x22x4.h"

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1SEL |= 0x0E; // P1.1 - P1.3 option select
P1DIR |= 0x0F; // P1.0 - P1.3 outputs
TACCTL0 = OUTMOD_4 + CCIE; // TACCR0 toggle, interrupt enabled
TACCTL1 = OUTMOD_4 + CCIE; // TACCR1 toggle, interrupt enabled
TACCTL2 = OUTMOD_4 + CCIE; // TACCR2 toggle, interrupt enabled
TACTL = TASSEL_1 + MC_2 + TAIE; // ACLK, contmode, interrupt enabled

__bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A0(void)
{
TACCR0 += 4; // Add Offset to TACCR0
}

// Timer_A3 Interrupt Vector (TAIV) handler
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1(void)
{
switch (__even_in_range(TAIV, 10)) // Efficient switch-implementation
{
case 2: TACCR1 += 16; // Add Offset to TACCR1
break;
case 4: TACCR2 += 100; // Add Offset to TACCR2
break;
case 10: P1OUT ^= 0x01; // Timer_A3 overflow
break;
}
}

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复