Advertisement
Guest User

Untitled

a guest
Jan 24th, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.26 KB | None | 0 0
  1. #include "msp430x16x.h"
  2. #include "intrinsics.h"
  3. #include "math.h"
  4. #include "string.h"
  5.  
  6. // sygnaly sterujace LCD
  7. #define CTRL_E 0x01
  8. #define CTRL_RS 0x04
  9.  
  10. // komendy sterujace LCD
  11. #define LCD_CLEAR 0x01
  12.  
  13. // adresy segmentu zapisu licznika
  14. #define SEGMENT_START 0xFC00
  15. #define SEGMENT_END 0xFDFE
  16.  
  17. // adresy segmentu zapisu sumy kontrolnej
  18. #define CS_SEG_START 0xFA00
  19. #define CS_SEG_END 0xFBFE
  20.  
  21. // stany ukladu
  22. #define S_NORMAL 0 // stan normalny
  23. #define S_WDOG_RESET 1 // uklad zostal zresetowany przez wdoga
  24. #define S_CTRL_SUM_ERROR 2 // wystapil blad sumy kontrolnej
  25.  
  26. #define DCO_FQ 1000000 // czestotliwosc DCO (glowny zegar uk³adu)
  27. #define ELIM_TIME_DIV 500 // 1/ELIM_TIME_DIV = czas eliminacji drgan
  28. #define TIMER_FQ 32768 // ACLK podlaczone do timer A
  29.  
  30. #define WATCHDOG_ON 1 // jesli ustawione - watchdog bedzie uzywany
  31.  
  32. int g_curr_input = 0; // stan portu P2 (WE, przyciski na b0 i b1)
  33. typedef unsigned short istate_t;
  34. /* znaczniki przekazywane miedzy ISR a petla glowna
  35. b0 = przycisk dolny zglasza przerwanie (cofnij sie o stacjê)
  36. b1 = przycisk górny zglasza przerwanie (naprzód o jedn¹ stacjê)
  37. */
  38. int g_flags = 0;
  39.  
  40. // tablica stacji metra warszawskiego
  41. char *stations[] = {"Kabaty", "Natolin", "Imielin", "Stoklosy",
  42. "Ursynow", "Sluzew", "Wilanowska", "Wierzbno", "Raclawicka",
  43. "Pola Mokotowskie", "Politechnika", "Centrum", "Swietokrzyska",
  44. "Ratusz Arsenal", "Dworzec Gdanski", "Plac Wilsona",
  45. "Marymont", "Slodowiec", "Stare Bielany", "Wawrzyszew",
  46. "Mlociny"};
  47.  
  48. const int stations_num = 21;// ilosc stacji
  49.  
  50. // komunikat oznajmiajacy ze watchdog nas zresetowal
  51. char *wdog_error = "RST by watchdog";
  52. // komunikat bledu sumy kontrolnej
  53. char *ctrl_sum_error = "Ctrl sum error";
  54.  
  55. // funkcje uzywane do sterowania wyswietlaczem LCD
  56. inline void strobe_e(); // puszcza impuls e na wyswietlacz
  57. inline void delay_us(int us_num); // czeka us_num mikrosekund (min 31 dla ACLK)
  58. void display_string(char *str); // wyswietla napis na LCD
  59.  
  60. // zapis do pamieci pod adres (mem_ptr + 2), w segmencie ograniczonym przez
  61. // segment_end
  62. // zwraca: 1 - nastapilo kasowanie pamieci; 0 - kasowanie nie nastapilo
  63. int save_to_memory(unsigned int int_to_save, unsigned int **mem_ptr,
  64. unsigned int segment_start, unsigned int segment_end);
  65.  
  66. // czyszczenie segmentu wskazanego przez mem_ptr
  67. void clear_memory(unsigned int *mem_ptr);
  68.  
  69. // wyszukiwanie adresu do zapisu w pamieci w segmencie seg_start - seg_end
  70. // zwraca adres ostatniej zapisanej wartosci
  71. // lub adres seg_start - 2, jesli nic nie znaleziono
  72. unsigned int* find_address(unsigned int seg_start, unsigned int seg_end);
  73.  
  74. // zwraca sume kontrolna dla wskazanego segmentu = zwykla suma
  75. // miesci sie w zakresie uint dla naszej ilosci stacji
  76. unsigned int calculate_ctrl_sum(unsigned int seg_start, unsigned int seg_end);
  77.  
  78. int main(void)
  79. {
  80. WDTCTL = WDTPW + WDTHOLD; // wylacz watchdoga
  81.  
  82. // ile razy nalezy sprawdzic wartosc WE podczas eliminacji drgan
  83. const int ELIM_CHECKS = DCO_FQ / ELIM_TIME_DIV;
  84.  
  85. int i = 0;
  86. int elim_state = 0; // stan eliminacji drgan :
  87. // 0 - czekamy na 0, 1 - czekamy na 1
  88.  
  89. int state = S_NORMAL; // stan ukladu - normalny
  90. int stations_index = 0; // indeks aktualnie wybranej stacji
  91. unsigned int control_sum = 0; // suma kontrolna segmentu licznikow
  92. int seg_clear = 0; // czy w operacji zapisu nastapilo kasowanie?
  93.  
  94. // wskaznik do pamieci - adres licznika stacji
  95. unsigned int *mem_ptr = 0;
  96. // adres sumy kontrolnej segmentu licznika stacji
  97. unsigned int *cs_mem_ptr = 0;
  98. // czy powiodlo sie policzenie sumy kontrolnej?
  99. int ctrl_sum_check1_succeeded = 0;
  100.  
  101. // timer A
  102. TACTL |= TASSEL_1;
  103. TACCTL0 |= CCIE;
  104.  
  105. // Wyjscie danych na LCD
  106. P1DIR = 0xFF;
  107. P1OUT = 0x00;
  108.  
  109. // Wyjscie sterujace LCD
  110. // pin 1 = wyjscie strobujace E
  111. // pin 2 = wyjscie RS
  112. P3DIR = 0xFF;
  113. P3OUT = 0x00;
  114.  
  115. // Uruchomienie wyswietlacza
  116. delay_us(30000); // Duzy delay, zeby LCD wstal poprawnie po resecie
  117. P1OUT = 0x38; // Function set (8bit, 1 line)
  118. strobe_e();
  119. P1OUT = 0x0C; // Display on/off control
  120. strobe_e();
  121. P1OUT = 0x06; // Entry mode set (increments DDRAM address)
  122. strobe_e();
  123. delay_us(1000);
  124. P1OUT = LCD_CLEAR;
  125. strobe_e();
  126. delay_us(3000);
  127. display_string("Abcdef");
  128.  
  129.  
  130.  
  131. //petla glowna programu
  132. while(1)
  133. {
  134.  
  135. }
  136. }
  137.  
  138. // fcja wysylajaca impuls e na wyswietlacz
  139. inline void strobe_e()
  140. {
  141. P3OUT |= CTRL_E;
  142. P3OUT &= ~CTRL_E;
  143. }
  144.  
  145. // czeka us_num mikrosekund (min 31 dla ACLK)
  146. inline void delay_us(int us_num)
  147. {
  148. istate_t istate;
  149. TACCR0 = (int)ceil((double)(us_num * TIMER_FQ) / 1000000);
  150. TAR = 0;
  151. TACTL |= MC_1; // wlacza timer. przerwania timera musza byc wl.
  152. istate = __get_interrupt_state(); // zachowanie stanu przerwan globalnych
  153. do
  154. {
  155. _BIS_SR(GIE); // zasnij w oczekiwaniu na timer A
  156. // zablokuj na czas sprawdzenia warunku while
  157. }
  158. while (TACTL & MC_1); // dopiero gdy timer A jest wylaczony,
  159. // wiemy ze nastapilo przerwanie timera A.
  160. __set_interrupt_state(istate); // przywrocenie poprzedniego stanu przerwan
  161. }
  162.  
  163. // wyswietla napis str na ekranie LCD
  164. void display_string(char *str)
  165. {
  166. int len = strlen(str);
  167. int i;
  168. P3OUT = 0x00;
  169. P1OUT = LCD_CLEAR;
  170. strobe_e();
  171. delay_us(3000);
  172. for (i = 0; i < len; i++)
  173. {
  174. P1OUT = str[i];
  175. P3OUT = CTRL_RS;
  176. strobe_e();
  177. }
  178. }
  179.  
  180.  
  181. // przerwanie przyciskow - samoblokujace
  182. #pragma vector=PORT2_VECTOR
  183. __interrupt void Port2 (void)
  184. {
  185. g_curr_input = P2IN; // przepisz wartosc wejsc
  186. g_flags |= P2IFG & 0x0003; // czy przyciski 0 lub 1 zglaszaja przerwanie?
  187. P2IFG = 0; // czysc znaczniki przerwan (:TODO: potrzebne?)
  188. P2IE = 0; // zablokuj wlasne przerwania
  189. if (WATCHDOG_ON)
  190. WDTCTL = WDTPW; // wlacz watchdoga
  191. _BIS_SR(LPM0_EXIT + GIE);
  192. }
  193.  
  194. // przerwanie zegara - samowylaczajace
  195. #pragma vector=TIMERA0_VECTOR
  196. __interrupt void TimerA (void)
  197. {
  198. TACTL &= 0xFFCF; // wylacz timer
  199. _BIS_SR(LPM0_EXIT);
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement