发新帖我要提问
123
返回列表
打印

MSP430使用指南- Timer定时器模块

[复制链接]
楼主: 无法去污粉
手机看帖
扫描二维码
随时随地手机跟帖
41
无法去污粉|  楼主 | 2023-10-19 15:57 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
TAIV : 只读寄存器,中断类型标志位,用来识别是哪个中断源引起的中断(因为除了TAxCCR0,其他中断源共享一个中断向量)

使用特权

评论回复
42
无法去污粉|  楼主 | 2023-10-19 15:57 | 只看该作者
TAxEX0寄存器

使用特权

评论回复
43
无法去污粉|  楼主 | 2023-10-19 15:57 | 只看该作者
TAxIDEX : 输入时钟分频寄存器,和TAxCTL寄存器中ID位效果一致,用来对所选的时钟进行分频后再输入给Timer_A。

使用特权

评论回复
44
无法去污粉|  楼主 | 2023-10-19 15:58 | 只看该作者
Timer_A输入捕捉
首先看,什么叫输入捕捉,用在什么地方:主要用于测量脉冲数量,监控外部脉冲等功能,其实最主要的就是连接增量式编码器来获取固定时间内的脉冲数量从而计算电机的转速,这个是最最常用的功能。

使用特权

评论回复
45
无法去污粉|  楼主 | 2023-10-19 15:58 | 只看该作者
如下是MSP430 输入捕捉功能的工作流程图:

使用特权

评论回复
46
无法去污粉|  楼主 | 2023-10-19 15:58 | 只看该作者
那么如何设定输入捕捉呢?

这个主要再TAxCCTLn寄存器,首先你需要将CAP设置成1,代表使用输入捕捉模式,其次根据你的硬件连接选择A或者B通道,然后设定同步位,捕捉类型等,最后依旧是要设定最基本的定时器功能,因为定时器要工作,开始计数嘛!

当然设置完这些后输入捕捉就可以工作了,但是捕捉到信号之后怎么办呢? 需要开中断嘛,这时进中断,将这个时刻计数器的值给记下来,用于脉冲频率等的测量。

使用特权

评论回复
47
无法去污粉|  楼主 | 2023-10-19 15:59 | 只看该作者
后续如何使用此项功能,在后面会给出详细的Example Code.

Timer_A输出比较

使用特权

评论回复
48
无法去污粉|  楼主 | 2023-10-19 15:59 | 只看该作者
输出比较最常用的就是输出PWM波了,这个电机控制,LED控制等中非常常用,原理上前面已经描述清除,就是靠Base计数器和CCRx计数器,当计数到CCRx寄存器时会进行相应的动作,从而实现PWM功能的输出,通过CCR0调节PWM频率,CCRx调节占空比。

Timer_A例程

使用特权

评论回复
49
无法去污粉|  楼主 | 2023-10-19 15:59 | 只看该作者
好啦,上面讲了一大堆最最主要的还是程序应该怎么写,怎么使用每个功能,下面给出几种常用的程序。(例程使用MSP430FR5969,别问为什么 主要因为刚好有这个板子。。。其实MSP430 内部Timer_A模块都是一样的,因此程序基本通用,可能仅仅有一些寄存器不一样或者功能有点区别而已,总的来说大同小异。)

基本定时功能(20ms中断)



使用特权

评论回复
50
无法去污粉|  楼主 | 2023-10-19 15:59 | 只看该作者
#include <msp430.h>

int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT
  // Configure GPIO
  P1DIR |= BIT0;
  P1OUT |= BIT0;

  // Disable the GPIO power-on default high-impedance mode to activate
  // previously configured port settings
  PM5CTL0 &= ~LOCKLPM5;
  TA0CCTL0 = CCIE;                          // TACCR0 interrupt enabled
  TA0CCR0 = 20000;                          // SMCLK default 1MHz,
                                     // Set 20000 : 20000/1000000 = 20ms
  TA0CTL = TASSEL__SMCLK | MC__UP;          // SMCLK, UP mode

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupt
  __no_operation();                         // For debugger
}

// Timer0_A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  P1OUT ^= BIT0;
}

使用特权

评论回复
51
无法去污粉|  楼主 | 2023-10-19 15:59 | 只看该作者
输入捕捉功能 (开始捕捉中断,捕捉到20个脉冲后反转P1.1口,同时记录下每个脉冲时刻的计数器的值)

使用特权

评论回复
52
无法去污粉|  楼主 | 2023-10-19 15:59 | 只看该作者
#include "msp430.h"

#define NUMBER_TIMER_CAPTURES       20
volatile unsigned int timerAcaptureValues[NUMBER_TIMER_CAPTURES];
unsigned int timerAcapturePointer = 0;

