Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "../h/pmc.h"
- #include "../h/tc.h"
- #include "../h/pio.h"
- #include "../h/aic.h"
- #define PROZESSORCLOCK 25000000 //Systemtakt - 25MHz Skript S.139
- #define VORTEILER 8 //Genutzter Vorteiler
- #define FREQUENZ 50 //Frequenz fuer Pumpe laut Aufgabenstellung
- #define TC_PUMPE_INIT TC_ACPC_CLEAR_OUTPUT | TC_ACPA_SET_OUTPUT | TC_WAVE | TC_CPCTRG | TC_CLKS_MCK8 //Mode fuer Timer 3 (Pumpe) initialisieren
- #define TC_WAAGE_INIT TC_CLKS_MCK2 | TC_LDBSTOP | TC_CAPT | TC_LDRA_RISING_EDGE | TC_LDRB_RISING_EDGE //Mode fuer Timer 4,5 (Waage) initialisieren
- #define C1 2000 //Waagenkonstante C1 - anpassen fuer echte Waage
- #define C2 0 //Waagenkonstante C2
- #define ABFUELLMENGE 500 //Wird noch bekannt gegeben
- void init_tasten( void );
- void taste_irq_handler (void) __attribute__ ((interrupt));
- void init_timer_pumpe( void );
- void init_timer_waage( void );
- int messungderMasse( void );
- void intToString( int, char * );
- void auschankstation(void);
- volatile int taste; //Speichert den Wert der zuletzt gedrueckten Taste SW1 = 1 oder SW2 = 2
- int main( void )
- {
- StructAIC* aicbase = AIC_BASE; // Basisadresse AIC
- StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO A
- //###### Aufgabe 1 ###### - Initialisierung der benoetigten Peripherie.
- init_tasten();
- init_timer_pumpe();
- init_timer_waage();
- init_ser();
- //Interrupt Service Routine ausfuehrbar machen
- aicbase->AIC_IDCR = (1<<14); //interrupt piob ausschalten
- aicbase->AIC_ICCR = (1<<14); //interrupt piob löschen
- aicbase->AIC_SVR[PIOB_ID] = (unsigned int)taste_irq_handler;
- aicbase->AIC_SMR[PIOB_ID] = 0x7; //priorität interrupt
- aicbase->AIC_IECR = (1<<14); //interrupt piob einschalten
- piobaseB->PIO_IER = KEY1 | KEY2; //interrupt für Key1 und Key2 erlauben
- while(1)
- {
- //###### Aufgabe 6 ###### - Wenn der Becher weg genommen ist soll von vorne (Aufgabe 2 evtl. Aufgabe1) begonnen werden
- auschankstation();
- }
- aicbase->AIC_IDCR = (1<<14); //interrupt piob ausschalten
- aicbase->AIC_ICCR = (1<<14); //interrupt piob löschen
- return 0;
- }
- void auschankstation( void )
- {
- StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO A
- //###### Aufgabe 2 ###### - Begruessung und Informationen über die serielle Schnittstelle
- puts("Begruessung");
- //###### Aufgabe 3 ###### - Wiegen, kalibrieren und anzeigen des Gefäßgewichtes nach Aufstellen eines Bechers und Drücken der Taste SW1
- taste = 0;
- //Warten bis Taste 1 gedrueckt wurde, was bedeutet der Becher wurde aufgestellt
- puts("Becher aufstellen und Taste SW1, oder 'b' auf Tastatur druecken");
- while(taste != 1)
- {
- char inputch = getc();
- if(inputch == 'b')
- break;
- }
- volatile int becherGewicht = 0;
- becherGewicht = messungderMasse();
- if(becherGewicht > 0) //Becher wurde aufgestellt
- {
- puts("Gewicht des Bechers: ");
- char gewicht[8];
- intToString(becherGewicht, gewicht); //Gewicht von integer in string umwandeln um es mit puts ausgeben zu können
- puts(gewicht);
- }
- else //Becher wurde nicht aufgestellt
- {
- puts("Becher wurde nicht erkannt");
- auschankstation(); //Neustart
- }
- //###### Aufgabe 4 ###### - Abfüllen einer Menge nach drücken der Taste SW2
- //Warten bis Taste 2 gedrueckt wurde, was bedeutet der Abfuellvorgang startet
- puts("Taste SW2, oder 's' auf Tastatur druecken um Abfuellvorgang zu starten");
- while(taste != 2)
- {
- char inputch = getc();
- if(inputch == 's')
- break;
- }
- //Pumpvorgang nur Starten wenn Becher noch auf Waage steht
- becherGewicht = messungderMasse();
- volatile int gesamtGewicht = becherGewicht;
- int fail = 0;
- if(becherGewicht > 0)
- {
- piobaseA->PIO_PDR = (1<<PIOTIOA3) ; //Controlle über Pin dem Timer geben -> sendet Signale an die Pumpe und diese beginnt zu pumpen
- //While schleife die so lange läuft bis das gewuenschte Gewicht erreicht ist
- while((gesamtGewicht - becherGewicht) < ABFUELLMENGE)
- {
- volatile int gewichtAlt; //variable um zu testen wie sich das Gewicht verändert hat
- gewichtAlt = gesamtGewicht;
- gesamtGewicht = messungderMasse();
- if(gesamtGewicht > gewichtAlt) //Gewicht ist angestiegen -> es wurde gepumpt
- {
- puts("Abgefuellte Menge: ");
- char aktGewicht[8];
- intToString(gesamtGewicht - becherGewicht, aktGewicht); //gesamtGewicht - becherGewicht um Gewicht der fluessigkeit zu bekommen
- puts(aktGewicht);
- }
- else //Gewicht ist wurde weniger -> Becher wurde entfernt
- {
- piobaseA->PIO_PDR = (1<<PIOTIOA3); //Mit pumpen aufhoeren!
- puts("Becher wurde entfernt, Abfuellvorgang wird gestoppt");
- fail = 1;
- break;
- }
- }
- piobaseA->PIO_PDR = (1<<PIOTIOA3); //Controlle über Pin dem Timer entziehen -> sendet keine Signale mehr an die Pumpe und diese hoert auf zu pumpen
- }
- else
- {
- puts("Becher wurde nicht erkannt, Abfuellvorgang wurde nicht gestartet");
- auschankstation(); //Neustart
- }
- //###### Aufgabe 5 ###### - Nach dem Abfüllvorgang melden welche Menge abgefüllt wurde und das der Becher weg genommen werden kann.
- if(fail != 1)
- {
- puts("Abfuellvorgang wurde beendet");
- puts("Abgefuellte Menge: ");
- char gewichtFl[8];
- intToString(gesamtGewicht - becherGewicht, gewichtFl); //Gewicht von integer in string umwandeln um es mit puts ausgeben zu können
- puts(gewichtFl);
- puts("Becher kann entfernt werden");
- }
- else
- {
- puts("Abfuellvorgang konnte nicht korrekt durchgefuehrt werden");
- }
- }
- //################## PRAKTIKUM 2 ##################
- //Keys SW1 und SW2 aktivieren
- void init_tasten( void )
- {
- StructPMC* pmcbase = PMC_BASE; //Basisadresse PMC
- StructPIO* piobaseB = PIOB_BASE; //Basisadresse PIO B
- pmcbase->PMC_PCER = (1<<14); //Peripheral Clock für PIOB einschalten
- piobaseB->PIO_PER = KEY1 | KEY2; //In PIO Enable Register Key1 und 2 einschalten.
- }
- //################## PRAKTIKUM 2 ##################
- //Interrupt Service Routine für Tasten SW1 und SW2
- void taste_irq_handler (void)
- {
- StructPIO* piobaseB = PIOB_BASE; //Basisadresse PIO B
- StructAIC* aicbase = AIC_BASE; //Basisadresse AIC
- //Prüfe ob Bit fuer Key1 gesetzt wurde durch Tastendruck
- if(!(piobaseB->PIO_PDSR & KEY1) )
- {
- taste = 1; //setze die globale auf 1 um sie in der Main abfragen zu können
- }
- //Prüfe ob Bit fuer Key2 gesetzt wurde durch Tastendruck
- if(!(piobaseB->PIO_PDSR & KEY2) )
- {
- taste = 2;
- }
- aicbase->AIC_EOICR = piobaseB->PIO_ISR; //end of interrupt command register
- }
- //################## PRAKTIKUM 3 ##################
- //Timer fuer Pumpe initialisieren - compare mode
- void init_timer_pumpe( void )
- {
- StructPMC* pmcbase = PMC_BASE; // Basisadresse PMC
- StructTC* tcbase3 = TCB3_BASE; // Basisadressse Timer 3
- StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO A
- //Peripheral Clock fuer PIOA und Timer 3 einschalten - AT91M63200(Complete) S.142
- pmcbase->PMC_PCER = (1<<13) | (1<<9);
- //Disable Clock - Reset, damit wir genau wissen in welchem Zustand er ist, TC_CCR=Control Register, TC_CLKDIS - AT91M63200(Complete) S.122
- tcbase3->TC_CCR = TC_CLKDIS;
- //Initialize the mode of the timer 3
- tcbase3->TC_CMR = TC_PUMPE_INIT;
- // Initialize the compare Register:
- int value_RC = PROZESSORCLOCK / VORTEILER / FREQUENZ; //Prozessor Clock geteilt durch Vorteiler geteilt durch gegebene Fequenz
- int value_RA = value_RC / 2; //geteilt durch 2, dadurch gleichmaessiges Taktsignal - 50% High
- tcbase3->TC_RC = value_RC; //25000000 / 8 / 50 = 62500
- tcbase3->TC_RA = value_RA; //25000000 / 8 / 50 / 2 = 31250
- // Start the timer :
- tcbase3->TC_CCR = TC_CLKEN ; //Enable Clock, TC_CLKEN=Counter Clock Enable Command - AT91M63200(Complete) S.122
- tcbase3->TC_CCR = TC_SWTRG ; //the counter is reset and clock is started, TC_SWTRG=Software Trigger Command
- piobaseA->PIO_PER = (1<<PIOTIOA3) ; //Kontrolle über Pin des Timers an PIOA geben damit pumpen noch nicht bei init beginnt
- piobaseA->PIO_OER = (1<<PIOTIOA3) ; //Outputenable
- piobaseA->PIO_CODR = (1<<PIOTIOA3) ; //Clear output data register -> kein anderes signal liegt an
- }
- //################## PRAKTIKUM 4 ##################
- //Timer fuer die beiden Frequenzen der Waage initialisieren - capture mode
- void init_timer_waage( void )
- {
- StructPMC* pmcbase = PMC_BASE; // Basisadresse PMC
- StructTC* tcbase4 = TCB4_BASE; // Basisadressse Timer 4
- StructTC* tcbase5 = TCB5_BASE; // Basisadressse Timer 5
- StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO A
- //Peripheral Clock fuer Timer 4,5 einschalten - AT91M63200(Complete) S.142
- pmcbase->PMC_PCER = (1<<10) | (1<<11);
- //Disablen der PIOA Kontrolle über die Pins PA4, PA7 -> Normale periperal funktion ist enabled - AT91M63200(Complete) S.60
- piobaseA->PIO_PDR = 0x90;
- //Timer4:
- tcbase4->TC_CCR = TC_CLKDIS; // Disable Clock, um bekannten Zustand zu bekommen
- tcbase4->TC_CMR = TC_WAAGE_INIT; // Initialize the mode of the timer 4
- tcbase4->TC_CCR = TC_CLKEN; // Enable Clock
- tcbase4->TC_CCR = TC_SWTRG; // the counter is reset and clock is started, TC_SWTRG=Software Trigger Command
- //Timer5:
- tcbase5->TC_CCR = TC_CLKDIS; // CCR= CounterControlRegister; TC_CLKDIS=0x2
- tcbase5->TC_CMR = TC_WAAGE_INIT; // Timer Counter Mode Register
- tcbase5->TC_CCR = TC_CLKEN; // 0x1
- tcbase5->TC_CCR = TC_SWTRG; // 0x4
- }
- //################## PRAKTIKUM 4 ##################
- int messungderMasse( void )
- {
- StructTC* tcbase4 = TCB4_BASE; // Basisadressse Timer 4
- StructTC* tcbase5 = TCB5_BASE; // Basisadressse Timer 5
- //Variablen zur PeriodendauerMessung von Timer 4
- volatile int captureRA4;
- volatile int captureRB4;
- volatile float Periodendauer4;
- //Variablen zur PeriodendauerMessung von Timer 5
- volatile int captureRA5;
- volatile int captureRB5;
- volatile float Periodendauer5;
- // Periodendauer der Waagensignale messen
- // Signal an TIOA4 ca. 16kHz entspricht ca. einer Periodendauer von 62,5us
- // durch den Teiler von 32 ergeben sich ca. 2ms
- // Zähler mit positiver Flanke starten
- //Status Register von Timer4/5 einmal lesen, da SR nach lesen zurückgesetzt wird und wir sicher sein können das es sich bei den naechsten gemessenen Werten um die von der Waage handelt
- int r1;
- r1 = tcbase4->TC_SR & 0x40;
- r1 = tcbase5->TC_SR & 0x40;
- int i;
- int avg;
- avg = 0;
- for(i = 0; i < 4; i++) //Vier Messungen durchfuehren um Messfehler zu vermeiden
- {
- //the counter is reset and clock is started, TC_SWTRG=Software Trigger Command
- tcbase4->TC_CCR = TC_SWTRG;
- tcbase5->TC_CCR = TC_SWTRG;
- //Capture Register B von Timer 4 wurde geladen (RB Loading Status) -> Messung abgeschlossen
- while (!(tcbase4->TC_SR & 0x40));
- captureRA4 = tcbase4->TC_RA;
- captureRB4 = tcbase4->TC_RB;
- // Capture Register B von Timer 5 wurde geladen (RB Loading Status) -> Messung abgeschlossen
- while (!(tcbase5->TC_SR & 0x40));
- captureRA5 = tcbase5->TC_RA;
- captureRB5 = tcbase5->TC_RB;
- //Periodendauer aus Differenz der beiden Capture Register RA und RB berechnen von Timer 4/5
- Periodendauer4 = captureRB4 - captureRA4;
- Periodendauer5 = captureRB5 - captureRA5;
- //Masse mit vorgegebener Formel anhand der Periodendauer berechnnen
- volatile int masse;
- masse = (C1 * ((Periodendauer4 / Periodendauer5) - 1)) - C2;
- avg = avg + masse;
- }
- avg = (avg / 4);//+2? testen!
- return avg;
- }
- //################## PRAKTIKUM 5 ##################
- void intToString(int number, char * gewicht)
- {
- int neg;
- int tmpi;
- int count;
- int tmpcount;
- char cache;
- //Zahl = 0
- if(number == 0)
- {
- gewicht[0]= '0';
- gewicht[1]= 0; //0 am Ende des Strings, da puts einen 0 terminierenden String erwartet
- return;
- }
- //Zahl negativ
- neg = 0;
- count = 0;
- if(number < 0)
- {
- neg = 1;
- number = number * -1;
- count++; //Anzahl der Ziffern erhoeht sich durch '-' um 1
- }
- //Anzahl Ziffern der Zahl
- tmpi = number;
- while(tmpi > 0)
- {
- tmpi = tmpi / 10;
- count++;
- }
- tmpcount = count + 1; //Laenge um 1 erhoehen fuer 0 am ende des Strings
- char chr[tmpcount];
- chr[count] = 0; //0 an letzte Stelle des Arrays schreiben
- if(neg == 1)
- {
- chr[0] = '-'; //Wenn Zahl negativ ist, '-' an position 0
- }
- //Ziffern extrahieren und in chararray schreiben
- int j;
- j = count - 1; //j = count - 1 da arrays bei 0 anfangen zu zaehlen
- for(j; j-neg >= 0; j--) //Wenn Zahl negativ ist bricht schleife bei chr[1] ab um das vorhandene '-' bei chr[0] nicht zu überschreiben
- {
- cache = number % 10; //Die hinterste Ziffer extrahieren
- number = number / 10; //Durch teilen durch 10 faellt die letzt Ziffer, die bereits im cache zwischengespeichert ist, weg
- chr[j] = cache + '0'; //und an die letzte Stelle des Arrays schreiben
- }
- //entstandenen String in lokale Variable des aufrufenden Programms uebertragen
- j = 0;
- for(j; j < 8; j++)
- {
- gewicht[j] = chr[j];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement