1 | /*
|
2 | * BCMTest.c
|
3 | *
|
4 | * Created: 18.12.2012 21:16:27
|
5 | * Author: Commander
|
6 | */
|
7 |
|
8 |
|
9 | #define F_CPU 8000000UL
|
10 | #include <avr/io.h>
|
11 | #include <util/delay.h>
|
12 | #include <avr/interrupt.h>
|
13 |
|
14 | // Zeitslots
|
15 | volatile uint8_t gTime[8] = {1,2,4,8,16,32,64,128};
|
16 | // BCM-Muster für jeden Zeitslot
|
17 | volatile uint8_t gBcm[8];
|
18 | // Helligkeit der LEDs
|
19 | //volatile uint8_t gBrightness[8] = {0,8,16,24,32,40,48,56};
|
20 |
|
21 | // LEDs 0 und 1 sind AUS, die übrigen leuchten wie gewünscht!
|
22 | volatile uint8_t gBrightness[8] = {128,128,16,24,32,40,48,56};
|
23 |
|
24 | // Aktueller Zeitslot
|
25 | volatile uint8_t gPos = 0;
|
26 |
|
27 | // Anzahl ISR-Aufrufe (für langsames Fading)
|
28 | volatile uint8_t gTick = 0;
|
29 |
|
30 | // Umwandeln der Helligkeiten in BCM-Muster
|
31 | void encodeBrightness(uint8_t brightness[]) {
|
32 | uint8_t portbits = 0;
|
33 |
|
34 | // Iteriere über alle Bits
|
35 | for(uint8_t bitPos = 0; bitPos < 8; bitPos++) {
|
36 | portbits = 0;
|
37 |
|
38 | // Iteriere über alle die Helligkeiten aller LEDs
|
39 | for(uint8_t ledPos = 0; ledPos < 8; ledPos++) {
|
40 | // Falls Bit gesetzt
|
41 | if(gBrightness[ledPos] & (1 << bitPos)) {
|
42 | // Setze entsprechendes Bit im BCM-Muster
|
43 | portbits |= (1 << ledPos);
|
44 | }
|
45 | }
|
46 |
|
47 | // Weise BCM-Muster dem Zeitslot zu
|
48 | gBcm[bitPos] = portbits;
|
49 | }
|
50 | }
|
51 |
|
52 | // Initialisiere SPI
|
53 | void initSPI() {
|
54 | // Ansteuerung erfolgt über PA3 bis PA5
|
55 | DDRA |= ((1 << DDA5) | (1 << DDA4) | (1 << DDA3));
|
56 |
|
57 | USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);
|
58 | }
|
59 |
|
60 | // Initialisiere Timer0, CTC Modus, Prescaler 64, Compare Match Interrupt enable
|
61 | void initTimer() {
|
62 | TCCR0A = (1 << WGM01);
|
63 | TCCR0B |= (1 << CS01)|(1 << CS00);
|
64 | OCR0A = 1;
|
65 | TIMSK0 |= (1 << OCIE0A);
|
66 | }
|
67 |
|
68 | // Sende Wert per SPI an HC595
|
69 | void sendSPI(uint8_t value) {
|
70 | PORTA |= (1 << PA3);
|
71 | USIDR = value;
|
72 | USISR |= (1 << USIOIF);
|
73 |
|
74 | while(!(USISR & (1 << USIOIF))) {
|
75 | USICR |= (1 << USITC);
|
76 | USICR |= (1 << USITC);
|
77 | }
|
78 | PORTA &= ~(1 << PA3);
|
79 | }
|
80 |
|
81 | int main(void)
|
82 | {
|
83 | // Starte mit Zeitslot 2^0
|
84 | gPos = 0;
|
85 |
|
86 | // Initialisiere SPI
|
87 | initSPI();
|
88 | // Initialisiere Timer
|
89 | initTimer();
|
90 | // Interrupt enables
|
91 | sei();
|
92 |
|
93 | encodeBrightness(gBrightness);
|
94 | while(1)
|
95 | {
|
96 | // Fade langsam hoch
|
97 | /*while(gTick < 16) {}
|
98 | gTick = 0;
|
99 |
|
100 | for(uint8_t i = 0; i < 8; i++) {
|
101 | gBrightness[i]++;
|
102 | }
|
103 |
|
104 | encodeBrightness(gBrightness); */
|
105 | }
|
106 | }
|
107 |
|
108 | ISR(TIM0_COMPA_vect) {
|
109 | // Übertrage aktuelles BCM-Muster an HC595
|
110 | sendSPI(gBcm[gPos]);
|
111 | // Setze Länge des nächsten Zeitslots
|
112 | OCR0A = gTime[gPos];
|
113 | // Reset TCNT0
|
114 | TCNT0 = 0;
|
115 |
|
116 | // Gehe zum nächsten Zeitslot
|
117 | gPos++;
|
118 | gPos &= 7;
|
119 |
|
120 | // Erhöhe Ticks wenn ein Durchlauf beendet wurde
|
121 | /*if(gPos == 0) {
|
122 | gTick += 1;
|
123 | }*/
|
124 | }
|