MSP430F149——定时器

前言

特点

msp430系列单片机是16位,51单片机为8位,stm32系列为32位。 位数越高代表着该单片机处理数据的能力越快,性能也就越高。32位机器处理性能好,8位机器廉价性价比高,16位机器超低功耗。就是有一个低功耗模式,可以长时间极少耗损地待机,定时唤醒cpu进行工作.

学习路线

详细理解时钟初始化配置。
熟悉基本操作IO口。
学习定时器三大功能。
学习中断的原理。
操作各种外设,模块。

MSP430内部结构

在接触一款单片机,首先应该了解其总体框架,了解其内部结构,方便后期进行学习理解。
系统内部总体结构

系统时钟

在MSP430F149单片机中一共有三个时钟源:

(1)LFXT1CLK,为低速/高速晶振源,通常接32.768kHz,也可以接(400kHz~16Mhz);

(2)XT2CLK,可选高频振荡器,外接标准高速晶振,通常是接8Mhz,也可以接(400kHz~16Mhz);

(3)DCOCLK,数控振荡器,为内部晶振,由RC震荡回路构成;

在MSP430F149内部一共有三个时钟系统:

(1)ACLK(Auxiliary Clock)辅助时钟,通常由LFXT1CLK或VLOCLK作为时钟源,可以通过软件控制更改时钟的分频系数;

(2)MCLK(Master Clock)系统主时钟单元,为系统内核提供时钟,它可以通过软件从四个时钟源选择;

(3)SMCLK(Sub-Main Clock)系统子时钟,也是可以由软件选择时钟源。

MSP430F149的时钟设置相关寄存器

DCOCTL

DCO控制寄存器,地址为56H,初始值为60H
在这里插入图片描述
DCO0~DCO2: 定义了8种频率之一,而频率由注入直流发生器的电流定义。

MOD0~MOD4: Modulation Bit,频率的微调。

该寄存器在不需要DCO的场合保持默认初始值

BCSCTL1

时钟配置寄存器 1,地址为57H,初始值为84H
在这里插入图片描述
RSEL0~RSEL2: 选择某个内部电阻以决定标称频率.0最低,7最高。

XT5V: 1.

DIVA0~DIVA1:选择ACLK的分频系数。DIVA=0,1,2,3,ACLK的分频系数分别是1,2,4,8;

XTS: 选择LFXT1工作在低频晶体模式(XTS=0)还是高频晶体模式(XTS=1)。

XT2OFF: 控制XT2振荡器的开启(XT2OFF=0)与关闭(XT2OFF=1)。

正常情况下把XT2OFF复位.

BCSCTL2

时钟配置寄存器2,地址为58H,初始值为00H
在这里插入图片描述
DCOR: 0,选择内部电阻;1,选择外部电阻

DIVS0~1: DIVS=0,1,2,3对应SMCLK的分频因子为1,2,4,8

SELS: 选择SMCLK的时钟源, 0:DCOCLK; 1:XT2CLK/LFXTCLK.

DIVM0~1: 选择MCLK的分频因子, DIVM=0,1,2,3对应分频因子为1,2,4,8.

SELM0~1: 选择MCLK的时钟源, 0与1:DCOCLK, 2:XT2CLK, 3:LFXT1CLK

下面是我自己进行的一段时钟系统初始化配置

void Clock_Init()
{
   unsigned char i;
   BCSCTL1 = RSEL0 + RSEL1 + RSEL2;          // 采用最高频率7   ACLK = XT2
   BCSCTL1&=~XT2OFF; //打开XT2振荡器
   do
   {
      IFG1 &= ~OFIFG; // 清除振荡器失效标志
      for (i = 255; i > 0; i--); // 延时,等待XT2起振
   }
    while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
   
   BCSCTL2 |= SELS+SELM_2;                          // SMCLK = MCLK = XT2   
}

接下来开始学习IO口配置

I/O

’|=‘,’&=~‘赋值操作

   P1DIR &= ~BIT1;   //P1.1端口设置为输入模式
   P1SEL |= BIT1;   //P1.1端口设置为功能复用
   
   P1DIR |= BIT0;   //P1.0端口设置为输出模式
   P1OUT |= BIT0;   //P1.0端口输出高电平

相关函数

在这里插入图片描述

跑马灯(延时函数)

#include <msp430x14x.h>

void Port_Init()
{
   P4DIR |= 0xff;  //P4端口配置为输出模式
}

void Clock_Init()
{
   unsigned char i;
   BCSCTL1 = RSEL0 + RSEL1 + RSEL2;          // 采用最高频率7   ACLK = XT2
   BCSCTL1&=~XT2OFF; //打开XT2振荡器
   do
   {
      IFG1 &= ~OFIFG; // 清除振荡器失效标志
      for (i = 255; i > 0; i--); // 延时,等待XT2起振
   }
    while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
   
   BCSCTL2 |= SELS+SELM_2;                          // SMCLK = MCLK = XT2   
}

void Delay_ms(unsigned int time)
{
   unsigned int i;
   for(i =0 ;i <1000 ;i++ )
     for( ; time >0 ;time--)
       _NOP();
}
void main(void)
{
   unsigned int i;
   
   WDTCTL = WDTPW + WDTHOLD;
   
   Port_Init();
   Clock_Init();
   
   while(1)
   {
       for(i = 0;i<8;i++)
       {
           P4OUT = ~(0x01<<i);
           Delay_ms(60000);

       }
   }
}

接下来使用定时器来实现跑马灯功能,这时候就要引入定时器这个概念了

定时器

内部集成有5种定时器:看门狗定时器WDT,基本定时器BT,定时器TimerA,定时器TimerB,实时时钟RTC.我们主要学习看门狗定时器WDT与定时器TimerA,B。

看门狗定时器WDT

作用

在程序死锁或着系统异常的情况下完成强制复位

特性

1.含有定时器与时钟源(定时器计数一定程度产生特定信号)
2.定时器计数过程中,可以通过某些信号清零定时器(简称喂狗)
3.可以禁止看门狗功能

在这里插入图片描述

相关寄存器:

WDTCTL:

控制看门狗的工作模式 时钟源 定时器时间间隔选择
在这里插入图片描述
WDTPW:看门狗密码设置
WDTHOLD:看门狗定时器挂起
WDTNMIES:看门狗定时器NMI边缘选择
WDTNMI:NMI功能选择位,控制RST/NMI引脚功能。
WDTTMSEL:看门狗功能模式选择。
WDTCNTCL:看门狗定时器清零。
WDTSSEL:看门狗定时器时钟选择。

IE1(系统中断控制寄存器):

控制看门狗电路中断信息
在这里插入图片描述
NMIIE:NMI中断使能控制位。
1:允许NMI中断; 0∶禁止NMI中断。

WDTIE:看门狗定时器中断允许位,控制当看门狗电路工作在周期定时模式时WDTIFG的中断使能。
1∶允许EDTIFG中断; 0:禁止WDTIFG中断。

IFG1(系统中断标志寄存器):

保留系统中断信息
在这里插入图片描述
NMIIFG:NMI中断请求标志位,用户必须软件清除该中断请求。
WDTIFG:看门狗定时器中断请求标志位。需要特别注意,在看门狗模式下该位必须由用户在软件中清除,而在周期定时模式下该位是可以被自动清除的。

程序中使用模式举例

1.禁止使用WDT:
WDTCTL = WDTPW +WDTHOL;//禁止看门狗定时器的使用
2.使用WDT模式:

#include <msp430x14x.h>
void main()//看门狗定时器产生方波
{
  WDTCTL = WDT_MDLY_32;   //看门狗定时器选用32ms的定时周期
  IE1 |= WDTIE;           //打开看门狗定时中断允许位
  P1DIR |= BIT1;          //设置方波输出引脚为输出方向
  _EINT();                //打开总中断使能
}
#pragma vector=WDT_VECTOR      //进入中断服务程序必须添加的语句
__interrupt void Watchdog(void)
{
  P1OUT ^= BIT1;               //看门狗定时器中断响应后将方波输出引脚电平取反,达到方波效果
}

定时器Timer

特点

16位定时器、4种工作模式;
多种可选择的计数器时钟源;
多个可配置输入端的捕获/比较寄存器;
8种输出模式的可配置输出单元

相关寄存器

TACTL:

16位计数器中的控制位和状态位;
在这里插入图片描述

TACCTLx

控制捕获/比较寄存器和比较器;
在这里插入图片描述

TACCRx

该寄存器使用最简单,可读可写,在PWM输出中CCR0常用作周期,CCR1中用作占空比。

TAR

16位计数器的技术执行单元,保存计数器内容

TAIV

保存了中断请求的中断源。
在这里插入图片描述

四种工作模式

停止模式

默认功能

增计数模式(产生两个中断标志)

计数到TACCR0值时,返回0,重新计数。此时计数到TACCR0的同时产生一个中断标志CCIFG,而当计数器溢出返回零的同时又同时产生一个中断标志TAIFG。

连续计数模式(产生一个中断标志)

计数器将直接计数到计数器所能计数的最大值0FFFFH之后重新返回零,再次计数。返回零的同时产生一个TAIFG中断标志。
如果相应中断位允许,每当一个定时间隔到来都会产生中断请求,在连续计数模式下,须将下一事件发生的时间在当前中断程序中加到CCRx中。

增减计数模式(产生两个中断标志)

当计数器计数到跟TACCR0一样的之后,然后从TACCR0开始又减少,直到为零,然后又开始增。当计数跟TACCR0一样的时候产生一个中断标志CCIFG,当减到为零的时候又产生一个中断标志TAIFG。

三种功能:

16位定时计数器

在这里插入图片描述
这是定时器的默认模式,当在比较模式下的时候,与捕获模式相关的硬件停止工作,如果这个时候开启定时器中断,然后设置定时器终值(将终值写入TACCRx),开启定时器,当TAR的值增到TACCRx的时候,中断标志位CCIFGx置1,同时产生中断。若中断允许未开启则只将中断标志位CCIFGx置1。

例子:能够软件设置定时间隔来产生中断处理一些事情,如键盘扫描,也可以结合信号输出产生时序脉冲发生器,PWM信号发生器。如:不断装载TACCRx,启动定时器,TAR和TACCRx比较产生中断处理。

//可以用来做跑马灯实验
#include <msp430x14x.h>

void Port_Init()
{
   P4DIR |= 0xff;   //P4端口设置为输出模式
}

void Clock_Init()
{
   unsigned char i;
   BCSCTL1 = RSEL0 + RSEL1 + RSEL2;          // 采用最高频率7   ACLK = XT2
   BCSCTL1&=~XT2OFF; //打开XT2振荡器
   do
   {
      IFG1 &= ~OFIFG; // 清除振荡器失效标志
      for (i = 255; i > 0; i--); // 延时,等待XT2起振
   }
    while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
   
   BCSCTL2 |= SELS+SELM_2;                          // SMCLK = MCLK = XT2   
}

void Delay_ms(unsigned int time)
{
   unsigned int i;
   for(i =0 ;i <1000 ;i++ )
     for( ; time >0 ;time--)
       _NOP();
}

void TimerA_Init()
{
   CCTL0 = CCIE;                              // 捕获/比较中断使能
   CCR0 = 6000;                               // 比较值为8000,即从0计数到8000产生一次中断  
   TACTL = TASSEL_2 + MC_1+TACLR;              // 使用SMCLK时钟,使用增计数模式,清零TACCR寄存器
}


void main(void)
{   
   WDTCTL = WDTPW + WDTHOLD;               //关闭看门狗
   
   Port_Init();
   Clock_Init();
   TimerA_Init();
   _BIS_SR(LPM0_bits + GIE);                   // _BIS_SR(LPM0_bits + GIE) 具有同时打开全局中断和进入LPM0;  等同于:_EINT();  LPM0;
}

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)             //定时器A中断服务程序
{
  unsigned int i;
  for(i=0;i<8;i++)
  {
    P4OUT=~(0x01<<i);
    Delay_ms(60000);
  } 
}

捕获功能

在这里插入图片描述

捕获模式:
利用外部信号的上升沿、下降沿或上升下降沿触发来测量外部或内部事件,也可以由软件停止。捕获源可以由CCISx选择CCIxA,CCIxB,GND,VCC。完成捕获后相应的捕获标志位CCIFGx置1

捕获模式的应用:
利用捕获源的来触发捕获TAR的值,并将每次捕获的值都保存到TACCRx中,可以随时读取TACCRx的值,TACCRx是个16位的寄存器,捕获模式用于事件的精确定位。如测量时间、频率、速度等

例子:利用两次捕获的值来测量脉冲的宽度。或捕获选择任意沿,CCISx=”11“(输入选择VCC),这样即当VCC与GND发生切换时产生

#include <msp430x14x.h>

void Port_Init()
{
   P1DIR &= ~BIT1;   //P1.1端口设置为输入模式
   P1SEL |= BIT1;   //P1.1端口设置为功能复用
   
   P1DIR |= BIT0;   //P1.0端口设置为输出模式
   P1OUT |= BIT0;
}

void Clock_Init()
{
   unsigned char i;
   BCSCTL1 = RSEL0 + RSEL1 + RSEL2;          // 采用最高频率7   ACLK = XT2
   BCSCTL1&=~XT2OFF; //打开XT2振荡器
   do
   {
      IFG1 &= ~OFIFG; // 清除振荡器失效标志
      for (i = 255; i > 0; i--); // 延时,等待XT2起振
   }
    while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
   
   BCSCTL2 |= SELS+SELM_2;                          // SMCLK = MCLK = XT2   
}

void TimerA_Init()
{
  //定时模式示例
   //CCTL0 = CCIE;                              // 捕获/比较中断使能
   //CCR0 = 6000;                               // 比较值为8000,即从0计数到8000产生一次中断  
   //TACTL = TASSEL_2 + MC_1+TACLR;              // 使用SMCLK时钟,使用增计数模式,清零TACCR寄存器  
   
   //捕获模式示例
   TACTL  = TACLR + TASSEL_2 + ID_2 + MC_3;      //清零TACCR寄存器,使用SMCLK时钟,8分频,使用增减计数模式
   TACCTL0 = CM_2+ CCIS_0 + SCS + CAP + CCIE;   //设置为 上升下降沿捕获,捕获通道0,同步捕获,捕捉模式,捕获/比较中断使能
   //TACCTL1 = CM_3 + CCIS_1 + SCS + CAP + CCIE;   //设置为 上升下降沿捕获,捕获通道1,同步捕获,捕捉模式,捕获/比较中断使能
}


void main(void)
{   
   WDTCTL = WDTPW + WDTHOLD;               //关闭看门狗
   
   Port_Init();
   Clock_Init();
   TimerA_Init();
   _BIS_SR(LPM0_bits + GIE);                   // _BIS_SR(LPM0_bits + GIE) 具有同时打开全局中断和进入LPM0;  等同于:_EINT();  LPM0;
                                              // 如果只使用定时器之类的功能时,可以使用低功耗模式,而不使用while(1)

}

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)             //定时器A中断服务程序
{
    P1OUT ^= BIT0;
}

输出PWM功能

在这里插入图片描述

#include <msp430x14x.h>

void Port_Init()
{
   P6DIR  = 0XFF;
   P6OUT  = 0Xff;
}

