Arduino Uno:第二次按下时,While-loop 无法 "restart" 使用按钮重置计时器?
Arduino Uno: While-loop fails to "restart" using Button to reset Timer when second-pressing?
代码的作用:
- 代码首先显示一个简短的“闪烁动画”,其中 A-F 段一次打开和关闭。
- “闪烁动画”持续 3-10 秒,然后开始计时。
- 计时器从 0-99 秒开始计时,数字 1 和 2 显示。而数字 3 和 4 分别显示第 10 秒和第 100 秒。
- 通过使用连接的按钮,您可以通过按下它来停止计时器。计时器停止并显示时间。
- 第二次按下按钮,它应该会重新启动计时器并将我们送回步骤 1。
我的问题:当我执行到代码中的第 5 步时,它不会重新启动。据我所知,问题与主要函数中的 while 循环有关,这是由函数“stopTimer”中的第二个 while 循环引起的。无法退出循环。至少这是我从无数次失败的尝试中了解到的!也尝试在“stopDisplay”函数中添加带有 if 语句的代码,包括 break;或 return;等等
#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, 2, 3, 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, 0B00010000, 0B00001000, 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 return 为真。
但是我觉得用变量来表示状态更好
#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;
}
}
edited
所以,我的想法是使用 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();
}
}
}
终于解决了我上面的问题。以为我 post 它以防其他人遇到类似的问题:
#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, 2, 3, 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, 0B00010000, 0B00001000, 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;
}
代码的作用:
- 代码首先显示一个简短的“闪烁动画”,其中 A-F 段一次打开和关闭。
- “闪烁动画”持续 3-10 秒,然后开始计时。
- 计时器从 0-99 秒开始计时,数字 1 和 2 显示。而数字 3 和 4 分别显示第 10 秒和第 100 秒。
- 通过使用连接的按钮,您可以通过按下它来停止计时器。计时器停止并显示时间。
- 第二次按下按钮,它应该会重新启动计时器并将我们送回步骤 1。
我的问题:当我执行到代码中的第 5 步时,它不会重新启动。据我所知,问题与主要函数中的 while 循环有关,这是由函数“stopTimer”中的第二个 while 循环引起的。无法退出循环。至少这是我从无数次失败的尝试中了解到的!也尝试在“stopDisplay”函数中添加带有 if 语句的代码,包括 break;或 return;等等
#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, 2, 3, 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, 0B00010000, 0B00001000, 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 return 为真。 但是我觉得用变量来表示状态更好
#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;
}
}
edited
所以,我的想法是使用 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();
}
}
}
终于解决了我上面的问题。以为我 post 它以防其他人遇到类似的问题:
#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, 2, 3, 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, 0B00010000, 0B00001000, 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;
}