Operácie

Projekt: Hodiny A: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentDVPS (diskusia | príspevky)
Bez shrnutí editace
Balogh (diskusia | príspevky)
Bez shrnutí editace
 
(10 medziľahlých úprav od 2 ďalších používateľov nie je zobrazených)
Riadok 1: Riadok 1:
== Hodiny na orientačný beh ==
=== '''A. Hodiny na orientačný beh.''' ===
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. Ako bonus doplňte riadenie intenzity displeja na základe vonkajšieho osvetlenia.
[[Obrázok:7-segmentLEDdisplayShield.jpg|center|300px]]
'''Literatúra:'''
* [http://www.uize.com/examples/seven-segment-display.html Ako pracuje 7-segmentový displej]
* [http://www.extremeelectronics.co.in/avrtutorials/pdf/7SegMUX.pdf Princíp multiplexu]
* [[Médiá:7-segmentLEDdisplayShield.pdf|Schéma zapojenia]] (.pdf)
* [http://www.gme.sk/_dokumentace/dokumenty/512/512-167/dsh.512-167.1.pdf HD-M514RD datasheet]
* [[Médiá:7-segmentTest.hex|Testovací program]] (.hex) - po zapnutí rozsvieti desatinné bodky a čaká na stlačenie S1. Potom zobrazí všetky číslice 0-9 a zhasne.


== Hodiny na orientačný beh ==


::::::::::::::::::'''Záverečný projekt'''
::::::::::::::::::'''Záverečný projekt'''
Riadok 39: Riadok 56:
'''Príkaz na určenie polohy:'''
'''Príkaz na určenie polohy:'''


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


'''Výpis znakov:'''
'''Výpis znakov:'''
Riadok 45: Riadok 62:
Jednotlivé znaky vypisujeme pomocou funkcie '''„znak“'''
Jednotlivé znaky vypisujeme pomocou funkcie '''„znak“'''


<source lang="c">
void znak(int number, unsigned char place)
void znak(int number, unsigned char place)


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


Riadok 65: Riadok 84:
}
}
if (number==0) //0
if (number==0) //0
{  
{
   
PORTD = 0b11000000;
PORTD = 0b11000000;
}
}


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


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


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


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


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


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


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


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


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


if (number==0) //0
if (number==0) '''//0'''
{           
{           
PORTD = 0b11000000;
PORTD = 0b11000000;
Riadok 176: Riadok 199:
PORTD = 0b01000000;
PORTD = 0b01000000;
}
}
 
</source>


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 veľmi podobná funkcii '''„znak“''', rozdiel je v tom, že má vždy vysvietenú aj desatinnú bodku.
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 veľmi podobná funkcii '''„znak“''', rozdiel je v tom, že má vždy vysvietenú aj desatinnú bodku.
Riadok 187: Riadok 210:
Hodnotu týchto premenných vypočítame podľa nasledovného algoritmu:
Hodnotu týchto premenných vypočítame podľa nasledovného algoritmu:


<source lang="c">


sec++;
sec++;
Riadok 242: Riadok 266:


}
}
 
</source>
'''Pípanie posledných 5 sekúnd každej minúty:'''
'''Pípanie posledných 5 sekúnd každej minúty:'''


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


<source lang="c">
void pip(void)
void pip(void)


Riadok 336: Riadok 361:


}
}
</source>


V posledných piatich sekundách pred každou celou minútou program odpípa, pričom posledné pípnutie bude dlhšie.  
V posledných piatich sekundách pred každou celou minútou program odpípa, pričom posledné pípnutie bude dlhšie.  
Riadok 341: Riadok 367:
'''Dĺžku pípnutia môžeme nastaviť počtom cyklov.'''
'''Dĺžku pípnutia môžeme nastaviť počtom cyklov.'''


<source lang="c">
   unsigned short i;
   unsigned short i;
   unsigned char sec,sekundy, dsec,min,dmin,hod;
   unsigned char sec,sekundy, dsec,min,dmin,hod;
Riadok 417: Riadok 444:


PORTD = 0b11111111; '''// prázdny displej'''
PORTD = 0b11111111; '''// prázdny displej'''
 
</source>


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.  
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.  
Riadok 430: Riadok 457:


Ak hodnotu X zmenšíme, tak program bude bežať rýchlejšie, ak ju zväčšíme, tak pôjde pomalšie.
Ak hodnotu X zmenšíme, tak program bude bežať rýchlejšie, ak ju zväčšíme, tak pôjde pomalšie.
*'''Hex subor:'''
[http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/S%C3%BAbor:Sem_AVR.hex Sem_Avr.hex]





Aktuálna revízia z 09:16, 19. november 2013

Hodiny na orientačný beh

A. Hodiny na orientačný beh.

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. Ako bonus doplňte riadenie intenzity displeja na základe vonkajšieho osvetlenia.

Literatúra:



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.

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


Tento typ sedem segmentového displeja slúži na zobrazovanie desatinných čísel a obmedzený počet znakov abecedy. Často sa vyskytuje v displejoch vo vreckových kalkulačkách, DVD prehrávačoch, digitálnych hodinkách, audio záznamníkoch, teplomeroch atď.

V našom prípade sú jednotlivé segmenty aktívne v nule. Zobrazený znak je riadený z registra D a najnižší bit zodpovedá segmentu A. Posledný bit je desatinná bodka.

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á port PB.0 a postupne až k portu PB.3 .

Zopnutie všetkých štyroch znakov naraz je možné uskutočniť rýchlym 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 veľmi podobná funkcii „znak“, rozdiel je v tom, že má vždy vysvietenú aj desatinnú bodku.


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

Na jednotlivých miestách sú vypísané premenné v tomto 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.

  • Hex subor:

Sem_Avr.hex


  • 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 záverečného projektu.