Operácie

Hodiny na orientačný beh: Rozdiel medzi revíziami

Z SensorWiki

 
(36 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 179: Riadok 179:
 
sekundy++;
 
sekundy++;
  
if (sec ==10) // ak prekročíme hodnotu 10 sek, zväčší sa dsek o 1
+
if (sec ==10)   '''// ak prekročíme hodnotu 10 sek, zväčší sa dsek o 1'''
{
+
sec = 0;
+
{
 +
 
 +
sec = 0;
 +
 
 
dsec++;
 
dsec++;
}
+
 
+
}
if (dsec ==6) // ak prekročíme dsek o viac ako 6, tak zväčší minúty o 1
+
 
{
+
if (dsec ==6)   '''// ak prekročíme dsek o viac ako 6, tak zväčší minúty o 1'''
 +
 +
{
 +
 
 
dsec = 0;
 
dsec = 0;
 +
 
min++;
 
min++;
 +
 
pip2();
 
pip2();
 +
 
sekundy = 0;
 
sekundy = 0;
 +
 
}
 
}
  
if (min ==10) // ak dosiahneme 10 min zväčší dmin o 1
+
if (min ==10)   '''// ak dosiahneme 10 min zväčší dmin o 1'''
{
+
min = 0;
+
{
dmin++;
+
 
 +
min = 0;
 +
 
 +
dmin++;
 +
 
 
}
 
}
  
 +
if (dmin ==6)
 +
 +
{
 +
 +
dmin = 1;
 +
 +
hod++;
 +
 +
}
 +
 +
if ((sekundy > 54) && (sekundy <60)) '''// od 54 sekundy voláme podprogram pipanie do 60 sekundy'''
 +
 +
{
 +
 +
pip();
 +
 +
}
 +
 +
'''Pípanie posledných 5 sekúnd každej minúty:'''
 +
 +
Pípanie je riešené pomocou časovača č/1.
 +
 +
 +
void pip(void)
 +
 +
{
 +
 +
  unsigned int pom;
 +
  pom = 0;
 +
  //DDRB = 0b00100000;              // SPEAKER on PB.5  is output
 +
  PORTB = PORTB | 0b00100000;             
 +
  TCCR1A = 0b00000000;              // T/C1 in timer mode
 +
  TCCR1B = 0b00000101;              // prescale ck
 +
  //TCNT1 = 0xff62;
 +
  TCNT1 = 57722;                  // start value of T/C1 Low+High bytes
 +
  TIFR1 = 0x01;                    //(1<<TOV1);  if a 1 is written to a TOV1 bit
 +
                                    //            - the TOV1 bit will be cleared
 +
 +
  while (pom<8000)
 +
 +
{
 +
 +
pom++;
 +
 +
  if ( (TIFR1 & 0x01) == 0x01)  // If the overflow flag is set
 +
     
 +
{
 +
 
 +
pom++;
 +
 +
  PORTB = PORTB ^ 0b00100000;  // Toggle the
 +
  //TCNT1 = 0xFF62;              // Restart T/C1 - reload
 +
  TCNT1 = 57722;                  // start value of T/C1 Low+High bytes
 +
 +
 +
TIFR1 = 0x01;                // Clear the overflow flag
 +
 +
}
 +
 +
else
 +
 +
asm("nop");
 +
 +
}
 +
 +
                      // And do this forever
 +
 +
}
 +
 +
void pip2(void)
 +
 +
{
 +
 +
unsigned int pom;
 +
 +
pom = 0;
 +
 +
  //DDRB = 0b00100000;              // SPEAKER on PB.5  is output
 +
  PORTB = PORTB | 0b00100000;             
 +
  TCCR1A = 0b00000000;              // T/C1 in timer mode
 +
  TCCR1B = 0b00000101;              // prescale ck
 +
  //TCNT1 = 0xFF62;                  // start value of T/C1 Low+High bytes
 +
  TCNT1 = 49910;
 +
  TIFR1 = 0x01;                    //(1<<TOV1);  if a 1 is written to a TOV1 bit
 +
                                    //            - the TOV1 bit will be cleared
 +
 +
 +
  while (pom<60000)
 +
 +
{
 +
 +
pom++;
 +
 +
  if ( (TIFR1 & 0x01) == 0x01)  // If the overflow flag is set
 +
 +
   
 +
{
 +
 +
pom++;
 +
  PORTB = PORTB ^ 0b00100000;  // Toggle the
 +
  TCNT1 = 49910;
 +
  //TCNT1 = 0xFF62;              // Restart T/C1 - reload
 +
  TIFR1 = 0x01;                // Clear the overflow flag
 +
 +
}
 +
 +
else
 +
 +
asm("nop");
 +
 +
}
 +
 +
                      // And do this forever
 +
 +
}
 +
 +
V posledných piatich sekundách pred každou celou minútou program odpípa, pričom posledné pípnutie bude dlhšie.
 +
 +
'''Dĺžku pípnutia môžeme nastaviť počtom cyklov.'''
 +
 +
  unsigned short i;
 +
  unsigned char sec,sekundy, dsec,min,dmin,hod;
 +
 +
DDRD = 0b11111111;
 +
 +
DDRB = 0b00101111;
 +
 +
sec = 0;
 +
 +
dsec = 0;
 +
 +
min = 0;
 +
 +
dmin = 0;
 +
 +
hod = 0;
 +
 +
sekundy = 0;
 +
 +
for (;;)
 +
 +
{
 +
znak(11,0);
 +
 +
znak(11,1);
 +
 +
znak(11,2);
 +
 +
znak(11,3);
 +
 +
if ( !( PINB & (1<<4) ) ) '''// čaká na stlačenie tlačidla'''
 +
 +
{
 +
 +
for(;;) '''// nekonečný cyklus'''
 +
 +
{
 +
 +
for(i=0;i<23526;i++) '''// for cyklus prejde za jednu sekundu'''
 +
 +
 +
                        '''//for(i=0;i<23526;i++)'''
  
if (dmin ==6)
 
 
{
 
{
dmin = 1;
+
hod++;
+
    PORTD = 0b11111111;     '''// prázdny displej'''
}
+
 
 +
znak(sec,0);       '''//sekundy'''
 +
   
 +
PORTD = 0b11111111;
 
 
if ((sekundy > 54) && (sekundy <60)) // od 54 sekundy voláme podprogram pipanie do 60 sekundy
+
znak (dsec,1); '''// desat. sekundy'''
{
+
 
pip();
+
PORTD = 0b11111111;
}
+
 +
znakmin (min,2); '''// minúty s desatinnou bodkou'''
 +
 
 +
PORTD = 0b11111111;
 +
 +
if (dmin>0) '''// dminuty, vypisuje iba vtedy keď dmin je>0'''
 +
 +
{
 +
 
 +
znak (dmin,3);
 +
 +
}
 +
 
 +
else
 +
 
 +
{
 +
 
 +
znak (10,3);
 +
 
 +
}
 +
 
 +
PORTD = 0b11111111; '''// prázdny displej'''
 +
 
 +
 
 +
Program vypisuje pomlčky kým nestlačíme tlačidlo, ktoré je umiestnené na pine PB5. Po stlačení tlačidla sa nám rozbehnú hodiny.
 +
 
 +
Rýchlosť behu hodiniek môžeme nastaviť pomocou cyklu '''„for“'''.  Náš zdrojový kód sme odkrokovali v programe AVR Studio a namerali sme dĺžku cyklov. Výpis znakov trvá '''42,5 μs''' a výpočet hodnôt premenných '''6 μs.'''
 +
 
 +
Nakoniec sme vypočítali počet cyklov, aby zostavený program inkrementoval každú sekundu:
 +
 
 +
:::::::::::::::::::::::::::'''X*42,5μ s + 6μs = 1s'''
 +
:::::::::::::::::::::::::::::'''X=23526'''
 +
 
 +
 
 +
Ak hodnotu X zmenšíme, tak program bude bežať rýchlejšie, ak ju zväčšíme, tak pôjde pomalšie.
 +
 
 +
 
 +
'''Záver:'''
 +
 
 +
Cieľom nášho projektu bolo naprogramovať hodiny na orientačný beh s požadovanou funkciou pípania. Na konci každej minúty odpípa posledné 4 sekundy a 5. sekundu dlhším tónom. Správne fungovanie naprogramovaného systému sme si overili na požičanom prípravku. Navrhnutý program bežal bez problémov, splnili sme definovanú úlohu daného projektu.

Aktuálna revízia z 11:36, 18. december 2012

Záverečný projekt
  • Vypracovali:
Bc. Andrej Berčák
Bc. Juraj Harmata
  • Študijný odbor: Aplikovaná mechatronika
  • Ročník: 2. Ing.


  • Úloha:
Veľkoplošný 7-segmentový LED displej treba pripojiť k mikroprocesoru a naprogramovať tak, aby po zapnutí odpočítaval minúty nasledujúce po štarte, pričom posledných 5 sekúnd pred každou celou minútou odpípa. Posledné pípnutie bude dlhšie a bude sprevádzané inkrementovaním čísla na displeji. Pred časom 00 bude displej zobrazovať pripravenosť symbolmi --.

K zapojeniu treba vypracovať dokumentáciu, popis programu, schému zapojenia displeja a riadiacej jednotky.

Displej.jpg
Obr. 1. Doska plošného spoja so zapojeným displejom
  • Vypracovanie:
Schéma zapojenia:

Schema.jpg


Sedem segmentový displej slúži na zobrazovanie desatinných čísel a obmedzený počet znakov abecedy. Často sa vyskytuje v displejoch vo vreckových kalkulačkách, VHS a DVD prehrávačoch, digitálnych hodinkách, audio záznamníkoch atď. V našom prípade jednotlivé segmenty sú aktívne v nule. Zobrazený znak je riadený z registra D. Najnižší bit zodpovedá segmentu A, posledný bit je desatinná bodka.

Segment.jpg
Obr. 2. Označenie jednotlivých segmentov

Polohu znaku môžeme určiť portom B. Určíme ho otváraním jednotlivých tranzistorov, kde znaku na poslednom mieste zodpovedá PB.0 a takto ďalej až ku PB.3 . Vysvietenie všetkých štyroch znakov naraz je možné riešiť rýchlim prepínaním medzi nimi.

Príkaz na určenie polohy:

PORTB = ~(1<<place) & 0b11011111;

Výpis znakov:

Jednotlivé znaky vypisujeme pomocou funkcie „znak“

void znak(int number, unsigned char place)

{

  PORTB = ~(1<<place) & 0b11011111;    // nastavenie miesta displeja ktorý chceme zobraziť

if (number==10) //prázdny znak { PORTD = 0b11111111; }

if (number==11) // pomlčka { PORTD = 0b10111111; } if (number==0) //0 { PORTD = 0b11000000; }

if (number==1) //1 { PORTD = 0b11111001; }

if (number==2) //2 { PORTD = 0b10100100; }

if (number==3) //3 { PORTD = 0b10110000; }

if (number==4) //4 { PORTD = 0b10011001; }

if (number==5) //5 { PORTD = 0b10010010; }

if (number==6) //6 { PORTD = 0b10000010; }

if (number==7) //7 { PORTD = 0b11111000; }

if (number==8) //8 { PORTD = 0b10000000; }

if (number==9) //9 { PORTD = 0b10010000; }

if (number==0) //0 { PORTD = 0b11000000; }


void znakmin(int number, unsigned char place)

{

  PORTB = ~(1<<place) & 0b11011111;

if (number==1) { PORTD = 0b01111001; }

if (number==2) { PORTD = 0b00100100; }

if (number==3) { PORTD = 0b00110000; }

if (number==4) { PORTD = 0b00011001; }

if (number==5) { PORTD = 0b00010010; }

if (number==6) { PORTD = 0b00000010; }

if (number==7) { PORTD = 0b01111000; }

if (number==8) { PORTD = 0b00000000; }

if (number==9) { PORTD = 0b00010000; }

if (number==0) { PORTD = 0b01000000; }


Polohu znaku určíme pomocou premennej „place“ , ak má hodnotu 0,píšeme na posledné miesto. Prvému miestu zodpovedá hodnota 3. Vypísaný znak určíme premennou „number“, kde jednotlivým číslam zodpovedá ich hodnota. Ak je hodnota premennej 10, píšeme prázdny znak ak je 11, píšeme pomlčku. Máme zadefinovanú aj funkciu „znakmin“, ktorá je skoro totožná s funkciou „znak“, len má vždy vysvietenú aj desatinnú bodku.


Výpočet jednotlivých hodnôt:

Na jednotlivých miestách sú vypísané premenné v nasledovnom poradí: “dmin“, “min“, “dsec“, “sec“.

Hodnotu týchto premenných vypočítame podľa nasledovného algoritmu:


sec++; sekundy++;

if (sec ==10) // ak prekročíme hodnotu 10 sek, zväčší sa dsek o 1

{

sec = 0;

dsec++;

}

if (dsec ==6) // ak prekročíme dsek o viac ako 6, tak zväčší minúty o 1

{

dsec = 0;

min++;

pip2();

sekundy = 0;

}

if (min ==10) // ak dosiahneme 10 min zväčší dmin o 1

{

min = 0;

dmin++;

}

if (dmin ==6)

{

dmin = 1;

hod++;

}

if ((sekundy > 54) && (sekundy <60)) // od 54 sekundy voláme podprogram pipanie do 60 sekundy

{

pip();

}

Pípanie posledných 5 sekúnd každej minúty:

Pípanie je riešené pomocou časovača č/1.


void pip(void)

{

 unsigned int pom;
 pom = 0;
 //DDRB = 0b00100000;              // SPEAKER on PB.5  is output
 PORTB = PORTB | 0b00100000;              
 TCCR1A = 0b00000000;              // T/C1 in timer mode
 TCCR1B = 0b00000101;              // prescale ck
 //TCNT1 = 0xff62; 
 TCNT1 = 57722;                  // start value of T/C1 Low+High bytes
 TIFR1 = 0x01;                    //(1<<TOV1);   if a 1 is written to a TOV1 bit
                                   //             - the TOV1 bit will be cleared
  while (pom<8000)

{

pom++;

  if ( (TIFR1 & 0x01) == 0x01)   // If the overflow flag is set
     

{

pom++;

 PORTB = PORTB ^ 0b00100000;  // Toggle the 
 //TCNT1 = 0xFF62;              // Restart T/C1 - reload
 TCNT1 = 57722;                  // start value of T/C1 Low+High bytes


TIFR1 = 0x01; // Clear the overflow flag

}

else

asm("nop");

}

                     // And do this forever

}

void pip2(void)

{

unsigned int pom;

pom = 0;

 //DDRB = 0b00100000;              // SPEAKER on PB.5  is output
 PORTB = PORTB | 0b00100000;              
 TCCR1A = 0b00000000;              // T/C1 in timer mode
 TCCR1B = 0b00000101;              // prescale ck
 //TCNT1 = 0xFF62;                  // start value of T/C1 Low+High bytes
 TCNT1 = 49910;
 TIFR1 = 0x01;                    //(1<<TOV1);   if a 1 is written to a TOV1 bit
                                   //             - the TOV1 bit will be cleared


  while (pom<60000)

{

pom++;

  if ( (TIFR1 & 0x01) == 0x01)   // If the overflow flag is set

    

{

pom++;

 PORTB = PORTB ^ 0b00100000;  // Toggle the 
 TCNT1 = 49910;
 //TCNT1 = 0xFF62;              // Restart T/C1 - reload
 TIFR1 = 0x01;                // Clear the overflow flag

}

else

asm("nop");

}

                     // And do this forever

}

V posledných piatich sekundách pred každou celou minútou program odpípa, pričom posledné pípnutie bude dlhšie.

Dĺžku pípnutia môžeme nastaviť počtom cyklov.

 unsigned short i;
 unsigned char sec,sekundy, dsec,min,dmin,hod;

DDRD = 0b11111111;

DDRB = 0b00101111;

sec = 0;

dsec = 0;

min = 0;

dmin = 0;

hod = 0;

sekundy = 0;

for (;;)

{ znak(11,0);

znak(11,1);

znak(11,2);

znak(11,3);

if ( !( PINB & (1<<4) ) ) // čaká na stlačenie tlačidla

{

for(;;) // nekonečný cyklus

{

for(i=0;i<23526;i++) // for cyklus prejde za jednu sekundu


//for(i=0;i<23526;i++)

{

PORTD = 0b11111111; // prázdny displej

znak(sec,0); //sekundy

PORTD = 0b11111111;

znak (dsec,1); // desat. sekundy

PORTD = 0b11111111;

znakmin (min,2); // minúty s desatinnou bodkou

PORTD = 0b11111111;

if (dmin>0) // dminuty, vypisuje iba vtedy keď dmin je>0

{

znak (dmin,3);

}

else

{

znak (10,3);

}

PORTD = 0b11111111; // prázdny displej


Program vypisuje pomlčky kým nestlačíme tlačidlo, ktoré je umiestnené na pine PB5. Po stlačení tlačidla sa nám rozbehnú hodiny.

Rýchlosť behu hodiniek môžeme nastaviť pomocou cyklu „for“. Náš zdrojový kód sme odkrokovali v programe AVR Studio a namerali sme dĺžku cyklov. Výpis znakov trvá 42,5 μs a výpočet hodnôt premenných 6 μs.

Nakoniec sme vypočítali počet cyklov, aby zostavený program inkrementoval každú sekundu:

X*42,5μ s + 6μs = 1s
X=23526


Ak hodnotu X zmenšíme, tak program bude bežať rýchlejšie, ak ju zväčšíme, tak pôjde pomalšie.


Záver:

Cieľom nášho projektu bolo naprogramovať hodiny na orientačný beh s požadovanou funkciou pípania. Na konci každej minúty odpípa posledné 4 sekundy a 5. sekundu dlhším tónom. Správne fungovanie naprogramovaného systému sme si overili na požičanom prípravku. Navrhnutý program bežal bez problémov, splnili sme definovanú úlohu daného projektu.