Search
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
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); } }