1 | //Bibliotheken einbinden
|
2 | #define F_CPU 8000000
|
3 | #include <avr/eeprom.h>
|
4 | #include <avr/interrupt.h>
|
5 | #include <avr/io.h>
|
6 | #include "lcd-routines.h"
|
7 | #include <stdlib.h>
|
8 | #include <util/delay.h>
|
9 |
|
10 | //Pinbelegung
|
11 | #define MosfetDriver1_PORT PORTD //OC2
|
12 | #define MosfetDriver1_DDR DDRD
|
13 | #define MosfetDriver1_DB PB6
|
14 | #define MosfetDriver2_PORT PORTC
|
15 | #define MosfetDriver2_DDR DDRC
|
16 | #define MosfetDriver2_DB PC0
|
17 | #define Stick_PORT PORTD //ICP1
|
18 | #define Stick_PIN PIND
|
19 | #define Stick_DDR DDRD
|
20 | #define Stick_DB PD6
|
21 | #define Taster1_PORT PORTC
|
22 | #define Taster1_PIN PINC
|
23 | #define Taster1_DDR DDRC
|
24 | #define Taster1_DB PC0
|
25 | #define Taster2_PORT PORTC
|
26 | #define Taster2_PIN PINC
|
27 | #define Taster2_DDR DDRC
|
28 | #define Taster2_DB PC1
|
29 | #define LEDRot_PORT PORTB
|
30 | #define LEDRot_DDR DDRB
|
31 | #define LEDRot_DB PB0
|
32 | #define LEDGruen_PORT PORTB
|
33 | #define LEDGruen_DDR DDRB
|
34 | #define LEDGruen_DB PB1
|
35 |
|
36 | //Variablendeklaration
|
37 | uint16_t eeunten EEMEM; //fuer EEPROM
|
38 | uint16_t unten; //fuer EEPROM
|
39 | uint16_t eeoben EEMEM; //fuer EEPROM
|
40 | uint16_t oben; //fuer EEPROM
|
41 | uint16_t eebrake EEMEM; //fuer EEPROM
|
42 | uint16_t brake; //fuer EEPROM
|
43 | int flanke; //fuer Stick
|
44 | uint16_t flankeStart; //fuer Stick
|
45 | volatile uint16_t stick; //fuer Stick (volatile = Global gueltig)
|
46 | float deltaStick; //fuer Stick
|
47 | float rechenwert; //fuer Stick
|
48 | int sollwert; //fuer Stick
|
49 | volatile uint8_t currentOverload = 0; //fuer currentOverload
|
50 | uint16_t voltage; //fuer voltage
|
51 | uint16_t overTemperature; //fuer overTemperature
|
52 | int lcdpwm; //fuer LCD
|
53 | char Buffer[20]; //fuer LCD
|
54 |
|
55 | ISR(TIMER1_CAPT_vect) {
|
56 | if (flanke==0) {
|
57 | flankeStart = ICR1;
|
58 | TCCR1B &= ~(1<<ICES1); // fallende Flanke zur Auswertung des ICP
|
59 | flanke = 1;
|
60 | }
|
61 | else {
|
62 | stick = ICR1 - flankeStart;
|
63 | flanke = 0;
|
64 | TCCR1B |= (1<<ICES1); // steigende Flanke zur Auswertung des ICP
|
65 | }
|
66 | TIFR1 = ( 1 << ICF1 );
|
67 | }
|
68 |
|
69 | ISR(ANA_COMP_vect) {
|
70 | if bit_is_clear(ACSR, ACO) {
|
71 | currentOverload = 1;
|
72 | }
|
73 | else {
|
74 | currentOverload = 0;
|
75 | }
|
76 | }
|
77 |
|
78 | void PWM_Mosfet(void) {
|
79 | /*Initialisierung fuer PWM ausgeben an Mosfet Treiber
|
80 | PWM = Prozessorgeschwindigkeit / (Prescaler * 256)
|
81 | PWM = 8000000 / (8 * 256) = 3906,25Hz = 3,9kHz*/
|
82 | MosfetDriver1_DDR |= (1 << MosfetDriver1_DB); //Motor OC2 = Ausgang
|
83 | OCR3A = 0; //von 0 bis 256 einstellbar
|
84 | TCCR3A |= (1 << COM3A1); //normaler Modus
|
85 | TCCR3A |= (1 << WGM31) | (1 << WGM30); //fast PWM
|
86 | TCCR3B |= (1 << CS31); //Prescaler Clock/8
|
87 | }
|
88 |
|
89 | void PWM_Empfaenger(void) {
|
90 | TCCR1B |= (1<<ICES1); //steigende Flanke zur Auswertung des ICP
|
91 | TCCR1B |= (1<<CS11) | (1<<CS10); //Quelle für Timer/Counter = CPU-Takt/64
|
92 | TIMSK1 |= (1<<ICIE1); //Capture Interrupt Enable
|
93 | Stick_DDR &= ~(1<<Stick_DB); //Impuls von Fernsteuerung ICP1 = Eingang
|
94 | Stick_PORT |= (1<<Stick_DB); //Pullup aktiviert
|
95 | }
|
96 |
|
97 | void Strommessung(void) {
|
98 | ACSR |= (0 << ACD); //Comparator ein
|
99 | ACSR |= (1 << ACBG); //interne Referenzspannung (1,3 Volt)
|
100 | ACSR |= (1 << ACI); //kann fuer Abfragen genutzt werden
|
101 | ACSR |= (1 << ACIE); //löst Interrupt aus
|
102 | ACSR |= (0 << ACIC); //verbindet Comparatorausgang mit Counter 1
|
103 | ACSR |= (0 << ACIS1) | (0 << ACIS0); //Interrupt auslösen bei jedem Flankenwechsel
|
104 | }
|
105 |
|
106 | void StickWay(void) {
|
107 | if(!(Taster1_PIN & (1 << Taster1_DB))) {
|
108 | LEDGruen_PORT |= (1 << LEDGruen_DB);
|
109 | LEDRot_PORT |= (1 << LEDRot_DB);
|
110 | while(1) {
|
111 | _delay_ms(3000);
|
112 | unten = stick + 2; //incl. Korrekturfaktor
|
113 | lcdpwm = unten;
|
114 | lcd_clear();
|
115 | itoa(lcdpwm, Buffer, 10);
|
116 | lcd_string(Buffer);
|
117 | eeprom_write_word (&eeunten, unten);
|
118 | _delay_ms(3000);
|
119 | LEDRot_PORT &= ~(1 << LEDRot_DB);
|
120 | _delay_ms(3000);
|
121 | oben = stick - 2; //incl. Korrerkturfaktor
|
122 | eeprom_write_word (&eeoben, oben);
|
123 | _delay_ms(3000);
|
124 | LEDGruen_PORT &= ~(1 << LEDGruen_DB);
|
125 | break;
|
126 | }
|
127 | }
|
128 | }
|
129 |
|
130 | void OptionalBrake (void) {
|
131 | if(!(Taster2_PIN & (1 << Taster2_DB))) {
|
132 | LEDGruen_PORT |= (1 << LEDGruen_DB);
|
133 | LEDRot_PORT |= (1 << LEDRot_DB);
|
134 | brake = eeprom_read_word (&eebrake);
|
135 | if (brake == 1) {
|
136 | brake = 0;
|
137 | }
|
138 | else {
|
139 | brake = 1;
|
140 | }
|
141 | eeprom_write_word (&eebrake, brake);
|
142 | _delay_ms(3000);
|
143 | LEDRot_PORT &= ~(1 << LEDRot_DB);
|
144 | LEDGruen_PORT &= ~(1 << LEDGruen_DB);
|
145 | }
|
146 | }
|
147 |
|
148 | void EepromRead(void) {
|
149 | unten = eeprom_read_word (&eeunten);
|
150 | oben = eeprom_read_word (&eeoben);
|
151 | brake = eeprom_read_word (&eebrake);
|
152 | unten = 1100;
|
153 | oben = 1900;
|
154 | deltaStick = oben - unten;
|
155 | if (deltaStick == 0) {
|
156 | while(1) {
|
157 | LEDRot_PORT |= (1 << LEDRot_DB);
|
158 | LEDGruen_PORT |= (1 << LEDGruen_DB);
|
159 | }
|
160 | }
|
161 | deltaStick = 512 / deltaStick;
|
162 | }
|
163 |
|
164 | void WaitForUserReady(void) {
|
165 | LEDGruen_PORT &= ~(1 << LEDGruen_DB);
|
166 | LEDRot_PORT |= (1 << LEDRot_DB);
|
167 | while(stick != unten);
|
168 | MosfetDriver2_PORT |= (1 << MosfetDriver2_DB);
|
169 | LEDRot_PORT &= ~(1 << LEDRot_DB);
|
170 | LEDGruen_PORT |= (1 << LEDGruen_DB);
|
171 | }
|
172 |
|
173 | void InputOutput(void) {
|
174 | MosfetDriver2_DDR |= (1 << MosfetDriver2_DB); //SD Pin IR2184 Mosfet Treiber
|
175 | Taster1_DDR &= ~(1 << Taster1_DB); //Taster 1
|
176 | Taster1_PORT |= (1 << Taster1_DB); //Pullup fuer Taster 1
|
177 | Taster2_DDR &= ~(1 << Taster2_DB); //Taster 2
|
178 | Taster2_PORT |= (1 << Taster2_DB); //Pullup fuer Taster 2
|
179 | LEDRot_DDR |= (1 << LEDRot_DB); //Rote LED
|
180 | LEDGruen_DDR |= (1 << LEDGruen_DB); //Gruene LED
|
181 | }
|
182 |
|
183 | void ADC_Init(void) {
|
184 | uint16_t result;
|
185 | ADMUX = (1<<REFS1) | (1<<REFS0); //interne Referenzspannung (2,56V)
|
186 | ADCSRA = (1<<ADPS2) | (1<<ADPS1); // Frequenzvorteiler, Dummyreadout
|
187 | ADCSRA |= (1<<ADEN); // ADC aktivieren
|
188 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
189 | while (ADCSRA & (1<<ADSC)) { // auf Abschluss der Konvertierung warten
|
190 | }
|
191 | result = ADCW;
|
192 | }
|
193 |
|
194 | uint16_t ADC_Read(uint8_t channel) {
|
195 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); //Kanal waehlen, ohne andere Bits zu beeinflußen
|
196 | ADCSRA |= (1<<ADSC); //eine Wandlung "single conversion"
|
197 | while (ADCSRA & (1<<ADSC) ) { //auf Abschluss der Konvertierung warten
|
198 | }
|
199 | return ADCW;
|
200 | }
|
201 |
|
202 | int main (void) {
|
203 | sei(); //erlaubt globale Interrupts
|
204 | lcd_init();
|
205 | lcd_clear();
|
206 | lcd_string("Regler");
|
207 | PWM_Empfaenger();
|
208 | PWM_Mosfet();
|
209 | Strommessung();
|
210 | InputOutput();
|
211 | StickWay();
|
212 | //OptionalBrake();
|
213 | EepromRead();
|
214 | WaitForUserReady();
|
215 | ADC_Init();
|
216 |
|
217 | while(1) {
|
218 | if(currentOverload == 1) {
|
219 | OCR3A = 0;
|
220 | MosfetDriver2_PORT &= ~(1 << MosfetDriver2_DB);
|
221 | WaitForUserReady();
|
222 | }
|
223 | overTemperature = ADC_Read(1);
|
224 | if (overTemperature >= 250) {
|
225 | OCR3A = 0;
|
226 | MosfetDriver2_PORT &= ~(1 << MosfetDriver2_DB);
|
227 | WaitForUserReady();
|
228 | }
|
229 | else {
|
230 | voltage = ADC_Read(0);
|
231 | if (voltage <= 125)
|
232 | {
|
233 | break;
|
234 | }
|
235 | rechenwert = stick - unten;
|
236 | rechenwert = rechenwert * deltaStick;
|
237 | sollwert = rechenwert;
|
238 | if(stick >= oben) {
|
239 | sollwert = 512;
|
240 | }
|
241 | if(stick <= unten) {
|
242 | sollwert = 0;
|
243 | }
|
244 | if (voltage <= 250) {
|
245 | if (sollwert >= 127) {
|
246 | sollwert = 127;
|
247 | }
|
248 | }
|
249 | OCR3A = sollwert;
|
250 | }
|
251 | }
|
252 | while(1) {
|
253 | OCR3A = 0;
|
254 | MosfetDriver2_PORT &= ~(1 << MosfetDriver2_DB);
|
255 | LEDGruen_PORT &= ~(1 << LEDGruen_DB);
|
256 | LEDRot_PORT |= (1 << LEDRot_DB);
|
257 | }
|
258 | return 0;
|
259 | }
|