#include #include #include volatile uint8_t line_counter ; #define WRITE_DISPLAY(c) while(!(UCSR0A & _BV(UDRE0)));\ UDR0 = c; int main(void) { // configure UART for SPI. UCSR0C = _BV(UMSEL01) | _BV(UMSEL00); // set baudrate to Fosc/4 UBRR0H = 0; UBRR0L = 1; // only enable tx, no rx. UCSR0B = _BV(TXEN0); // Use timer for selecting lines TCCR0A = _BV(WGM01); // run timer on Fosc/256 => 62.5us/count TCCR0B = _BV(CS02); // about 4ms/line, 60ms for entire display OCR0A = 60; TIMSK0 = _BV(OCIE0A); uint8_t i,j; uint8_t line_counter_prev; for(i=16; i<34; i++) { WRITE_DISPLAY(0x02); WRITE_DISPLAY(i); WRITE_DISPLAY(0x00); for (j=0; j<6; j++){ // 7 time 0xff is on, 6 times 0xef is on? // 6 time 0xff is off, 7 or 6 teime 0xfe is off WRITE_DISPLAY(0xef); } }; sei(); // this code unlocks the shift registers WRITE_DISPLAY(0x00); WRITE_DISPLAY(0x02); WRITE_DISPLAY(0x0f); WRITE_DISPLAY(0x00); sei(); while (1) { if (line_counter != line_counter_prev) { cli(); for (j=0; j < 8; j++) { line_counter_prev = line_counter; for (i=0; i<1; i++) { WRITE_DISPLAY(0); } WRITE_DISPLAY(0x00) for (i=0; i<(line_counter+1); i++) { WRITE_DISPLAY(0x03) WRITE_DISPLAY(0x00) } WRITE_DISPLAY(0x00) for (i=0; i<(23-line_counter); i++) { WRITE_DISPLAY(0x03) WRITE_DISPLAY(0x01) } WRITE_DISPLAY(0x00) } sei(); } WRITE_DISPLAY(0x00) } return 666; } ISR(TIMER0_COMPA_vect) { // wait for UART free WRITE_DISPLAY(0x00); WRITE_DISPLAY(0x02); WRITE_DISPLAY(0xa0 | line_counter); if (line_counter == 0x0f) { line_counter = 0; } else { line_counter += 1; } WRITE_DISPLAY(0x80); return; }