Egy PICit választhatunk...
Ott hagytuk abba, hogy jó lenne, ha a különböző fény minták közül, kiválaszthatnánk egyet. Ez nem egy bonyolult feladat, többféleképpen meg lehet oldani. Talán a legegyszerűbb módszer az, ha a Speed_Adj procedúrába - mivel az, minden fénymintában végrehajtódik - beírjuk a szükséges utasításokat. Persze kell azért néhány sort máshová is...

Hirdetés

Rögtön a deklarációs részben felveszünk egy új konstanst: Mode = 2; ez a konstans, egy új nyomógomb konstansa amely, a B Port 2-es Bitjén fog elhelyezkedni.

És deklarálunk egy új változót: Select_1 néven, amely Byte-os típusú. Ezután a Pic_Init-ben beállítjuk a kezdő értékét. (Inicializáljuk)
Ja,.. És közben string típusúra cseréltem a tömbváltozót, mert itt felesleges tömböt deklarálni.

Const Speed_Fel=0; Speed_le=1; Mode=2;

Var Loop, Bemenet, Speed_Fut, Select_1 : byte;
Text : string[3];
Text_1 : string[8];

var LCD_RS : sbit at RD2_bit;
var LCD_EN : sbit at RD3_bit;
var LCD_D4 : sbit at RD4_bit;
var LCD_D5 : sbit at RD5_bit; // LCD Port Beállítás
var LCD_D6 : sbit at RD6_bit;
var LCD_D7 : sbit at RD7_bit;
var LCD_RS_Direction : sbit at TRISD2_bit;
var LCD_EN_Direction : sbit at TRISD3_bit;
var LCD_D4_Direction : sbit at TRISD4_bit;
var LCD_D5_Direction : sbit at TRISD5_bit;
var LCD_D6_Direction : sbit at TRISD6_bit;
var LCD_D7_Direction : sbit at TRISD7_bit;

//---------------------------- Pic_Init ---------------------------------------

Procedure Pic_Init;
Begin
TrisC:=$00;
LatC:=$00;
TrisB:=$FF;
PortB := $00;
Intcon2.RBPU := 0;
Loop := 0;
Bemenet := 0;
Select_1 := 1;
Speed_Fut := EEprom_read(0);
If Speed_Fut = $FF Then Speed_Fut := 70;
LCD_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1, 1, '* FERYSERVICE * ');
Lcd_Out(2, 1, ' FUTO FENY ');
Delay_ms(3000);
Lcd_Cmd(_LCD_Clear);
Lcd_Out(1, 1, 'MINTA:');
Lcd_Out(2, 1, 'DELAY:');
Lcd_Out(2, 10, 'mS');
End;


Utána belemászunk egy kicsit a Speed_Adj procedúra lelkivilágába.
No, nem nagyon, csak egy PICikét...
Hozzáírunk egy keveset az elejéhez, na meg a végéhez is...


If Bemenet.mode = 1 Then
Begin
Delay_ms(300);
Select_1 := Select_1+1;
If Select_1= 8 Then Select_1:=1;
End;


A B Port 2-es Bitjén levő gombot megnyomjuk, akkor a Bemenet.mode felveszi az 1-es értéket ? mivel az egész Port-ot negáltuk ? és a program végrehajtja a következőket:
Delay_ms(300); Ismerős, a nyomógomb prellezését küszöböljük ki.
Select_1 := Select_1+1; Ahányszor megnyomjuk a gombot a Select_1 változó értékéhez hozzáad egyet.
If Select_1= 8 Then Select_1:=1; Ha eléri a 8-at, akkor egyre állítja a Select_1-et.

Persze ez még nem elég, hiszen a program jelenleg nem tudja, hogy mit kezdjen a Select_1 változóval. Ahhoz, hogy a fénymintákból egyet kiemeljünk, bele kell nyúlni a fényminták procedúráiba.

Procedure Villog;
Var Loop_1 : Byte;
Begin
If (Select_1=2) Or (Select_1=1) Then
Begin
For Loop_1:=0 To 5 Do
Begin
Speed_Adj;
LatC:=$AA; // %10101010
Vdelay_ms(Speed_Fut+30);
Speed_adj;
LatC:= not LatC;
Vdelay_ms(Speed_Fut+30);
End;
End;
End;

Procedure Villog_2;
Var Loop_1 : Byte;
Begin
If (Select_1=3) Or (Select_1=1) Then
Begin
For Loop_1:=0 To 5 Do
Begin
Speed_adj;
LatC:=%10000001;
Vdelay_ms(Speed_Fut+10);
Speed_adj;
LatC:=%01000010;
Vdelay_ms(Speed_Fut+10);
Speed_adj;
LatC:=%00100100;
Vdelay_ms(Speed_Fut+10);
Speed_adj;
LatC:=%00011000;
Vdelay_ms(Speed_Fut+10);
Speed_adj;
LatC:=%00100100;
Vdelay_ms(Speed_Fut+10);
Speed_adj;
LatC:=%01000010;
Vdelay_ms(Speed_Fut+10);
End;
End;
End;

