欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于msp430Timer_A定时器的LED

程序员文章站 2022-06-08 18:16:49
...

相信学过430的朋友对Timer_A应该不陌生吧,反正我是难忘了,感觉学的比stm32的定时器都吃力啊,看起来简单,但是,,,就是学起来吃力,怪我咯!

闲话少说,今天我就来总结一下我学习Timer_A的痛苦经历。

首先,我们要知道Timer_A的基本结构吧:
基于msp430Timer_A定时器的LED

总结起来就两点:

  1. 16位的定时/计数器
  2. 3个捕获/比较寄存器

然后,我们来看看它的基本特征
基于msp430Timer_A定时器的LED
总结如下:

  1. 支持多多个捕获/比较同时工作
  2. 支持PWM波的输出
  3. 支持输出时间间隔
  4. 拥有多种中断,如溢出中断,捕获/比较中断

在然后,我就我这个项目要用到的知识跟大家讲一下,其余的知识呢,,,,啥,你给我糖,我也懒的讲(傲娇)

那么,首先是定时器A,要工作,是不是要时钟呢?没有时钟,它是工作不了滴!
所以,我们在用它之前,肯定是要选一个时钟的。那是不是只有一个时钟呢?
Of Course Not! 它可是有4种时钟可以选择呢?
基于msp430Timer_A定时器的LED
基于msp430Timer_A定时器的LED
呐呐,看到没? 手册里说了,我么可以通过TASSELx(2bits,属于TACTL(时钟控制的缩写)寄存器)来选择它的时钟,具体有四种:ACLK(辅助时钟),SMCLK(子系统时钟),TACLK(外接引脚时钟),INCLK(外接时钟)。除此之外,我们还可以通过IDx(同TASSELx)来对时钟进行分频。至于TACLR(1bit ,属于TACTL),是用来清零的,可以复位分频设置等。

时钟源选好了,那么就该选比较/捕获寄存器了。比较/捕获寄存器有三个,这里我只用了第一个TACCR0,所以,下面我就讲它一个,其余两个,你们要用到的话,就去看数据手册吧,也很简单的。

基于msp430Timer_A定时器的LED
上图列出了Timer_A的9中寄存器,我们只先介绍TACCR0,TACCTL0.
首先,TACCTL0,这是比较/捕获寄存器0的控制寄存器。里面有些位用来控制TACCR0。我们这里要只用到它的比较中断,就是当TAR(计数器寄存器)和TACCR0中的设置值相等时,TACCR0发生比较中断,置位标志位CCIFG。(CCIE,CCIFG都是TACCTL0中的位)
基于msp430Timer_A定时器的LED
基于msp430Timer_A定时器的LED
介绍完中断,还不算完,我们还有设置计数器的计数方式呢!TAR有三种计数方式:而它的设置是在TACTL中:
基于msp430Timer_A定时器的LED
它是通过设置MCx来对计数方式进行设置,翻译为:

  1. 停止计数
  2. 增计数
  3. 连续计数
  4. 增减计数
    我们这里会用到增计数,也就是在TACCR0中设置一个值,然后定时器就会启动,从0开始,每一个时钟周期加1,直到加到与TACCR0中值相等时,产生中断。然后TAR继续从0开始计数,重复刚才的动作。
    基于msp430Timer_A定时器的LED
    再然后就是具体电路了,这里可以参见我的我的另一篇博客:

    最后就是代码了:
#include <msp430x14x.h>
#include "Config.h"                     //开发板硬件宏

uchar i=0;                              //跑马灯循环变量
long long  count=40000;                 //TACCR0的值
uchar flag=0;                           //中断标志位

//***********************************************************************
//               MSP430IO口初始化
//***********************************************************************
void Port_Init()
{
  LED8DIR  = 0xFF;                          //设置IO口方向为输出
  LED8     = 0xFF;                          //P6口初始设置为FF
}
//***********************************************************************
//             TIMERA初始化,设置为UP模式计数
//***********************************************************************
void TIMERA_Init()                       
{
  TACTL |= TASSEL_1 + TACLR+MC_3;     //SMCLK做时钟源,8分频,增计数模式,计数到TACCR0
  CCR0=count;
  TACCTL0=CCIE;
}
//***********************************************************************
//             TIMERA中断服务程序,需要判断中断类型
//***********************************************************************
#pragma vector = TIMERA0_VECTOR                //TACCR0的中断向量
__interrupt void Timer_A(void)
{
   i++;
   flag=1;
}
void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  //Clock_Init();                                 //系统时钟设置
  Port_Init();                                   //端口初始化
  TIMERA_Init();                                //设置TIMERA
  _EINT();
  while(1)
  {
    if(flag==1)
    {
      switch(i)
       {
          case 1:
            LED8 &= ~(1<<0);flag=0; //点亮D1灯
            break;
          case 2:
            LED8 &= ~(1<<1);flag=0;  //点亮D2灯
            break;
          case 3:
            LED8 &= ~(1<<2);flag=0;//点亮D3灯
            break;
          case 4:
            LED8 &= ~(1<<3);flag=0;  //点亮D4灯
            break; 
          case 5:
            LED8 &= ~(1<<4);flag=0;  //点亮D5灯
            break;
          case 6:
            LED8 &= ~(1<<5);flag=0;  //点亮D6灯
            break;
          case 7:
            LED8 &= ~(1<<6);flag=0;  //点亮D7灯
            break;
          case 8:
            LED8 &= ~(1<<7);flag=0; i=0;//点亮D8灯
            break;              
       }
    }
  }
}

搞定!


有待更新。。。。。。

相关标签: 定时器 430