[英]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.