Computer Systems Experiments 21 | 0 to F Counter By the GPIO Module

Series: Computer Systems Experiments

Computer Systems Experiments 21 | 0 to F Counter By the GPIO Module

In the previous experiment, we create a 0 to 9 counter by the pointer. And in this experiment, we are going to develop the same counter (actually with more values from 0 to 9 and then A to F and finally a dash - ) with the GPIO module from the last experiment.

We are going to implement this counter in the clock.c file and this file can be compiled by command,

$ make install

First, let’s add a global array as we have used in the previous experiments. We are going to use the hexadecimal value for this case and also A to F should also be in this digit array,

unsigned int digit[] = {
0x3f, // 0 0b00111111
0x06, // 1 0b00000110
0x5b, // 2 0b01011011
0x4f, // 3 0b01001111
0x66, // 4 0b01100110
0x6d, // 5 0b01101101
0x7d, // 6 0b01111101
0x07, // 7 0b00000111
0x7f, // 8 0b01111111
0x6f, // 9 0b01101111
0x77, // A 0b01110111
0x7f, // B 0b01111111
0x39, // C 0b00111001
0x3f, // D 0b00111111
0x79, // E 0b01111001
0x71, // F 0b01110001
0x40, // - 0b01000000
};

Second, let’s set up the output pins for the 7-segment display. The GPIO 10 — 13 is used to control the position of the digits and the GPIO 20 — 26 is used to for displaying the digits,

for (int t = 10; t <= 13; t++) {
gpio_set_output(t);
}
for (int t = 20; t <= 26; t++) {
gpio_set_output(t);
}

In this experiment, we only want to display on the last digit. So let’s set the value of the GPIO 13 pin to 1 ,

gpio_write(GPIO_PIN13, 1);

Third, it can be quite complicated to display a digit value. We have to set value 1 or 0 to the 7 LED segments corresponding to the values and rules in the global digit array. To make the program easier for us to understand, we will construct a new function called displaydigit . There are two parts to this function,

  • Check if the value is valid.
if (value < 0 || value > 16) return;
  • Display the value by each bit.
int toDisplay =  digit[value];
for (int i = 20; i <= 26; i++) {
if (toDisplay & 0b1) {
gpio_write(i, 1);
} else {
gpio_write(i, 0);
}
toDisplay = toDisplay >> 1;
}

Also, we have to declare this function at the beginning of this file,

void displaydigit(int value);

Finally, the loop we use to display the digits in the main function should be,

// Display the digits.
for (int i = 0; ; i++) {
displaydigit(i);
// Delay a certain time.
for (int c = DELAY; c != 0; c--) ;
if (i == 16) i = -1;
}

In conclusion, the overall program is,

#include "gpio.h"
#include "timer.h"
#define DELAY 0x3f0000
void displaydigit(int value);
unsigned int digit[] = {
0x3f, // 0 0b00111111
0x06, // 1 0b00000110
0x5b, // 2 0b01011011
0x4f, // 3 0b01001111
0x66, // 4 0b01100110
0x6d, // 5 0b01101101
0x7d, // 6 0b01111101
0x07, // 7 0b00000111
0x7f, // 8 0b01111111
0x6f, // 9 0b01101111
0x77, // A 0b01110111
0x7f, // B 0b01111111
0x39, // C 0b00111001
0x3f, // D 0b00111111
0x79, // E 0b01111001
0x71, // F 0b01110001
0x40, // - 0b01000000
};
void main(void)
{
// Set the output pins.
for (int t = 10; t <= 13; t++) {
gpio_set_output(t);
}
for (int t = 20; t <= 26; t++) {
gpio_set_output(t);
}
   // Set 1 to the GPIO 13 pin to display 
// on the last digit.
gpio_write(GPIO_PIN13, 1);
   // Display the digits.
for (int i = 0; ; i++) {
displaydigit(i);
// Delay a certain time.
for (int c = DELAY; c != 0; c--) ;
if (i == 16) i = -1;
}
}
void displaydigit(int value) {
// Check if the value is valid.
if (value < 0 || value > 16) return;
   // Display the value by each bit.
int toDisplay = digit[value];
for (int i = 20; i <= 26; i++) {
if (toDisplay & 0b1) {
gpio_write(i, 1);
} else {
gpio_write(i, 0);
}
toDisplay = toDisplay >> 1;
}
}

Note that this file can also be found from my repo, but from the branch A2FCounter .