1 | #define F_CPU 16000000
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 |
|
5 | volatile uint16_t matrix[5];
|
6 | volatile uint8_t flag_slow;
|
7 |
|
8 | void Init();
|
9 | void InitPorts();
|
10 | void InitTimer();
|
11 |
|
12 | int main(void) {
|
13 | uint16_t tmp=1;
|
14 |
|
15 | Init();
|
16 | while (1) {
|
17 | if (flag_slow) {
|
18 | flag_slow = 0;
|
19 | tmp <= 1;
|
20 | if (tmp > (1<<13)) tmp = 1;
|
21 | // Update der Matrix
|
22 | matrix[4] = matrix[3];
|
23 | matrix[3] = matrix[2];
|
24 | matrix[2] = matrix[1];
|
25 | matrix[1] = matrix[0];
|
26 | matrix[0] = tmp;
|
27 | }
|
28 | }
|
29 | }
|
30 |
|
31 | void Init() {
|
32 | InitPorts();
|
33 | InitTimer();
|
34 | }
|
35 |
|
36 | void InitPorts() {
|
37 | DDRA= 0xFF;
|
38 | DDRB= 0x1F;
|
39 | DDRC= 0xFF;
|
40 | DDRD= 0x00;
|
41 | }
|
42 |
|
43 | void InitTimer() {
|
44 | //Timer1
|
45 | TCCR1B |= (1<<CS10) | (1<<CS12) | (1<<WGM12);
|
46 | TIMSK |= (1<<OCIE1A);
|
47 | OCR1A = 5;
|
48 |
|
49 | sei();
|
50 | }
|
51 |
|
52 | ISR(TIMER1_COMPA_vect) {
|
53 | static uint8_t c;
|
54 | static uint16_t slowly;
|
55 |
|
56 | // Multiplexen der Spalten
|
57 | PORTB = 0xFF; // Spalte aus, low active
|
58 | spalte <<= 1;
|
59 | c++;
|
60 | if (spalte==32) {
|
61 | spalte=1;
|
62 | c = 0;
|
63 | }
|
64 | //Ausgabe der neuen Spalte
|
65 | PORTA |= matrix[c]>>8;
|
66 | PORTC |= matrix[c];
|
67 | PORTB = ~spalte; // neue Spalte ein, low active
|
68 |
|
69 | //Debug LED
|
70 | PORTA ^= (1<<PA7);
|
71 |
|
72 | // slowy für eine "angenehme" Geschwindigkeit
|
73 | slowly++;
|
74 | if (slowly == 1500) {
|
75 | slowly = 0;
|
76 | flag_slow = 1;
|
77 | }
|
78 | }
|