4-MSP430定時器_定時器中斷


一開始沒寫好就上傳了,,,,,,,,這次來個全的

自己學MSP430是為了寫一篇關於PID的文章,需要430在proteus上做仿真,一則認為在自動控制算法上PID真的很經典,PLC設備上大多是模塊式的,拿來就是參考說明書設置,設置,,,而對於單片機而言就是程序!!!只有自己寫出來PID算法,才能對PID有更深刻的理解,..二來感覺自己已經好久都沒有寫一篇讓自己感到滿意的文章了......

這些天,,,,今天終於解除了我的很大疑惑了,,,,,,,終於可以完成這篇普通普通定時器中斷的文章了,,,,,,其實說普通也不普通,,MSP430的定時器確實設計的很強悍,,,,,,,,

其實對於普通定時器吧!不外乎,,,,定時,,,,產生中斷,,,,細節問題就不說了,,,,看我下面的理論介紹部分,,其實寫文章一部分是為了分享,最重要的是考驗自己到底有沒有真正的學會,真正的深入理解了自己所學的東西,自己學東西是一步一個腳印,這倒是高中的班主任的功勞,現在想想自己自學從高三就開始了,沒想到當年的班主任的一段話對自己的影響竟然如此的大..如果文章有問題希望親們給意見哈,,,

CCR0   和  TACCR0  是一個哈,,,,,,,,別在別處看到CCR0就蒙了哈,,,這是設置的計數比較值,,

 

430的定時器能選擇時鍾來源,,具體看下面,,,如果不選擇那么就是用一個引腳(特定的)的輸入PWM作為他的時鍾了

先上菜----外部引腳來四個上升沿就進入下面的中斷函數  

實質----內部計數器TAR在計數到CCR0(TACCR0)時就進來了

 

__interrupt void Timer_A0 (void)     //定時器A0中斷服務程序
{
  P4OUT ^= BIT1; //P4_1引腳反轉
}

然后再來一個上升沿,,就會進入---溢出中斷-------可以取消,不讓他有溢出中斷   

實質----內部計數器TAR在計數到CCR0后,,再來一個上升沿就變成 0 了,,,然后就就進來了

 

__interrupt void Timer_A1 (void) //A1,A2,溢出中斷都會進
{
  switch( TAIV )
  {
  case  TAIV_TAIFG://溢出中斷
             P4OUT ^= BIT1; //P4_1反轉
             break;
  }
}

 

下面是完整的程序

P1_0引腳,來四個上升沿TAR變為4,,P4_1反轉,,,再來一個沿TAR變為0,再來四個,TAR變為4,,P4_1反轉,再來一個沿TAR變為0,再來四個,TAR變為4,,P4_1反轉,,,循環

所以發現第一次來四個P4_1反轉,,,,后來的都是來5個再反轉了,,所以如果你想來四個反轉,,那么TACCR0應該為3

#include "io430.h"

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;//關閉看門狗
  
  P4DIR |= BIT1; 
  
  TACTL |= TASSEL_0 + MC_1+ TAIE + TACLR;//時鍾外部引腳輸入,增計數模式,產生溢出中斷(可以取消),清除一下溢出,,其實嚴謹一點嘛,先清除再說

  TACCR0 = 3;//計數值3
  TACCTL0 = CCIE;//允許中斷
  
  __enable_interrupt();//打開總中斷
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0 (void)     //定時器A0中斷服務程序
{
  P4OUT ^= BIT1; 
}

#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A1 (void) //A1,A2,溢出中斷都會進
{
  switch( TAIV )
  {
  case  TAIV_TAIFG://溢出中斷
             P4OUT ^= BIT1; 
             break;
  }
}

現在去掉溢出中斷

 

#include "io430.h"

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;//關閉看門狗
  
  P4DIR |= BIT1; 
  
  TACTL |= TASSEL_0 + MC_1+TACLR;//外部引腳模式,,增計數模式

  TACCR0 = 3;//計數值3,其實是4,,因為有一個溢出變為0
  TACCTL0 = CCIE;//允許中斷
  
  __enable_interrupt();//打開總中斷
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0 (void)     //定時器A0中斷服務程序
{
  P4OUT ^= BIT1; 
}

