VEndymionV

Wejściówka 2 SW

May 6th, 2018
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.78 KB | None | 0 0
  1. Notatki:
  2.  
  3. ****Przerwania****
  4. Przerwania są zdarzeniami które tymczasowo wstrzymują wykonywanie głównego programu aby wykonać obsługę przerwania czyli zadeklarowany przez nas fragment kodu (funkcja w języku C). Po wykonaniu procedury obsługi przerwania, główny program zostaje kontynuowany od miejsca przerwania. 8051 posiada 5 sygnałów wywołujących przerwania: dwa sygnały zewnętrzne, dwa sygnały przepełnienia timerów oraz sygnał przerwania z portu szeregowego.
  5.  
  6. Rejestr IE:
  7. Za włączanie lub wyłączanie przerwań odpowiada rejestr IE (Interrupt Enable) - jest to 8 bitowy rejestr jednak w 8051 znaczące jest tylko 6 spośród jego bitów. Ustawienie bitu powoduje włączenie danego przerwania, wyczyszczenie jego wyłączenie.
  8. EA - - ES ET1 EX1 ET0 EX0
  9.  
  10. EA - bit decydujący o wszystkich przerwaniach, gdy EA = 0 żadne z przerwań nie będzie włączone, niezależnie od ustawień innych bitów rejestru.
  11. - Dwa kolejne bity nie są wykorzystywane w 8051.
  12. ES - Włącza lub wyłącza przerwania portu szeregowego (na zajęciach jeszcze nie wykorzystywany)
  13. ET1 - Włącza lub wyłącza przerwania przepełnienia timera 1
  14. EX1 - Włącza lub wyłącza zewnętrzne przerwanie nr 1 - przerwanie pinu 3.3
  15. ET0 - Włącza lub wyłącza przerwania przepełnienia timera 0
  16. EX0 - Włącza lub wyłącza zewnętrzne przerwanie nr 0 - przerwanie pinu 3.2
  17.  
  18. Piorytet przerwań maleje od najmłodszego bitu tzn. EX0 czyli przerwanie zewnętrzne nr 0 ma piorytet najwyższy a ES czyli przerwanie portu szeregowego ma piorytet najniższy. Przerwanie o wyższym piorytecie może przerwać obsługę przerwania o piorytecie niższym, lecz nie odwrotnie.
  19.  
  20. Rejestr IP:
  21. Piorytetem przerwań możemy sterować korzystając z rejestru IP (Interrupt Priority). Ustawiony odpowiadający bit w rejestrze IP powoduje, że dane przerwanie ma wysoki piorytet, wyczyszczony bit to niski piorytet (domyślny). Przerwania z wysokim piorytetem zawsze mają pierwszeństwo niezależnie od domyślnego piorytetu - chyba, że dojdzie do sytuacji gdzie dwa przerwania z takim samym piorytetem (wysokim) chcą się wykonać, wtedy znaczenie ma domyślny piorytet omawiany wcześniej.
  22. Rejestr IP jest 8 bitowy jednak korzystamy tylko z 5 bitów tego rejestru. Trzy najstarsze bity (bit 7, 6 i 5) nie są w 8051 wykorzystywane.
  23. - - - PS PT1 PX1 PT0 PX0
  24.  
  25. - Trzy najstarsze bity nieużywane.
  26. - PS - określa piorytet przerwania portu szeregowego.
  27. - PT1 - określa piorytet przerwania przepełnienia timera 1.
  28. - PX1 - określa piorytet zewnętrznego przerwania nr 1.
  29. - PT0 - określa piorytet przerwania przepełnienia timera 0.
  30. - PX0 - określa piorytet zewnętrznego przerwania nr 0.
  31.  
  32. Rejestr TCON:
  33. TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
  34. Cztery najstarsze bity dotyczą Timerów:
  35. TF1 - Flaga przepełnienia Timera 1, gdy zostaje ustawiona następuje również przerwanie Timera 1 (gdy jest włączone),
  36. TR1 - Bit sterujący Timera 1, gdy ustawiony to Timer włączony, gdy wyczyszczony to Timer wyłączony,
  37. TF0 - Analogicznie jak TF1 ale dla Timera 0,
  38. TR0 - Analogicznie jak TR1 ale dla Timera 0.
  39. Kolejne cztery dotyczą przerwać zewnętrznych:
  40. IE1 - Flaga przerwania INT1 - zewnętrzne przerwanie nr 1
  41. IT1 - Wybór rodzaju zgłoszenia przerwania INT1, 0 - gdy poziom niski, 1 - gdy zbocze opadające
  42. IE0 - Flaga przerwania INT0 - zewnętrzne przerwanie nr 0
  43. IT0 - Wybór rodzaju zgłoszenia przerwania INT0, 0 - gdy poziom niski, 1 - gdy zbocze opadające
  44.  
  45. Wektor przerwań:
  46. Wektor przerwań określa miejsce w pamięci gdzie znajdują się procedury obsługi konretnego przerwania.
  47. 03H - EX0
  48. 0BH - ET0
  49. 13H - EX1
  50. 1BH - ET1
  51. 23H - ES
  52. Schemat działania:
  53. ORG 0BH ; w tym wypadku będziemy pisać obsługę przerwania ET0
  54. ;
  55. ;
  56. ; kod obsługi
  57. ;
  58. ;
  59. RETI ; powrót do wykonania głównego programu
  60.  
  61.  
  62. ****Timery****
  63. 8051 posiada dwa timery - Timer 0 i Timer 1. Timery mogą zliczać impulsy zegarowe (TIMER) lub zliczać impulsy zewnętrzne (COUNTER). Zajmowaliśmy się tylko tym pierwszym zastosowaniem. Timer jest inkrementowany z każdym cyklem maszynowym, przy kwarcu taktującym 11,0592MHz czas trwania cyklu zegarowego wynosi 1,08507 us - czyli w ciągu sekundy Timer zostanie zwiększony o 1 około 921600 razy bo 11059200 / 12 = 921600.
  64. Do konfiguracji timerów wykorzystywane są dwa rejestry - TCON i TMOD, z kolei wartość timerów jest zapisywana w rejestrach TH0, TL0, TH1, TL1.
  65.  
  66. THx i TLx:
  67. TH0 i TH1 to starsze 8 bitów Timera 0 lub Timera 1 TL0 i TL1 to 8 młodszych bitów. Aby otrzymać 8 starszych lub młodszych bitów w assemblerze korzystamy z dyrektywy #HIGH liczba i #LOW liczba, w C korzystamy z dzielenia i modulo - liczba / 256 - odpowiednik #HIGH, liczba % 256 - odpowiednik #LOW. Wrzucanie liczby na te rejestry przydaje się żeby zacząć liczyć od konkretnej wartości przez co odliczyć konretny czas - o czym później.
  68.  
  69. Rejestr TMOD:
  70. Cztery starsze bity rejestru TMOD konfigurują Timer 1, a cztery młodsze Timer 0. Oba timery konfiguruje się w ten sam sposób. Pierwszy (czyli bit 0 dla Timera 0 lub bit 4 dla Timera 1) oraz drugi bit konfiguruje tryb pracy Timera. Na dwóch bitach możemy zapisać cztery różne wartości - i tyle właśnie trybów posiada 8051. Bit trzeci gdy jest ustawiony to Timer zlicza zdarzenia na pinie P3.4 (Timer 0) lub P3.5 (Timer 1), gdy ten bit(y) nie jest ustawiony to Timer inkrementuje się w każdym cyklu (na tę chwilę tylko to nas interesuje więc zawsze będzie tam 0). Ostatni bit (czyli 3 lub 7) powoduje, że Timer 0 działa tylko gdy pin P3.2 jest w stanie wysokim, a Timer 1 tylko gdy P3.3 (tym bitem też nie musimy się przejmować - będzie ustawiony na 0).
  71.  
  72. Rejestr TCON:
  73. Cztery najstarsze bity dotyczą Timerów:
  74. TF1 - Flaga przepełnienia Timera 1, gdy zostaje ustawiona następuje również przerwanie Timera 1 (gdy jest włączone),
  75. TR1 - Bit sterujący Timera 1, gdy ustawiony to Timer włączony, gdy wyczyszczony to Timer wyłączony,
  76. TF0 - Analogicznie jak TF1 ale dla Timera 0,
  77. TR0 - Analogicznie jak TR1 ale dla Timera 0.
  78.  
  79. Tryby Timerów:
  80. Tryb 0:
  81. Timer działa w trybie 13 bitowym. Timer może zostać inkrementowany 8192 razy. Ten tryb jest analogiczny do trybu 1, nic specjalnego.
  82. Tryb 1:
  83. Najczęściej używany tryb. Timer działa w trybie 16 bitowym. Timer może zostać inkrementowany 65536 razy.
  84. Tryb 2:
  85. Timer działa w trybie 8 bitowym z auto uzupełnianiem. THx trzyma wartość która będzie wrzucana na TLx po przepełnieniu. Czyli dla przykładu gdy wrzucimy na THx 44 Timer będzie liczył od tej wartości, gdy osiągnie 255, zostanie zinkrementowany i nastąpi przepełnienie zamiast znów wkoczyć na wartość 0 znów automatycznie ustawi się na 44 czyli wartość rejestru THx, wygodne jeżeli liczymy małe wartości, upraszcza kod ale nie wnosi nic więcej - oprócz tego, że jest wykorzystywany przy komunikacji szeregowej.
  86. Tryb 3:
  87. Tryb nie do ogarnięcia. Gdy Timer 0 zostanie ustawiony w tryb 3 to tak naprawdę staje się dwoma oddzielnymi 8 bitowymi timerami. Timer 0 kontroluje TL0, a Timer 1 TH0. Każdy z timerów liczy od 0 do 255, bity odpowiadające za Timer 1 czyli np. TF1 teraz odpowiadają TH0. Timer 1 może być ustawiony w tryb 0, 1 lub 2 ale nie możemy go kontrolować, będzie on zliczał w każdym cyklu maszynowym.
  88.  
  89. Wzór na liczenie wartości dla trybu 1:
  90. 2^16 - ((0-71ms) * 1000) / 1,08507) - czyli możemy zliczyć maksymalnie 71ms
  91. Wzór na liczenie wartości dla trybu 0:
  92. 2^13 - ((0-8ms) * 1000) / 1,08507) - maksymalnie 8ms
  93. Wzór na liczenie wartości dla trybów 8 bitowych:
  94. W trybie 8 bitowym nie zliczymy nawet jednej mikrosekundy, możemy zliczyć maksymalnie 255 * 1,08507 us czyli 276.69285 us
  95. 2^8 - ((0 - 276us) / 1,08507)
  96.  
  97. Schemat uruchamiania Timerów:
  98. MOV TH0, #HIGH liczba - Timer 0
  99. MOV TH1, #HIGH liczba - Timer 1
  100. MOV TL0, #LOW liczba - Timer 0
  101. MOV TL1, #LOW liczba - Timer 1
  102. MOV TMOD, #x - wysyłamy liczbę która ustawi nam bity któryś z bitów 0, 1, 4, 5, bity 0 i 1 odpowiadają za tryb Timera 0, a 4 i 5 za Timer 1, pozostałe bity nas nie interesują gdy po prostu zliczamy czas.
  103. SETB TR0 - włącza Timer 0
  104. SETB TR1 - włącza Timer 1
  105. Teraz gdy nastąpi przepełnienie to ustawi nam się TF0 lub TF1 i nastąpi również przerwanie (gdy włączone).
  106.  
  107. Zadania:
  108. 1. Napisz ponga w C używając softwarowych przerwań
  109. 2. Omów system przerwań (wszystko co wiesz, obszernie)
  110. 3. Napisz miganie diodą z przerwaniami
  111. 4. Jak ogarnąć przyciski wiedząc to co było na zajęciach
  112.  
  113. 1. Napisz ponga w C używając softwarowych przerwań
  114.  
  115. #include <8051.h>
  116.  
  117. #define TIM 19456 // 50ms
  118. #define LEDS P1 // port do diod
  119.  
  120. unsigned char acc, flag; // flag = 0 - lewo, flag = 1 - prawo
  121.  
  122. void timer0(void) __interrupt(1) __using(1){
  123.  
  124. // Lewo czy prawo?
  125. if(flag)
  126. acc = acc >> 1;
  127. else
  128. acc = acc << 1;
  129.  
  130. // Jeżeli pali się ostatnia dioda z lewej lub z prawej:
  131. if(acc == 128 || acc == 1)
  132. flag = !flag;
  133.  
  134. LEDS = acc; // wartość zostaje wrzucona na port diod
  135.  
  136. // Ponownie wrzucam wartości od których ma zliczać Timer 0:
  137. TH0 = TIM / 256; // 4 starsze bity
  138. TL0 = TIM % 256; // 4 młodsze bity
  139.  
  140. return;
  141. }
  142.  
  143. int main(void){
  144.  
  145. acc = 1; // wartość wrzucana na port diod
  146. flag = 0; // lewo czy prawo, lewo = 0, prawo = 1
  147.  
  148. LEDS = 1; // zaczynam od zapalenia pierwszej diody z prawej
  149. // Timer:
  150. TH0 = TIM / 256; // 4 starsze bity
  151. TL0 = TIM % 256; // 4 młodsze bity
  152. TMOD = 1; // Timer 0 w trybie 1
  153. TR0 = 1; // włączam Timer 0
  154. // Przerwania:
  155. EA = 1; // włączenie przerwań
  156. ET0 = 1 // włączenie przerwania Timera 0
  157.  
  158. while(1){
  159. // nieskończona pętla, przerywana przerwaniami
  160. }
  161. }
  162.  
  163. 3. Napisz miganie diodą z przerwaniami
  164.  
  165. // Dioda migająca co 500ms.
  166. #include <8051.h>
  167.  
  168. #define TIM 19456 // 50ms
  169. #define LEDS P2 // port diod
  170. #define LED P2.0 // konkretna dioda
  171.  
  172. unsigned char count = 1;
  173.  
  174. void timer1(void) __interrupt(3) __using(1){
  175.  
  176. if(count == 10){
  177. LED = !LED;
  178. count = 1;
  179. }
  180. else
  181. count++;
  182.  
  183. TH1 = TIM / 256;
  184. TL1 = TIM % 256;
  185.  
  186. return;
  187. }
  188.  
  189. int main(void){
  190.  
  191. LED = 0;
  192. // Wartości timerów:
  193. TH1 = TIM / 256;
  194. TL1 = TIM % 256;
  195. // Ustalenie trybu timera 1
  196. TMOD = 0b00010000; // timer 1 w trybie 1 - 16 bitowym
  197. // Włączenie timera 1
  198. TR1 = 1;
  199. // Włączenie przerwań
  200. ET1 = 1; // włączenie przerwania timera 1
  201. EA = 1; // włączenie przerwań - w ogóle
  202. // Nieskończona pętla przerywana przerwaniami co 50ms
  203. while(1);
  204. }
  205.  
  206. 4. Jak ogarnąć przyciski wiedząc to co było na zajęciach
  207.  
  208. Przycisk może być podłączony do pinu 3.2 lub 3.3. Domyślnie przerwanie EX0 i EX1 jest wywoływane przez stan niski dlatego przycisk musi zostać podciągnięty do zasilania (przez rezystor w celu odszumienia). Gdy przycisk zostanie wciśnięty - na pinie 3.2 lub 3.3 będzie stan niski, wywoła się przerwanie, w przerwaniu powinniśmy odczekać pewien czas zanim podejmiemy działania ze względu na drgania styków przycisku. Po odczekaniu można wykonać działania.
Advertisement
Add Comment
Please, Sign In to add comment