background image

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

Data
1.12.2009

Ćwiczenie nr 5

Temat: Clock

Zespół nr 2       1. Robert Jarocki
Grupa  nr 6       2. Jarosław Jastrzębski

Prowadzący
…......................
Ocena
…......................

Zadanie:

Napisać program wyświetlający na wyświetlaczu msp430 napis zawierający:

dzień,

miesiąc,

rok,

godzinę,

minuty.

Teoria:

Podstawowe zegary w układzie:

LFXT1CLK – może być używany z niskoczęstotliwościowym kwarcem 32678 Hz, 
bądź z rezonatorami z zakresu 450 kHz – 8 MHz (tryb pracy 
wysokoczęstotliwościowej),

XT2CLK – 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.

Zegary sterujące komponentami mikrokontrolera:

ACLK – zegar pomocniczy, jego źródłem jest LFXT1CLK,

MCLK – zegar używany przez CPU oraz system, jego źródłem może być 
LFXT1CLK, XT2CLK, oraz DCO,

SMCLK – jest przeznaczony do współpracy z urządzeniami peryferyjnymi, jego 
źródłem może być LFXT1CLK, XT2CLK, oraz DCO.

Ustawienie zegara początkowego:
1. Włączenie oscylatora 
2. Wyczyszczenie flagi OFIFG 
3. Odczekanie około 50 ns 
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 

background image

Schemat blokowy zegara:

Podstawowe rejestry zegara:

Rejestr

Krótka forma

Typ rejestru

Adres

Initial State

DCO control 
register

DCOCTL

Read / write

056h

060h with PUC

Basic clock 
system control 1

BCSCTL1

Read / write

057h

084h with PUC

Basic clock 
system control 2

BCSCTL2

Read / write

058h

Reset with POR

SFR Interrupt 
enable register 1

IE1

Read / write

000h

Reset with PUC

SFR interrupt 
flag register 1

IFG1

Read / write

002h

Reset with PUC

background image

Zdjęcie wykonania programu:

Kod programu:

#include<msp430x14x.h>
#include "lcd.h"
#include "portyLcd.h"
#define PRZYCISK BIT4&P4IN

unsigned int i=0;
unsigned int dziesiatkidni=3;
unsigned int dni=0;
unsigned int dziesiatkigodz=2;
unsigned int godz=3;
unsigned int dziesiatkiminut=5;
unsigned int minuty=9;
unsigned int dziesiatkisekund=3;
unsigned int sekundy=5;
unsigned int licznik=0;
unsigned int miesiac=8;
unsigned int dziesiatkimiesiecy=0;
unsigned int tysiaceroku=2;
unsigned int setkiroku=0;
unsigned int dziesiatkiroku=0;
unsigned int rok=9;
unsigned char znak;
unsigned char literar;

char sty[12]={" sty        "};
char lut[12]={" lut        "};
char mar[12]={" mar        "};
char kwi[12]={" kwi        "};
char maj[12]={" maj        "};
char cze[12]={" cze        "};
char lip[12]={" lip        "};
char sie[12]={" sie        "};
char wrz[12]={" wrz        "};
char paz[12]={" paz        "};
char lis[12]={" lis        "};
char gru[12]={" gru        "};

void Clock(void);

background image

void main( void )
{

znak=':';

     

literar='r';

     

P2DIR |= BIT1;                                 

 // STATUS LED

     

WDTCTL=WDTPW + WDTHOLD;                           // Wyłączenie WDT

     

InitPortsLcd();                                  

// inicjalizacja portów LCD

    

InitLCD();                                       

// inicjalizacja LCD

     

clearDisplay();                                  

// czyszczenie wyświetlacza     

     

// Basic Clock Module ustawiamy na ACLK(zegar 8 MHz ) i dzielimy częstotliwość przez 2 (4 MHz)

     

BCSCTL1 |= XTS;                                  

// ACLK = LFXT1 = HF XTAL 8MHz

     

do

     

{

IFG1 &= ~OFIFG;                             

// Czyszczenie flgi OSCFault

          

for (i = 0xFF; i > 0; i--);                 

// odczekanie

     

}

     

while ((IFG1 & OFIFG) == OFIFG);            

// dopóki OSCFault jest ciągle ustawiona  

     

BCSCTL1 |= DIVA_1;                               

// ACLK=8 MHz/2=4 MHz

     

BCSCTL2 |= SELM0 | SELM1;                        

// MCLK= LFTX1 =ACLK

     

// Timer_A  ustawiamy na 500 kHz

     

// a przerwanie generujemy co 100 ms

     

TACTL = TASSEL_1 + MC_1 +ID_3;                   

// Wybieram ACLK, ACLK/8=500kHz,tryb Up

     

CCTL0 = CCIE;                                    

// włączenie przerwań od CCR0

     

CCR0=50000;                                      

// podzielnik 50000: przerwanie co 100 ms

     

_EINT();                                         

// włączenie przerwań

     

for (;;)                             

     

{

_BIS_SR(LPM3_bits);                         

// przejscie do trybu LPM3

          

Clock();

     

}

}

