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

[复制链接]
 楼主| 无法去污粉 发表于 2023-10-19 15:57 | 显示全部楼层
TAIV : 只读寄存器,中断类型标志位,用来识别是哪个中断源引起的中断(因为除了TAxCCR0,其他中断源共享一个中断向量)
 楼主| 无法去污粉 发表于 2023-10-19 15:57 | 显示全部楼层
TAxEX0寄存器
QQ截图20231019155731.jpg
 楼主| 无法去污粉 发表于 2023-10-19 15:57 | 显示全部楼层
TAxIDEX : 输入时钟分频寄存器,和TAxCTL寄存器中ID位效果一致,用来对所选的时钟进行分频后再输入给Timer_A。
 楼主| 无法去污粉 发表于 2023-10-19 15:58 | 显示全部楼层
Timer_A输入捕捉
首先看,什么叫输入捕捉,用在什么地方:主要用于测量脉冲数量,监控外部脉冲等功能,其实最主要的就是连接增量式编码器来获取固定时间内的脉冲数量从而计算电机的转速,这个是最最常用的功能。
 楼主| 无法去污粉 发表于 2023-10-19 15:58 | 显示全部楼层
如下是MSP430 输入捕捉功能的工作流程图:
QQ截图20231019155819.jpg
 楼主| 无法去污粉 发表于 2023-10-19 15:58 | 显示全部楼层
那么如何设定输入捕捉呢?

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

当然设置完这些后输入捕捉就可以工作了,但是捕捉到信号之后怎么办呢? 需要开中断嘛,这时进中断,将这个时刻计数器的值给记下来,用于脉冲频率等的测量。
 楼主| 无法去污粉 发表于 2023-10-19 15:59 | 显示全部楼层
后续如何使用此项功能,在后面会给出详细的Example Code.

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

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

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



 楼主| 无法去污粉 发表于 2023-10-19 15:59 | 显示全部楼层
  1. #include <msp430.h>

  2. int main(void)
  3. {
  4.   WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT
  5.   // Configure GPIO
  6.   P1DIR |= BIT0;
  7.   P1OUT |= BIT0;

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

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

  18. // Timer0_A0 interrupt service routine
  19. #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
  20. #pragma vector = TIMER0_A0_VECTOR
  21. __interrupt void Timer0_A0_ISR (void)
  22. #elif defined(__GNUC__)
  23. void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
  24. #else
  25. #error Compiler not supported!
  26. #endif
  27. {
  28.   P1OUT ^= BIT0;
  29. }
 楼主| 无法去污粉 发表于 2023-10-19 15:59 | 显示全部楼层
输入捕捉功能 (开始捕捉中断,捕捉到20个脉冲后反转P1.1口,同时记录下每个脉冲时刻的计数器的值)
 楼主| 无法去污粉 发表于 2023-10-19 15:59 | 显示全部楼层
  1. #include "msp430.h"

  2. #define NUMBER_TIMER_CAPTURES       20
  3. volatile unsigned int timerAcaptureValues[NUMBER_TIMER_CAPTURES];
  4. unsigned int timerAcapturePointer = 0;

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

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

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

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

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

  20.   // Timer0_A3 Setup
  21.   TA0CCTL2 = CM_1 | CCIS_1 | SCS | CAP | CCIE;
  22.                                             // Capture rising edge,
  23.                                             // Use CCI2B=ACLK,
  24.                                             // Synchronous capture,
  25.                                             // Enable capture mode,
  26.                                             // Enable capture interrupt
  27.   TA0CTL = TASSEL__SMCLK | MC__CONTINUOUS;  // Use SMCLK as clock source,
  28.                                             // Start timer in continuous mode

  29.   __bis_SR_register(LPM0_bits | GIE);
  30.   __no_operation();
  31. }

  32. // Timer0_A3 CC1-4, TA Interrupt Handler
  33. #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
  34. #pragma vector = TIMER0_A1_VECTOR
  35. __interrupt void Timer0_A1_ISR(void)
  36. #elif defined(__GNUC__)
  37. void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) Timer0_A1_ISR (void)
  38. #else
  39. #error Compiler not supported!
  40. #endif
  41. {
  42.   switch (__even_in_range(TA0IV, TA0IV_TAIFG)) {
  43.     case TA0IV_TA0CCR1:
  44.       break;
  45.     case TA0IV_TA0CCR2:
  46.       timerAcaptureValues[timerAcapturePointer++] = TA0CCR2;
  47.       if (timerAcapturePointer >= 20) {
  48.         while (1) {
  49.           P1OUT ^= 0x01;                    // Toggle P1.0 (LED)
  50.           __delay_cycles(100000);
  51.         }
  52.       }
  53.       break;
  54.     case TA0IV_TA0IFG:
  55.       break;
  56.     default:
  57.       break;
  58.   }
  59. }
 楼主| 无法去污粉 发表于 2023-10-19 16:00 | 显示全部楼层
输出比较功能(输出两路PWM波,频率1KHz,占空比分别为25%和75%)
  1. #include <msp430.h>

  2. int main(void)
  3. {
  4.   WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT

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

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

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

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

  23.   __bis_SR_register(LPM0_bits);             // Enter LPM0
  24.   __no_operation();                         // For debugger
  25. }
 楼主| 无法去污粉 发表于 2023-10-19 16:00 | 显示全部楼层
下面看一下Timer_B,和Timer_A基本都没区别,功能,使用方法等,那么回归最初的问题,区别在那些地方呢:
B可以配置成8,10,12,16位模式,A只能用16位模式

B的CCRn寄存器是双缓冲,即Double-buffered,可以形成组
B的每一个输出口都可配置成高阻态
B中没有SCCI位
 楼主| 无法去污粉 发表于 2023-10-19 16:01 | 显示全部楼层
 楼主| 无法去污粉 发表于 2023-10-19 16:01 | 显示全部楼层
先看一下结构图的区别:B可以成组,因此多了TBCLGRP,其次可以设置成8,10,12,16位模式,因此多了CNTL位,没有SCCI位,故CCI不能到EQU模块。
 楼主| 无法去污粉 发表于 2023-10-19 16:01 | 显示全部楼层
先说第一条:B可以设定成8,10,12,16位模式,也就是说计数的最大值不同,这个在TBxCTL中你会发现多了CNT位(12-11),用于选择定时器位数: QQ截图20231019160134.jpg
 楼主| 无法去污粉 发表于 2023-10-19 16:02 | 显示全部楼层
其次没有SCCI,因此也就没有这个设定位了。

最后就是Group,看下面寄存器截图:
QQ截图20231019160207.jpg
 楼主| 无法去污粉 发表于 2023-10-19 16:02 | 显示全部楼层
这个功能就是在输出比较模式下,这几个通道可以同时成组的去更新数据,用于多个输出比较形成同步的功能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部