1 | ********************************************************************************************************/
|
2 | #ifndef F_CPU
|
3 | #define F_CPU 16000000
|
4 | #endif
|
5 | /*******************************************************************************************************/
|
6 | // Einbindung von Standardbibliotheken...
|
7 | #include <stdint.h> // Datentypen (standardisiert)
|
8 | #include <avr/io.h> // Registernamen
|
9 | #include <avr/interrupt.h>
|
10 | #include <stdio.h> // Rechenoperationen, etc.
|
11 | #include <math.h>
|
12 | //#include <string.h> // Zeichenketten-Funktionen
|
13 | // ... und externen Dateien
|
14 | #include "buttons.h"
|
15 | //#include "SPI.h"
|
16 | #include "usart.h"
|
17 | /*******************************************************************************************************/
|
18 | #define RELAIS_ON_DDR DDRD
|
19 | #define RELAIS_ON_PORT PORTD
|
20 | #define RELAIS_ON 7
|
21 | #define RELAIS_OFF_DDR DDRB
|
22 | #define RELAIS_OFF_PORT PORTB
|
23 | #define RELAIS_OFF 0
|
24 |
|
25 | #define PWM1_DDR DDRB
|
26 | #define PWM1_PORT PORTB
|
27 | #define PWM1 1
|
28 | /*******************************************************************************************************/
|
29 | // Enumeration: Typen-Definition von bool(Boolean)
|
30 | typedef enum {
|
31 | false = 0,
|
32 | true
|
33 | } bool;
|
34 | /*******************************************************************************************************/
|
35 | void LED_FADING(int16_t data,int16_t mode); // zum Ein-/Ausblenden von LEDs
|
36 | /*******************************************************************************************************/
|
37 | // Deklaration globaler Variablen
|
38 | volatile uint8_t sreg_local;
|
39 |
|
40 | #define SECOND ((F_CPU/16)/1024) // Wert für 1s Durchlaufzeit im Timer1-Overflow-Interrupt
|
41 | #define RELAIS_TIMEOUT 15 // Timeout-Wert(in ~m) für die Abschaltung des 230V-Verbrauchers
|
42 | #define nBtnModeTimeout 300 // Timeout-Wert(in ~ms) für das 'key_press'-Ereignis
|
43 | #define nFadingTime 200 // Ein-/Ausblendzeit(in ~ms)
|
44 | #define DIMM_TIMEOUT 150 // Zählerschritte(keine s!), bevor von 100% wieder heruntergedimmt wird
|
45 |
|
46 | int16_t bRelaisSignal = 0;
|
47 | int32_t nRelaisCount = 0;
|
48 | int16_t nBtnMode = 0; // Programm-Modus des Tasters
|
49 | int16_t nBtnModeCount = 0; // Zähler für das 'key_press'-Ereignis
|
50 | int16_t nDimmCount = 0; // Zähler für
|
51 | int16_t bDimmDirection = 1; // Dimmungrichtung(1:EIN;0:AUS)
|
52 | int16_t bFadingSignal = 0;
|
53 | int16_t nFadingCount = 0; // Zähler für die Ein-/Ausblendfunktion(Fading)
|
54 | int16_t nFadingLED = 0;
|
55 | int16_t nSavedPWM = 50; // Variable zur Speicherung des letzten PWM- bzw. Helligkeitswertes
|
56 | /*******************************************************************************************************/
|
57 | // zum Speichern und Deaktivieren der Interrupts auf globaler Ebene
|
58 | void ISR_0()
|
59 | {
|
60 | sreg_local = SREG; // Erstellung einer lokalen Sicherungskopie von SREG
|
61 | cli();
|
62 | }
|
63 | /*******************************************************************************************************/
|
64 | // zum Laden und Aktivieren der Interrupts auf globaler Ebene
|
65 | // (Es werden nur die Interrupts aktiviert, die auch vor dem Abschalten schon in Benutzung waren!)
|
66 | void ISR_1()
|
67 | {
|
68 | SREG = sreg_local; // Sicherungskopie von SREG laden
|
69 | }
|
70 | /*******************************************************************************************************/
|
71 | // Auswertung des Timer1-Overflow-Interrupts
|
72 | ISR(TIMER1_OVF_vect)
|
73 | {
|
74 | if(bRelaisSignal != 0)
|
75 | {
|
76 | nRelaisCount++;
|
77 | if(bRelaisSignal == 1)
|
78 | {
|
79 | if(nRelaisCount <= SECOND/3)
|
80 | RELAIS_ON_PORT |= (1<<RELAIS_ON);
|
81 | else
|
82 | RELAIS_ON_PORT &= ~(1<<RELAIS_ON);
|
83 |
|
84 | if(nRelaisCount > ((int32_t)(SECOND*RELAIS_TIMEOUT)*60))
|
85 | {
|
86 | bRelaisSignal = 2;
|
87 | nRelaisCount = 0;
|
88 | }
|
89 | }
|
90 | else
|
91 | {
|
92 | if(nRelaisCount <= SECOND/3)
|
93 | RELAIS_OFF_PORT |= (1<<RELAIS_OFF);
|
94 | else
|
95 | {
|
96 | RELAIS_OFF_PORT &= ~(1<<RELAIS_OFF);
|
97 | bRelaisSignal = 0;
|
98 | nRelaisCount = 0;
|
99 | }
|
100 | }
|
101 | }
|
102 | /***************************************************************************************************/
|
103 | if(nBtnMode != 0) // sobald irgendein Programm-Modus(s. Tasterabfragen) ausgewählt wurde,...
|
104 | {
|
105 | nBtnModeCount++; // ... Start des Zählers für die 'key'-Events(Timeout)
|
106 |
|
107 | if(KEY_PIN & (1<<KEY1))
|
108 | {
|
109 | if(nBtnModeCount > nBtnModeTimeout && nBtnModeCount < nBtnModeTimeout*3)
|
110 | {
|
111 | switch(nBtnMode)
|
112 | {
|
113 | /*---------------------------------------------------------------------------------*/
|
114 | case(1): if(!(PINB & (1<<PINB1)))
|
115 | {
|
116 | OCR1A = nSavedPWM;
|
117 | TCCR1A |= (1<<COM1A1);
|
118 | bRelaisSignal = 1;
|
119 | }
|
120 | else
|
121 | {
|
122 | OCR1A = 0;
|
123 | TCCR1A &= ~(1<<COM1A1);
|
124 | }
|
125 | break;
|
126 | /*---------------------------------------------------------------------------------*/
|
127 | case(2): nFadingLED = 4;
|
128 | if(!(PINB & (1<<PINB1)))
|
129 | bFadingSignal = 1; // Signal:FadeIN
|
130 | else
|
131 | bFadingSignal = 2; // Signal:FadeOUT
|
132 | break;
|
133 | /*---------------------------------------------------------------------------------*/
|
134 | }
|
135 | nBtnMode = 0; // Zurücksetzung des Programm-Modus
|
136 | nBtnModeCount = 0; // Zurücksetzung des Zählers
|
137 | }
|
138 | if(nBtnModeCount >= nBtnModeTimeout*3)
|
139 | {
|
140 | nBtnMode = 0; // Zurücksetzung des Programm-Modus
|
141 | nBtnModeCount = 0; // Zurücksetzung des Zählers
|
142 | }
|
143 | }
|
144 | }
|
145 | /***************************************************************************************************/
|
146 | if(bFadingSignal != 0)
|
147 | {
|
148 | nFadingCount++;
|
149 |
|
150 | if(nFadingCount <= nFadingTime)
|
151 | if(bFadingSignal == 1)
|
152 | LED_FADING(nFadingLED,1);
|
153 | else
|
154 | LED_FADING(nFadingLED,0);
|
155 | else
|
156 | {
|
157 | bFadingSignal = 0;
|
158 | nFadingCount = 0;
|
159 | }
|
160 | }
|
161 | }
|
162 | /*******************************************************************************************************/
|
163 | // zum Überblenden(Ein-/Ausblenden) von LEDs
|
164 | void LED_FADING(int16_t data,int16_t mode)
|
165 | {
|
166 | int16_t tmp;
|
167 |
|
168 | if(mode == 1) // FadeIN
|
169 | {
|
170 | // da 'nFadingCount*(nSavedPWM/nFadingTime)' nur int-Werte verarbeiten kann, wird
|
171 | // hier durch Benutzung einer temporären größeren 32Bit-Variable UND der
|
172 | // LEFT-Shift-Operation in einem 'Vielfachen' der Ausgangswerte weitergerechnet
|
173 | tmp = (nFadingCount*(((int32_t)nSavedPWM << 16)/nFadingTime)) >> 16;
|
174 |
|
175 | if(data == 1) TCCR0A |= (1<<COM0A1);
|
176 | else if(data == 2) TCCR0B |= (1<<COM0B1);
|
177 | else if(data == 3) TCCR2B |= (1<<COM2B1);
|
178 | else if(data == 4) TCCR1A |= (1<<COM1A1);
|
179 | }
|
180 | else // FadeOUT
|
181 | // mit 'nSavedPWM-Zählerfaktor(s.o.)' wird hier der Zähler rückwärts ausgewertet
|
182 | tmp = nSavedPWM-((nFadingCount*(((int32_t)nSavedPWM << 16)/nFadingTime)) >> 16);
|
183 |
|
184 | // Zuweisung des PWM-Wertes an das jeweilige Compare-Register
|
185 | if(data == 1) OCR0A = tmp;
|
186 | else if(data == 2) OCR0B = tmp;
|
187 | else if(data == 3) OCR2B = tmp;
|
188 | else if(data == 4) OCR1A = tmp;
|
189 |
|
190 | if(tmp == 0)
|
191 | {
|
192 | if(data == 1) TCCR0A &= ~(1<<COM0A1);
|
193 | else if(data == 2) TCCR0B &= ~(1<<COM0B1);
|
194 | else if(data == 3) TCCR2B &= ~(1<<COM2B1);
|
195 | else if(data == 4) TCCR1A &= ~(1<<COM1A1);
|
196 | }
|
197 | }
|
198 | /*******************************************************************************************************/
|
199 | int main (void)
|
200 | {
|
201 | // Initialisierung des USART
|
202 | char stringbuffer[32]; // Definition eines allgemeinen Puffers für die Strings
|
203 |
|
204 | USART_INIT(); // Grundeinstellungen des USART
|
205 |
|
206 | // Konfiguration der I/Os:
|
207 | KEY_DDR &= ~ALL_KEYS; // Taster als Eingang
|
208 | KEY_PORT |= ALL_KEYS; // Aktivierung der internen Pull-Ups
|
209 |
|
210 | RELAIS_OFF_DDR |= (1<<RELAIS_OFF); // Relais1 als Ausgang
|
211 | RELAIS_ON_DDR |= (1<<RELAIS_ON); // Relais2 als Ausgang
|
212 |
|
213 | PWM1_DDR |= (1<<PWM1); // PWM1 als Ausgang
|
214 | /***************************************************************************************************/
|
215 | // Konfiguration von Timer1 für die PWM und den allg. Zeitgeber:
|
216 | // Mode:Fast PWM;TOP:OCR1A;Update:BOTTOM;TOV1:TOP;Prescaler:1(FRQ@16MHz = 16MHz)
|
217 | TCCR1A = (1<<WGM11);
|
218 | TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10);
|
219 | OCR1A = 0; // PWM-Wert
|
220 | ICR1 = 1023; // TOP-Wert des Zählers
|
221 | TIMSK1 |= 1<<TOIE1; // Aktivierung des Interrupts(Timer1 Overflow Interrupt Enable)
|
222 |
|
223 | // Konfiguration von Timer0 für die Tasterentprellung:
|
224 | TCCR0B = (1<<CS02)|(1<<CS00); // Prescaler:1024
|
225 | TIMSK0 |= 1<<TOIE0; // Aktivierung des Interrupts(Timer0 Overflow Interrupt Enable)
|
226 | sei(); // Aktivierung der Interrupts auf globaler Ebene
|
227 | /***************************************************************************************************/
|
228 |
|
229 |
|
230 | while(1)
|
231 | {
|
232 | // USART-Kommunikation
|
233 | if(uart_rx_flag==1) // String komplett empfangen?
|
234 | {
|
235 | USART_RECEIVE_STRING(stringbuffer); // Einlesen des Strings
|
236 | //SWITCHBOARD_PINS_USART(stringbuffer); // PIN-Ansteuerung
|
237 | //USART_SEND_STRING(stringbuffer);
|
238 | }
|
239 |
|
240 | // Abfrage der Taster:
|
241 | // (Für die zeitliche Signal-Verarbeitung wird bei jedem 'key_press'-Ereignis ein Zähler in
|
242 | // TIMER1_OVF_vect(s.o.) gestartet!)
|
243 | /***********************************************************************************************/
|
244 | if(get_key_press(1<<KEY1))
|
245 | {
|
246 | //nBtnMode++; // Umschalten/Hochzählen des Programm-Modus
|
247 | //nBtnModeCount = 0; // Zurücksetzung des Zählers(s.TIMER1_OVF_vect)
|
248 | USART_SEND_STRING("Dynasoft' autoDesk: ...loaded.");
|
249 | }
|
250 | /***********************************************************************************************/
|
251 | if(get_key_short(1<<KEY1) || get_key_long_r(1<<KEY1) || get_key_rpt_l(1<<KEY1))
|
252 | {
|
253 | /*if(!(TCCR1A & (1<<COM1A1)))
|
254 | {
|
255 | TCCR1A |= (1<<COM1A1);
|
256 | OCR1A = 0;
|
257 | nSavedPWM = 0;
|
258 | }*/
|
259 | // bei COM1A1=0 auch den PIN auf 0 schalten!
|
260 |
|
261 | switch(nBtnMode)
|
262 | {
|
263 | /*-------------------------------------------------------------------------------------*/
|
264 | case(2): if(bDimmDirection == 1)
|
265 | {
|
266 | TCCR1A |= (1<<COM1A1);
|
267 |
|
268 | if(OCR1A < ICR1)
|
269 | OCR1A += 5;
|
270 | else
|
271 | {
|
272 | nDimmCount++;
|
273 | if(nDimmCount > DIMM_TIMEOUT)
|
274 | bDimmDirection = 0;
|
275 | }
|
276 | }
|
277 | else
|
278 | {
|
279 | if(OCR1A > 0)
|
280 | OCR1A -= 5;
|
281 | else
|
282 | {
|
283 | OCR1A = 0;
|
284 | TCCR1A &= ~(1<<COM1A1);
|
285 | bDimmDirection = 1;
|
286 | nDimmCount = 0;
|
287 | }
|
288 | }
|
289 | nSavedPWM = OCR1A;
|
290 | break;
|
291 | /*-------------------------------------------------------------------------------------*/
|
292 | }
|
293 | }
|
294 | }
|
295 | return 0;
|
296 | }
|
297 | /*******************************************************************************************************/
|