现在在做的温控部分算法,需要每隔0.25s采集一次温度数据,然后计算出相应的控制量,并以PWM的形式输出。为了实现这个功能,时钟系统是不可或缺的,现就MSP430F5438A的时钟系统进行研究。

MSP430F5438A 里面有三个计时器,如下图所示

这三个计时器为TA0,TA1,TB0。TA0有5个capture/compare 寄存器, TA1有3个, TB0 有7个。

TA0 is a 16-bit timer/counter (Timer_A type) with five capture/compare registers. It can support multiple capture/compares, PWM outputs, and interval timing. It also has extensive interrupt capabilities. Interrupts may be generated from the counter on overflow conditions and from each of the capture/compare registers.

也就是说TA0计时器可以实现计时功能,也可以产生大量的中断,这些中断可以来自于计数器的溢出和每一个capture/compare寄存器。

好了,现在可以来深入了解这些东西了。

 

Timer_A features include:
• Asynchronous 16-bit timer/counter with four operating modes
• Selectable and configurable clock source
• Up to seven configurable capture/compare registers
• Configurable outputs with pulse width modulation (PWM) capability
• Asynchronous input and output latching
• Interrupt vector register for fast decoding of all Timer_A interrupts

 就像其他的模块一样,Timer_A模块同样需要选择时钟,也需要选择模式。这些都需要寄存器的控制,现将一些主要的寄存器列在下面:

(1) TAxCTL : 定时器控制寄存器。主要包括定时器时钟的选择,模式控制,定时器清零和定时器终端使能和标志位的功能。

(2)TAxR :这个寄存器用来存储Timer_A的计数量。

(3)TAxCCTLn: Timer_A capture/compare 寄存器控制寄存器。这个寄存器用以控制Timer_A寄存器(TAxCCRn),主要包括capture mode , output mode ,interrupt enable 等一系列内容。

(4)TAxCCRn: 比较模式:Timer_A 计时器的值

                     捕捉模式:is copied into the TAxCCRn register when a capture is performed.

 

 (5) TAxIV: Timer_Ax中断向量寄存器

 

好了,大体就需要了解这么多,先写一段程序验证一下这些功能。

一:使用定时器控制LED的闪烁(在P11.0上连着一个红色led等,当P11.0=0时,灯亮)

#include "msp430x54x.h"

 

void main(void)

{

  WDTCTL = WDTPW + WDTHOLD; // Stop WDT

  P11DIR |= 0x01; // P11.0 output

  TA1CCTL0 = CCIE; // CCR0 interrupt enabled

  TA1CCR0 = 50000;

  TA1CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR

 

  __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts

  __no_operation(); // For debugger

}

 

// Timer A0 interrupt service routine

#pragma vector=TIMER1_A0_VECTOR

__interrupt void TIMER1_A0_ISR(void)

{

  P11OUT ^= 0x01; // Toggle触发 P1.0

}

 每次TARx计数到50000闪烁一次。事实证明,红色led灯闪烁。

二:使用定时器产生PWM的波形

比如我想要的到一个周期约为10ms,占空比为1/5的方波波形。

#include "io430x54xA.h"

//这个函数用来产生5MHz的时钟信号
void InitClock()
{
P1DIR |= BIT0;
P1SEL |= BIT0; //ACLK output,这时候可以使用示波器观察时钟信号

UCSCTL3 |= SELREF_2; // FLLref = REFO
UCSCTL4 = SELM__DCOCLKDIV + SELS__DCOCLKDIV + SELA__DCOCLKDIV;// 时钟来源:主系统时钟来源DCOCLKDIV;子系统时钟来源DCOCLKDIV;辅助系统时钟来源DCOCLKDIV
UCSCTL5 |= DIVM__1 + DIVS__1 + DIVA__1; // 分频:主系统时钟1分频;子系统时钟1分频;辅助系统时钟1分频

__bis_SR_register(SCG0); // Disable FLL
UCSCTL1 = DCORSEL_6; // 10.7MHz<Fdco<39MHz
UCSCTL2 |= FLLD__2 +151 ; // 5MHz DCOCLKDIV Fdco/4
__bic_SR_register(SCG0); // Enable FLL

// 等待错误标志清除,振动器稳定
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}


//初始化Timer_A

void Init_Timer_A()
{


P2DIR |= 0x04; // P2.2  output

P2SEL |= 0x04; // P2.2  options select

TA1CCR0 = 50000; // PWM Period 约为10ms

TA1CCTL1 = OUTMOD_3; // CCR1 set/reset

TA1CCR1 = 40000; // CCR1 PWM duty cycle 1/5

//TA1CCTL2 = OUTMOD_7; // CCR2 reset/set

//TA1CCR2 = 128; // CCR2 PWM duty cycle

TA1CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, up mode, clear TAR

}



void main(void)

{

WDTCTL = WDTPW + WDTHOLD; // Stop WDT

InitClock();

Init_Timer_A();

__bis_SR_register(LPM0_bits); // Enter LPM0

__no_operation(); // For debugger

 

}

 示波器检测结果为:

由此可以看出,输出的波形周期约为10ms,占空比约为1/5 。

 

其他的问题就具体考虑就ok。