× Aktuálně z oboru

Programátoři po celém světě dnes slaví Den programátorů [ clanek/2018091300-programatori-po-celem-svete-dnes-slavi-den-programatoru/ ]
Celá zprávička [ clanek/2018091300-programatori-po-celem-svete-dnes-slavi-den-programatoru/ ]

AVR - čítače

[ http://programujte.com/profil/90-ondrej-karas/ ]Google [ ?rel=author ]       [ http://programujte.com/profil/118-zdenek-lehocky/ ]Google [ ?rel=author ]       21. 9. 2006       32 362×

Dnes bude řeč o čítačích/časovačích AVR. Díl buze téměř celý teoretický. Na konci si ukážeme jak přesně časovat události, aniž bychom podstatně ovlivnili jiné důležité úkoly proceosru.

Úvodem

Procesory ATMEGA16 obsahuji celkem tři čítače/časovače. Dva osmibitové, jeden šestnáctibitový. Vstupní signály mohou být předděleny předřazenou předděličkou, a to v hodnotách 1;8;64;1024.

Především si ale musíme říci, na co nám čítače/časovače budou. Vzpomeňme si na náš program s blikající LEDkou. Procesor musel zpracovávat smyčky pro čekání a během tohoto procesu samozřejmě nemohl dělat nic jiného. Tento způsob je velmi neefektivní a využít jej můžeme pouze v malém množství případů. Lepším řešením by bylo, aby se časování odehrávalo na pozadí, toho právě můžeme dosáhnout pomocí čítačů/časovačů…

Teorie

Čítače časovače nastavujeme speciálními registry. Zde je jejich krátký výčet:

  • TCNT(N) – obsahuje načítanou hodnotu
  • OCR(N) – obshuje hodnotu, s níž se TCNT(N) porovnává
  • TCCR(N) – řídí funkce čítače/časovače
  • TIMSK – masky přerušení

Lépe než mnoho teoretických řádků poslouží jednoduchý příklad, který nám, jak jinak, zajistí blikání LED v pravidelných intervalech, během nichž však tentokrát můžeme vykonávat výpočty…

;********************************************************************************************
;*                              PROGRAM_BLIK03.ASM;                                         *
;*  Procesor ATMEGA16 - DIL                                                                 *
;********************************************************************************************

;--------------------------------------------
; popis fce registru:
;   -> R19 - pomocny registr (platny lokalne)
;   -> R1  - slouzi pro pocitadlo preruseni
;   -> R2  - slouzi pro pocitadlo preruseni


        .NOLIST
		.INCLUDE "m16def.inc"
		.LIST


        ; PRIRAZENI JMEN PINUM, PORTUM A REGISTRUM 
		.CSEG

		.ORG	0
		RJMP	RESET
		.ORG	OC0addr
		RJMP	PRERUSENI

		.DEF	TEMP	   = R19
		.DEF	INT_CNT = R2

		.EQU    BLIK_PORT_DRIVE = DDRC
		.EQU	BLIK_PORT_DATA	= PORTC
		.EQU	BLIK_PIN = PORTC0

		
		; NASTAVENI ZASOBNIKU
RESET:	        LDI	        R16,LOW(RAMEND)
		OUT		SPL,R16
		LDI		R16,HIGH(RAMEND)
		OUT		SPH,R16

		; NASTAVENI CASOVACE_0 A JEHO PRERUSENI
		LDI		R19,12       ; nastavi zdroj signalu 
		OUT		TCCR0,R19    ; casovace 0 na 31250Hz
		LDI		R19,250      ; nastavi porovnavanou
		OUT		OCR0,R19     ; hodnotu na 250 (preruseni 125/s)
		LDI		R19,02       ; povoli preruseni,
		OUT		TIMSK,R19    ; kdyz TCNT0=OCR0.
				
		; NASTAVENI REGISTRU
		CLR		INT_CNT	     ; smaze pocitadlo preruseni
		CLR		INT_CNT	     ; smaze pocitadlo preruseni

                LDI		TEMP,255
		OUT		BLIK_PORT_DRIVE,TEMP

// ************************ HLAVNI PROGRAM ********************** //


ZACATEK_PROGRAMU:

        SEI
		// tady neco muzeme delat

	RJMP	ZACATEK_PROGRAMU	; skoci na zacatek (stale dokola)

// ************************ PODPOROGRAMY ************************ //



// ****************** OBSLUHY PRERUSENI *********************** //
PRERUSENI:												
		INC	INT_CNT     ; inkrementuje R2
		LDI	TEMP,125  
                CP	R2,TEMP	    ; je-li R2 mensi 
		BRLO	PRYC_LABEL  ; nez TEMP jde pryc					                                                   
		CLR	INT_CNT
        
		SBIC	BLIK_PORT_DATA,BLIK_PIN
		RJMP	CLEAR_PIN_LABEL
		SBI     BLIK_PORT_DATA,BLIK_PIN
                RJMP	PRYC_LABEL


CLEAR_PIN_LABEL:
		CBI     BLIK_PORT_DATA,BLIK_PIN		


PRYC_LABEL:	
		NOP
RETI

Vysvětlení programu bude stručné. Nevíme sice zatím, co je to přerušení, ale můžeme si říci, že je to situace, kdy se stane určitá událost, běh programu se přeruší v místě právě zpracovávané instrukce a program skočí na vektor přerušení (řádek v programu). Z tohoto vektoru je zavolnána obslužná rutina, zde PRERUSENI. Po jejim konci se program vrátí na místo, odkud byl přerušen.

Náš program by měl zajistit blikání LED připojené na PC0, a to frekvencí závisející na frekvenci oscilátoru, který jsme si vybrali. Při oscilátoru 8 Mhz bude perioda 2 s. Ostatně, to si můžete sami ověřit v AVR studiu.

Podrobněji

		; NASTAVENI CASOVACE_0 A JEHO PRERUSENI
		LDI		R19,12       ; nastavi zdroj signalu 
		OUT		TCCR0,R19    ; casovace 0 na 31250Hz
		LDI		R19,250      ; nastavi porovnavanou
		OUT		OCR0,R19     ; hodnotu na 250 (preruseni 125/s)
		LDI		R19,02       ; povoli preruseni,
		OUT		TIMSK,R19    ; kdyz TCNT0=OCR

Tato část kódu nastaví časovač nula do režimu, kdy je porovnáván registr TCNT0 (čítač) a OCR0 (nastavená hodnota) – bity WGM01, WGM02. V tomto případě je čítač vynulován a je vyvoláno přerušení. Bity CS02, CS01, CS00 určují zdroj hodinového signálu. V tomto případě je to oscilátor předdělený 256. Tím dostaneme frekvenci přerušení (8 000 000 / 256) / (OCR0 + 1). Přerušení nám tedy vznikají 125× za sekundu.

7 6 5 4 3 2 1 0
FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00

Jakmile je vyvoláno přerušení, program odskočí na tento řádek:

		RJMP	PRERUSENI

Ten zajistí, že je vyvolána potředná obslužná rutina, která dovolí změnit stav LED pouze 125× za její vyvolání.

Pro dnešek je to vše. Do příště si vyzkoušejte uvedený program odsimulovat v AVR studiu. Sledujte zvláště registr TCNT0 a jeho změny. Významy jednotlivých bitů uvedených registrů si můžete nastudovat v katalogovém listu procesoru. Bude-li vám i tak něco nejasného, pište do komentářů pod článkem.


Článek stažen z webu Programujte.com [ http://programujte.com/clanek/2006091410-avr-citace/ ].