void Clock_Init()
{
   unsigned char i;
   BCSCTL1 = RSEL0 + RSEL1 + RSEL2;          // 采用最高频率7   ACLK = XT2
   BCSCTL1&=~XT2OFF; //打开XT2振荡器
   do
   {
      IFG1 &= ~OFIFG; // 清除振荡器失效标志
      for (i = 255; i > 0; i--); // 延时,等待XT2起振
   }
    while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
   
   BCSCTL2 |= SELS+SELM_2;                          // SMCLK = MCLK = XT2   
}

void Delay_ms(unsigned int time)
{
   unsigned int i;
   for(i =0 ;i <1000 ;i++ )
     for( ; time >0 ;time--)
       _NOP();
}

void TimerA_Init()
{
  //定时模式示例
   //CCTL0 = CCIE;                              // 捕获/比较中断使能
   //CCR0 = 6000;                               // 比较值为8000,即从0计数到8000产生一次中断  
   //TACTL = TASSEL_2 + MC_1+TACLR;              // 使用SMCLK时钟,使用增计数模式,清零TACCR寄存器  
   
   //捕获模式示例
   //TACTL  = TACLR + TASSEL_2 + ID_3 + MC_3;      //清零TACCR寄存器,使用SMCLK时钟,8分频,使用增减计数模式
   //TACCTL0 = CM_2+ CCIS_0 + SCS + CAP + CCIE;   //设置为 下降沿捕获,捕获通道0,同步捕获,捕捉模式,捕获/比较中断使能
   //TACCTL1 = CM_3 + CCIS_1 + SCS + CAP + CCIE;   //设置为 上升下降沿捕获,捕获通道1,同步捕获,捕捉模式,捕获/比较中断使能
   
  //PWM输出模式示例
   TACTL |= TASSEL_2 + ID_3 + MC_2 + TACLR + TAIE; //使用SMCLK时钟,8分频,使用连续计数模式,清零TACCR寄存器,定时器溢出中断
   TACCTL0= CCIE;
   CCR0 = 5000;
}


void main(void)
{   
   WDTCTL = WDTPW + WDTHOLD;               //关闭看门狗
   
   Port_Init();
   Clock_Init();
   TimerA_Init();
   _BIS_SR(LPM0_bits + GIE);                   // _BIS_SR(LPM0_bits + GIE) 具有同时打开全局中断和进入LPM0;  等同于:_EINT();  LPM0;
                                               // 如果只使用定时器之类的功能时,可以使用低功耗模式,而不使用while(1)
}

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)             //定时器A中断服务程序
{
   P6OUT ^= BIT0;
   CCR0 = CCR0 + 5000;
  
}

  • 12
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
msp430f5529lp定时器的输出模式可以通过设置captureOutputMode参数来实现。根据引用\[2\]中的描述,可以选择以下几种输出模式: - TIMER_A_OUTPUTMODE_OUTBITVALUE:定时器输出电平由OUT位控制。 - TIMER_A_OUTPUTMODE_SET:定时器输出电平为高电平。 - TIMER_A_OUTPUTMODE_TOGGLE_RESET:定时器输出电平在每次比较中切换一次。 - TIMER_A_OUTPUTMODE_SET_RESET:定时器输出电平在每次比较中先置高再置低。 - TIMER_A_OUTPUTMODE_TOGGLE:定时器输出电平在每次比较中切换一次。 - TIMER_A_OUTPUTMODE_RESET:定时器输出电平为低电平。 - TIMER_A_OUTPUTMODE_TOGGLE_SET:定时器输出电平在每次比较中切换一次。 - TIMER_A_OUTPUTMODE_RESET_SET:定时器输出电平在每次比较中先置低再置高。 根据你的需求,选择适合的输出模式即可。 #### 引用[.reference_title] - *1* *2* [MSP430F5529库函数定时器A——捕获实验](https://blog.csdn.net/qq_63922192/article/details/127779050)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [MSP430F5529库函数定时器A——硬件PWM](https://blog.csdn.net/qq_63922192/article/details/127778390)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值