4-digit LED display is connected to microcontroler by the use of two serial-in shift registers with output latches SN74LS595. To display any information on the display it is necessary to send two bytes:
Used pins of microcontroller:
Figure 1 shows time diagram of communication between microcontroller and LED display. Bits are sent starting from MSB.
Example of serial data sequence (two bytes) to show number 0 on 1st digit (from the left): 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
shift register (1B):
output (8 bits)
^ ^ ^ ^ ^ ^ ^ ^
| x | x | x | x | x | x | x | x | < input data (1 bit) GPIOA9
< input clock (1 bit) GPIOA8
< input latch (1 bit) GPIOB5
00110011 -> store it in register memory
series of bits on data input (GPIOA9)
clock (change from 0->1 on GPIOA8) at the moment, when value on the data input is set
set 0 to data input | x | x | x | x | x | x | x | x | < 0
clock | x | x | x | x | x | x | x | 0 |
set 0 to data input | x | x | x | x | x | x | x | 0 | < 0
clock | x | x | x | x | x | x | 0 | 0 |
set 1 to data input | x | x | x | x | x | x | 0 | 0 | < 1
clock | x | x | x | x | x | 0 | 0 | 1 |
set 1 to data input | x | x | x | x | x | 0 | 0 | 1 | < 1
clock | x | x | x | x | 0 | 0 | 1 | 1 |
...
set 1 to data input | x | 0 | 0 | 1 | 1 | 0 | 0 | 1 | < 1
clock | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
latch - change from 0->1 propagates 1B word stored in memory to the output of register
1 byte representation of 0/1
0: 00000000
1: 00000001
byte to serialize: X
bit to be set on the GPIOA9: bit
for (int i = 7; i >= 0; i--)
{
bit = (X >> i) & 0x01; // -> 00010001 & 0x01 -> 00000001
}
LED segments LOW - LED segment in on, HIGH - LED segment is off
0: 11000000
1: 11111001
algorithm:
unsigned char segments[10] = {192, 249, ....};
unsigned char digits[3] = {1, 2, 4, 8};
we want to show 0 on the 2 position from the left
select 0 from segments -> A
select 1 from digits -> B
setup of registers: most significan bit of B is connected to least significant bit of A
A: | x | x | x | x | x | x | x | x | B: | x | x | x | x | x | x | x | x |
^ ^
\---------/
latch = 0
loop for A:
7..0
clock = 0 (8th bit in ODR)
bit = (A >> i) & 0x01; (9th bit in ODR)
clock = 1
loop for B
7..0
clock = 0
bit = (B >> i) & 0x01; (9th bit in ODR)
clock = 1
latch = 1
1s precission stop watch
this display can only show one digit of four in one time (have no memory)
long T = 1; // global
while(1)
{
// update display without any delay
display(T);
}
// systick interrupt
void systick_handle(void)
{
T++;
}