如何解决Arduino Uno:二次按下时,While循环无法使用Button来“重启”计时器吗?
代码的作用:
- 代码通过显示简短的“闪烁动画”开始,其中A-F段一次打开和关闭。
- “闪烁动画”持续3到10秒,计时器开始计时。
- 计时器的计数范围是数字1和2显示的0-99秒,而数字3和4分别显示的是秒的10分和100分。
- 使用连接的按钮,您可以通过按下计时器来停止计时器。计时器停止并显示时间。
- 通过再次按下按钮,可以重新启动计时器并将我们返回到步骤1。
我的问题:当我进入代码中的STEP 5时,它不会重新启动。据我所知,该问题与主要功能中的while循环有关,据我所知,此功能是“ stopTimer”功能中的第二个while循环引起的。无法使其退出循环。至少从所有不成功的尝试中我了解到了!尝试在“ stopDisplay”函数中添加带有if语句的代码,包括break;或返回等
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <avr/io.h>
#include <util/delay.h>
#define BUTTONPRESSED PINC & 1 << PC0
/*
- PORT = D
Segment-A Pin 1 PD1 0B00000010
Segment-B Pin 2 PD2 0B00000100
Segment-C Pin 3 PD3 0B00001000
Segment-D Pin 4 PD4 0B00010000
Segment-E Pin 5 PD5 0B00100000
Segment-F Pin 6 PD6 0B01000000
Segment-G Pin 7 PD7 0B10000000
- PORT = B
Digit 1 Pin 10 PB2 0B00000100
Digit 2 Pin 11 PB3 0B00001000
Digit 3 Pin 12 PB4 0B00010000
Digit 4 Pin 13 PB5 0B00100000
- PORT = C
Button Pin A0 PC0 0B00000001
*/
//Number: 0,1,2,3,4,5,6,7,8,9 in a array.
int segmentNumberArray[10] = {0B01111110,0B00001100,0B010110110,0B10011110,0B011001100,0B11011010,0B11111010,0B00001110,0B11111110,0B11011110};
//Digit: 1,4 in a array
int digitArrayOff[4] = {0B00000100,0B00001000,0B00010000,0B00100000};
int digitArrayOn[4] = {0B11111011,0B11110111,0B11101111,0B11011111};
//Blinking animation: segment-E,segment-D,segment-C,segment-G,segment-F,segment-A,segment-B,segment-G
int blinkingArray[8] = {0B00100000,0B10000000,0B01000000,0B00000010,0B00000100,0B10000000};
long number = 0;
int recentTime;
int digit1,digit2,digit3,digit4;
int stopButton;
void startTimer();
void stopTimer();
void choseDigit(int x);
void showNumberOnDisplay(int x);
void blinkingAnimation();
int main()
{
DDRC = 0;
DDRD = 255;
DDRB = 0B00111100; //DDRB = 28;
srand(time(NULL));
while (1)
{
if (number == 0)
{
int randomWaitTime = rand() % 10 + 3; //Calls random number between 3-10
for (int i = 0; i < randomWaitTime; i++)
{
blinkingAnimation();
}
}
startTimer();
if (BUTTONPRESSED)
{
stopButton = 0;
stopTimer();
}
if (BUTTONPRESSED)
{
break;
}
}
return 0;
}
void startTimer()
{
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay((number / 1000)); //Get value of thousand
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay((number % 1000) / 100); //Get value of hundred
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(number % 100 / 10); //Get value of ten
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 3 on
showNumberOnDisplay(number % 10); //Get value of single digit
_delay_ms(1); //Delay 1 ms
number++;
if (number == 9999) // Reset number count to 1;
{
number = 1;
}
}
void stopTimer()
{
recentTime = number;
digit1 = recentTime / 1000;
digit2 = (recentTime % 1000) / 100;
digit3 = recentTime % 100 / 10;
digit4 = recentTime % 10;
while (stopButton == 0)
{
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay(digit1); //Get value of thousand
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay(digit2); //Get value of hundred
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(digit3); //Get value of ten
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 3 on
showNumberOnDisplay(digit4); //Get value of single digit
_delay_ms(1); //Delay 1 ms
}
}
void choseDigit(int x)
{
PORTB = 0B11111111;
switch (x)
{
case 1:
PORTB = digitArrayOn[0]; //Display 1 on
break;
case 2:
PORTB = digitArrayOn[1]; //Display 2 on
break;
case 3:
PORTB = digitArrayOn[2]; //Display 3 on
break;
case 4:
PORTB = digitArrayOn[3]; //Display 4 on
break;
}
}
void showNumberOnDisplay(int x)
{
switch (x)
{
case 1:
PORTD = segmentNumberArray[1];
break;
case 2:
PORTD = segmentNumberArray[2];
break;
case 3:
PORTD = segmentNumberArray[3];
break;
case 4:
PORTD = segmentNumberArray[4];
break;
case 5:
PORTD = segmentNumberArray[5];
break;
case 6:
PORTD = segmentNumberArray[6];
break;
case 7:
PORTD = segmentNumberArray[7];
break;
case 8:
PORTD = segmentNumberArray[8];
break;
case 9:
PORTD = segmentNumberArray[9];
break;
default:
PORTD = segmentNumberArray[0];
break;
}
}
void blinkingAnimation()
{
for (int i = 0; i < 8; i++)
{
PORTD = blinkingArray[i];
_delay_ms(125);
}
}
解决方法
变量 stopButton 的值仍为0,结果stopButton == 0返回true。 但是我认为最好使用变量来表示状态。
#define STATE_COUNT 1
#define STATE_STOP 2
int currentState = 1;
while(1){
if(currentState == STATE_COUNT && BUTTONPRESSED){
//do something
currentState = STATE_STOP;
}
if(currentState == STATE_STOP && BUTTONPRESSED){
//do something
currentState = STATE_COUNT;
}
}
编辑
所以,我的想法是使用STATE定义要运行的代码。因此您可以消除第二个while循环。
while (1) {
if(currentState == STATE_BLINK){
blink(); //run code 1 time and change state
currentState = STATE_COUNT;
}
if(currentState == STATE_COUNT){
startTimer();
}
if(currentState == STATE_STOP){
stopTimer(); // while loop inside is removed
}
if (BUTTONPRESSED) {
//change state here
}
}
void stopTimer() {
recentTime = number;
digit1 = recentTime / 1000;
digit2 = (recentTime % 1000) / 100;
digit3 = recentTime % 100 / 10;
digit4 = recentTime % 10;
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay(digit1); //Get value of thousand
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay(digit2); //Get value of hundred
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(digit3); //Get value of ten
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 3 on
showNumberOnDisplay(digit4); //Get value of single digit
_delay_ms(1); //Delay 1 ms
}
void blink(){
if (number == 0) {
int randomWaitTime = rand() % 10 + 3; //Calls random number between 3-10
for (int i = 0; i < randomWaitTime; i++) {
blinkingAnimation();
}
}
}
,
这里终于可以解决我的上述问题。以为我将其发布,以防其他人遇到类似问题:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <avr/io.h>
#include <util/delay.h>
#define BUTTONPRESSED PINC &(1 << PC0)
/*
- PORT = D
Segment-A Pin 1 PD1 0B00000010
Segment-B Pin 2 PD2 0B00000100
Segment-C Pin 3 PD3 0B00001000
Segment-D Pin 4 PD4 0B00010000
Segment-E Pin 5 PD5 0B00100000
Segment-F Pin 6 PD6 0B01000000
Segment-G Pin 7 PD7 0B10000000
- PORT = B
Digit 1 Pin 10 PB2 0B00000100
Digit 2 Pin 11 PB3 0B00001000
Digit 3 Pin 12 PB4 0B00010000
Digit 4 Pin 13 PB5 0B00100000
- PORT = C
Button Pin A0 PC0 0B00000001
*/
//Number: 0,1,2,3,4,5,6,7,8,9 in a array
int segmentNumberArray[10] = {0B01111110,0B00001100,0B010110110,0B10011110,0B011001100,0B11011010,0B11111010,0B00001110,0B11111110,0B11011110};
//Digit: 1,4 in a array
int digitArrayOff[4] = {0B00000100,0B00001000,0B00010000,0B00100000};
int digitArrayOn[4] = {0B11111011,0B11110111,0B11101111,0B11011111};
//Blinking animation: segment-E,segment-D,segment-C,segment-G,segment-F,segment-A,segment-B,segment-G
int blinkingArray[8] = {0B00100000,0B10000000,0B01000000,0B00000010,0B00000100,0B10000000};
long number = 0;
int recentTime;
int digit1,digit2,digit3,digit4;
int isCounting = 0;
int isButtonDown = 0;
void startTimer();
void stopTimer();
void choseDigit(int x);
void showNumberOnDisplay(int x);
void blinkingAnimation();
int main()
{
DDRC = 0; // För knappen -->> alt. DDRC&= ~(1 << PC0);
DDRD = 255;
DDRB = 0B00111100; //DDRB = 28; -->> detta är för Displayerna
srand(time(NULL));
blinkingAnimation();
while (1)
{
if (isCounting == 1)
{
startTimer();
}
if (BUTTONPRESSED)
{
if (isButtonDown == 0) //Button has not been pressed before
{
isButtonDown = 1;
if (isCounting == 0)
{
blinkingAnimation();
}
else
{
isCounting = 0;
}
}
}
else
{
isButtonDown = 0; //Button has been released
}
stopTimer();
}
return 0;
}
void startTimer()
{
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay((number / 1000)); //Get value of thousand
_delay_ms(2.3); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay((number % 1000) / 100); //Get value of hundred
_delay_ms(2.3); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(number % 100 / 10); //Get value of ten
_delay_ms(2.3); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 4 on
showNumberOnDisplay(number % 10); //Get value of single digit
_delay_ms(2.3); //Delay 1 ms
number++;
if (number > 5999) // Reset number count to 1;
{
number = 1;
}
}
void stopTimer()
{
recentTime = number;
digit1 = recentTime / 1000;
digit2 = (recentTime % 1000) / 100;
digit3 = recentTime % 100 / 10;
digit4 = recentTime % 10;
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay(digit1); //Get value of thousand
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay(digit2); //Get value of hundred
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(digit3); //Get value of ten
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 3 on
showNumberOnDisplay(digit4); //Get value of single digit
_delay_ms(1); //Delay 1 ms
}
void choseDigit(int x)
{
PORTB = 0B11111111;
switch (x)
{
case 1:
PORTB = digitArrayOn[0]; //Display 1 on
break;
case 2:
PORTB = digitArrayOn[1]; //Display 2 on
break;
case 3:
PORTB = digitArrayOn[2]; //Display 3 on
break;
case 4:
PORTB = digitArrayOn[3]; //Display 4 on
break;
}
}
void showNumberOnDisplay(int x)
{
switch (x)
{
case 1:
PORTD = segmentNumberArray[1];
break;
case 2:
PORTD = segmentNumberArray[2];
break;
case 3:
PORTD = segmentNumberArray[3];
break;
case 4:
PORTD = segmentNumberArray[4];
break;
case 5:
PORTD = segmentNumberArray[5];
break;
case 6:
PORTD = segmentNumberArray[6];
break;
case 7:
PORTD = segmentNumberArray[7];
break;
case 8:
PORTD = segmentNumberArray[8];
break;
case 9:
PORTD = segmentNumberArray[9];
break;
default:
PORTD = segmentNumberArray[0];
break;
}
}
void blinkingAnimation()
{
PORTB = digitArrayOn[4];
//Random wait time:
int randomWaitTime = rand() % 10 + 3; //Calls random number between 3-10 seconds
for (int i = 0; i < randomWaitTime; i++)
{
//Blink animation:
for (int i = 0; i < 8; i++)
{
PORTD = blinkingArray[i];
_delay_ms(125);
}
}
number = 0;
isCounting = 1;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。