1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <avr/pgmspace.h>
|
4 |
|
5 | /*! \def arraysize
|
6 | * \brief Begrenzung der Feldgroesse\n
|
7 | * Hier wird die Anzahl der Punkte pro Kurve festgelegt
|
8 | */
|
9 |
|
10 | #define arraysize 1024 // Begrenzung der Feldgröße
|
11 |
|
12 | #include "tabelle.h" // Kennlinientabelle(n)
|
13 |
|
14 |
|
15 | /*! \brief Interrupt Service Routine fuer das Setzen der Werte fuer Strom und Spannung\n\n
|
16 | Diese Routine wird aufgerufen, wenn der ADC seine Wandlung beendet hat. Dieser Wert wird\n
|
17 | in die Variable 'temp' umgespeichert und dann einer Begrenzung unterzogen, damit keine\n
|
18 | ungueltigen Feldwerte auftreten koennen. Dann wird ueber eine switch-Anweisung die entsprechende\n
|
19 | Kurve ausgewaehlt. Jetzt findet eine Pruefung statt, ob der Kurzschlusstrom erreicht wurde oder\n
|
20 | nicht. Wenn ja, dann werden feste Werte fuer Strom und Spannung vorgegeben und das Netzteil\n
|
21 | uebernimmt dann die Regelung. Falls der Kurzschlusstrom nicht erreicht wird, dann fungiert der\n
|
22 | Wert des Stromes als Index, worauf der enstprechende Wert aus der Tabelle genommen und\n
|
23 | und als PWM-Wert gesetzt wird. Der Wert fuer die Strombegrenzung wird so gesetzt, dass sie\n
|
24 | nicht eingreift.
|
25 |
|
26 | */
|
27 |
|
28 | volatile uint16_t mittelwert;
|
29 |
|
30 | ISR(ADC_vect) {
|
31 | uint16_t SPG_Wert;
|
32 |
|
33 | SPG_Wert = ADCW;
|
34 |
|
35 | if (SPG_Wert>=arraysize) {
|
36 | SPG_Wert = arraysize-1;
|
37 | }
|
38 |
|
39 | mittelwert += SPG_Wert; // Filterung der Eingangswerte
|
40 | mittelwert /= 2;
|
41 |
|
42 | OCR0A = 255; // Strombegrenzungswert
|
43 |
|
44 | OCR1A = pgm_read_word( &table1[mittelwert] ); // Kennlinienwert am gefilterten Eingangswert
|
45 | }
|
46 |
|
47 |
|
48 | /*! \brief Interrupt Service Routine fuer das Setzen des Abtastintervalls und Starten des ADC\n\n
|
49 | Mit dieser Routine wird das Abtastintervall festgelegt. Timer 2 (8-Bit) wurde so konfiguriert,\n
|
50 | das er im Fast-PWM-Modus laeuft und sobald er sein Maximum (0xFF) erreicht, diesen Interrupt\n
|
51 | ausloest. Mit einer Systemfreqenz von 20Mhz, eimem Vorteiler von 32 und seiner Zaehlweite von 0xFF\n
|
52 | laeuft dieser Interrupt mit rund 2450Hz. Sobald dieser aufgerufen wird, beginnnt der ADC mit der\n
|
53 | Umwandlung des analogen Wertes. Es ist zu beachten, dass dem ADC genuegend Zeit eingeraeumt wird,\n
|
54 | damit er die Umwandlung korrekt ausfuehren kann.
|
55 |
|
56 | */
|
57 |
|
58 | /*
|
59 | ISR(TIMER2_OVF_vect) {
|
60 | ADCSRA |= (1<<ADSC); //Starte Umwandlung des analogen Wertes
|
61 | }
|
62 | */
|
63 |
|
64 |
|
65 | /*! \fn main
|
66 | * \brief Hauptprogramm\n
|
67 | * Hier stehen die Einstellungen fuer die\n
|
68 | * Timer und des ADC
|
69 | */
|
70 |
|
71 | int main (void) {
|
72 |
|
73 | PORTB |= (1<<PB2) | (1<<PB3) | (1<<PB0); //setzen der internen Pull-up-Widerstände
|
74 | DDRB &= ~( (1<<DDB2) | (1<<DDB3) | (1<<DDB0) ); //PB0, PB2 und PB3 als Eingänge definert
|
75 | DDRB |= (1<<PB1); //setzte PB1 von Port B als Ausgang
|
76 | DDRB |= (1<<PB5); //setzte PB5 von Port B als Ausgang
|
77 |
|
78 | DDRC |= (1<<DDC5); //setze Pin5 von PORTC als Ausgang
|
79 |
|
80 | ADMUX = (1<<REFS0); //nutze AVCC als Referenz (5V)
|
81 | ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) | (1<<ADIE); //Teilungsfaktor 128 = 20Mhz/128=156,25kHz / Eingang 0
|
82 | ADCSRA |= (1<<ADEN); //ADC aktivieren
|
83 | ADCSRA |= (1<<ADSC);
|
84 |
|
85 |
|
86 | TCCR1A = (1<<WGM11)|(1<<COM1A1); //Fast PWM, Zählweite einstellbar durch ICR1
|
87 | TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS10); // Teiler 1==> 20Mhz/512==> 39062,5kHz
|
88 | ICR1 = 512; //Frequenz 39,06kHz
|
89 |
|
90 | TCCR2B = (1<<CS20) | (1<<CS21);// | (1<<CS22) ; //Teiler 32==> 625kHz==>625000/255=2450Hz
|
91 | TIMSK2 = (1<<TOIE2); //Interrupt enable
|
92 |
|
93 |
|
94 | /************************************* Zähler für Strombegrenzung (Netzteil)*********************************************/
|
95 |
|
96 | TCCR0A = (1<<WGM00) | (1<<WGM01) | (1<<COM0A1); //Fast PWM, Top 0xFF
|
97 | TCCR0B = (1<<CS00); //kein Prescaler, Frequenz 20MHz/255 = 78,3kHz
|
98 | DDRD |= (1 << PD6 ); //setzte PD6 von Port D als Ausgang
|
99 |
|
100 | /************************************************************************************************************************/
|
101 |
|
102 | sei (); //global Interrupt enable
|
103 |
|
104 | while(1){
|
105 | }
|
106 |
|
107 | }
|