Uživatel:Kahljan

Z MAM wiki

Přejít na: navigace, hledání

Jan Kahl



[editovat] Semestrální práce

Téma semestrální práce:

Regulátor PC ventilátoru se zpětnou vazbou ze signálu TACHO, rychlost je zadávána ve stupních 0-9 z klávesnice - společně s Janem Oravcem.


Základní zapojení

Protože budeme ovládat zařízení s vyšším odběrem proudu a vyšším pracovním napětím 12V / 0,45 A, budeme potřebovat spínat ventilátor přes tranzistor (např. tento IRFZ44N).

Elektrické zapojení úlohy na zapnutí a regulaci ventilátoru s třídrátovým připojením, používaného např. k chlazení PC:

Soubor:CPU-FAN.png


Softwarové řešení

Řešení naší semestrální práce by se dalo rozdělit do několika dílčích úloh (viz dále).

1. Čtení stisknutí klávesy na maticové klávesnici

Pro ovládání použijeme maticovou klávesnici 4×4, my z ní použijeme pouze 3 sloupce a 4 řádky.


Propojení klávesnice s procesorem

Na černém konektoru do kontaktního pole, od kterého vede barevný plochý kabel dolů, jsou sloupce a řádky klávesnice připojeny takto:

COL1 COL3 ROW1 ROW3
COL2 COL4 ROW2 ROW4

Vývody ATmega168, ke kterým by tato klávesnice šla připojit:

PC5 PC4 PC3 PC2 ... ... ...
)
RESET PD0 PD1 PD2 PD3 ... ... ...


My pro připojení sloupců klávesnice používáme PC2 - PC4 a pro řádky PD0 - PD3.

// Nastavení vstupů a výstupů pro klávesnici
	cbi 	DDRC, 2  	// nastavení vstupů pro klávesnici (sloupec 1 - 3)
	cbi 	DDRC, 3
	cbi 	DDRC, 4

	sbi 	PORTC, 2 	// nastavení pull-upů
	sbi 	PORTC, 3
	sbi 	PORTC, 4

	sbi 	DDRD, 0 	// nastavení výstupů pro klávesnici (řádek 1 - 4)
	sbi 	DDRD, 1
	sbi 	DDRD, 2
	sbi 	DDRD, 3

	cbi 	PORTD, 0	// nastavení log. nuly na všech řádcích
	cbi 	PORTD, 1
	cbi 	PORTD, 2
	cbi 	PORTD, 3

// Čtení klávesnice
OVLADANI:

// Stisknutí klávesy 0
KL0:
	sbi	PORTD, 0	// nastavení jedničky pro první řádek
	sbi	PORTD, 1	// nastavení jedničky pro druhý řádek
	sbi	PORTD, 2	// nastavení jedničky pro třetí ředek
	cbi	PORTD, 3	// nastavení nuly pro čtvrtý řádek (* 0 # D)
	
	sbic	PINC, 3		// pokud je na druhém sloupci (2 5 8 0) nula, přeskoč následující instrukci
	rjmp	KL1		// pokračuj na KL1 (testuj, jestli je zmáčknutá 1)
	ldi	R16, 0		// zapiš do registru R16, že byla stisknuta 0
	rjmp 	STISK		// pokračuj na část STISK, kde dojde k vypnutí výstupů

// Stisknutí klávesy 1
KL1:
	cbi	PORTD, 0	// log. nula na prvním řádku (1 2 3 A)
	sbi	PORTD, 1	// log. jednička na ostatních řádcích
	sbi	PORTD, 2
	sbi	PORTD, 3

	sbic	PINC, 2		// pokud je na prvním sloupci (1 4 7 *) nula, přeskoč následující instrukci
	rjmp	KL2		// pokračuj na KL2 (testuj, jestli je zmáčknutá 2)
	ldi	R16, 1		// zapiš do R16, že byla stisknuta 1
	rjmp	STISK		// pokračuj na část STISK

// Stisknutí klávesy 2
// Výstupy máme nastavené od KL1, pouze testujeme vstup
KL2:
	sbic 	PINC, 3 	// pokud je na druhém sloupci (2 5 8 0) nula, přeskoč následující instrukci
	rjmp 	KL3		// pokračuj na KL3 (testuj, jestli je zmáčknutá 3)
	ldi	R16, 2		// zapiš do R16, že byla stisknuta 2
	rjmp 	STISK		// pokračuj na STISK

// Stisknutí klávesy 3
// Výstupy máme nastavené od KL1, pouze testujeme vstup
KL3:
	sbic	PINC, 4		// pokud je na třetím sloupci (3 6 9 #) nula, přeskoč následující instrukci
	rjmp	KL4		// pokračuj na KL4 (testuj jestli je zmáčknutá 4)
	ldi 	R16, 3		// zapiš 3 do R16
	rjmp	STISK		// pokračuj na STISK
	
// Stisknutí klávesy 4
KL4:
	sbi	PORTD, 0	// log. jednička na prvním řádku
	cbi	PORTD, 1	// log. nula na druhém řádku (4 5 6 B)
	sbi 	PORTD, 2	// log. jednička na třetím a čtvrtém řádku
	sbi 	PORTD, 3

	sbic	PINC, 2		// jestli je na prvním sloupci (1 4 7 *) nula
	rjmp	KL5
	ldi	R16, 4		// zapiš 4 do R16
	rjmp	STISK

