首页 > 技术文章 > MSP430-定时器A相关库函数

SergeyuiL 2022-03-13 00:29 原文

0、宏定义

  • 基地址(baseAddress)
#define TIMER_A1_BASE          __MSP430_BASEADDRESS_T1A3__
  • 定时器模式
#define TIMER_A_STOP_MODE                                                  MC_0
#define TIMER_A_UP_MODE                                                    MC_1
#define TIMER_A_CONTINUOUS_MODE                                            MC_2
#define TIMER_A_UPDOWN_MODE                                                MC_3

1、API函数

开启定时器A计数器

void Timer_A_startCounter(uint16_t baseAddress, uint16_t timerMode);

配置定时器A的连续模式

void Timer_A_initContinuousMode(uint16_t baseAddress, Timer_A_initContinuousModeParam ∗param)
typedef struct Timer_A_initContinuousModeParam{
    //! Selects Clock source.	选择时钟源
    //! \n Valid values are:
    //! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]
    //! - \b TIMER_A_CLOCKSOURCE_ACLK
    //! - \b TIMER_A_CLOCKSOURCE_SMCLK
    //! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK
    uint16_t clockSource;
    //! Is the desired divider for the clock source	  选择分频系数
    //! \n Valid values are:
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64
    uint16_t clockSourceDivider;
    //! Is to enable or disable Timer_A interrupt	使能中断
    //! \n Valid values are:
    //! - \b TIMER_A_TAIE_INTERRUPT_ENABLE
    //! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default]
    uint16_t timerInterruptEnable_TAIE;
    //! Decides if Timer_A clock divider, count direction, count need to be		定时器是否跳过清零
    //! reset.
    //! \n Valid values are:
    //! - \b TIMER_A_DO_CLEAR
    //! - \b TIMER_A_SKIP_CLEAR [Default]
    uint16_t timerClear;
    //! Whether to start the timer immediately	是否立即开始计时器
    bool startTimer;
} Timer_A_initContinuousModeParam;

配置定时器A的上升模式

void Timer_A_initUpMode(uint16_t baseAddress, Timer_A_initUpModeParam ∗param)
typedef struct Timer_A_initUpModeParam{
    //! Selects Clock source.
    //! \n Valid values are:
    //! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]
    //! - \b TIMER_A_CLOCKSOURCE_ACLK
    //! - \b TIMER_A_CLOCKSOURCE_SMCLK
    //! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK
    uint16_t clockSource;
    //! Is the desired divider for the clock source
    //! \n Valid values are:
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64
    uint16_t clockSourceDivider;
    //! Is the specified Timer_A period. This is the value that gets written
    //! into the CCR0. Limited to 16 bits[uint16_t]
    uint16_t timerPeriod;
    //! Is to enable or disable Timer_A interrupt
    //! \n Valid values are:
    //! - \b TIMER_A_TAIE_INTERRUPT_ENABLE
    //! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default]
    uint16_t timerInterruptEnable_TAIE;
    //! Is to enable or disable Timer_A CCR0 captureComapre interrupt.
    //! \n Valid values are:
    //! - \b TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE
    //! - \b TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE [Default]
    uint16_t captureCompareInterruptEnable_CCR0_CCIE;
    //! Decides if Timer_A clock divider, count direction, count need to be
    //! reset.
    //! \n Valid values are:
    //! - \b TIMER_A_DO_CLEAR
    //! - \b TIMER_A_SKIP_CLEAR [Default]
    uint16_t timerClear;
    //! Whether to start the timer immediately
    bool startTimer;
} Timer_A_initUpModeParam;

配置定时器A的上升下降模式

void Timer_A_initUpDownMode(uint16_t baseAddress, Timer_A_initUpDownModeParam ∗param)
typedef struct Timer_A_initUpDownModeParam{
    //! Selects Clock source.
    //! \n Valid values are:
    //! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]
    //! - \b TIMER_A_CLOCKSOURCE_ACLK
    //! - \b TIMER_A_CLOCKSOURCE_SMCLK
    //! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK
    uint16_t clockSource;
    //! Is the desired divider for the clock source
    //! \n Valid values are:
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64
    uint16_t clockSourceDivider;
    //! Is the specified Timer_A period
    uint16_t timerPeriod;
    //! Is to enable or disable Timer_A interrupt
    //! \n Valid values are:
    //! - \b TIMER_A_TAIE_INTERRUPT_ENABLE
    //! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default]
    uint16_t timerInterruptEnable_TAIE;
    //! Is to enable or disable Timer_A CCR0 captureComapre interrupt.
    //! \n Valid values are:
    //! - \b TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE
    //! - \b TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE [Default]
    uint16_t captureCompareInterruptEnable_CCR0_CCIE;
    //! Decides if Timer_A clock divider, count direction, count need to be
    //! reset.
    //! \n Valid values are:
    //! - \b TIMER_A_DO_CLEAR
    //! - \b TIMER_A_SKIP_CLEAR [Default]
    uint16_t timerClear;
    //! Whether to start the timer immediately
    bool startTimer;
} Timer_A_initUpDownModeParam;

配置定时器的捕获模式

void Timer_A_initCaptureMode(uint16_t baseAddress, Timer_A_initCaptureModeParam ∗param)
typedef struct Timer_A_initCaptureModeParam{
    //! Selects the Capture register being used. Refer to datasheet to ensure
    //! the device has the capture compare register being used.
    //! \n Valid values are:
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6
    uint16_t captureRegister;
    //! Is the capture mode selected.
    //! \n Valid values are:
    //! - \b TIMER_A_CAPTUREMODE_NO_CAPTURE [Default]
    //! - \b TIMER_A_CAPTUREMODE_RISING_EDGE
    //! - \b TIMER_A_CAPTUREMODE_FALLING_EDGE
    //! - \b TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE
    uint16_t captureMode;
    //! Decides the Input Select
    //! \n Valid values are:
    //! - \b TIMER_A_CAPTURE_INPUTSELECT_CCIxA
    //! - \b TIMER_A_CAPTURE_INPUTSELECT_CCIxB
    //! - \b TIMER_A_CAPTURE_INPUTSELECT_GND
    //! - \b TIMER_A_CAPTURE_INPUTSELECT_Vcc
    uint16_t captureInputSelect;
    //! Decides if capture source should be synchronized with timer clock
    //! \n Valid values are:
    //! - \b TIMER_A_CAPTURE_ASYNCHRONOUS [Default]
    //! - \b TIMER_A_CAPTURE_SYNCHRONOUS
    uint16_t synchronizeCaptureSource;
    //! Is to enable or disable timer captureComapre interrupt.
    //! \n Valid values are:
    //! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE [Default]
    //! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE
    uint16_t captureInterruptEnable;
    //! Specifies the output mode.
    //! \n Valid values are:
    //! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE [Default]
    //! - \b TIMER_A_OUTPUTMODE_SET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET
    //! - \b TIMER_A_OUTPUTMODE_SET_RESET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE
    //! - \b TIMER_A_OUTPUTMODE_RESET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET
    //! - \b TIMER_A_OUTPUTMODE_RESET_SET
    uint16_t captureOutputMode;
} Timer_A_initCaptureModeParam;

配置定时器的比较模式

void Timer_A_initCompareMode(uint16_t baseAddress, Timer_A_initCompareModeParam ∗param)
typedef struct Timer_A_initCompareModeParam {
    //! Selects the Capture register being used. Refer to datasheet to ensure
    //! the device has the capture compare register being used.
    //! \n Valid values are:
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6
    uint16_t compareRegister;
    //! Is to enable or disable timer captureComapre interrupt.
    //! \n Valid values are:
    //! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE [Default]
    //! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE
    uint16_t compareInterruptEnable;
    //! Specifies the output mode.
    //! \n Valid values are:
    //! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE [Default]
    //! - \b TIMER_A_OUTPUTMODE_SET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET
    //! - \b TIMER_A_OUTPUTMODE_SET_RESET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE
    //! - \b TIMER_A_OUTPUTMODE_RESET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET
    //! - \b TIMER_A_OUTPUTMODE_RESET_SET
    uint16_t compareOutputMode;
    //! Is the count to be compared with in compare mode
    uint16_t compareValue;
} Timer_A_initCompareModeParam;

使能中断

void Timer_A_enableInterrupt(uint16_t baseAddress)

停止中断

void Timer_A_disableInterrupt(uint16_t baseAddress)

获取中断标志位

uint32_t Timer_A_getInterruptStatus(uint16_t baseAddress)

返回TIMER_A_INTERRUPT_NOT_PENDINGTIMER_A_INTERRUPT_PENDING