void Clock(void)
{
    

if (licznik %10 ==0)                             

// gdy mineła sekunda (10 * 100 milisekund)

     

{

licznik=0;

          

P2OUT ^=BIT1;                               

//zapal diodę

          

++sekundy;                                  

// licz sekundy

          

sekundy = sekundy%10;

          

dziesiatkisekund = dziesiatkisekund%6;

          

SEND_CMD(DD_RAM_ADDR);        

// gorna linia wyswietlacza

          

SEND_CHAR(dziesiatkidni+48);                // wyswietla dziesiatki dni

          

SEND_CHAR(dni+48);                          

// wyswietla jednosci dni

          

SEND_CHAR(' ');                             

// wyswietla pustny znak (odstęp)   

          

SEND_CHAR(' ');                             

// wyswietla pustny znak (odstęp)

          

if (dziesiatkimiesiecy==0 && miesiac==1)

               

for (i=0;i<=11;i++) SEND_CHAR(sty[i]); // wyswietla styczen, jesli spelnione

          

if (dziesiatkimiesiecy==0 && miesiac==2) 

               

for (i=0;i<=11;i++) SEND_CHAR(lut[i]); // wyswietla luty, jesli spelnione

         

if (miesiac==3)

               

for (i=0;i<=11;i++) SEND_CHAR(mar[i]);// wyswietla marzec, jesli spelnione

          

if (miesiac==4)

               

for (i=0;i<=11;i++) SEND_CHAR(kwi[i]);// wyswietla kwiecien, jesli spelnione

          

if (miesiac==5)

               

for (i=0;i<=11;i++) SEND_CHAR(maj[i]);// wyswietla maj, jesli spelnione   
if (miesiac==6)

               

for (i=0;i<=11;i++) SEND_CHAR(cze[i]); // wyswietla czerwiec, jeśli spelnione

          

if (miesiac==7)

               

for (i=0;i<=11;i++) SEND_CHAR(lip[i]); // wyswietla lipiec, jesli spelnione

background image

          

if (miesiac==8)

               

for (i=0;i<=11;i++) SEND_CHAR(sie[i]); // wyswietla sierpien, jesli spelnione

          

if (miesiac==9)

               

for (i=0;i<=11;i++) SEND_CHAR(wrz[i]);// wyswietla wrzesien, jesli spelnione

          

if (dziesiatkimiesiecy==1 && miesiac==0)

               

for (i=0;i<=11;i++) SEND_CHAR(paz[i]);// wyswietla pazdziernik, jeśli spelnione

          

if (dziesiatkimiesiecy==1 && miesiac==1)

               

for (i=0;i<=11;i++) SEND_CHAR(lis[i]);  // wyswietla listopad, jesli spelnione

          

if (dziesiatkimiesiecy==1 && miesiac==2)

               

for (i=0;i<=11;i++) SEND_CHAR(gru[i]);// wyswietla grudzien, jeśli spelnione

          

SEND_CMD(DD_RAM_ADDR2);          

// dolna linia wyswietlacza 

          

SEND_CHAR(dziesiatkigodz+48);               // wyswietla dziesiatki godzin

          

SEND_CHAR(godz+48);                         

// wyswietla jednosci godzin

          

SEND_CHAR(znak);                            

// wyswietla dwukropek

          

SEND_CHAR(dziesiatkiminut+48);            // wyswietla dziesiatki minut

          

SEND_CHAR(minuty+48);                        // wyswietla jednosci minut

          

SEND_CHAR(' ');                             

// wyswietla pustny znak (odstęp)

          

SEND_CHAR(' ');                             

// wyswietla pustny znak (odstęp)

          

SEND_CHAR(' ');                             

// wyswietla pustny znak (odstęp)

          

SEND_CHAR(' ');                             

// wyswietla pustny znak (odstęp)

          

SEND_CHAR(' ');                             

// wyswietla pustny znak (odstęp)

          

SEND_CHAR(' ');                             

// wyswietla pustny znak (odstęp)

          

SEND_CHAR(tysiaceroku+48);                   // wyswietla tysiace lat

          

SEND_CHAR(setkiroku+48);                       // wyswietla setki lat

          

SEND_CHAR(dziesiatkiroku+48);             // wyswietla dziesiatki lat

          

SEND_CHAR(rok+48);                          

// wyswietla jednosci lat

          

SEND_CHAR(literar);                         

// wyswietla literke "r"

          

SEND_CMD(CUR_SHIFT_LEFT );             // wróć kursorem na początek

          

if(sekundy==9)                              

// przeskok z X9 sekund na (X+1)0 sekund

               

dziesiatkisekund++;                            

          

if(dziesiatkisekund==6)              

// przeskok z 59 sekund na X minut 00 sekund

          

{

               

dziesiatkisekund=0;

               

minuty++;

          

}

          

if(minuty==10)                              

// przeskok z X9 minut na (X+1)0 minut

          

{

               

minuty=0;

               

dziesiatkiminut++;

          

}

          

if(dziesiatkiminut==6)                

// przeskok z 59 minut na X godzin 00 minut

          

{

               

dziesiatkiminut=0;

               

godz++;

          

}

          

if(godz==10)                               

// przeskok z X9 godzin na (X+1)0 godzin

          

{

               

godz=0;

               

dziesiatkigodz++;

          

}

          

if(dziesiatkigodz==2 && godz==4 )    

// przeskok z 23:59:59 na 00:00:00

          

{

               

dziesiatkigodz=0;

               

godz=0;

               

dni++;

          

}

          

if(dni==9)                                  

// przeskok z X9 dni na (X+1)0 dni

          

{

               

dni=1;

               

dziesiatkidni++;

background image

          

}

          

// przeskok z 31 dnia na dzień 1 kolejnego miesiąca (dla miesięcy: 1,3,5,7,8,10,12)

          

if(dziesiatkidni==3 && dni==2 && (miesiac==1 || miesiac==3 || miesiac==5 ||miesiac==7 

||miesiac==8 ||(miesiac==0 && dziesiatkimiesiecy==1) ||(miesiac==2 && dziesiatkimiesiecy==1)))
          

{

               

dziesiatkidni=0;

               

dni=1;

               

miesiac++;

          

}

          

// przeskok z 30 dnia na dzień 1 kolejnego miesiąca (dla miesięcy: 4,6,9,11)

          

if(dziesiatkidni==3 && dni==1 && (miesiac==4 || miesiac==6 ||miesiac==7 ||miesiac==9 

||(miesiac==1 && dziesiatkimiesiecy==1)))
          

{

               

dziesiatkidni=0;

               

dni=1;

               

miesiac++;

          

}

          

// przeskok z 28 dnia na dzień 1 kolejnego miesiąca (dla miesięca: 2)

          

if(dziesiatkidni==2 && dni==9 && miesiac==2)

          

{

               

dziesiatkidni=0;

               

dni=1;

               

miesiac++;

          

}

          

if(dziesiatkimiesiecy==0 && miesiac==10)// przeskok z 9 miesiaca na 10

          

{

               

miesiac=0;

               

dziesiatkimiesiecy=1;

          

}

          

if(dziesiatkimiesiecy==1 && miesiac==3) // przeskok z 12 miesiaca na 1 

          

{

               

dziesiatkimiesiecy=0;

               

miesiac=1;

               

rok++;

          

}

          

if(rok==10)                                 

// przeskok z XXX9 lat na XX(X+1)0 lat

          

{

               

rok=0;

               

dziesiatkiroku++;

          

}

          

if(dziesiatkiroku==10)                        

// przeskok z XX99 lat na X(X+1)00 lat

          

{

               

dziesiatkiroku=0;

               

setkiroku++;

          

}

          

if(setkiroku==10)                                

// przeskok z X999 lat na (X+1)000 lat

          

{

               

setkiroku=0;

               

tysiaceroku++;

          

     

}

}

// procedura obsługi przerwania od TimerA
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
     

++licznik;

     

_BIC_SR_IRQ(LPM3_bits);             

// wyjście z trybu LPM3

}