// Stisknutí klávesy 5
KL5:
	sbic 	PINC, 3		// jestli je na druhém sloupci (2 5 8 0) nula
	rjmp	KL6
	ldi 	R16, 5		// zapiš 5 do R16
	rjmp	STISK

// Stisknutí klávesy 6
KL6:
	sbic 	PINC, 4		// jestli je na třetím sloupci (3 6 9 #) nula
	rjmp	KL7
	ldi 	R16, 6		// zapiš 6 do R16
	rjmp 	STISK

// Stisknutí klávesy 7
KL7:
	sbi 	PORTD, 0	// log. jednička na prvním, druhém a čtvrtém řádku
	sbi	PORTD, 1
	cbi	PORTD, 2	// log. nula na třetím řádku (7 8 9 C)
	sbi	PORTD, 3

	sbic	PINC, 2		// jestli je na prvním sloupci (1 4 7 *) nula
	rjmp	KL8
	ldi	R16, 7		// zapiš 7 do R16
	rjmp	STISK

// Stisknutí klávesy 8
KL8:
	sbic	PINC, 3		// jestli je na druhém sloupci (2 5 8 0) nula
	rjmp 	KL9
	ldi	R16, 8		// zapiš 8 do R16
	rjmp	STISK

// Stisknutí klávesy 9
KL9:
	sbic 	PINC, 4		// jestli je na třetím sloupci (3 6 9 #) nula
	rjmp	STISK
	ldi	R16, 9		// zapiš 9 do R16

// Část STISK, která vynuluje výstupy
STISK:
	cbi 	PORTD, 0	// log. nula na všech řádcích
	cbi	PORTD, 1
	cbi	PORTD, 2
	cbi	PORTD, 3
	ret

2. Ovládání výstupu PWM podle stisknuté klávesy

PWM čítač čítá od 0 do FF (tedy 0 - 255). Jeho frekvence Je 1 MHz. Pokud použijeme celý rozsah, tedy 256 kroků, dostaneme se na frekvenci 1 MHz / 256 = 3,9 kHz. Na ovládání otáček ventilátoru jsou vhodné pulzy s frekvencí cca. 25 kHz. Nebudeme proto čítat od 0 až do 256, ale pouze do 45. Při tomto počtu kroků se dostaneme na frekvenci pulzů 1 MHz / 45 = 22,22 kHz a zároveň je tato hodnota dělitelná 9 (rychlost ovládáme v 9ti krocích). Případně bychom mohli ještě čítat do 36, kde by frekvence pulzů byla 27,78 kHz.

.INCLUDE "m168def.inc" 		// obsahuje instrukce pro nastavení zásobníků

.EQU	PULZY_PWM = 45		// Do této hodnoty bude čítat PWM, odpovídá frekvenci 22,22 kHz

.ORG 0x0000 
	jmp 	Main 	// Reset Handler
.ORG 0x0008 
	jmp 	START 	// PCINT1 Handler

// .ORG je direktiva překladače  - kód za direktivou bude v paměti programu 
//  na adrese, která je za direktivou uvedena


// Hlavní část programu
Main: 

// Inicializace pointeru
	ldi 	r17, high(RAMEND)	// Náhrání hodnoty do R16
	out 	SPH, r17 		// Nastavení Stack Pointeru na začátek RAM
	ldi 	r17, low(RAMEND)
	out 	SPL, r17		// Nastavení Stack Pointeru na konec RAM


// Nastavení PWM
PWM:
	ldi 	R17, 0b00100011		// pouze pomocné, v příštím kroku zapíšeme do registru pro nastavení PWM hodnotu pro Fast PWM mód, výstup na OC0B, neinvertující
	out 	TCCR0A, R17		// do registru pro nastavení PWM nastavíme hodnotu z pomocného registru R17
	ldi	R17, 0B00001001 	// hodnota pro WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	out 	TCCR0B, R17 
	ldi 	R17, PULZY_PWM
	out	OCR0A, R17		// nastavíme, aby čítač čítal do předem zadané hodnoty

	sbi 	DDRD, 5			// jako výstup PWM nastavíme pin PD5

// Ovládání PWM
START:
	rcall 	OVLADANI

	mov 	R17, R16	// hodnotu R16 zapíšeme do R17 (stisknutá klávesa)
	lsl 	R17
	lsl 	R17		// znásobení hodnoty R17 4x
	out 	OCR0B, R17	// zapsání R17 do výstupu	

V tento moment dokážeme ovládat rychlost otáček větráku různou šířkou pulzů za pomoci registrů určených přímo pro PWM modulaci. Pokud roztočíme větrák, můžeme měnit jeho rychlost stiskem tlačítka na klávesnici. Problém nastává v případě, kdy chceme roztočit větrák na nižší otáčky. V současné době totiž posíláme stále stejnou řadu pulzů a pokud zvolíme rychlost, při které není na začátku dostatečně široký pulz, který by dokázal větrák roztočit, větrák se pouze "cuká" a netočí se. Proto potřebujeme při zvolené nižší rychlosti na začátku vyslat několik širších pulzů.


3. Pomocí signálu TACHO můžeme snímat aktuální rychlost otáček a tu pak třeba zobrazit na displeji nebo nějak jinak zpracovat

Osobní nástroje