Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.21 KB | None | 0 0
  1. #include "../h/pmc.h"
  2. #include "../h/tc.h"
  3. #include "../h/pio.h"
  4. #include "../h/aic.h"
  5.  
  6. #define PROZESSORCLOCK 25000000 //Systemtakt - 25MHz Skript S.139
  7. #define VORTEILER 8 //Genutzter Vorteiler
  8. #define FREQUENZ 50 //Frequenz fuer Pumpe laut Aufgabenstellung
  9.  
  10. #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
  11.  
  12. #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
  13.  
  14. #define C1 2000 //Waagenkonstante C1 - anpassen fuer echte Waage
  15. #define C2 0 //Waagenkonstante C2
  16.  
  17. #define ABFUELLMENGE 500 //Wird noch bekannt gegeben
  18.  
  19.  
  20. void init_tasten( void );
  21. void taste_irq_handler (void) __attribute__ ((interrupt));
  22. void init_timer_pumpe( void );
  23. void init_timer_waage( void );
  24. int messungderMasse( void );
  25. void intToString( int, char * );
  26. void auschankstation(void);
  27.  
  28. volatile int taste; //Speichert den Wert der zuletzt gedrueckten Taste SW1 = 1 oder SW2 = 2
  29.  
  30.  
  31. int main( void )
  32. {
  33. StructAIC* aicbase = AIC_BASE; // Basisadresse AIC
  34. StructPIO* piobaseB = PIOB_BASE; // Basisadresse PIO A
  35.  
  36.  
  37. //###### Aufgabe 1 ###### - Initialisierung der benoetigten Peripherie.
  38. init_tasten();
  39. init_timer_pumpe();
  40. init_timer_waage();
  41. init_ser();
  42.  
  43. //Interrupt Service Routine ausfuehrbar machen
  44. aicbase->AIC_IDCR = (1<<14); //interrupt piob ausschalten
  45. aicbase->AIC_ICCR = (1<<14); //interrupt piob löschen
  46. aicbase->AIC_SVR[PIOB_ID] = (unsigned int)taste_irq_handler;
  47. aicbase->AIC_SMR[PIOB_ID] = 0x7; //priorität interrupt
  48. aicbase->AIC_IECR = (1<<14); //interrupt piob einschalten
  49. piobaseB->PIO_IER = KEY1 | KEY2; //interrupt für Key1 und Key2 erlauben
  50.  
  51. while(1)
  52. {
  53. //###### Aufgabe 6 ###### - Wenn der Becher weg genommen ist soll von vorne (Aufgabe 2 evtl. Aufgabe1) begonnen werden
  54. auschankstation();
  55. }
  56.  
  57. aicbase->AIC_IDCR = (1<<14); //interrupt piob ausschalten
  58. aicbase->AIC_ICCR = (1<<14); //interrupt piob löschen
  59.  
  60. return 0;
  61. }
  62.  
  63. void auschankstation( void )
  64. {
  65. StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO A
  66.  
  67. //###### Aufgabe 2 ###### - Begruessung und Informationen über die serielle Schnittstelle
  68. puts("Begruessung");
  69.  
  70.  
  71. //###### Aufgabe 3 ###### - Wiegen, kalibrieren und anzeigen des Gefäßgewichtes nach Aufstellen eines Bechers und Drücken der Taste SW1
  72. taste = 0;
  73.  
  74. //Warten bis Taste 1 gedrueckt wurde, was bedeutet der Becher wurde aufgestellt
  75. puts("Becher aufstellen und Taste SW1, oder 'b' auf Tastatur druecken");
  76. while(taste != 1)
  77. {
  78. char inputch = getc();
  79. if(inputch == 'b')
  80. break;
  81. }
  82.  
  83. volatile int becherGewicht = 0;
  84. becherGewicht = messungderMasse();
  85.  
  86. if(becherGewicht > 0) //Becher wurde aufgestellt
  87. {
  88. puts("Gewicht des Bechers: ");
  89. char gewicht[8];
  90. intToString(becherGewicht, gewicht); //Gewicht von integer in string umwandeln um es mit puts ausgeben zu können
  91. puts(gewicht);
  92. }
  93. else //Becher wurde nicht aufgestellt
  94. {
  95. puts("Becher wurde nicht erkannt");
  96. auschankstation(); //Neustart
  97. }
  98.  
  99.  
  100. //###### Aufgabe 4 ###### - Abfüllen einer Menge nach drücken der Taste SW2
  101. //Warten bis Taste 2 gedrueckt wurde, was bedeutet der Abfuellvorgang startet
  102. puts("Taste SW2, oder 's' auf Tastatur druecken um Abfuellvorgang zu starten");
  103. while(taste != 2)
  104. {
  105. char inputch = getc();
  106. if(inputch == 's')
  107. break;
  108. }
  109.  
  110. //Pumpvorgang nur Starten wenn Becher noch auf Waage steht
  111. becherGewicht = messungderMasse();
  112. volatile int gesamtGewicht = becherGewicht;
  113. int fail = 0;
  114. if(becherGewicht > 0)
  115. {
  116. piobaseA->PIO_PDR = (1<<PIOTIOA3) ; //Controlle über Pin dem Timer geben -> sendet Signale an die Pumpe und diese beginnt zu pumpen
  117.  
  118. //While schleife die so lange läuft bis das gewuenschte Gewicht erreicht ist
  119. while((gesamtGewicht - becherGewicht) < ABFUELLMENGE)
  120. {
  121. volatile int gewichtAlt; //variable um zu testen wie sich das Gewicht verändert hat
  122. gewichtAlt = gesamtGewicht;
  123. gesamtGewicht = messungderMasse();
  124.  
  125. if(gesamtGewicht > gewichtAlt) //Gewicht ist angestiegen -> es wurde gepumpt
  126. {
  127. puts("Abgefuellte Menge: ");
  128. char aktGewicht[8];
  129. intToString(gesamtGewicht - becherGewicht, aktGewicht); //gesamtGewicht - becherGewicht um Gewicht der fluessigkeit zu bekommen
  130. puts(aktGewicht);
  131. }
  132. else //Gewicht ist wurde weniger -> Becher wurde entfernt
  133. {
  134. piobaseA->PIO_PDR = (1<<PIOTIOA3); //Mit pumpen aufhoeren!
  135. puts("Becher wurde entfernt, Abfuellvorgang wird gestoppt");
  136. fail = 1;
  137. break;
  138. }
  139. }
  140.  
  141. piobaseA->PIO_PDR = (1<<PIOTIOA3); //Controlle über Pin dem Timer entziehen -> sendet keine Signale mehr an die Pumpe und diese hoert auf zu pumpen
  142. }
  143. else
  144. {
  145. puts("Becher wurde nicht erkannt, Abfuellvorgang wurde nicht gestartet");
  146. auschankstation(); //Neustart
  147. }
  148.  
  149.  
  150. //###### Aufgabe 5 ###### - Nach dem Abfüllvorgang melden welche Menge abgefüllt wurde und das der Becher weg genommen werden kann.
  151. if(fail != 1)
  152. {
  153. puts("Abfuellvorgang wurde beendet");
  154. puts("Abgefuellte Menge: ");
  155. char gewichtFl[8];
  156. intToString(gesamtGewicht - becherGewicht, gewichtFl); //Gewicht von integer in string umwandeln um es mit puts ausgeben zu können
  157. puts(gewichtFl);
  158. puts("Becher kann entfernt werden");
  159. }
  160. else
  161. {
  162. puts("Abfuellvorgang konnte nicht korrekt durchgefuehrt werden");
  163. }
  164. }
  165.  
  166.  
  167. //################## PRAKTIKUM 2 ##################
  168. //Keys SW1 und SW2 aktivieren
  169. void init_tasten( void )
  170. {
  171. StructPMC* pmcbase = PMC_BASE; //Basisadresse PMC
  172. StructPIO* piobaseB = PIOB_BASE; //Basisadresse PIO B
  173. pmcbase->PMC_PCER = (1<<14); //Peripheral Clock für PIOB einschalten
  174. piobaseB->PIO_PER = KEY1 | KEY2; //In PIO Enable Register Key1 und 2 einschalten.
  175. }
  176.  
  177. //################## PRAKTIKUM 2 ##################
  178. //Interrupt Service Routine für Tasten SW1 und SW2
  179. void taste_irq_handler (void)
  180. {
  181. StructPIO* piobaseB = PIOB_BASE; //Basisadresse PIO B
  182. StructAIC* aicbase = AIC_BASE; //Basisadresse AIC
  183.  
  184. //Prüfe ob Bit fuer Key1 gesetzt wurde durch Tastendruck
  185. if(!(piobaseB->PIO_PDSR & KEY1) )
  186. {
  187. taste = 1; //setze die globale auf 1 um sie in der Main abfragen zu können
  188. }
  189.  
  190. //Prüfe ob Bit fuer Key2 gesetzt wurde durch Tastendruck
  191. if(!(piobaseB->PIO_PDSR & KEY2) )
  192. {
  193. taste = 2;
  194. }
  195.  
  196. aicbase->AIC_EOICR = piobaseB->PIO_ISR; //end of interrupt command register
  197. }
  198.  
  199. //################## PRAKTIKUM 3 ##################
  200. //Timer fuer Pumpe initialisieren - compare mode
  201. void init_timer_pumpe( void )
  202. {
  203. StructPMC* pmcbase = PMC_BASE; // Basisadresse PMC
  204. StructTC* tcbase3 = TCB3_BASE; // Basisadressse Timer 3
  205. StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO A
  206.  
  207.  
  208. //Peripheral Clock fuer PIOA und Timer 3 einschalten - AT91M63200(Complete) S.142
  209. pmcbase->PMC_PCER = (1<<13) | (1<<9);
  210.  
  211. //Disable Clock - Reset, damit wir genau wissen in welchem Zustand er ist, TC_CCR=Control Register, TC_CLKDIS - AT91M63200(Complete) S.122
  212. tcbase3->TC_CCR = TC_CLKDIS;
  213.  
  214. //Initialize the mode of the timer 3
  215. tcbase3->TC_CMR = TC_PUMPE_INIT;
  216.  
  217. // Initialize the compare Register:
  218. int value_RC = PROZESSORCLOCK / VORTEILER / FREQUENZ; //Prozessor Clock geteilt durch Vorteiler geteilt durch gegebene Fequenz
  219. int value_RA = value_RC / 2; //geteilt durch 2, dadurch gleichmaessiges Taktsignal - 50% High
  220.  
  221. tcbase3->TC_RC = value_RC; //25000000 / 8 / 50 = 62500
  222. tcbase3->TC_RA = value_RA; //25000000 / 8 / 50 / 2 = 31250
  223.  
  224. // Start the timer :
  225. tcbase3->TC_CCR = TC_CLKEN ; //Enable Clock, TC_CLKEN=Counter Clock Enable Command - AT91M63200(Complete) S.122
  226. tcbase3->TC_CCR = TC_SWTRG ; //the counter is reset and clock is started, TC_SWTRG=Software Trigger Command
  227.  
  228. piobaseA->PIO_PER = (1<<PIOTIOA3) ; //Kontrolle über Pin des Timers an PIOA geben damit pumpen noch nicht bei init beginnt
  229. piobaseA->PIO_OER = (1<<PIOTIOA3) ; //Outputenable
  230. piobaseA->PIO_CODR = (1<<PIOTIOA3) ; //Clear output data register -> kein anderes signal liegt an
  231. }
  232.  
  233. //################## PRAKTIKUM 4 ##################
  234. //Timer fuer die beiden Frequenzen der Waage initialisieren - capture mode
  235. void init_timer_waage( void )
  236. {
  237. StructPMC* pmcbase = PMC_BASE; // Basisadresse PMC
  238. StructTC* tcbase4 = TCB4_BASE; // Basisadressse Timer 4
  239. StructTC* tcbase5 = TCB5_BASE; // Basisadressse Timer 5
  240. StructPIO* piobaseA = PIOA_BASE; // Basisadresse PIO A
  241.  
  242.  
  243. //Peripheral Clock fuer Timer 4,5 einschalten - AT91M63200(Complete) S.142
  244. pmcbase->PMC_PCER = (1<<10) | (1<<11);
  245.  
  246. //Disablen der PIOA Kontrolle über die Pins PA4, PA7 -> Normale periperal funktion ist enabled - AT91M63200(Complete) S.60
  247. piobaseA->PIO_PDR = 0x90;
  248.  
  249. //Timer4:
  250. tcbase4->TC_CCR = TC_CLKDIS; // Disable Clock, um bekannten Zustand zu bekommen
  251. tcbase4->TC_CMR = TC_WAAGE_INIT; // Initialize the mode of the timer 4
  252. tcbase4->TC_CCR = TC_CLKEN; // Enable Clock
  253. tcbase4->TC_CCR = TC_SWTRG; // the counter is reset and clock is started, TC_SWTRG=Software Trigger Command
  254.  
  255. //Timer5:
  256. tcbase5->TC_CCR = TC_CLKDIS; // CCR= CounterControlRegister; TC_CLKDIS=0x2
  257. tcbase5->TC_CMR = TC_WAAGE_INIT; // Timer Counter Mode Register
  258. tcbase5->TC_CCR = TC_CLKEN; // 0x1
  259. tcbase5->TC_CCR = TC_SWTRG; // 0x4
  260. }
  261.  
  262. //################## PRAKTIKUM 4 ##################
  263. int messungderMasse( void )
  264. {
  265. StructTC* tcbase4 = TCB4_BASE; // Basisadressse Timer 4
  266. StructTC* tcbase5 = TCB5_BASE; // Basisadressse Timer 5
  267.  
  268.  
  269. //Variablen zur PeriodendauerMessung von Timer 4
  270. volatile int captureRA4;
  271. volatile int captureRB4;
  272. volatile float Periodendauer4;
  273.  
  274. //Variablen zur PeriodendauerMessung von Timer 5
  275. volatile int captureRA5;
  276. volatile int captureRB5;
  277. volatile float Periodendauer5;
  278.  
  279. // Periodendauer der Waagensignale messen
  280. // Signal an TIOA4 ca. 16kHz entspricht ca. einer Periodendauer von 62,5us
  281. // durch den Teiler von 32 ergeben sich ca. 2ms
  282. // Zähler mit positiver Flanke starten
  283.  
  284. //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
  285. int r1;
  286. r1 = tcbase4->TC_SR & 0x40;
  287. r1 = tcbase5->TC_SR & 0x40;
  288.  
  289. int i;
  290. int avg;
  291. avg = 0;
  292. for(i = 0; i < 4; i++) //Vier Messungen durchfuehren um Messfehler zu vermeiden
  293. {
  294. //the counter is reset and clock is started, TC_SWTRG=Software Trigger Command
  295. tcbase4->TC_CCR = TC_SWTRG;
  296. tcbase5->TC_CCR = TC_SWTRG;
  297.  
  298. //Capture Register B von Timer 4 wurde geladen (RB Loading Status) -> Messung abgeschlossen
  299. while (!(tcbase4->TC_SR & 0x40));
  300. captureRA4 = tcbase4->TC_RA;
  301. captureRB4 = tcbase4->TC_RB;
  302.  
  303. // Capture Register B von Timer 5 wurde geladen (RB Loading Status) -> Messung abgeschlossen
  304. while (!(tcbase5->TC_SR & 0x40));
  305. captureRA5 = tcbase5->TC_RA;
  306. captureRB5 = tcbase5->TC_RB;
  307.  
  308. //Periodendauer aus Differenz der beiden Capture Register RA und RB berechnen von Timer 4/5
  309. Periodendauer4 = captureRB4 - captureRA4;
  310. Periodendauer5 = captureRB5 - captureRA5;
  311.  
  312. //Masse mit vorgegebener Formel anhand der Periodendauer berechnnen
  313. volatile int masse;
  314. masse = (C1 * ((Periodendauer4 / Periodendauer5) - 1)) - C2;
  315. avg = avg + masse;
  316. }
  317. avg = (avg / 4);//+2? testen!
  318.  
  319. return avg;
  320. }
  321.  
  322. //################## PRAKTIKUM 5 ##################
  323. void intToString(int number, char * gewicht)
  324. {
  325. int neg;
  326. int tmpi;
  327. int count;
  328. int tmpcount;
  329. char cache;
  330.  
  331. //Zahl = 0
  332. if(number == 0)
  333. {
  334. gewicht[0]= '0';
  335. gewicht[1]= 0; //0 am Ende des Strings, da puts einen 0 terminierenden String erwartet
  336. return;
  337. }
  338.  
  339. //Zahl negativ
  340. neg = 0;
  341. count = 0;
  342. if(number < 0)
  343. {
  344. neg = 1;
  345. number = number * -1;
  346. count++; //Anzahl der Ziffern erhoeht sich durch '-' um 1
  347. }
  348.  
  349. //Anzahl Ziffern der Zahl
  350. tmpi = number;
  351. while(tmpi > 0)
  352. {
  353. tmpi = tmpi / 10;
  354. count++;
  355. }
  356.  
  357. tmpcount = count + 1; //Laenge um 1 erhoehen fuer 0 am ende des Strings
  358. char chr[tmpcount];
  359. chr[count] = 0; //0 an letzte Stelle des Arrays schreiben
  360. if(neg == 1)
  361. {
  362. chr[0] = '-'; //Wenn Zahl negativ ist, '-' an position 0
  363. }
  364.  
  365. //Ziffern extrahieren und in chararray schreiben
  366. int j;
  367. j = count - 1; //j = count - 1 da arrays bei 0 anfangen zu zaehlen
  368. 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
  369. {
  370. cache = number % 10; //Die hinterste Ziffer extrahieren
  371. number = number / 10; //Durch teilen durch 10 faellt die letzt Ziffer, die bereits im cache zwischengespeichert ist, weg
  372. chr[j] = cache + '0'; //und an die letzte Stelle des Arrays schreiben
  373. }
  374.  
  375. //entstandenen String in lokale Variable des aufrufenden Programms uebertragen
  376. j = 0;
  377. for(j; j < 8; j++)
  378. {
  379. gewicht[j] = chr[j];
  380. }
  381. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement