Đếm 1s bằng Timer MSP430

BBlackmoon

Thành Viên PIF
Mình cần cho LED nháy 1s dùng timer. Tinh thần là cho TimerA0 đếm 0,5s, ngắt 2 lần thì nháy LED. Code như sau:
void Timer0_init()
{
TA0CTL = TASSEL_2 + MC_2 + ID_3 + TAIE ;//SMCLK(1Mhz)
//continuous mode
//divided by 8

TA0CCR0 = halfsecond;//enable interrupt when the timer count to 62500 (=0.5s)
TA0CCTL0 = CCIE;//enable interrupt CCR0

}

__interrupt void CCR0_Interrupt (void)//name of the interrupt vector
{
count ++;
TA0CCR0+=halfsecond;//add 0.5s to CCR0
if (count == 2)
{
count = 0;
P2OUT ^= BIT3;
}
}

Biến count được khai báo toàn cục đầu chương trình:
#include<msp430.h>
#define halfsecond 62500

unsigned int count = 0;

Tuy nhiên code không chạy, cụ thể là cứ mỗi lần ra khỏi vector ngắt của timer thì count lại bị về 0.
Ai giúp mình với.
Xin cảm ơn!
 

honghiep

Cố Vấn CLB
Staff member
Bạn thử khai báo: volatile unsigned int count = 0; coi sao nhé:)
 

lee_trieu

Gà con
Của bạn đây ! Đảo LED P1.6 sau mỗi giây !!:)

PHP:
//Code by: Thanh Trieu;
#include "msp430g2553.h"
 
int call_count=0;
void EOS_init(unsigned int x);
void main( void )
{
  // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;
    EOS_init(50000);//KHoi dong Timer ngat moi 100ms
    P1DIR |= BIT6;
    while(1)
    {
        LPM1;
    }
}
 
void EOS_init(unsigned int x)
{  TACCR0 = x+300;    // canh chinh lai thoi gian vi dung bo dao dong SMCLK khong chinh xac
    __enable_interrupt();    //  Cho phep ngat
    TACCTL0|= CCIE;  //  Enable timer interrupt (compare)
    TACTL |= (TASSEL1 + MC0 +ID0 ) ; //  Start timer,UP to CCR0, DIV 2
}
 
#pragma vector = TIMER0_A0_VECTOR
__interrupt void EOS_ISR(void)
{
    if(++call_count==10)//Thuc hien chuong trinh phuc vu ngat sau moi 1s;
        {
        call_count=0;
        P1OUT ^=BIT6;
        LPM1_EXIT;
        }
}
 

BBlackmoon

Thành Viên PIF
Tại sao 2 code giống nhau, code của bạn chạy còn của mình không chạy nhỉ?
 

lee_trieu

Gà con
Tại sao 2 code giống nhau, code của bạn chạy còn của mình không chạy nhỉ?
Thứ nhất : Mình không thấy trong code bạn có vector ngắt nào.
Thứ hai: Nếu bạn dùng Vector ngắt:
PHP:
#pragma vector = TIMER0_A0_VECTOR
thì bạn không cần phải add offset cho CCR0 nghĩa là trong chương trình vục phụ ngắt bạn không cần thêm dòng lệnh
PHP:
TA0CCR0+=halfsecond;//add 0.5s to CCR0
.
 

BBlackmoon

Thành Viên PIF
Mình có vector ngắt
Code:
#pragma vector=TIMER0_A0_VECTOR            //interrupt vector of CCR0
__interrupt void CCR0_Interrupt (void)    //name of the interrupt vector
{
    count ++;
 
    if (count == 2)
    {
        count = 0;
        P2OUT ^= BIT3;
        _bic_SR_register_on_exit(LPM1_bits);
    }
    TA0CCR0+=halfsecond;                //add 0.5s to CCR0
 
}
Do mình dùng continuous mode nên phải cộng thêm lượng 62500 để ngắt đúng 0.5s.
Code:
void Timer0_init()
{
TA0CTL = TASSEL_2 + MC_2 + ID_3 + TAIE ;//SMCLK(1Mhz)
//continuous mode
//divided by 8
 
TA0CCR0 = halfsecond;//enable interrupt when the timer count to 62500 (=0.5s)
TA0CCTL0 = CCIE;//enable interrupt CCR0
 
}
Mình thắc mắc bạn configure MC0, tức là timer không hoạt động, tại sao code vẫn chạy nhỉ?
 

lee_trieu

Gà con
Mình thắc mắc bạn configure MC0, tức là timer không hoạt động, tại sao code vẫn chạy nhỉ?
Không phải bạn ! bạn mở file msp430g2553.h lên xem có 2 cái define thế này
PHP:
#define MC1                (0x0020u)  /* Timer A mode control 1 */
#define MC0                (0x0010u)  /* Timer A mode control 0 */
nếu mình set MC0 thì nghĩa là mode control là 01 tương ứng với cái define
PHP:
#define MC_1                (1*0x10u)  /* Timer A mode control: 1 - Up to CCR0 */
Cái chia tần và chọn nguồn xung cũng tương tự nhé !:)
 

BBlackmoon

Thành Viên PIF
Thank bạn.
Hai chương trình đâu có khác biệt, mình cũng đã thử dùng Up mode, nhưng tại sao code của mình không chạy nhỉ?
 

lee_trieu

Gà con
Thank bạn.
Hai chương trình đâu có khác biệt, mình cũng đã thử dùng Up mode, nhưng tại sao code của mình không chạy nhỉ?
Bạn up full code lên đây minh xem thế nào?:-(
 

BBlackmoon

Thành Viên PIF
Code:
#include<msp430.h>
 
//define a half second use for timer
//timer use (1:8)Mhz project
//=>62500*8*10^(-6)=0.5s
#define halfsecond 62500
 
unsigned int count = 0;
 
void Timer0_init();            //configure and set up timer_A0
void Port_init();                //configure port
 
 
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;            //turn off watch dog timer
    Port_init();                        //call Port_int() funtion
    Timer0_init();                        //call Timera0_ini() funtion
    while(1)
    {
        _BIS_SR( LPM1_bits + GIE);
    }
    //low power mode, if there is nothing to do, the CPU will sleep,
    //end the program
    //+ global interrupt
}
 
//********************************
//declate Timera0_init()
void Timer0_init()
{
    TA0CTL = TASSEL_2 + MC_1 + ID_3 + TAIE ;        //SMCLK(1Mhz)
                                                    //up mode
                                                    //divided by 8
 
    TA0CCR0 = halfsecond;        //enable interrupt when the timer count to 62500 (=0.5s)
    TA0CCTL0 = CCIE;            //enable interrupt CCR0
 
}
 
 
void Port_init()
{
    P2DIR |=BIT3 + BIT6;        //1.0,1.6 output
    P2DIR &= ~BIT2;                //1.2 input
 
}
 
 
//*********************************
//declare interrupt vector Timer_A0
 
#pragma vector=TIMER0_A0_VECTOR            //interrupt vector of CCR0
__interrupt void CCR0_Interrupt (void)    //name of the interrupt vector
{
    count ++;
    if (count == 2)
    {
        count = 0;
        P2OUT ^= BIT3;
        _bic_SR_register_on_exit(LPM1_bits);
    }
//    TA0CCR0+=halfsecond;                //add 0.5s to CCR0
 
}
MÌnh thử lại thì thấy tại dòng này
TA0CTL = TASSEL_2 + MC_1 + ID_3 + TAIE
Nếu mình không cho ngắt tràn TAIE thì chạy được. Còn cho ngắt thì không chạy. ???
 
Top