簡體   English   中英

如何根據使用 C、PIC16 和 PIC 開發板按下的按鈕改變 LED 方向?

[英]How to change led direction depending on button pressed using C, PIC16 and PIC development board?

我創建了一個程序來根據在端口 a 和端口 b 上按下哪個按鈕來切換 LED 燈,因為當在端口 a 上按下按鈕時,LED 會從左到右或從右到左閃爍。 當按下按鈕 3 時,LED 開始從左到右彈跳並重置並繼續永遠做同樣的事情。 當按下按鈕 0 時,它會反轉方向並從右向左移動。 當按下按鈕 4 時,它再次反轉方向,現在它從左向右移動。 我的問題是,一旦按下按鈕 4,我無法通過按下按鈕 0 再次反轉方向。我將如何修改代碼以使其工作? 使用PIC16F877A和pic開發板

#include <system.h>

void delay(int j) {
int i;
int x = 8600;
while (j != 0) {
    for (i = x; i != 0; i--);
    j--;
}
}

void main() {

trisb = 0; // sets all bits in port B as outputs
adcon1 = 0x06; // sets port A as digital inputs
while (1) // creates infinite loop
{

    if ((porta & 0x8)) { // Switch 3 - Left bounces from left to right and right to left

        portb = 0x80;
        delay(1);

        while (1) {
            while ((portb != 0)) { // Shifts LED from left to right as long as LED 0 is not active
                portb = portb >> 1;
                delay(1);

                if ((portb == 0)) { // When LED 0 is lit, it resets to LED 7
                    portb = 0x80;
                    delay(1);
                }

                if ((porta & 0x1)) { // If SA0 is pressed, LED shifting direction will reverse (right to left)
                    while ((portb != 0x80)) {
                        portb = portb << 1;
                        delay(1);
                        if ((portb == 0x80)) {
                            portb = 0x1;
                            delay(1);
                        }
                        if ((porta & 0x10)) { // If SA4 is pressed, LED shifting direction will reverse (left to right)
                            while ((portb != 0)) {
                                portb = portb >> 1;
                                delay(1);
                                if ((portb == 0)) {
                                    portb = 0x80;
                                    delay(1);
                                }
                            }

                        }
                    }

                }


            }

        }

    }

}

}

編輯:

void shiftRight() {

char value;
value = 0x80;

for (int i = 0; i < 8; i++) {
    portb = value;
    value = value >> 1;
    delay(1);
}

}

void shiftLeft() {

char value;
value = 0x1;

for (int i = 0; i < 8; i++) {
    portb = value;
    value = value << 1;
    delay(1);
}
}

編輯2:

#include <system.h>

void delay(int j) {
int i;
int x = 8600;
while (j != 0) {
    for (i = x; i != 0; i--);
    j--;
}
}

void shiftRight() {

char value = 0b10000000;


for (int i = 0; i < 8; i++) {
    portb = value;
    value = value >> 1;
    delay(1);
}

 }

void shiftLeft() {

char value = 0b00000001;


for (int i = 0; i < 8; i++) {
    portb = value;
    value = value << 1;
    delay(1);
}
}

void main() {

trisb = 0; // sets all bits in port B as outputs
adcon1 = 0x06; // sets port A as digital inputs


int movingRight = 1; //which way the led is moving - 0 = left, 1 = right

// creates infinite loop
while(1)
{

    if(movingRight == 1)
    {
        //led is moving right   
        shiftRight();

        if((porta & 0b00000001) && portb == 0b00000001) /*right button is pressed AND led is at the far right*/ 
        {
            //flip direction
            movingRight = 0;
        }
    }
    else
    {
        //led is moving left
        shiftLeft();

        if((porta&  0b00010000) && portb == 0b10000000) /*left button is pressed AND led is at the left right*/
        {
            //flip direction
            movingRight = 1;
        }
    }
}
}

使用 state 變量來跟蹤 LED 是否應該彈跳、向左移動或向右移動,並使用沒有任何嵌套 while 循環的單個 while 循環。 每次通過循環時,您會延遲一段時間,然后根據變量向左或向右移動 LED,然后檢查按鈕的狀態,相應地設置 state 變量。 就像 Weather Vane 所說,將 LED 模式保持在變量中也是一個好主意。

可能的類似 Python 的偽代碼是

state = 0  # 0 = LEDs off
           # 1 = LEDs bounce left
           # 2 = LEDs bounce right
           # 3 = LEDs cycle left
           # 4 = LEDs cycle right
led_pattern = 0x00 

while True:
    set_leds(led_pattern)          # portb = led_pattern

    delay()

    # Update led_pattern according to the current state

    if state == 1 or state == 3:   # bounce or cycle left
        led_pattern <<= 1          
        if led_pattern & 0xFF == 0x00:
            if state == 1:         # bounce
                led_pattern = 0x40
                state = 2          # start bouncing right
            else:
                led_pattern = 0x01

    if state == 2 or state == 4:   # bounce or cycle right
        led_pattern >>= 1          
        if led_pattern == 0x00:
            if state == 2:         # bounce
                led_pattern = 0x02
                state = 1          # start bouncing left
            else:
                led_pattern = 0x80

    # Check the buttons and change state if necesssary

    if button_3_pressed():         # porta & 0x08
        if state == 1 or state == 3:
             state = 1             # continue moving left if already moving left
        else:
             if state == 0: 
                 led_pattern = 0x80  
             state = 2             # otherwise start moving LEDs to the right

    if button_0_pressed():         # porta & 0x01
        state = 3                  # start cycling left

    if button_3_pressed():         # porta & 0x10
        state = 4                  # start cycling right

該程序以state變量設置為0開始,而 led_pa led_pattern變量設置為0x00 在 state 0中,循環不會更改led_pattern ,因此它始終保持0x00保持所有 LED 關閉。 但是,它正在檢查按鈕的狀態,如果按下其中任何一個按鈕,它將更改 state 變量的值。

在 state 0中按下按鈕 3 會導致state變量更改為2並將led_pattern變量設置為0x80 而在 state 2中,循環的每次迭代將led_pattern向右移動一位。 當這導致led_pattern變為 0 時,它會“反彈”將led_pattern設置為 0x02(因為它在循環開始時是 0x01),並將state變量更改為1 在 state 1中, led_pattern變量向左移動,一旦它“反彈”, state 就會變回2

在任何 state 原因中按下按鈕 1 會導致state變量更改為3 在此 state 中, led_pattern變量在循環的每次迭代期間向左移動,就像在 state 1中一樣,但不是“彈跳”它“循環”。 由於這不會改變 LED 應該移動的方向,因此 state 保持為3 ,並且僅更新了led_pattern 同樣按下按鈕 4 將 state 更改為4 ,其中 LED 循環向右。

現在,如果這實際上是您希望代碼執行的操作,您的問題並不完全清楚。 例如,在檢查按鈕之前,它不會等到移動的 LED 達到其移動的終點。 您可以隨時按下按鈕,這將導致 LED 立即開始朝指示的方向移動。

無論如何,您應該能夠看到如何僅使用一個 while 循環和一個或兩個 state 變量來實現您想要的任何行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM