MSP430系列教程之定时器
MSP430的定时器 Timer_A 是一个 16 位定时器/计数器,具有多达七个捕捉/比较寄存器,支持多个捕获/比较、PWM 输出和间隔时序等多种输出方式,同时具有中断功能。
也就是说,我们可以用定时器来做这些事情
- 精准定时(精确控制LED灯的亮灭时间)
- 对外部电平的捕获比较(超声波模块等)
- 输出PWM波(控制电机、舵机等)
- 定时器中断(实现在不干扰CPU正常运行的情况下,判断是否要停止当前工作,能有效避免CPU的空转)
MSP430FR6989系列教程之流水灯
MSP430FR6989系列教程之串口通信
MSP430FR6989系列教程之定时器
MSP430FR6989系列教程之PWM波
MSP430FR6989系列教程之LCD
前言
这次学习MSP430主要是为了备战电赛,虽然不确信一定会用到MSP430FR6989这块板子,但还是想尝试一下,毕竟未来的事谁也说不准。
一、定时器
MSP430单片机的时钟模块主要包括:
三个时钟:辅助时钟ACLK 、主时钟MCLK 、子系统时钟SMCLK
三个振荡器:低频时钟源LFXT1 、高频时钟源XT2 、数字控制RC振荡器DCO
而MSP430单片机工作所需时钟就是由这些振荡器振荡后经处理产生的。
Timer_A 的功能包括:
• 具有四种工作模式的异步 16 位定时器/计数器 • 可选择和可配置的时钟源
• 多达七个可配置的捕捉/比较寄存器
• 具有脉宽调制 (PWM) 功能的可配置输出
• 异步输入和输出锁存
• 中断用于快速解码所有 Timer_A 中断的向量寄存器
二、代码编写
这里附上完整的main.c代码
#include <msp430.h>
#include "stdio.h"
#include "driverlib/uart.h"
#include "driverlib/timerA0.h"
/**
* main.c
*/
#define CPU_CLOCK 8000000
#define Delay_Us(us) __delay_cycles(CPU_CLOCK / 1000000 * (us))
#define Delay_Ms(ms) __delay_cycles(CPU_CLOCK / 1000 * (ms))
#define S1_IN P1IN_bit.P1IN1
#define S2_IN P1IN_bit.P1IN2
void Initial_Clock(void);
void Initial_Led(void);
int main( void )
{
/* 关闭看门狗 */
WDTCTL = WDTPW | WDTHOLD;
Initial_Clock();
Initial_Uart();
Initial_Led();
Initial_Timer1();
Initial_Timer0();
__bis_SR_register(GIE);//使能全局中断
/* 使配置完成的IO口生效,从LPMx.5退出 */
PM5CTL0 &= ~LOCKLPM5;
while(1)
{
if(RxDataFlag){
if(RxDataBuf[0] == 'l' && RxDataBuf[1] == 'e' && RxDataBuf[2] == 'd' && RxDataLen == 4)
{
printStr("hello\n");
}
RxDataFlag = 0;
RxDataLen = 0;
}
Delay_Ms(10);
}
}
void Initial_Clock(void)
{
/* 外部32.768k使能 */
PJSEL0 |= BIT4;
PJSEL1 &= ~BIT4;
PJSEL0 |= BIT5;
PJSEL1 &= ~BIT5;
/* 使配置完成的IO口生效,从LPMx.5退出 */
PM5CTL0 &= ~LOCKLPM5;
/* 使能时钟寄存器设置 */
CSCTL0_H = CSKEY_H;
CSCTL1 = DCOFSEL_6; // DCO = 8M
CSCTL2 = SELA__LFXTCLK + SELS__DCOCLK + SELM__DCOCLK; // ACLK = LFXT ,SMCLK和MCLK=DCO
CSCTL3 = 0; // ACLK/SMCLK/MCLK 分频=1
CSCTL4 = HFXTOFF + VLOOFF + LFXTDRIVE_3; // 关闭HFXT VLO ,打开LFXT
/* 禁止时钟寄存器设置 */
CSCTL0_H = 0;
}
void Initial_Led(void)
{
P1DIR |= BIT0; // 设置P10方向为输出
P1OUT &= ~BIT0; // P10输出为0,熄灭LED1
P9DIR |= BIT7; // 设置P97方向为输出
P9OUT &= ~BIT7; // P97输出为0,熄灭LED2
}
TimerA0.c
#include <msp430.h>
#include "timerA0.h"
#include "uart.h"
#define ACLK_Frequency_HZ 32768
#define A0_TICK_RATE_HZ 2 //2Hz == 0.5s
#define A1_TICK_RATE_HZ 1 //1Hz == 1s
void Initial_Timer0(void)
{
TA0CTL = TASSEL_1; // 使用辅助时钟
TA0CTL |= TACLR; // 清除配置运行
TA0CCR0 = ACLK_Frequency_HZ / A0_TICK_RATE_HZ; //根据想要的嘀嗒速率设置匹配值
TA0CTL |= MC_1; // 向上计数模式
TA0CCTL0 = CCIE; // 使用捕获中断
}
void Initial_Timer1(void)
{
TA1CCR0 = ACLK_Frequency_HZ / A1_TICK_RATE_HZ; //根据想要的嘀嗒速率设置匹配值
TA1CTL |= TACLR; // 清除配置运行
TA1CTL = TASSEL_1 + MC_1 + TAIE; // 使用辅助时钟 向上计数模式 中断启用
}
#pragma vector = TIMER1_A1_VECTOR
__interrupt void ISR_USCI_TimerA1(void)
{
TA1CTL &= ~TAIFG; // 清除中断标志位
P9OUT ^= BIT7;
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void ISR_USCI_TimerA0(void)
{
P1OUT ^= BIT0;
}
三、总结
以上就是今天要讲的内容,本文仅仅简单介绍了定时器,以及如何配置及使用定时器来进行对时间的精准控制方法。
参考
[1].TI https://www.ti.com/tool/MSP-EXP430FR6989
[2].TI MSP430FR6989用户指南