background image

Wydział Informatyki 
Katedra Systemów Czasu Rzeczywistego 
Laboratorium Architektury Komputerów 

Data:  27.03.2008  

Sprawozdanie z projektu nr.2 
Grupa III: 
Cieśluk Krzysztof 
Kiełpiński Krzysztof 

Prowadzący: 
dr inŜ. Krzysztof Bielawski 
Ocena: 

 
 

Teoria 

 
  System zegarowy jest podstawowym elementem kaŜdego urządzenia 
mikroprocesorowego. W przypadku mikrokontrolerów z rodziny MSP430 system zegarowy 
został znacząco rozbudowany. Takie podejście konstruktorów firmy T.I. miało za zadanie 
danie programistom swobodę w operowaniu zegarami. Umiejętne poruszanie się w systemie 
zegarowym umoŜliwia tworzenie najefektywniejszych aplikacji energooszczędnych. 
Zaimplementowany został zegar podstawowy (Basic Clock) oraz  Timery( w zaleŜności od 
urządzenia TimerA, bądź teŜ TimerB). Schemat zegara podstawowego moŜemy zobaczyć na 
rysunku : 

 
 Jak moŜna na nim zauwaŜyć zegar podstawowy składa się z dwóch, bądź trzech 
wewnętrznych źródeł zegarowych. Są to: 

background image

· LFXT1CLK (Low Frequency/High Frequency Oscillator ) – moŜe on być uŜyty z 
niskoczęstotliwościowym kwarcem 32678Hz, bądź z rezonatorami z zakresu 450kHz- 8MHz 
(tryb pracy wysokoczęstotliwościowej) 
· XT2CLK (High Frequency Oscillator) jest uŜywany opcjonalnie moŜe być zasilany 
standardowym kwarcem, bądź rezonatorami z zakresu 450kHz-8MHz 
· DCO- wewnętrzny zegar taktujący posiadający charakterystykę RC 
 
PowyŜej wymienione źródła zegarowe taktują trzy zegary, a mianowicie są to : 
· ACLK (Auxilary Clock) –zegar pomocniczy jego źródłem jest LFXT1CLK 
· MCLK (Main Clock) – zegar uŜywany przez CPU oraz system, jego źródłem moŜe być        
 

:LFXT1CLK, bądź XT2CLK, bądź DCO. 

· SMCLK (Sub-main Clock)- jest przeznaczony do współpracy z urządzeniami peryferyjnymi, 
jego źródłem moŜe być :LFXT1CLK, bądź XT2CLK, bądź DCO. 
 
Po restarcie urządzenie MCLK=SMCLK=DCO. Mamy jednak moŜliwość przełączania 
MCLK, oraz SMCLK z taktowania przez DCO na taktowanie przez LFXT1CLK, bądź jeśli w 
urządzeniu istnieje na XT2CLK. Takie przełączenie odbywa się wedle określonego schematu: 
1. Włączenie oscylatora 
2. Wyczyszczenie flagi OFIFG 
3. Odczekanie około 50µs 
4. Sprawdzenie stanu flagi OFIFG jeśli jest nadal ustawiona to powtórzenie kroków 1-4 
5. Zmiana taktowania zegarów w rejestrze BCSCTL2 
 
MSP430f149; posiada dwa timery - TimerA oraz TimerB. TimerA jest 16bitowym 
licznikiem/zegarem, który posiada trzy zliczające/porównujące rejestry. Natomiast TimerB 
równieŜ jest 16 bitowym licznikiem/zegarem, który z kolei posiada, aŜ siedem takich 
rejestrów. 
TimerA oraz TimerB posiadają identyczną budowę. 
 
