1 | /*------------------------------------------------------------------*/
|
2 | /* Funktion: Einschaltverzögerung */
|
3 | /* */
|
4 | /* Timer Interrupt für Zeitbasis (CTC Mode),entprellen */
|
5 | /* und fallunterscheidung (nicht-,kurz- oder lang-gedrückt) */
|
6 | /* */
|
7 | /* Quarzfrequenz = 16 MHz */
|
8 | /* */
|
9 | /* Pollin Funk-AVR-Evaluationsboard v1.1 mit ATmega644P */
|
10 | /* */
|
11 | /* Autor: Johannes Häußermann */
|
12 | /* Email: Johannes_H88@gmx.de */
|
13 | /*------------------------------------------------------------------*/
|
14 | //verwendete Biblioteken
|
15 | #include <avr/io.h>
|
16 | #include <avr/interrupt.h>
|
17 | #include <stdbool.h>
|
18 | #include <stdio.h>
|
19 |
|
20 |
|
21 | #define F_CPU 16000000 // processor clock frequency
|
22 |
|
23 | #define TASTER ( 1<<PORTB1 ) //Bitoperation für den Taster Pin
|
24 | #define LED1 6 //Pin der LED 1
|
25 | #define LED2 5 //Pin der LED 2
|
26 |
|
27 | #define DDR_Taster DDRB //data direction des Port B
|
28 | #define DDR_LED DDRD //data direction des Port D
|
29 |
|
30 | #define PORT_LED PORTD //Port D
|
31 | #define PORT_Taster PORTB //Port B
|
32 |
|
33 |
|
34 | #define LED_AN(LED) (PORTD |= (1<<(LED))) //LED an gehen "funktion"
|
35 | #define LED_AUS(LED) (PORTD &= ~(1<<(LED))) //LED aus gehen "funktion"
|
36 | #define TASTER_GEDRUECKT() (PINB & (1<<PORTB1)) //if(TASTER_GEDRUECKT())
|
37 |
|
38 |
|
39 | volatile unsigned int interrupt_zaehler = 0; //Deklaration des Zeitbasis Zählers
|
40 | volatile unsigned int DelayON = 0; //Deklaration der berechneten Verzögerung
|
41 | volatile unsigned int tasten_zeit = 0; //Deklaration des entprell Zählers
|
42 |
|
43 | volatile unsigned char tasten_modus = 0; // Deklaration der Tasten Modi
|
44 | //0 ist nicht gedrückt
|
45 | //1 ist kurz gedrückt
|
46 | //2 st lang gedrückt
|
47 | volatile unsigned char enable_interrupt_zaehler = 0;//Deklatation wann Zeitbasis gestartet wird
|
48 | volatile unsigned char Funktion = 0; //Funktionswahl 0=einschaltverzögerung 1=ausschaltverzögerung 2=treppenhausfunktion
|
49 |
|
50 | volatile bool LedAn = 0;
|
51 | volatile bool ein = 0; //Deklaration des letztentlichen Einschaltend der LED
|
52 |
|
53 | //------------------------------------------------------------------------------------------------------
|
54 | //Funktionen
|
55 |
|
56 | //Printf umleitung an USART, wartet immer bis ein zeichen ausgegeben ist
|
57 | int uart_putchar( char c, FILE *stream )
|
58 | {
|
59 |
|
60 | loop_until_bit_is_set( UCSR0A, UDRE0 ); //Warten bis Zeichen ausgegeben ist
|
61 | UDR0 = c; //Zeichen ins Ausgaberegister Schreiben
|
62 | return 0; //Wenn fertig 0 zurück geben
|
63 | }
|
64 |
|
65 | //variable mystdout vom typ file der ich den USART stream zuweise
|
66 | static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL, _FDEV_SETUP_WRITE );
|
67 |
|
68 | //Initialisierung des Timers 2A CTC Mode
|
69 | void timer2A_init_wave()
|
70 | {
|
71 | //timer konfiguration, 8bit = 256
|
72 |
|
73 | //vergleichen: TCNT2 == OCR2A, wenn ja kann bedingung als interrupt oder waveform Pin (OC2A) Bedingung genutzt werden
|
74 | OCR2A = 0xFF;
|
75 |
|
76 | //Timermodus einstellen CTC mit WGM22 und toggle mit COM2A0
|
77 | //TCCR2A = Timer/Counter Control Register A [COM2A1 COM2A0 COM2B1 COM2B0 - - WGM21 WGM20] übergabe bsp (1 << COM2A0) | (1 << WGM21)
|
78 | //TCCR2A = 0x82;
|
79 | TCCR2A = (1 << COM2A1) | (1 << WGM21);
|
80 |
|
81 | //TCCR2B = Timer/Counter Control Register B [FOC2A FOC2B - - WGM22 CS22 CS21 CS20 ] 16MHz/(1024*256)
|
82 | //TCCR2B = 0x07;
|
83 | TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20);
|
84 |
|
85 | //interrupt enable für CTC
|
86 | //TIMSK2 = Timer/Counter2 Interrupt Mask Register[- - - - - OCIE2B OCIE2A TOIE2]
|
87 | //TIMSK2 = 0x02;
|
88 | TIMSK2 = (1 << OCIE2A);
|
89 |
|
90 | }
|
91 |
|
92 | //------------------------------------------------------------------------------------------------------
|
93 | //Interrupt Service Rputine des Timers 2A
|
94 | ISR (TIMER2_COMPA_vect)
|
95 | {
|
96 | //Start des Entprell Zählers
|
97 | if( TASTER_GEDRUECKT() )
|
98 | {
|
99 | tasten_zeit++;
|
100 | printf("tasten_zeit: %d \r", tasten_zeit);
|
101 | }
|
102 |
|
103 | else tasten_zeit = 0;
|
104 |
|
105 |
|
106 |
|
107 | //Tastenmodus 2 setzen (Taster lange gedrückt), bedingung für Interruptzähler NICHT starten
|
108 | /* if(tasten_zeit >= 200)
|
109 | {
|
110 | tasten_modus = 2;
|
111 | enable_interrupt_zaehler = 0;
|
112 | }*/
|
113 |
|
114 | //Tastenmodus 1 setzen (Taster kurz gedrückt), bedingung für Interruptzähler starten
|
115 | if (tasten_zeit >= 10)
|
116 | {
|
117 | //tasten_zeit = 0;
|
118 | //tasten_modus = 1;
|
119 |
|
120 |
|
121 | switch(Funktion)
|
122 | {
|
123 | case 1: //Einschaltverzögerung
|
124 | if(LedAn) ein = 1;
|
125 | else
|
126 | {
|
127 | enable_interrupt_zaehler = 1;
|
128 | //printf("BLUBB \r");
|
129 | }
|
130 | break;
|
131 | case 2: //Ausschaltverzögerung
|
132 | if(LedAn) enable_interrupt_zaehler = 1;
|
133 | else ein = 1;
|
134 | break;
|
135 | case 3://Treppenhausfunktion
|
136 | if(LedAn) interrupt_zaehler = 0;
|
137 | else ein = 1;
|
138 | break;
|
139 | }
|
140 |
|
141 | //printf("tasten_modus: %d \r", tasten_modus);
|
142 | }
|
143 | //Tastenmodus 0 (Taster nicht gedrückt), LED geht aus
|
144 | else
|
145 | {
|
146 | tasten_modus = 0;
|
147 | //printf("tasten_modus: %d \r", tasten_modus);
|
148 | }
|
149 |
|
150 | //Zeitbasis starten
|
151 | if(enable_interrupt_zaehler == 1)
|
152 | {
|
153 | interrupt_zaehler++;
|
154 | //Bedingung ob Verzögerungszeit erreicht
|
155 | if(interrupt_zaehler >= DelayON)
|
156 | {
|
157 | ein = 1;
|
158 | enable_interrupt_zaehler = 0;
|
159 | interrupt_zaehler = 0;
|
160 | //printf("ein: %d \r", ein);
|
161 | }
|
162 | }
|
163 | else
|
164 | {
|
165 | interrupt_zaehler = 0;
|
166 | //printf("interrupt_zaehler: %d \r",interrupt_zaehler);
|
167 | }
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 | }
|
175 |
|
176 |
|
177 |
|
178 | //------------------------------------------------------------------------------------------------------
|
179 | //Hauptroutine
|
180 |
|
181 | int main( void )
|
182 | {
|
183 | //ununterbrochene Initialisierung
|
184 | //cli();
|
185 | //mystd wird auf stdout umgeleitet
|
186 | stdout = &mystdout;
|
187 |
|
188 | //USART initialisierung
|
189 | UCSR0C = 0b00000110;
|
190 | UCSR0B = 0b10011000;
|
191 | UBRR0 = 103; //9600 Baud bei 16Mhz System Clock
|
192 |
|
193 | //Eingabevariable in sekunden für Verzögerungszeit
|
194 | unsigned int Delay = 0;
|
195 |
|
196 |
|
197 | //Angabe in sekunden
|
198 | Delay = 1;
|
199 | //Berechnung der Anzahl der zu verzögerten Interrupts
|
200 | DelayON = (F_CPU * Delay)/ 262144;//(16MHz * Delay)(1024 * 256)
|
201 |
|
202 | // setzen der data direction in PORT D von den LEDs
|
203 | DDR_LED |= (1 << LED1) | (1 << LED2);
|
204 |
|
205 | // Taster initialisierung TASTER = (1<<PB1)
|
206 | DDR_Taster &= ~TASTER; // data direction PB1
|
207 | PORT_Taster |= TASTER; // pull up Widerstand angeschalten
|
208 | MCUCR &= ~(1 << PUD);
|
209 |
|
210 |
|
211 |
|
212 | //initialisierung des Timer 2A
|
213 | timer2A_init_wave();
|
214 | Funktion = 1;
|
215 |
|
216 | sei();
|
217 |
|
218 | //Hauptprogramm
|
219 | printf(" START \r");
|
220 | //printf(" DelayON:%d \r", DelayON);
|
221 |
|
222 | while(1)
|
223 | {
|
224 | //printf(" interrupt_zaehler:%d \r", interrupt_zaehler);
|
225 | //wenn Verzögerungszeit abgelaufen LED anschalten
|
226 | if( ein == 1)
|
227 | {
|
228 | if(LedAn)
|
229 | {
|
230 | printf("LED_AN - mache jetzt aus\r");
|
231 | LED_AUS(LED1);
|
232 | LedAn = 0;
|
233 | ein = 0;
|
234 | //enable_interrupt_zaehler = 0;
|
235 |
|
236 | }
|
237 | else if(!LedAn)
|
238 | {
|
239 | printf("LED_AUS - mache jetzt an\r");
|
240 | LED_AN(LED1);
|
241 | LedAn = 1;
|
242 | ein = 0;
|
243 | //enable_interrupt_zaehler = 0;
|
244 | }
|
245 | }
|
246 |
|
247 |
|
248 | }
|
249 | }
|