2015-02-08 51 views
0

這不是一項任務,我只是想學習嵌入式C從Arduino中移走。 (基於this interrupt LED example簡單的8051 C中斷事件計數器演示,不增加。

我想創建一箇中斷輸入事件計數器。使用連接到P3.2的去抖按鈕開關在LCD上增加一個3位數的數字。 000在啓動時顯示,並且中斷中的觸發LED確實關閉&,但顯示號碼不遞增。我的目標是:推1:顯示001,推2:顯示002等按下重置返回到000.

我認爲問題是用while()。當while()被註釋時,LCD顯示屏快速閃爍並且不清楚要讀取,但是當按下開關時我會看到'1'(帶LED亮) - 當開關被釋放時LED熄滅(不切換)然而'1'清除。對於while()取消註釋,LCD顯示屏固定爲&清除,LED將打開&,但沒有計數器數量增量。

的代碼:

// ****Event counter using external interrupt 0**** 

#include<reg51.h> 
#include "lcd4bit.h" 
void cct_init(void); 
void InitINT0(void); 
sbit LED = P2^3;  // Int status LED  
unsigned char str1[]="Line2"; 
char stringy[3] = {'0','0','0'}; 
char count = 0; 
int number = 0; 

void main() 
{ 
char count = 0; 
if (number != 0) 
cct_init();  // Make all ports zero 
InitINT0();  // Intialize INT0 interrupts 
    stringy[count]=(number%10)+48; 
    number/=10; 
init_lcd(); 
    gotoxy_lcd(1,1); //(Col, Line#) 
    print_lcd("Line One"); 
    gotoxy_lcd(1,2); 
    print_lcd(stringy); 
    while(1) 
    { } 
} 

void cct_init(void) // Init CCT function 
{ 
    P3 = 0x04; // Make P3.2 (INT0) pin high only 
} 

void InitINT0(void) // External INT0 pin interrupt init function 
{ 
    IT0 = 1;  //Edge triggered interrupt mode (Neg) 
    EX0 = 1;  //Enable external interrupt INT0 
    EA = 1;  //Enable global interrupts 
} 

void external0_isr(void) interrupt 0 // Inturrupt 0 ISR 
{ 
    number = number + 1; 
    LED = ~LED; // Toggle LED 
} 

任何建議表示讚賞。

+0

在中斷或'while()'循環中,代碼似乎不會改變顯示,所以爲什麼除LED之外的任何可見變化? – chux 2015-02-08 19:25:44

+0

您可以在AVR上使用嵌入式C,它將使用您的Arduino硬件,並將您從8051的恐怖中拯救出來。 – 2015-03-02 03:13:27

回答

1

我想你誤解了ISR的工作原理。除了while(1) {}之外的所有主代碼都會在程序開始時執行一次。然後主線程就在其餘的執行過程中位於循環旋轉的內部。

發生的中斷不會將主線程重置回main()或任何其他東西。

此外,代碼:

if (number != 0) 
cct_init();  // Make all ports zero 
InitINT0();  // Intialize INT0 interrupts 

不會叫cct_init()因爲number == 0這裏,然後調用InitINT0()。除非使用{ }來組合語句,否則if語句只綁定到它後面的一條語句。

根據您鏈接的示例中,這應該僅僅是:

cct_init(); 
InitINT0(); 

如果你想在main()代碼中斷觸發,那麼你將不得不改變你的while環路檢測的結果來執行number的變化。

這可能會實現:

// global var 
volatile int number = 0; 

// in main() instead of your existing while loop 
int previous_number = 0; 

while (1) 
{ 
    if (number != previous_number) 
    { 
     previous_number = number; 
     // put your LCD updating code here 
     // possibly you should disable the interrupt before the LCD code 
     // and re-enable the interrupt afterwards 
    } 
} 

有一個在一個潛在的漏洞比較number != previous_number可能不是原子。使用unsigned char代替int代替number似乎是一種很好的預防措施。

這個話題的原子性和操作應該在文檔中提到8051嵌入到平臺的文檔中,所以我會試着去查看它的確認。

+0

我失去了我的初始LCD顯示屏。我必須採取不同的方法。我無法在此處發佈我的修改代碼。處理你的建議。 – Ashton 2015-02-09 01:23:28

+0

@Ashton將'previous_number'關閉到不同的值以獲得初始顯示 – 2015-02-09 03:13:52