TimerA moŜe być inkrementowany bądź dekrementowany, ma to miejsce z kaŜdym 
narastającym zboczem zegara. MoŜe być programowo czytany oraz zapisywany. Dodatkowo 
w przypadku wystąpienia przepełnienia jest generowane przerwanie. Źródłem zegara 
taktującego TimerA mogą być (TACLK,ACLK,SMCLK,INCLK), dodatkowo istnieje 
moŜliwość podziału częstotliwości sygnału taktującego przez 1,2,4,8. TimerA ma moŜliwość 
pracowania w czterech trybach pracy, za ich ustawienie odpowiada znacznik MCx w rejestrze 
TACTL. Są to tryby pracy: 
· Stop – MC=00 – Timer jest zatrzymany 
· Up – MC=01 – Timer cyklicznie liczy od zera do wartości zapisanej w rejestrze TACCR0 
· Continuous- MC-10- Timer cyklicznie liczy od zera do wartości 0xffff 
· Up/Down – MC=11- Timer cyklicznie inkrementuje od zera do wartości zapisanej w 
rejestrze TACCR0 , a dekrementuje od wartości w rejestrze TACCR0 do zera 
 
Tryb Compare jest stosowany do generowania sygnałów wyjściowych PWM, oraz do 
generowania przerwań w określonym odstępie czasowy. Przerwanie jest generowane w 
przypadku gdy wartość w rejestrze TAR zostanie doliczona do wartości w rejestrze TACCRx. 
Wówczas to: 
· Flaga CCIFG zostaje ustawiona 
· Wewnętrzny sygnał EQUx równa się jeden 
· Przychodzący sygnał CCI jest zatrzaskiwany w SCCI 
 

background image

Tryb Capture jest uŜywany do rejestrowania zdarzeń czasowych. Jako wejścia brane są 
CCIxA oraz CCIxB. Mogą być do nich podłączone sygnały zewnętrze jak równieŜ 
wewnętrzne. Znacznik CMx odpowiada za rodzaj zbocza na które mamy zareagować. W 
przypadku zajścia zdarzenia: 
· Wartość z TAR jest kopiowana do rejestru TACCRx 
· CCIFG jest ustawiana 
 
W kaŜdej chwili jest moŜliwe odczytywanie wartości sygnału wejściowego, a moŜemy to 
czynić przez znacznik CCI. 
 

Zadanie 
 

Zadanie polega na stworzeniu zegara czasu rzeczywistego z kurantem co 15 sec. 
Specyfikacja.  

 

zegar ma być wyświetlany na LCD płytki MSP430  

 

zegar nie moŜe się spóźniać  

 

kuran ma być wyraźnie słyszalny  

 

naleŜy wykorzystać przerwania 

 
 

Kod 

 
#include <msp430x14x.h> 
#include "lcd.h" 
#include "portyLcd.h" 
 
unsigned int s_licznik=0; 
 
unsigned int sekundy = 0; 
unsigned int minuty = 0; 
unsigned int godziny = 0; 
 
int brzeczyk = 0;   //ile tickniec 
int odwroc_bity = 0; 
int tick=0; 
 
