Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "msp430x16x.h"
- #include "intrinsics.h"
- #include "math.h"
- #include "string.h"
- // sygnaly sterujace LCD
- #define CTRL_E 0x01
- #define CTRL_RS 0x04
- // komendy sterujace LCD
- #define LCD_CLEAR 0x01
- // adresy segmentu zapisu licznika
- #define SEGMENT_START 0xFC00
- #define SEGMENT_END 0xFDFE
- // adresy segmentu zapisu sumy kontrolnej
- #define CS_SEG_START 0xFA00
- #define CS_SEG_END 0xFBFE
- // stany ukladu
- #define S_NORMAL 0 // stan normalny
- #define S_WDOG_RESET 1 // uklad zostal zresetowany przez wdoga
- #define S_CTRL_SUM_ERROR 2 // wystapil blad sumy kontrolnej
- #define DCO_FQ 1000000 // czestotliwosc DCO (glowny zegar uk³adu)
- #define ELIM_TIME_DIV 500 // 1/ELIM_TIME_DIV = czas eliminacji drgan
- #define TIMER_FQ 32768 // ACLK podlaczone do timer A
- #define WATCHDOG_ON 1 // jesli ustawione - watchdog bedzie uzywany
- int g_curr_input = 0; // stan portu P2 (WE, przyciski na b0 i b1)
- typedef unsigned short istate_t;
- /* znaczniki przekazywane miedzy ISR a petla glowna
- b0 = przycisk dolny zglasza przerwanie (cofnij sie o stacjê)
- b1 = przycisk górny zglasza przerwanie (naprzód o jedn¹ stacjê)
- */
- int g_flags = 0;
- // tablica stacji metra warszawskiego
- char *stations[] = {"Kabaty", "Natolin", "Imielin", "Stoklosy",
- "Ursynow", "Sluzew", "Wilanowska", "Wierzbno", "Raclawicka",
- "Pola Mokotowskie", "Politechnika", "Centrum", "Swietokrzyska",
- "Ratusz Arsenal", "Dworzec Gdanski", "Plac Wilsona",
- "Marymont", "Slodowiec", "Stare Bielany", "Wawrzyszew",
- "Mlociny"};
- const int stations_num = 21;// ilosc stacji
- // komunikat oznajmiajacy ze watchdog nas zresetowal
- char *wdog_error = "RST by watchdog";
- // komunikat bledu sumy kontrolnej
- char *ctrl_sum_error = "Ctrl sum error";
- // funkcje uzywane do sterowania wyswietlaczem LCD
- inline void strobe_e(); // puszcza impuls e na wyswietlacz
- inline void delay_us(int us_num); // czeka us_num mikrosekund (min 31 dla ACLK)
- void display_string(char *str); // wyswietla napis na LCD
- // zapis do pamieci pod adres (mem_ptr + 2), w segmencie ograniczonym przez
- // segment_end
- // zwraca: 1 - nastapilo kasowanie pamieci; 0 - kasowanie nie nastapilo
- int save_to_memory(unsigned int int_to_save, unsigned int **mem_ptr,
- unsigned int segment_start, unsigned int segment_end);
- // czyszczenie segmentu wskazanego przez mem_ptr
- void clear_memory(unsigned int *mem_ptr);
- // wyszukiwanie adresu do zapisu w pamieci w segmencie seg_start - seg_end
- // zwraca adres ostatniej zapisanej wartosci
- // lub adres seg_start - 2, jesli nic nie znaleziono
- unsigned int* find_address(unsigned int seg_start, unsigned int seg_end);
- // zwraca sume kontrolna dla wskazanego segmentu = zwykla suma
- // miesci sie w zakresie uint dla naszej ilosci stacji
- unsigned int calculate_ctrl_sum(unsigned int seg_start, unsigned int seg_end);
- int main(void)
- {
- WDTCTL = WDTPW + WDTHOLD; // wylacz watchdoga
- // ile razy nalezy sprawdzic wartosc WE podczas eliminacji drgan
- const int ELIM_CHECKS = DCO_FQ / ELIM_TIME_DIV;
- int i = 0;
- int elim_state = 0; // stan eliminacji drgan :
- // 0 - czekamy na 0, 1 - czekamy na 1
- int state = S_NORMAL; // stan ukladu - normalny
- int stations_index = 0; // indeks aktualnie wybranej stacji
- unsigned int control_sum = 0; // suma kontrolna segmentu licznikow
- int seg_clear = 0; // czy w operacji zapisu nastapilo kasowanie?
- // wskaznik do pamieci - adres licznika stacji
- unsigned int *mem_ptr = 0;
- // adres sumy kontrolnej segmentu licznika stacji
- unsigned int *cs_mem_ptr = 0;
- // czy powiodlo sie policzenie sumy kontrolnej?
- int ctrl_sum_check1_succeeded = 0;
- // timer A
- TACTL |= TASSEL_1;
- TACCTL0 |= CCIE;
- // Wyjscie danych na LCD
- P1DIR = 0xFF;
- P1OUT = 0x00;
- // Wyjscie sterujace LCD
- // pin 1 = wyjscie strobujace E
- // pin 2 = wyjscie RS
- P3DIR = 0xFF;
- P3OUT = 0x00;
- // Uruchomienie wyswietlacza
- delay_us(30000); // Duzy delay, zeby LCD wstal poprawnie po resecie
- P1OUT = 0x38; // Function set (8bit, 1 line)
- strobe_e();
- P1OUT = 0x0C; // Display on/off control
- strobe_e();
- P1OUT = 0x06; // Entry mode set (increments DDRAM address)
- strobe_e();
- delay_us(1000);
- P1OUT = LCD_CLEAR;
- strobe_e();
- delay_us(3000);
- display_string("Abcdef");
- //petla glowna programu
- while(1)
- {
- }
- }
- // fcja wysylajaca impuls e na wyswietlacz
- inline void strobe_e()
- {
- P3OUT |= CTRL_E;
- P3OUT &= ~CTRL_E;
- }
- // czeka us_num mikrosekund (min 31 dla ACLK)
- inline void delay_us(int us_num)
- {
- istate_t istate;
- TACCR0 = (int)ceil((double)(us_num * TIMER_FQ) / 1000000);
- TAR = 0;
- TACTL |= MC_1; // wlacza timer. przerwania timera musza byc wl.
- istate = __get_interrupt_state(); // zachowanie stanu przerwan globalnych
- do
- {
- _BIS_SR(GIE); // zasnij w oczekiwaniu na timer A
- // zablokuj na czas sprawdzenia warunku while
- }
- while (TACTL & MC_1); // dopiero gdy timer A jest wylaczony,
- // wiemy ze nastapilo przerwanie timera A.
- __set_interrupt_state(istate); // przywrocenie poprzedniego stanu przerwan
- }
- // wyswietla napis str na ekranie LCD
- void display_string(char *str)
- {
- int len = strlen(str);
- int i;
- P3OUT = 0x00;
- P1OUT = LCD_CLEAR;
- strobe_e();
- delay_us(3000);
- for (i = 0; i < len; i++)
- {
- P1OUT = str[i];
- P3OUT = CTRL_RS;
- strobe_e();
- }
- }
- // przerwanie przyciskow - samoblokujace
- #pragma vector=PORT2_VECTOR
- __interrupt void Port2 (void)
- {
- g_curr_input = P2IN; // przepisz wartosc wejsc
- g_flags |= P2IFG & 0x0003; // czy przyciski 0 lub 1 zglaszaja przerwanie?
- P2IFG = 0; // czysc znaczniki przerwan (:TODO: potrzebne?)
- P2IE = 0; // zablokuj wlasne przerwania
- if (WATCHDOG_ON)
- WDTCTL = WDTPW; // wlacz watchdoga
- _BIS_SR(LPM0_EXIT + GIE);
- }
- // przerwanie zegara - samowylaczajace
- #pragma vector=TIMERA0_VECTOR
- __interrupt void TimerA (void)
- {
- TACTL &= 0xFFCF; // wylacz timer
- _BIS_SR(LPM0_EXIT);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement