====== T02 - LED display driver ======
Header with definitions: {{ :courses:be2m37mam:tasks:mam.zip |}}
4-digit [[courses:be2m37mam:hardware:start#led_display_driven_by_74hc595|LED display]] is connected to microcontroler by the use of two serial-in shift registers with output latches [[http://www.ti.com/product/SN74LS595|SN74LS595]]. To display any information on the display it is necessary to send two bytes:
* 1st byte represents individual segments of single LED display (D7..D0)
* 2nd byte represents address of digit (A7..A0)
Used pins of microcontroller:
* GPIOA9 - serial data
* GPIOA8 - clock
* GPIOB5 - latch
Figure 1 shows time diagram of communication between microcontroller and LED display. Bits are sent starting from MSB.
{{ :courses:be2m37mam:tasks:shieldled2.svg |}}
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);
}
}