The temperature control algorithm we are working on now needs to collect temperature data every 0.25s, then calculate the corresponding control amount and output it in the form of PWM. In order to achieve this function, the clock system is indispensable, and the clock system of MSP430F5438A is now studied.
There are three timers in the MSP430F5438A, as shown in the figure below
The three timers are TA0, TA1, and TB0. TA0 has 5 capture/compare registers, TA1 has 3, and TB0 has 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.
That is to say, the TA0 timer can realize the timing function and can also generate a large number of interrupts, which can come from the overflow of the counter and each capture/compare register.
Okay, now it’s time to dig deeper into this stuff.
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
Like other modules, the Timer_A module also needs to select the clock and mode. These all require register control. Some of the main registers are listed below:
(1) TAxCTL: Timer control register. Mainly includes the timer clock selection, mode control, timer clearing, timer terminal enable and flag functions.
(2)TAxR: This register is used to store the count of Timer_A.
(3)TAxCCTLn: Timer_A capture/compare register control register. This register is used to control the Timer_A register (TAxCCRn), mainly including capture mode, output mode, interrupt enable and other contents.
(4)TAxCCRn: Compare mode: Timer_A value
Capture mode: is copied into the TAxCCRn register when a capture is performed.
(5) TAxIV: Timer_Ax interrupt vector register
Okay, that's all you need to know. Let's write a program to verify these functions.
1: Use a timer to control the flashing of the LED (connect a red LED to P11.0, and when P11.0=0, the light is on)
#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 trigger P1.0
}
It flashes once every time TARx counts to 50000. It turns out that the red LED is flashing.
2: Use the timer to generate PWM waveform
For example, I want a square wave with a period of about 10ms and a duty cycle of 1/5.
#include "io430x54xA.h"
//This function is used to generate a 5MHz clock signal
void InitClock()
{
P1DIR |= BIT0;
P1SEL |= BIT0; //ACLK output, you can use an oscilloscope to observe the clock signal
UCSCTL3 |= SELREF_2; // FLLref = REFO
UCSCTL4 = SELM__DCOCLKDIV + SELS__DCOCLKDIV + SELA__DCOCLKDIV; // Clock source: main system clock source DCOCLKDIV; subsystem clock source DCOCLKDIV; auxiliary system clock source DCOCLKDIV
UCSCTL5 |= DIVM__1 + DIVS__1 + DIVA__1; // Frequency division: main system clock divided by 1; subsystem clock divided by 1; auxiliary system clock divided by 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
// Wait for the error flag to be cleared and the oscillator to be stabledo
{
UCSCTL7
&= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
//Initialize Timer_A
void Init_Timer_A()
{
P2DIR |= 0x04; // P2.2 output
P2SEL |= 0x04; // P2.2 options select
TA1CCR0 = 50000; // PWM Period is about 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
}
The oscilloscope test results are:
From this we can see that the output waveform period is about 10ms and the duty cycle is about 1/5.
Other issues can be considered in detail.
|