2017-06-26 82 views
-1

我在mikroC for PIC中實現基於計時器的中斷時遇到問題。使用mikroC for PIC的PIC單片機中的基於計時器的中斷

如果在PORTC.F0上有一個按鍵,並且在切換之間應該有100ms的延遲,我想切換一個端口引腳8次。

正常情況下應該使用延遲功能

for (i=0;i<=8;i++) 
{ 
    PORTB.F0=~PORTB.F0; 
    Delay_ms(100); 
} 

但在此期間,任何其他按鍵被系統錯過了會很容易。所以我想用中斷來實現解決方案。

#define SW PORTC.F0 

char ttime,i; 
volatile flag; 

void Inittimer() 
{ 
T1CON   = 0x01; 
TMR1IF_bit = 0; 
TMR1H   = 0x06; 
TMR1L   = 0x00; 
TMR1IE_bit = 1; 
INTCON  = 0xC0; 
} 

void Interrupt() 
{ 
if (TMR1IF_bit) 
{ 
    TMR1IF_bit = 0; 
    TMR1H   = 0x06; 
    TMR1L   = 0x00; 
    ttime--; 
    if (ttime==0) 
    { 
    flag=1; 
    } 
} 
} 

void main() 
{ 
Inittimer1(); 
TRISB = 0; 
TRISC.F0 = 1; 
PORTB = 0x00; 
while(1) 
{ 
if (SW==0) 
{ 
    ttime=3; 
} 
    if (flag==1) 
    { 
    for (i=0;i<=8;i++) 
    { 
    PORTB=~PORTB; 
    flag=0; 
    } 
    } 
} 
} 

沒有任何工作。有人可以幫我改正代碼嗎?

+2

「沒有什麼工作」不是問題描述。 _什麼不工作? – Lundin

+0

事後看來,沒有任何工作確實是一個非常模糊的評論。我正在嘗試使用定時器中斷每隔100ms實現一次PORT切換8次。我嘗試了許多選擇,他們都沒有爲我工作。最接近的是使用中斷在延遲一段時間後切換PORT。但無法阻止它在n次之後切換。 – Ace

回答

0

當你初始化定時器:

void Inittimer() 
{ 
T1CON   = 0x01; 
TMR1IF_bit = 0; 
TMR1H   = 0x06; // No prescaler? I doubt your clock speed is 40-some KHz! 
TMR1L   = 0x00; 
TMR1IE_bit = 1; 
INTCON  = 0xC0; 
} 

你爲什麼不直接控制從ISR LED?

if (ttime) 
     PORTB.F0 = (--ttime & 1); // ttime is not decremented when led is not blinking. 
    else 
     PORTB.F0 = 0;    // ensures the LED is off. 

要開始閃爍8次:

if (SW==0) 
{ 
    PORTB.F0 = 1; 
    ttime = 16; 
} 

注意,有100ms的時鐘中斷,LED的第一個「眨眼」可能長達200ms的...這就是爲什麼許多喜歡以更快的定時器中斷工作(這通常有其他用途以及),控制LED將需要新增軟後縮放

if (blinking) 
    { 
     if (--blinkTimer == 0) 
     { 
     blinkTimer = BLINK_DELAY;  // whatever number it takes for 100ms. 
     PORTB.F0 = (--blinking & 1); 
     } 
    } 
    else 
    { 
     PORTB.F0 = 0 
    } 

要開始閃爍:

if (SW==0) 
{ 
    blinking = (2 * BLINKS) - 1; 
    blinkTimer = BLINK_DELAY; 
    PORTB.F0 = 1; 
} 

這應該會讓你更眨眼。

+0

謝謝你的幫助邁克爾。我確實解決了這個問題,你能否檢查一下這個方法是否正確? while(i <8){if(flag == 1){i ++; PORTB.F0 =〜PORTB.F0; CNT = 0;標誌= 0; }}'這會切換端口引腳8次,並且設置cnt的值允許精確設置端口引腳切換的延遲。這種方法是否正確? – Ace

+0

這是正確的,但它阻止了你的主循環。您可能需要執行的所有其他操作中有哪些? –

1

嗯,這看起來不正確:

if (flag==1) 
    { 
    for (i=0;i<=8;i++) 
    { 
    PORTB=~PORTB; 
    flag=0; 
    } 
    } 

當你第一次看到flag設置,你馬上循環和切換輸出的8倍,沒有等待flag回頭1。這是不對的,它太簡單了。

您需要尋找flag,然後切換輸出並清除flag,然後等待它再次置位,並使計數器保持並行。 for循環並不是適當的結構,因爲它會「鎖定」程序的其餘部分,並可能導致錯按按鍵。

+0

我試着做你的建議, – Ace

+0

我試着做你所建議的......而不是for循環,在端口被切換並且標誌被清除後,我增加了另一個變量i。我確實放了一個條件語句if(i> = 8){PORTB = 0x00;我= 0;}'這沒有奏效。基本上,我可以啓動PORT在一定延遲後切換,但無法理解如何在n次循環後停止切換。 – Ace