下面是一些具體解釋

#include "io430.h"

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;//關閉看門狗
  
  P4DIR |= BIT1+BIT2; 
  
  TACTL |= TASSEL_0 + MC_2+TACLR;//外部引腳模式,,連續計數模式

  TACCR0 = 4;//計數值4
  TACCTL0 = CCIE;//允許中斷
  
  __enable_interrupt();//打開總中斷
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0 (void)     //定時器A0中斷服務程序
{
  P4OUT ^= BIT1; 
}

可以這樣

#include "io430.h"

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;//關閉看門狗
  
  P4DIR |= BIT1+BIT2; 
  
  TACTL |= TASSEL_0 + MC_2+TACLR;//外部引腳模式,,連續計數模式

  TACCR0 = 4;//計數值4
  TACCTL0 = CCIE;//允許中斷
  
  __enable_interrupt();//打開總中斷
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0 (void)     //定時器A0中斷服務程序
{
  TACCR0 = TACCR0 + 4;//******這里,這里***********//
  P4OUT ^= BIT1; 
}

因為是連續計數模式,所以可以用TACCR1了,,,,

#include "io430.h"

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;//關閉看門狗
  
  P4DIR |= BIT1+BIT2; 
  
  TACTL |= TASSEL_0 + MC_2+TACLR;//外部引腳模式,,連續計數模式

  TACCR0 = 4;//計數值4,TAR==TACCR0進入它的中斷函數
  TACCTL0 = CCIE;//允許中斷
  
  TACCR1 = 6;//計數值6,TAR==TACCR1進入它的中斷函數
  TACCTL1 = CCIE;//允許中斷
  
  __enable_interrupt();//打開總中斷
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0 (void)     //定時器A0中斷服務程序
{
  TACCR0 = TACCR0 + 4;//******這里,這里***********//
  P4OUT ^= BIT1; 
}

#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A1 (void) //A1,A2,溢出中斷都會進(共用)
{
  switch( TAIV )
  {
  case  TAIV_TACCR1://計數"  TACCR1 "的中斷
             TACCR1 = TACCR1 + 6;
             P4OUT ^= BIT2; 
             break;
  }
}

既然有溢出中斷那么再加上溢出中斷吧

#include "io430.h"

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;//關閉看門狗
  
  P4DIR |= BIT1+BIT2+BIT3; 
  
  TACTL |= TASSEL_0 + MC_2 + TAIE +TACLR;//外部引腳模式,,增計數模式

  TACCR0 = 4;//計數值4,TAR==TACCR0進入它的中斷函數
  TACCTL0 = CCIE;//允許中斷
  
  TACCR1 = 6;//計數值6,TAR==TACCR1進入它的中斷函數
  TACCTL1 = CCIE;//允許中斷
  
  __enable_interrupt();//打開總中斷
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0 (void)     //定時器A0中斷服務程序
{
  TACCR0 = TACCR0 + 4;//******這里,這里***********//
  P4OUT ^= BIT1; 
}

#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A1 (void) //A1,A2,溢出中斷都會進(共用)
{
  switch( TAIV )
  {
  case  TAIV_TACCR1://計數"  TACCR1 "的中斷
             TACCR1 = TACCR1 + 6;
             P4OUT ^= BIT2; 
             break;
  case  TAIV_TAIFG://溢出中斷,,,,ffff變0時
             P4OUT ^= BIT3; 
             break;           
  }
}

下面是理論知識的介紹,,,看了上面再看一下下面,,,,,

 

通俗來講,430F249有三個振盪器,LFXT1,,XT2,,DCO,

內部的主時鍾MCLK,,子系統時鍾SMCLK和輔助時鍾ACLK是由這三個振盪器來源提供的.

MCLK:主時鍾

可以選擇3個振盪器(LFXT1、XT2、DCO)之一,或它們1/2/4/8分頻后作為其信號源;

SMCLK:子系統時鍾

可以選擇2個振盪器(XT2、DCO),或它們1/2/4/8分頻后作為其信號源;

ACLK:輔助時鍾

只能由LFXT1時鍾信號或1/2/4/8分頻后作為其信號源。

有三個呢!!!真多

 

 

自從博客可以復制粘貼圖片,感覺真是太方便了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM