一開始沒寫好就上傳了,,,,,,,,這次來個全的
自己學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分頻后作為其信號源。
有三個呢!!!真多
自從博客可以復制粘貼圖片,感覺真是太方便了