使能捕获比较中断

void Timer_A_enableCaptureCompareInterrupt(uint16_t baseAddress, uint16_t captureCompareRegister)

可选寄存器

#define TIMER_A_CAPTURECOMPARE_REGISTER_0                                  0x02
#define TIMER_A_CAPTURECOMPARE_REGISTER_1                                  0x04
#define TIMER_A_CAPTURECOMPARE_REGISTER_2                                  0x06
#define TIMER_A_CAPTURECOMPARE_REGISTER_3                                  0x08
#define TIMER_A_CAPTURECOMPARE_REGISTER_4                                  0x0A
#define TIMER_A_CAPTURECOMPARE_REGISTER_5                                  0x0C
#define TIMER_A_CAPTURECOMPARE_REGISTER_6                                  0x0E

停止捕获比较中断

void Timer_A_disableCaptureCompareInterrupt(uint16_t baseAddress, uint16_t captureCompareRegister)

获取捕获比较中断标志位

uint32_t Timer_A_getCaptureCompareInterruptStatus(uint16_t baseAddress, uint16_t captureCompareRegister, uint16_t mask)

mask:TIMER_A_CAPTURE_OVERFLOW,TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG

返回TIMER_A_CAPTURE_OVERFLOW|TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG

清除定时器的配置timer clock divider, count direction, count

void Timer_A_clear(uint16_t baseAddress)

获取同步捕获比较输入

uint8_t Timer_A_getSynchronizedCaptureCompareInput(uint16_t baseAddress, uint16_t captureCompareRegister, uint16_t synchronized)

synchronized:TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT,TIMER_A_READ_CAPTURE_COMPARE_INPUT

返回TIMER_A_CAPTURECOMPARE_INPUT_HIGH,TIMER_A_CAPTURECOMPARE_INPUT_LOW

获取输出模式的输出位

uint8_t Timer_A_getOutputForOutputModeOutBitValue(uint16_t baseAddress, uint16_t captureCompareRegister)

获取当前捕获比较计数

uint16_t Timer_A_getCaptureCompareCount(uint16_t baseAddress, uint16_t captureCompareRegister)

设置输出模式的输出位

void Timer_A_setOutputForOutputModeOutBitValue(uint16_t baseAddress, uint16_t captureCompareRegister, uint8_t outputModeOutBitValue)

outputModeOutBitValue:TIMER_A_OUTPUTMODE_OUTBITVALUE_HIGH,TIMER_A_OUTPUTMODE_OUTBITVALUE_LOW

在上升模式配置下产生PWM波

void Timer_A_outputPWM(uint16_t baseAddress, Timer_A_outputPWMParam ∗param)
typedef struct Timer_A_outputPWMParam {
    //! Selects Clock source.
    //! \n Valid values are:
    //! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]
    //! - \b TIMER_A_CLOCKSOURCE_ACLK
    //! - \b TIMER_A_CLOCKSOURCE_SMCLK
    //! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK
    uint16_t clockSource;
    //! Is the desired divider for the clock source
    //! \n Valid values are:
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56
    //! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64
    uint16_t clockSourceDivider;
    //! Selects the desired timer period
    uint16_t timerPeriod;
    //! Selects the compare register being used. Refer to datasheet to ensure
    //! the device has the capture compare register being used.
    //! \n Valid values are:
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5
    //! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6
    uint16_t compareRegister;
    //! Specifies the output mode.
    //! \n Valid values are:
    //! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE [Default]
    //! - \b TIMER_A_OUTPUTMODE_SET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET
    //! - \b TIMER_A_OUTPUTMODE_SET_RESET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE
    //! - \b TIMER_A_OUTPUTMODE_RESET
    //! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET
    //! - \b TIMER_A_OUTPUTMODE_RESET_SET
    uint16_t compareOutputMode;
    //! Specifies the dutycycle for the generated waveform
    uint16_t dutyCycle;
} Timer_A_outputPWMParam;

停止定时器

void Timer_A_stop(uint16_t baseAddress)

设置捕获比较寄存器的值

void Timer_A_setCompareValue(uint16_t baseAddress, uint16_t compareRegister, uint16_t
compareValue)

配置为输出模式

void Timer_A_setOutputMode(uint16_t baseAddress, uint16_t compareRegister, uint16_t compareOutputMode)

compareOutputMode:

#define TIMER_A_OUTPUTMODE_OUTBITVALUE                                 OUTMOD_0
#define TIMER_A_OUTPUTMODE_SET                                         OUTMOD_1
#define TIMER_A_OUTPUTMODE_TOGGLE_RESET                                OUTMOD_2
#define TIMER_A_OUTPUTMODE_SET_RESET                                   OUTMOD_3
#define TIMER_A_OUTPUTMODE_TOGGLE                                      OUTMOD_4
#define TIMER_A_OUTPUTMODE_RESET                                       OUTMOD_5
#define TIMER_A_OUTPUTMODE_TOGGLE_SET                                  OUTMOD_6
#define TIMER_A_OUTPUTMODE_RESET_SET                                   OUTMOD_7

清除TAIFG中断标志位

void Timer_A_clearTimerInterrupt(uint16_t baseAddress)

清除捕获比较中断标志位

void Timer_A_clearCaptureCompareInterrupt(uint16_t baseAddress, uint16_t captureCompareRegister)

读取当前定时器计数值

uint16_t Timer_A_getCounterValue(uint16_t baseAddress)

2、例程

(1)、定时器中断实验任务

要求

利用定时器A的定时中断功能,控制一个LED灯开启和关断。在满足接口条件下,开启LED,同时定时器开始计时(如果查询一直满足接口条件则定时器在每次查询时均重新开始计时);不满足接口条件下,定时器计时检查,到达5s则引起中断,中断服务程序完成关断LED灯的操作。

思路说明

  • 此处接口条件选取为按键S1(P1.2),按下时读取为低电平则满足接口条件;LED选取为L1(P8.1)
  • 时钟源选取SMCLK,10分频,SMCLK配置为8MHz
  • 定时器A配置时钟为SMCLK,连续计数模式,每过1s进入中断,计数+1,到5s时检查是否满足接口条件,若满足则重新计数,不满足则关闭LED

源码

#include "driverlib.h"

#define FREQ_TIMER (8000000/10)
#define COMPARE_VALUE 50000

int led_sta = 0;
int cnt = 0;

void ClockInit()
{
    //最终MCLK:16MHZ,SMCLK:8MHZ,ACLK:32KHZ
    UCSCTL6 &= ~XT1OFF;       //启动XT1
    P5SEL |= BIT2 + BIT3;     //XT2引脚功能选择
    UCSCTL6 &= ~XT2OFF;       //打开XT2
    __bis_SR_register(SCG0);
    UCSCTL0 = DCO0+DCO1+DCO2+DCO3+DCO4;
    UCSCTL1 = DCORSEL_4;  //DCO频率范围在28.2MHZ以下
    UCSCTL2 = FLLD_5 + 1;       //D=16,N=1

    //n=8,FLLREFCLK时钟源为XT2CLK;
    //DCOCLK=D*(N+1)*(FLLREFCLK/n);
    //DCOCLKDIV=(N+1)*(FLLREFCLK/n);
    UCSCTL3 = SELREF_5 + FLLREFDIV_3;

    //ACLK的时钟源为DCOCLKDIV,
    //MCLK\SMCLK的时钟源为DCOCLK
    UCSCTL4 = SELA_4 + SELS_3 +SELM_3;

    //ACLK由DCOCLKDIV的32分频得到,
    //SMCLK由DCOCLK的2分频得到
    UCSCTL5 = DIVA_5 +DIVS_1;
}

// 消抖延时
void delay(int cnt)
{
    while(cnt)
        cnt--;
}

//  IO口初始化
void IO_Init()
{
    // LED
    GPIO_setAsOutputPin(GPIO_PORT_P8, GPIO_PIN1);
    GPIO_setOutputLowOnPin(GPIO_PORT_P8, GPIO_PIN1);
    //  S1
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN2);
    // 配置按键中断
    _enable_interrupts();
    GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN2);
    GPIO_selectInterruptEdge(GPIO_PORT_P1, GPIO_PIN2, GPIO_HIGH_TO_LOW_TRANSITION);
    GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN2);
}

//  接口条件
int IS_Meet()
{
    return !GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN2);
}

//  定时器A初始化
void TIMERA_Init()
{
    Timer_A_initContinuousModeParam initContParam = {0};
    initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
    initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_10;
    initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
    initContParam.timerClear = TIMER_A_DO_CLEAR;
    initContParam.startTimer = false;
    Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam);

    Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);

    Timer_A_initCompareModeParam initCompParam = {0};
    initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
    initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
    initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
    initCompParam.compareValue = COMPARE_VALUE;
    Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);
}


void main()
{
    WDT_A_hold(WDT_A_BASE);

    ClockInit();
    IO_Init();
    TIMERA_Init();

    return 0;
}

//  按键中断函数
#pragma vector=PORT1_VECTOR
__interrupt
void Port_1(void)
{
    delay(50000);
    if(!(GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN2) | led_sta))
    {
        GPIO_setOutputHighOnPin(GPIO_PORT_P8, GPIO_PIN1);
        led_sta = 1;
        Timer_A_startCounter( TIMER_A1_BASE, TIMER_A_CONTINUOUS_MODE);  //开启计数器
    }
    //清除中断标志位
    GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3);
}
//  定时器中断函数
#pragma vector=TIMER1_A0_VECTOR
__interrupt
void Timer_A0(void)
{
    uint16_t compVal = Timer_A_getCaptureCompareCount(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0) + COMPARE_VALUE;
    if(cnt == (5 * FREQ_TIMER / COMPARE_VALUE))
    {
        cnt = 0;
        if(!IS_Meet())
        {
            if(led_sta)
            {
                GPIO_setOutputLowOnPin(GPIO_PORT_P8, GPIO_PIN1);
                led_sta = 0;
                Timer_A_stop(TIMER_A1_BASE);    //停止计数器
            }
        }
    }
    else
        cnt++;
    Timer_A_setCompareValue(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0, compVal);
}

(2)、LED1呼吸灯效果

要求

使用提供的时钟接口,将SMCLK时钟频率提高到8MHz,SMCLK做定时器A的时钟。请制作一个自动呼吸灯,让主板LED1自动呼吸,思路不限。

思路

使用PWM驱动LED,随着时钟计数改变PWM的占空比,实现LED的呼吸明暗控制

使用杜邦线将LED1连接端口P2.5/TA2.2

源码

#include "driverlib.h"

#define PWM_PERIOD 100

// 配置时钟
void ClockInit()
{
    //最终MCLK:16MHZ,SMCLK:8MHZ,ACLK:32KHZ
    UCSCTL6 &= ~XT1OFF;       //启动XT1
    P5SEL |= BIT2 + BIT3;     //XT2引脚功能选择
    UCSCTL6 &= ~XT2OFF;       //打开XT2
    __bis_SR_register(SCG0);
    UCSCTL0 = DCO0+DCO1+DCO2+DCO3+DCO4;
    UCSCTL1 = DCORSEL_4;  //DCO频率范围在28.2MHZ以下
    UCSCTL2 = FLLD_5 + 1;       //D=16,N=1

    //n=8,FLLREFCLK时钟源为XT2CLK;
    //DCOCLK=D*(N+1)*(FLLREFCLK/n);
    //DCOCLKDIV=(N+1)*(FLLREFCLK/n);
    UCSCTL3 = SELREF_5 + FLLREFDIV_3;

    //ACLK的时钟源为DCOCLKDIV,
    //MCLK\SMCLK的时钟源为DCOCLK
    UCSCTL4 = SELA_4 + SELS_3 +SELM_3;

    //ACLK由DCOCLKDIV的32分频得到,
    //SMCLK由DCOCLK的2分频得到
    UCSCTL5 = DIVA_5 +DIVS_1;
}

int main()
{
    WDT_A_hold(WDT_A_BASE);

    ClockInit();

    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN5);

    Timer_A_outputPWMParam PWMparam = {0};
    PWMparam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
    PWMparam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
    PWMparam.timerPeriod = PWM_PERIOD;
    PWMparam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;
    PWMparam.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;

    int i;
    while(1)
    {
        for(i = 0; i < PWM_PERIOD; i++)
        {
            PWMparam.dutyCycle = i;
            Timer_A_outputPWM(TIMER_A2_BASE, &PWMparam);
            __delay_cycles(100000);
        }
        for(i = PWM_PERIOD; i > 0; i--)
        {
            PWMparam.dutyCycle = i;
            Timer_A_outputPWM(TIMER_A2_BASE, &PWMparam);
            __delay_cycles(100000);
        }

    }
    return 0;
}

推荐阅读