What the code does:
My problem: when I get to STEP 5 in the code, it won't restart. The problem is linked to the while-loop in the main function caused by, as far as I can see, the second while-loop in the function "stopTimer". Can't make it to exit the loop. At least that's what I've understood from all the numerous unsuccessful tries! Tried adding code with if-statements inside the "stopDisplay" function as well, including break; or return; etc.
#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);
}
}
the value of variable stopButton still 0, resulting stopButton == 0 return true. But i think it better to use variable to represent the state.
#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
so, my idea is to use STATE to define what code to run. so you can eliminate second while loop.
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();
}
}
}
Here is finally a solution to my problem above. Thought I post it in case anyone else runs into a similar problem:
#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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.