Procedure Fut;
Var Loop_1 : Byte;
Begin
If (Select_1=4) Or (Select_1=1) Then
Begin
For Loop_1:=0 To 5 Do
Begin
LatC:=$03;
For Loop:=0 to 7 do
Begin
Speed_Adj;
Vdelay_ms(Speed_Fut);
asm
rlncf LatC,F;
End;
End;
End;
End;
End;

Procedure Fut_2;
Var Loop_1 : Byte;
Begin
If (Select_1=5) Or (Select_1=1) Then
Begin
For Loop_1:=0 To 5 Do
Begin
LatC:=$C0;
For Loop:=0 to 7 do
Begin
Speed_Adj;
Vdelay_ms(Speed_Fut);
asm
rrncf LatC,F;
End;
End;
End;
End;
End;

Procedure Night_Rider;
Var Loop_1 : Byte;
Begin
If (Select_1=6) Or (Select_1=1) Then
Begin
For Loop_1:=0 To 5 Do
Begin
PortC:=$03;
For Loop:=0 To 5 Do
Begin
Speed_Adj;
VDelay_ms(Speed_Fut);
asm
rlncf PortC,F;
End;
End;
For Loop:=0 to 5 do
Begin
Speed_Adj;
VDelay_ms(Speed_Fut);
asm
rrncf PortC,F;
End;
End;
End;
End;
End;


A Led_Blink procedúrát azért neveztem át, Night_Rider-nek, mert a funkció így benne van a nevében.
Nincs sok változás, csak azért tettem ide az összes fényminta procedúráját, hogy átláthatóbb legyen az egész.
Tulajdonképpen itt is, indirekt módon van megoldva a szelektálás, ugyanis, nem azt csináljuk, hogy egy procedúrát hívunk meg, hanem egy változó, a Select_1 értékét figyeljük a program futása során, és csak azok a fényminták procedúrái futnak le, amelyekben az IF THEN szerkezet ezt megengedi.
Pl.: A Villog procedúra, csak akkor hajtódik végre, ha a Select_1 változó értéke 2. vagy 1, a villog_2 pedig ha 3 vagy 1. stb. Ha a Select_1 értéke 1 akkor az összes villogásminta végrehajtódik, a főprogramban beírt sorrendben, a kijelzőre pedig kiírja a program, hogy "Sorozat". Ha pedig a Select_1 értéke 2 akkor csak a Villog, ha 3, akkor a Villog 2, ha 4, akkor a Fut, stb... procedúra hajtódik végre.
Itt találkozunk egy újdonsággal az "OR" utasítással. Ez egy logikai művelet, ami pontosan azt jelenti: "VAGY".
Tehát az a sor, hogy "If (Select_1=2) Or (Select_1=1) Then"
Azt jelenti, hogy "HA Select_1 =2 VAGY Select_1 =1" AKKOR ...
Tehát kettős feltételrendszert használunk ebben az esetben. Ilyen esetben a feltételeket zárójel közé kell tenni.
A THEN után Begin...End közé tesszük a teljes procedúrát, így a feltétel megléte esetén a teljes procedúra végrehajtásra kerül. Igaz, a Pollozás miatt, be kell ezt írnunk az összes procedúrába, de ez még nem akkora probléma.

Van még egy apróság, ha már van kijelzőnk, akkor írjuk is ki rá, hogy éppen melyik fényminta fut a Port-on.
Itt megismerkedünk egy újabb utasítással, ami nem más, mint a CASE.
A néhány gondolat a PicPascal-ról című cikkben leírtam a definíciót, most nem tenném újra.

Case Select_1 of
1 : Lcd_Out(1, 7, 'Sorozat ');
2 : Lcd_Out(1, 7, 'Villog ');
3 : Lcd_Out(1, 7, 'Villog 2');
4 : Lcd_Out(1, 7, 'Fut ');
5 : Lcd_Out(1, 7, 'Fut 2 ');
6 : Lcd_Out(1, 7, 'Night R.');
7 : Lcd_Out(1, 7, 'STOP ');
End;


Ez sem bonyolult, mindössze annyi történik, hogy a Select_1 változó értékének megfelelő szöveget, írjuk ki a kijelzőre.
Így néz ki jelenleg a teljes Speed_Adj procedúra.
Egyrészt választhatunk villogás mintát, és amelyiket kiválasztjuk, az fog menni folyamatosan.
Amennyiben a Select_1 értéke 7 lesz, akkor azt írja ki a kijelző, hogy "STOP" és a program egyik mintát sem hajtja végre.
Mivel a Pic_Init-ben 1-re állítottuk a Select_1 értékét, mindig "Sorozat" funkcióval indul, a bekapcsolás után.

Procedure Speed_Adj;
Begin
Bemenet:= not PortB;
If Bemenet.mode = 1 Then
Begin
Delay_ms(300);
Select_1 := Select_1+1;
If Select_1= 8 Then Select_1:=1;
End;
If Bemenet.Speed_Fel = 1 Then
Begin
Delay_ms(300);
Speed_Fut := Speed_Fut +5;
If Speed_Fut >= 120 Then Speed_Fut := 120;
EEprom_write(0, Speed_Fut); //EEprom-ba Kiír!
End;
If Bemenet.Speed_Le = 1 Then
Begin
Delay_ms(300);
Speed_Fut := Speed_Fut -5;
If Speed_Fut <= 5 Then Speed_Fut := 5;
EEprom_write(0, Speed_Fut); //EEprom-ba Kiír!
End;
ByteToStr(Speed_Fut, Text);
Lcd_Out(2, 7, Text);
Case Select_1 of
1 : Lcd_Out(1, 7, 'Sorozat ');
2 : Lcd_Out(1, 7, 'Villog ');
3 : Lcd_Out(1, 7, 'Villog 2');
4 : Lcd_Out(1, 7, 'Fut ');
5 : Lcd_Out(1, 7, 'Fut 2 ');
6 : Lcd_Out(1, 7, 'Night R.');
7 : Lcd_Out(1, 7, 'STOP ');
End;
End;


Még egy PICi változás azért a főprogramban is van, nem sok, de két sort azért be kell még írnunk.
Egyrészt a Speed_Adj procedúrát is, be kell illeszteni a főprogramba Különben abban az esetben, ha a Select_1 értéke 7, akkor nem tudjuk újra indítani, mivel egyszer sem megy be a program a Speed_Adj procedúrába.
Ezen kívül, amikor a Speed_adj értéke 7, akkor a kimenetet le kell kapcsolni, azaz nullára kell állítani a C Portot.

Begin
Pic_init;
While True Do
Begin
Speed_adj;
If Select_1 = 7 Then LatC:=$00;
Temperature_In;
Temperature_Out;
Fut;
Villog;
Fut_2;
Villog;
Night_Rider;
Villog;
Villog_2;
Villog;
End;
End.


Ismételten bővült néhány funkcióval a programunk, így hát elkezdtem gondolkodni azon, hogy mire lehetne használni a kész kapcsolást. Rájöttem.
Nagy divat, legalábbis ezen a környéken, a karácsonyi díszkivilágítás a házakra. Mivel találtam itthon pár darab kb. 30 cm-es LED sort, úgy döntöttem ez a program lesz, az ajtó körüli világításnak a vezérlése. A LED csíkokat, körbe rakom az ajtó mellett, oldalanként hármat, felülre pedig kettőt. A panel a kijelzővel pedig belülre, az előszoba falára fog kerülni.
Így ennek az ismertetőnek, végül is meglesz a maga haszna, nemcsak a vakvilágba írogatjuk a programot hanem, fel is tudjuk majd használni.

Mivel csak erre, azért ez a PIC egy kicsit luxus, bővítünk még a programon és a kapcsoláson, hogy minél jobban kihasználjuk a PIC-ben rejlő lehetőségeket. Persze még akkor is luxus lesz, amikor végleg kész leszünk ezzel a kütyüvel, de manapság annyira mindegy, hogy választok-e egy kicsit kisebbet vagy sem, 100-200.-Ft a különbség, ami sajnos ma már annyit sem ér, hogy átírjam érte a programot. Akkor érné meg, ha több ezer darabos szériában gyártanánk, de egy-egy darabnál, szerintem semmi értelme ezen rágódni. Mellékesen személy szerint én, nagyon szeretem a 4520-ast, igazán nem is tudom miért, de legtöbbször ezt használom.
Most már célirányosan fejlesztünk, mivel már tudjuk, hogy mire fogjuk használni. Mivel a kijelző bent lesz a lakásban, Pl.: remek bővítési lehetőségnek tűnik egy külső-belső hőmérő.
Azt hiszem a folytatásban, kapunk hideget-meleget...


Fájlok:
FájlnévFájlméretLetöltve
A cikkhez tartozó fájlok csak bejelentkezés után tölthetőek le!

Hozzászólások
Hozzászólás csak bejelentkezés után lehetséges...
grandiloquent-yearly
grandiloquent-yearly
grandiloquent-yearly
grandiloquent-yearly