Advertisement
yutai

RHP_Aufgabe_1

Jul 5th, 2015
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.01 KB | None | 0 0
  1. #ifdef V3_Aufgabe_1
  2.  
  3. /*
  4. ES GELTEN DIE BEI "rollosteuerung_moore" AN GLEICHER STELLE VORANGESTELLTEN KOMMENTARE
  5. */
  6.  
  7. // Einige Defines zum leichteren Wiederfinden
  8. #define BIT_POS_IST_OBEN 0
  9. #define BIT_POS_IST_UNTEN 1
  10. #define BIT_POS_NACH_OBEN 4
  11. #define BIT_POS_NACH_UNTEN 5
  12. #define BIT_POS_FAHRE_NACH_OBEN 9
  13. #define BIT_POS_MOTOR_AN 8
  14. #define BIT_POS_FAHRE_NACH_UNTEN 10
  15.  
  16. typedef enum {hoch, runter, steht} STATE; // Datentyp für den Zustand das Automaten.
  17. // Vergleichbar mit "TYPE .... IS" in VHDL.
  18. typedef unsigned short int USHORT; // Eigener Datentyp zur Abkuerzung
  19.  
  20. typedef struct { unsigned char hh;
  21. unsigned char mm;
  22. unsigned char ss;} UHRZEIT;
  23.  
  24. UHRZEIT akt_zeit;
  25.  
  26. void steuerungsfunktion ( USHORT ist_oben, USHORT ist_unten,
  27. USHORT nach_oben, USHORT nach_unten,
  28. USHORT* p_fahre_nach_oben,
  29. USHORT* p_fahre_nach_unten,
  30. STATE* p_state, USHORT nach_oben_wegen_zeit, USHORT nach_unten_wegen_zeit
  31. )
  32. {
  33.  
  34. // 5.) switch-case-Konstrukt zur "Verwaltung" der Zustaende
  35. switch (*p_state) {
  36.  
  37. // 6.) Ein CASE je Zustand
  38. case steht:
  39.  
  40. // 7a.) .... Ausgabesignale bestimmen
  41. *p_fahre_nach_unten=0; *p_fahre_nach_oben=0;
  42.  
  43. // 8.) Eingabesignale auswerten und Zustandswechsel herbei fuehren
  44. // Ein IF je Pfeil
  45. /*if ( (ist_unten == 0) && (nach_unten == 1) && (nach_oben == 0)) {
  46. *p_state = runter; // Wechsel in den Zustand "runter"
  47. }
  48. if ( (ist_oben == 0) && (nach_oben == 1)){
  49. *p_state = hoch; // Wechsel in den Zustand "hoch"
  50. }*/
  51. if ( (ist_unten == 0) && (nach_unten_wegen_zeit != 0)) {
  52. *p_state = runter; // Wechsel in den Zustand "runter"
  53. }
  54. if ( (ist_oben == 0) && (nach_oben_wegen_zeit != 0)){
  55. *p_state = hoch; // Wechsel in den Zustand "hoch"
  56. }
  57.  
  58. // Diese if-Anweisung kann entfallen, da sie cstate nicht veraendert.
  59. /*if ( !( ((ist_unten == 0) && (nach_unten == 1) && (nach_oben == 0))
  60. || ((ist_oben == 0) && (nach_oben == 1)) ) ) {
  61. *p_state = steht; // Bleibe im Zustand "steht"
  62. }*/
  63. break;
  64.  
  65. case runter:
  66.  
  67. // 7a.) Ausgabesignale bestimmen
  68. *p_fahre_nach_unten=1; *p_fahre_nach_oben=0;
  69.  
  70.  
  71. // 8.) Eingabesignale auswerten und Zustandswechsel herbei fuehren
  72. if (ist_unten == 1) {
  73. *p_state = steht; // Wechsel in den Zustand "steht"
  74. }
  75.  
  76. // Diese if-Anweisung kann entfallen, da sie cstate nicht veraendert.
  77. if (ist_unten == 0) {
  78. *p_state = runter; // Bleibe im Zustand "runter"
  79. }
  80.  
  81. break;
  82.  
  83. case hoch:
  84.  
  85. // 7a.) Ausgabesignale bestimmen
  86. *p_fahre_nach_unten=0; *p_fahre_nach_oben=1;
  87.  
  88. // 8.) Eingabesignale auswerten und Zustandswechsel herbei fuehren
  89. if (ist_oben == 1){
  90. *p_state = steht; // Wechsel in den Zustand "steht"
  91. }
  92.  
  93. // Diese if-Anweisung kann entfallen, da sie cstate nicht veraendert.
  94. if (ist_oben == 0){
  95. *p_state = hoch; // Bleibe im Zustand "hoch"
  96. }
  97. break;
  98.  
  99. // 9.) nicht erlaubte Zustaende "abfangen"
  100. default:
  101. *p_state = runter;
  102.  
  103. } // end switch
  104. } // end steuerungsfunktion()
  105.  
  106. void timer1_init()
  107. {
  108. /* Zur Berechnung der Werte fuer den Prescaler und den Compare-Match:
  109. Bei einer Frequenz von 4 Mhz zaehlt der Timer mit einem Takt von 0,25us.
  110. Er kann mit seinen 65536 moeglichen Zaehlstaenden eine maximale Interrupt-Periode von 65536 * 0,25us = 16384us realisieren.
  111. Dies ist zu schnell. => Der Zaheler muss mittels des Prescalers langsamer eingestellt werden.
  112. Die ideale Untersetzung waere 50000us / 16384us = 3,0517.
  113. Da es diese Unterssetzung (Prescaler-Wert) nicht gibt waehlen wir den naechst groesseren Wert also 8.
  114. Der Zaehler zaehlt jetzt mit einem Takt vom 2us. => Die Interrupts haben bei einem Compare-Match-Wert von 65535
  115. eine Periode von 131072 us.Der Compare-Match-Wert muss auf 50000us/131072us*65536us = 25000 eingestellt werden.
  116. */
  117.  
  118. unsigned short buf = 0;
  119.  
  120. // TCRA1
  121. // Clock Source auf intern/8 Prescaler
  122. // Timer Modus Clear-Timer-On-Compare-Match
  123. buf = (1 << PS11) | (1 << TM10);
  124. io_out16(TCRA1, buf);
  125.  
  126. // TCRB1
  127. // Counter Enable
  128. buf = (1 <<CE1);
  129. io_out16(TCRB1, buf);
  130.  
  131. // TIMR1
  132. // Compare Match Interrupt enable
  133. buf = (1 << OCIE1);
  134. io_out16(TIMR1, buf);
  135.  
  136. // CMPA1
  137. // Compare Match Register auf ...
  138. buf = 5000;
  139. io_out16(CMPA1, buf);
  140. }
  141.  
  142. // Makros damit man beim Testen nicht so lange warten muss
  143. // Die korrekten Werte stehen als Kommentare jeweils dahinter
  144. #define ZT_MAXW 2 //20 wegen 20*50ms= 1s
  145. #define SS_MAXW 60 //60
  146. #define MM_MAXW 2 //60
  147. #define HH_MAXW 1 //24
  148.  
  149. // Interrupt Service Routine
  150. void timer1_oco1_isr()
  151. {
  152. unsigned short int buf;
  153. unsigned short zt;
  154.  
  155. zt++;
  156.  
  157. if(zt==ZT_MAXW){
  158. zt=0;
  159. akt_zeit.ss++;
  160. }
  161.  
  162. if(akt_zeit.ss==SS_MAXW){
  163. akt_zeit.ss=0;
  164. akt_zeit.mm++;
  165. }
  166.  
  167. if(akt_zeit.mm==MM_MAXW){
  168. akt_zeit.mm=0;
  169. akt_zeit.hh++;
  170. }
  171. if(akt_zeit.hh==HH_MAXW){
  172. akt_zeit.hh=0;
  173. }
  174.  
  175. // Zuruecksetzen des Interrupt-Flags
  176. buf = io_in16(TIFR1);
  177. buf = buf & ~(1 << OCIF1);
  178. io_out16(TIFR1, buf);
  179.  
  180. }
  181.  
  182.  
  183. void emain(void* arg)
  184. {
  185. STATE cstate; // Variable für den Zustand das Automaten.
  186.  
  187. // Variablen für die Eingabesignale. Eine Variable fuer jedes Signal.
  188. USHORT nach_oben;
  189. USHORT nach_unten;
  190. USHORT ist_oben;
  191. USHORT ist_unten;
  192.  
  193. // Variablen für die Ausgabesignale. Eine Variable fuer jedes Signal.
  194. USHORT fahre_nach_oben;
  195. USHORT fahre_nach_unten;
  196.  
  197. USHORT input, output, last_output;
  198.  
  199. //!!!
  200. UHRZEIT hoch_zeit, runter_zeit;
  201. USHORT nach_oben_wegen_zeit, nach_unten_wegen_zeit;
  202.  
  203. USHORT buf;
  204.  
  205. INIT_BM_WITH_REGISTER_UI; // Nur fuer Simulation
  206.  
  207.  
  208.  
  209. // 1.) Hardware konfigurieren
  210. io_out16(DIR1, 0xFF00); // Ausgang: Bits 15 bis 8 Eingang: Bits 7 bis 0
  211.  
  212. // 2.) Definition des Startzustandes. Entspricht dem asynchronen Reset in VHDL.
  213. cstate = runter;
  214. //!!!
  215.  
  216.  
  217. // Timer 1 initialisieren
  218. akt_zeit.hh=0; akt_zeit.mm=0; akt_zeit.ss=0;
  219. timer1_init();
  220.  
  221.  
  222. //!!! Initialisieren der Zeiten
  223. hoch_zeit.hh=0; hoch_zeit.mm=0; hoch_zeit.ss=0;
  224. runter_zeit.hh=0; runter_zeit.mm=1; runter_zeit.ss=55;
  225.  
  226.  
  227. // 3.) Unendliche Schleife. Ein Schleifendurchlauf entspricht einem Zyklus des Automaten
  228. while (1) {
  229.  
  230. SYNC_SIM; // Nur fuer Simulation
  231.  
  232. // Zur Sicherheit vor Initialisierung den Interupt des PIC generell deaktivieren
  233. buf = io_in16(PICC);
  234. buf = buf & ~(1 << PICE);
  235. io_out16(PICC, buf);
  236.  
  237. // ISR registrieren
  238. setInterruptHandler(IVN_OC1, timer1_oco1_isr);
  239.  
  240. // Interrupt des PIC jetzt zulassen
  241. buf = buf | (1 << PICE);
  242. io_out16(PICC, buf);
  243.  
  244. // 4.) Einlesen der Eingabesignale einmal je Zyklus
  245. input = io_in16(IN1);
  246.  
  247. // extrahieren von "ist_oben" (BIT_POS_IST_OBEN)
  248. ist_oben = (input >> BIT_POS_IST_OBEN) & 0x01;
  249.  
  250. // extrahieren von "ist_unten" (BIT_POS_IST_UNTEN)
  251. ist_unten = (input >> BIT_POS_IST_UNTEN) & 0x01;
  252.  
  253. // extrahieren von "nach_oben" (BIT_POS_NACH_OBEN)
  254. nach_oben = (input >> BIT_POS_NACH_OBEN) & 0x01;
  255.  
  256. // extrahieren von "nach_unten" (BIT_POS_NACH_UNTEN)
  257. nach_unten = (input >> BIT_POS_NACH_UNTEN) & 0x01;
  258.  
  259. //!!!!
  260. if((akt_zeit.hh==hoch_zeit.hh) && (akt_zeit.mm==hoch_zeit.mm) && (akt_zeit.ss==hoch_zeit.ss)) {
  261. nach_oben_wegen_zeit=1;
  262. }
  263. if((akt_zeit.hh==runter_zeit.hh) && (akt_zeit.mm==runter_zeit.mm) && (akt_zeit.ss==runter_zeit.ss)) {
  264. nach_unten_wegen_zeit=1;
  265. }
  266. // Aufruf der Steuerungsfunktion
  267. steuerungsfunktion ( ist_oben, ist_unten, nach_oben, nach_unten,
  268. &fahre_nach_oben, &fahre_nach_unten, &cstate, nach_oben_wegen_zeit, nach_unten_wegen_zeit );
  269.  
  270.  
  271. // 7b.) Ausgabesignale ausgeben
  272. output=fahre_nach_unten<<BIT_POS_FAHRE_NACH_UNTEN;
  273. output=output | (fahre_nach_oben<< BIT_POS_FAHRE_NACH_OBEN);
  274.  
  275.  
  276. // Nur wirklich ausgeben wenn notwendig
  277. // Optimierung mittels bedigter Portausgabe
  278. if (last_output != output) {
  279. output=output | (1<< BIT_POS_MOTOR_AN); // Nur fuer Bandmodell
  280. io_out16(OUT1, io_in16(OUT1) & 0x00FF);
  281. io_out16(OUT1, io_in16(OUT1) | output);
  282. last_output = output;
  283. }
  284. } // end while
  285. } // end main
  286. #endif // V3_Aufgabe_1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement