[C14] Em hỏi về dịch bit để sáng led

Pham Dat

Thành Viên PIF
em không biết tại sao led sáng từng led được 1 vòng r` sáng mãi led đầu mà nó ko lặp lại đc
#include <msp430.h>
#include "stdbool.h"
/*
* main.c
*/
int i = 0;
int s = 0;
int k = 0;
unsigned int a = 0x01;
unsigned int b = 0x03; // để tăng lượng led

void main(void)
{
// GPIO Init
WDTCTL = WDTPW + WDTHOLD; // Stop watch dog timer
P2SEL = 0;
P2SEL2=0;
P2DIR|=0XFF;
P2OUT |=0XFF;
//P1DIR |= BIT0 + BIT6; // Set P1.0 and P1.6 to output
// P1OUT &= ~(BIT0 + BIT6);

P1DIR &= ~BIT3; // Set P1.3 to input
P1REN |=BIT3;
P1OUT |=BIT3;

// Interrupt config
P1IE |= BIT3; // Enable P1.3 Interrupt
P1IES |= BIT3; // Falling Edge Interrupt
P1IFG &= ~BIT3; // Clear Interrupt Flags

_BIS_SR(GIE); // enable global interrupt

i = 0;
s = 0;
int m = 2;
int B = 0; // tăng lượng led
while(1)
{
if(i == 1)
{
if(s <= 8 )
{
a = 0x01 << s++;
P2OUT = ~a;
__delay_cycles(200000);
}
else if(s > 8)
{
a = 0x80 >> k++;
P2OUT = ~a;
__delay_cycles(200000);
}
if(k == 8)
{
s = 0;
}
if(s == 8)
{
k = 0;
}

}

}
}

/******************************************************************************
* INTERRUPT
*****************************************************************************/
#pragma vector = PORT1_VECTOR
__interrupt void P1_ISR (void)
{
switch (P1IFG & BIT3)
{
case BIT3:
{
i++;
}
}

__delay_cycles(200000);
P1IFG &= ~BIT3; // Clear Interrupt Flags
}
 

Võ Hồng Đức

Thành Viên PIF
-trong trường hợp của bạn có thể do có delay trong chương trình ngắt, nên nó treo luôn trong ngắt
-bạn nên khai báo biến
Code:
int i = 0;
thành
Code:
volatile int i = 0;
, nếu chỉ khai báo int i = 0; trong 1 số trường hợp nó sẽ không chạy (xảy ra trường hợp race condition), bạn có thể google từ volatile
 

black_knight

Trứng gà
Cho em hỏi là tại sao khi em đặt biến toàn cục dùng làm biến chạy vòng lặp for thì nó không chạy đúng. Trong CCS không cho phép code for(int i;i<8; i++) mà phải khai báo biến i ở ngoài vòng lặp for. Em thử khai báo biến i toàn cục để nếu viết nhiều chương trình con thì đỡ phải khai báo lại nhưng chương trình chạy không đúng, nếu khai báo biến i làm biến cục bộ trong hàm con thì chạy đúng.
 

black_knight

Trứng gà
Code:
#include <msp430.h>
#include <math.h>
#include "stdbool.h"
/*
* main.c
*/
 
volatile int led_dir;  //variable to control led direction
volatile int led_num;  //variable to control number led run
 
int matrixtodecade(int m[])
{
    unsigned int count;
    int decade = 0;
    for(count=0; count<8; count++)
    {
        if(m[count]==1)
            decade += pow(2,count);
    }
 
    return decade;
}
 
int led_run(int led[])
{
    int m[8];
    unsigned int count;
    //led run right
    if(led_dir==0)
    {
        for(count=0; count<8; count++)
        {
            if(count==0)
                m[0]=led[7];
            else
                m[count]=led[count-1];
        }
    }
    // led run left
    else
    {
        for(count=0; count<8; count++)
        {
            if(count==7)
                m[7]=led[0];
            else
                m[count]=led[count + 1];
        }
    }
 
    for(count=0; count<8; count++)
        led[count]=m[count];
 
    return matrixtodecade(led);
}
 
void main(void)
{
    // GPIO Init
    WDTCTL = WDTPW + WDTHOLD;    // Stop watch dog timer
 
    // Setup P2
    P2SEL = P2SEL2 = 0;
    P2DIR |= 0xFF;  //set P2 output all port
    P2OUT = 0xFF; //turn off all led
 
    // Setup P1
    P1DIR &= ~(BIT3);    //set P1.0 & P1.3 input
    P1REN |= BIT3;    //enable pull up registor p1.0 & p1.3
    P1OUT |= BIT3;
 
    //Interrupt config
    P1IE |= BIT3;        //enable p1.0 & p1.3 interrupt
    P1IES |= BIT3;    //falling edge interrupt
    P1IFG &= ~(BIT3);    //clear flag
 
    _BIS_SR(GIE);    //enable global interrupt
 
    //config variable
    led_num = 1;
    led_dir = 1;
    int led[8] = {0,1,1,1,1,1,1,1};
 
    //run led
    while(1)
    {
        if(led_dir==1)
        {
            P2OUT = led_run(led);
            _delay_cycles(200000);
        }
        else
            P2OUT = 0xFF;
    }
}
 
 
 
/******************************************************************************
* INTERRUPT
*****************************************************************************/
#pragma vector = PORT1_VECTOR
__interrupt void P1_ISR (void)
{
    led_dir = (led_dir == 0);
    P1IFG &= ~BIT3;    // Clear Interrupt Flags
}
Cho em hỏi là tại sao khi em dùng vòng lặp trong chương trình con thì ngắt không hoạt động, khi không sử dụng vòng lặp thì ngắt hoạt động bình thường. Nếu em bỏ lệnh P2OUT = led_run(led) để nhảy vào vòng lặp mà thay bằng lệnh xử lý chớp tắt 1 led khi có ngắt xảy ra thì mạch hoạt động bình thường, nếu có lệnh led_run, chương trình chạy vòng lặp thì dường như là khi biến led_dir chỉ thay đổi tức thì khi nhấn nút và quay về giá trị đầu ngay lặp tức chứ không đợi nhấn lần thứ hai.
 

black_knight

Trứng gà
Em đã tìm ra nguyên nhân, đó là do hàm pow(2,k) gây ra, thay hàm pow bằng 1 hàm mũ tự viết thì led chạy bình thường. Tuy nhiên vẫn còn có 1 khúc mắc là tại sao lại không dùng hàm pow chung với ngắt được?
 
Top