char zegar[] = "00:00:00"; 
void clock(void) { 
  char *zegar_tmp = zegar; 
  if(!(s_licznik%10)) { 
   sekundy = (s_licznik/10) % 60; 
   minuty = (s_licznik/600) % 60; 
   godziny = (s_licznik/36000) % 24; 
   
   if((sekundy%15) == 0) { 
    brzeczyk = (sekundy / 15)*100 ; 
    if(sekundy == 0) 
      brzeczyk = 4*100; 
   } 

background image

   else {  
    brzeczyk = 0; 
   }  
  zegar[0] = godziny/10 + '0'; 
  zegar[1] = godziny%10 + '0'; 
  zegar[3] = minuty/10 + '0'; 
  zegar[4] = minuty%10 + '0'; 
  zegar[6] = sekundy/10 + '0'; 
  zegar[7] = sekundy%10 + '0'; 
   
  clearDisplay(); 
  while(*zegar_tmp) 
    SEND_CHAR(*(zegar_tmp++)); 
   
  } 

 
 
 
void main(void) { 
  int i; 
   
 
  WDTCTL = WDTPW + WDTHOLD; //zatrzymanie watchdoga 
   
  P2DIR |= BIT1; 
  P4DIR |= BIT2 | BIT3; 
   
  BCSCTL1 |= XTS; //*MHz rezonator LFXT1 
   
  do {                                          //czyszczenie flagi ofifg 
    IFG1 &= ~OFIFG; 
    for(i = 0; i < 0xFF; i++)  
      ; 
  } while((IFG1 & OFIFG) == OFIFG); 
   
 
  BCSCTL1 |= DIVA_3;                              //podzielnik do ACLK, ACLK = 1Mhz 
  BCSCTL2 |= SELM0 | SELM1;                       //zegar glowny = ACLK = rezonator LFTX1 
   
  TACTL = TASSEL_1 + MC_1 + ID_2;                 //co czwarte narastajace zbocze timer ma 
"tykniecie", tryb up 
  TACCTL0 = CCIE;                                   //bedziemy generowac przerwania 
  TACCR0 = 25000;                                    
   
  TBCTL = TBSSEL_1 + MC_1 + ID_2; 
  TBCCTL0 = CCIE; 
  TBCCR0 = 500;                                    
   
  _EINT();                                        //wlaczenie przerwań 

background image

  InitPortsLcd(); 
  InitLCD(); 
  clearDisplay(); 
  SEND_CMD(DD_RAM_ADDR); 
   
   
  while(1) { 
   clock();  
  } 

 
 
#pragma vector=TIMERA0_VECTOR 
__interrupt void timer_a(void) { 
  s_licznik++; 

 
#pragma vector=TIMERB0_VECTOR 
__interrupt void timer_b(void) { 
  if(brzeczyk) { 
      tick++;//ile tickniec 
      tick %= 100; 
      brzeczyk--; 
  } else { 
   tick = 0;  
  } 
 
    if(brzeczyk && (tick > 50)) { 
   
     
      if(odwroc_bity) { 
        P4OUT |= BIT2; 
        P4OUT &= ~BIT3; 
        odwroc_bity = 0; 
      } else { 
        P4OUT &= ~BIT2; 
        P4OUT |= BIT3; 
        odwroc_bity = 1; 
      } 
    } 

 
 
 
 
 
 
 
 

background image

Wyliczenia 
 

Timer_A generuje przerwanie co 0.1 s czyli 10 przerwań na sekundę. 
Timer_B generuje przerwanie co 0.002s czyli 500 przerwań na sekundę. 
 
Z tego wynika, Ŝe między jednym przerwaniem Timera_A a drugim występuje 50 przerwań 
Timera_B. 
 
Zmienna brzeczyk wskazuje ile razy usłyszymy dźwięk z buzzera. 
 
  wartość zmiennej brzeczyk   liczba sekund   ile razy usłyszymy dźwięk 
        

    400                 

         0                                     4 

 

    300   

  

        45  

 

 

 3 

 

    200   

                    30 

 

 

 2 

 

    100   

                    15  

 

 

 1 

 
Jeden dźwięk składa się z dwóch części: przerwy i grania. KaŜda z nich składa się z 50 
przerwań Timera_B. 
 
Zmienna tick przyjmuję wartości modulo 100 i słuŜy do sprawdzenia czy naleŜy  
grać(tick<50 to przerwa,tick>50 to granie). 
 
Jeśli brzeczyk przyjmnie wartość 100 to wystąpi jeden dźwięk trwający 0.2s. 
 
Jeśli brzeczyk przyjmnie wartość 200 to wystąpią dwa dźwięki trwające 0.4s. 
 
Jeśli brzeczyk przyjmnie wartość 300 to wystąpią trzy dźwięki trwający 0.6s. 
 
Jeśli brzeczyk przyjmnie wartość 400 to wystąpią cztery dźwięki trwający 0.8s. 
 
Czyli kurant nie bedzie trwał więcej niŜ 1 s, co nie zakłóci pracy zegara. 
 
 
 

Wnioski:

   Program działa poprawnie spełniając wszystkie załoŜenia.