Header with definitions: mam.zip
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++;
}
#include "mam.h" void gpio_init (void) { // AHB1 - enable clock for GPIOA setbit(RCC->AHB1ENR, 0); // AHB1 - enable clock for GPIOB setbit(RCC->AHB1ENR, 1); // set mode of GPIOA5 to output setbit(GPIOA->MODER, 10); // set mode of GPIOA8 to output - clock setbit(GPIOA->MODER, 16); // set mode of GPIOA9 to output - data setbit(GPIOA->MODER, 18); // set mode of GPIOB5 to output - latch signal setbit(GPIOB->MODER, 10); } // delay function - doing literally nothing void delay(unsigned long count) { while(count--); } void send_data (unsigned char data) { for (int i = 7; i >= 0; i--) { // calculate value of a bit on i-th position unsigned char bit = (data >> i) & 0x01; if (bit == 1) setbit(GPIOA->ODR, 9); else clearbit(GPIOA->ODR, 9); // clock clearbit(GPIOA->ODR, 8); setbit(GPIOA->ODR, 8); } } static unsigned char number[10] = {192, 249, 164, 176, 153, 146, 130, 248, 128, 144}; static unsigned char position[] = {1, 2, 4, 8}; void set_digit (int a, int b) { clearbit(GPIOB->ODR, 5); send_data (number[a]); send_data (position[b]); setbit(GPIOB->ODR, 5); } int main(void) { gpio_init(); while(1) { set_digit(1, 0); set_digit(2, 1); set_digit(3, 2); set_digit(4, 3); } }