Matrices are some of the coolest ways to play with LEDs when it comes to MCUs. It is also difficult to create smooth and pretty LED pictures or font on matrices without a library. With a good library you can make the leds look like any character you want, and even draw pictures. The math behind the scrolling of text and producing a smooth animation between characters is done by alot of bit shifting and a lot of math. The module from MikroElektronika does all of these things with a easy-to-use library to make drawing and writing characters to the LEDs an easy task.
Initialization
To initialize the 8x8 Click you must call the led_eight_init function which sets digits to be scanned which means all leds are activated. The Intensity by default are set to full intensity, ( full brightness ). The LED module also has a decode mode for when the MCU is wired to seven segment displays, but this Click board is wired for 8x8 LED display so it is set to decode nothing. After initialization all functions are ready to use. You can also try our examples from Libstock.
Drawing to LEDs
The cool part about LEDs and software is you can take whatever you like to display on the LEDs on the hardware, and render it differently with software. On this particular 8x8 LED module the rows and columns ( 0, 0 ) coordinates are actually at the bottom right instead of bottom left, but by using a frame buffer and different refresh functions to render the frame buffer into the hardware differently, we can be creative and display the image however we like. The module uses a frame buffer along with a refresh function to produce what the user will see on the LEDs. Functions are able to use the user input to write to a frame buffer, and use different refresh functions to render what the user ends up seeing on the LEDs.
void led_eight_display_image( uint8_t* image ) { int i; if( image == NULL ) return; for( i = 0; i <=7; i++ ) { frame_buffer[i] = image[i];library } refresh(); return; }
In this snippet the function is simply taking the uint8_t array of 8 and sending them to the frame_buffer. After populating the frame buffer it calls a refresh function to take the frame buffer and render it onto the hardware to look like what the user intended.
Animation
A more complex function used for refreshing a scrolling string of characters on the screen would be the scroll_refresh() and led_eight_scroll_text( uint8_t* str, uint8_t delay ) functions. They use bit shifting along with pointer arithmetic to prepare the frame buffer and then render it on the hardware to display a smooth scrolling animation for the user.
void led_eight_scroll_text( uint8_t* str, uint8_t delay) { uint8_t *ptr = str; uint8_t *p_font = 0; int i, j, k, m; memset( frame_buffer, 0, sizeof(frame_buffer) ); if( ptr == NULL ) //Sanity Check return; p_font = font[*ptr]; while( *ptr != NULL ) { for( i = 0, m = 8; i < 8; i++, m-- ) { for( j = 0, k = 8; j < 8; j++, k-- ) { frame_buffer[j] <<= 1; frame_buffer[j] |= ( font[( *ptr * 8) + m ] & ( 1 << j) ) >> j; scroll_refresh(); vDelay_ms( delay ); } p_font++; } ptr++; } }
The led_eight_scroll_text function first takes the frame_buffer and clears it, followed by a sanity check for safety. The while loop is dependent on whether the next character in the string is null or not, and inside the while loop we begin the bit shifting. The first shift takes the frame_buffer and shifts it once, which in our case is actually shifting the first column upwards. The next step is to place the next characters' first row onto the frame_buffers last row. This is done by taking the ASCII character in the array , and using it as the index in the font array we have included. The characters' indexes in the font array are directly parallel with their ASCII representation, meaning we can just take the 1 byte character sent, and use it as the index for our font, multiply it by eight ( 8 x 8 display means each character is 8 bytes ) and then shift each bit one at a time onto the frame buffer until the first row is populated. This is when the creative refresh comes in.
Refreshing
void static scroll_refresh() { int j,k; uint8_t buffer[2]; uint8_t result = 0; uint8_t *ptr = frame_buffer; for( j = 0; j <= 7; j++ ) { for( k = 7; k >= 0; k-- ) { result |= ( ptr[7 - k] & ( 1 << j ) ) >> j << k; //Rotate 270 deg } result = eight_b_reverse_byte( result ); //Reverse bits on each digit buffer[0] = j + 1; buffer[1] = result; eight_b_hal_write( buffer ); result = 0; } }
The task of writing creative software to render the frame buffer, is to take what is given in the frame_buffer and making it look like something on the hardware. If you noticed in the previous snippet, the characters were moving upwards towards the top, and we wanted the text to scroll as if we were reading it. Even though the text is scrolling up, we still have an animation of characters moving one row at a time in a direction, with the next character becoming visible while the other is still on the LEDs. Now, with this scroll_refresh() function we simply take the upside down characters and rotate them 270 degrees with bit shifts to make the text scroll left instead of up, and then flip each row to make the characters appear on the LEDs correctly. To further explain how the connection between software and hardware happens, here is a diagram of the relation between the software buffer and LEDs.

Settings
Along with drawing to the LEDs there is also settings for the LEDs like intensity, scan limit, and a display test for testing the display. The intensity or brightness of the LEDs depend on the PWM duty cycle which can be set by using led_eight_set_intensity( uint8_t intensity ). The scan limit refers to how many of the columns of leds are on, by default it is set to scan all digits, meaning that all leds on the 8x8 are turned on.
Example
Here is how easy it is to write a string of characters, set the intensity, and add any image you'd like to the LEDs.
#include "stdint.h" sbit EIGHT_B_CS at GPIOD_ODR.B13; int main(void) { uint8_t text_1[] = "MikroE"; uint8_t text_2[] = "Low"; uint8_t text_3[] = "Medium"; uint8_t text_4[] = "Highest"; uint8_t image[8] = { 0xFF, //Image to be displayed on 8x8 0xBD, 0xA1, 0xB9, 0xA1, 0xBD, 0x81, 0xFF }; GPIO_Digital_Output( &GPIOD_BASE, _GPIO_PINMASK_13 ); SPI3_Init_Advanced( _SPI_FPCLK_DIV128, _SPI_MASTER | _SPI_8_BIT | _SPI_CLK_IDLE_LOW | _SPI_FIRST_CLK_EDGE_TRANSITION | _SPI_MSB_FIRST | _SPI_SS_DISABLE | _SPI_SSM_ENABLE | _SPI_SSI_1, &_GPIO_MODULE_SPI3_PC10_11_12 ); Delay_ms(300); eight_b_init(); //Initialize 8x8 Click Delay_ms(400); while(1) { eight_b_scroll_text( text_1, 7 ); //Display first string eight_b_set_intensity( 1 ); //Set intensity to lowest 1 eight_b_scroll_text( text_2, 6 ); //Display second string eight_b_set_intensity( 5 ); //Set intensity to 5 eight_b_scroll_text( text_3, 6 ); //Display third string eight_b_set_intensity( 15 ); //Set intensity to max 15 eight_b_scroll_text( text_4, 6 ); //Display fourth string eight_b_display_image( image ); //Display image Delay_ms(1500); //Small delay } return 0; }
Summary
This click board is awesome for smooth LED scrolling, and easy to implement 8x8 LED images in your project. The libraries are there for writing strings of characters with a simple call of a function.
References
8x8 Github Library https://github.com/MikroElektronika/Click_8x8_MAX7219 2016
Libstock https://libstock.mikroe.com/ 1998-2016
MikroElektronika www.mikroe.com 1998-2016
Github www.github.com/coreylakey 2016