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