int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;                 // Stop watchdog timer

  // Configure GPIO
  P1OUT &= ~0x01;                           // Clear P1.0 output
  P1DIR |= 0x01;                            // Set P1.0 to output direction

  // Disable the GPIO power-on default high-impedance mode to activate
  // previously configured port settings
  PM5CTL0 &= ~LOCKLPM5;

  // Clock System Setup
  CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
  CSCTL2 &= ~SELA_7;
  CSCTL2 |= SELA__VLOCLK;                   // Select ACLK=VLOCLK
  CSCTL0_H = 0x00;                        // Lock CS module (use byte mode to upper byte)

  __delay_cycles(1000);                     // Allow clock system to settle

  // Timer0_A3 Setup
  TA0CCTL2 = CM_1 | CCIS_1 | SCS | CAP | CCIE;
                                            // Capture rising edge,
                                            // Use CCI2B=ACLK,
                                            // Synchronous capture,
                                            // Enable capture mode,
                                            // Enable capture interrupt
  TA0CTL = TASSEL__SMCLK | MC__CONTINUOUS;  // Use SMCLK as clock source,
                                            // Start timer in continuous mode

  __bis_SR_register(LPM0_bits | GIE);
  __no_operation();
}

// Timer0_A3 CC1-4, TA Interrupt Handler
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A1_VECTOR
__interrupt void Timer0_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) Timer0_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch (__even_in_range(TA0IV, TA0IV_TAIFG)) {
    case TA0IV_TA0CCR1:
      break;
    case TA0IV_TA0CCR2:
      timerAcaptureValues[timerAcapturePointer++] = TA0CCR2;
      if (timerAcapturePointer >= 20) {
        while (1) {
          P1OUT ^= 0x01;                    // Toggle P1.0 (LED)
          __delay_cycles(100000);
        }
      }
      break;
    case TA0IV_TA0IFG:
      break;
    default:
      break;
  }
}

使用特权

评论回复
53
无法去污粉|  楼主 | 2023-10-19 16:00 | 只看该作者
输出比较功能(输出两路PWM波,频率1KHz,占空比分别为25%和75%)
#include <msp430.h>

int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT

  // Configure GPIO
  P1DIR |= BIT0 | BIT1;                     // P1.0 and P1.1 output
  P1SEL0 |= BIT0 | BIT1;                    // P1.0 and P1.1 options select

  // Disable the GPIO power-on default high-impedance mode to activate
  // previously configured port settings
  PM5CTL0 &= ~LOCKLPM5;

  CSCTL0_H = CSKEY >> 8;                    // Unlock CS registers
  CSCTL1 = DCOFSEL_6;                       // Set DCO = 8MHz
  CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;// Set ACLK=VLO SMCLK=DCO
  CSCTL3 = DIVA__8 | DIVS__8 | DIVM__8;     // Set all dividers
  CSCTL0_H = 0;                             // Lock CS registers

  // Configure Timer0_A
  TA0CCR0 = 1000-1;                         // PWM Period 1KHz
  TA0CCTL1 = OUTMOD_7;                      // CCR1 reset/set
  TA0CCR1 = 750;                            // CCR1 PWM duty cycle
  TA0CCTL2 = OUTMOD_7;                      // CCR2 reset/set
  TA0CCR2 = 250;                            // CCR2 PWM duty cycle
  TA0CTL = TASSEL__SMCLK | MC__UP | TACLR;  // SMCLK, up mode, clear TAR

  __bis_SR_register(LPM0_bits);             // Enter LPM0
  __no_operation();                         // For debugger
}

使用特权

评论回复
54
无法去污粉|  楼主 | 2023-10-19 16:00 | 只看该作者
下面看一下Timer_B,和Timer_A基本都没区别,功能,使用方法等,那么回归最初的问题,区别在那些地方呢:
B可以配置成8,10,12,16位模式,A只能用16位模式

B的CCRn寄存器是双缓冲,即Double-buffered,可以形成组
B的每一个输出口都可配置成高阻态
B中没有SCCI位

使用特权

评论回复
55
无法去污粉|  楼主 | 2023-10-19 16:01 | 只看该作者

使用特权

评论回复
56
无法去污粉|  楼主 | 2023-10-19 16:01 | 只看该作者
先看一下结构图的区别:B可以成组,因此多了TBCLGRP,其次可以设置成8,10,12,16位模式,因此多了CNTL位,没有SCCI位,故CCI不能到EQU模块。

使用特权

评论回复
57
无法去污粉|  楼主 | 2023-10-19 16:01 | 只看该作者
先说第一条:B可以设定成8,10,12,16位模式,也就是说计数的最大值不同,这个在TBxCTL中你会发现多了CNT位(12-11),用于选择定时器位数:

使用特权

评论回复
58
无法去污粉|  楼主 | 2023-10-19 16:02 | 只看该作者
其次没有SCCI,因此也就没有这个设定位了。

最后就是Group,看下面寄存器截图:

使用特权

评论回复
59
无法去污粉|  楼主 | 2023-10-19 16:02 | 只看该作者
这个功能就是在输出比较模式下,这几个通道可以同时成组的去更新数据,用于多个输出比较形成同步的功能。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则