Controlling a MAX7219 8-digit 7-segment display from ATtiny85

[code]/*[br] One MAX7219 connected to an 8-digit 7-sgement display[br] Adapted from https://halfbyteblog.wordpress.com/2015/11/29/using-a-max7219-8x8-led-matrix-with-an-attiny85-like-trinket-or-digispark/[br] */[br][br]#include [br]#include [br][br]#define CLK_HIGH() PORTB |= (1<#define CLK_LOW() PORTB &= ~(1<#define CS_HIGH() PORTB |= (1<#define CS_LOW() PORTB &= ~(1<#define DATA_HIGH() PORTB |= (1<#define DATA_LOW() PORTB &= ~(1<#define INIT_PORT() DDRB |= (1<[br]uint8_t ZERO = 0b01111110;[br]uint8_t ONE = 0b00110000;[br]uint8_t TWO = 0b01101101;[br]uint8_t THREE = 0b01111001;[br]uint8_t FOUR = 0b00110011;[br]uint8_t FIVE = 0b01011011;[br]uint8_t SIX = 0b00011111;[br]uint8_t SEVEN = 0b01110000;[br]uint8_t EIGHT = 0b01111111;[br]uint8_t NINE = 0b01110011;[br]uint8_t DOT = 0b10000000;[br][br][br]uint8_t smile[8] = {[br] ZERO,[br] ONE,[br] TWO,[br] THREE,[br] FOUR,[br] FIVE,[br] SIX,[br] SEVEN};[br][br]uint8_t sad[8] = {[br] EIGHT,[br] NINE,[br] ZERO + DOT,[br] ONE + DOT,[br] TWO + DOT,[br] THREE + DOT,[br] FOUR + DOT,[br] FIVE + DOT,[br]};[br][br][br]void spi_send(uint8_t data)[br]{[br] uint8_t i;[br][br] for (i = 0; i < 8; i++, data <<= 1)[br] {[br] CLK_LOW();[br] if (data & 0x80)[br] DATA_HIGH();[br] else[br] DATA_LOW();[br] CLK_HIGH();[br] }[br] [br]}[br][br]void max7219_writec(uint8_t high_byte, uint8_t low_byte)[br]{[br] CS_LOW();[br] spi_send(high_byte);[br] spi_send(low_byte);[br] CS_HIGH();[br]}[br][br]void max7219_clear(void)[br]{[br] uint8_t i;[br] for (i = 0; i < 8; i++)[br] {[br] max7219_writec(i+1, 0);[br] }[br]}[br][br]void max7219_init(void)[br]{[br] INIT_PORT();[br] // Decode mode: none[br] max7219_writec(0x09, 0);[br] // Intensity: 3 (0-15)[br] max7219_writec(0x0A, 1);[br] // Scan limit: All "digits" (rows) on[br] max7219_writec(0x0B, 7);[br] // Shutdown register: Display on[br] max7219_writec(0x0C, 1);[br] // Display test: off[br] max7219_writec(0x0F, 0);[br] max7219_clear();[br]}[br][br][br]uint8_t display[8];[br][br]void update_display(void)[br]{[br] uint8_t i;[br][br] for (i = 0; i < 8; i++)[br] {[br] max7219_writec(i+1, display[i]);[br] }[br]}[br][br]void image(uint8_t im[8])[br]{[br] uint8_t i;[br][br] for (i = 0; i < 8; i++)[br] display[i] = im[i];[br]}[br][br]void set_pixel(uint8_t r, uint8_t c, uint8_t value)[br]{[br] switch (value)[br] {[br] case 0: // Clear bit[br] display[r] &= (uint8_t) ~(0x80 >> c);[br] break;[br] case 1: // Set bit[br] display[r] |= (0x80 >> c);[br] break;[br] default: // XOR bit[br] display[r] ^= (0x80 >> c);[br] break;[br] }[br]}[br][br][br]int main(void)[br]{[br] uint8_t i;[br] [br] max7219_init();[br] [br] while(1)[br] {[br] image(sad);[br] update_display();[br] _delay_ms(500);[br] image(smile);[br] update_display();[br] _delay_ms(500);[br][br] // Invert display[br]// for (i = 0 ; i < 8*8; i++)[br]// {[br]// set_pixel(i / 8, i % 8, 2);[br]// update_display();[br]// _delay_ms(10);[br]// }[br] _delay_ms(500);[br] }[br]}[/code]

Information: Controlling a MAX7219 8-digit 7-segment display from ATtiny85