Na osnovu vaseg koda pretpostavljam da ne poznajete dovoljno asembler da biste uspesno mogli resiti problem. Jos gore, objasnjenja su i dalje nejasna, tako da se stice utisak da ni sami ne znate sta zelite postici. Moze se ponesto pretpostaviti, ali to nije to. Buduci da niste naveli kompletan kod (sta rade potprogrami zeleno_1, off_1 i druga) niti elektricnu semu, tesko je uopste ponuditi Vam ikakvo resenje, ali bnuduci da ovakav zadatak predstavlja izazov, hajde da probam.
Imate 6 senzora. Morate brojati impulse na njima. Pretpostavicu da su impulsi dovoljne duzine za sigurnu detekciju, kako bi se izbeglo testiranje interaptima (jer nema dovoljno ulaza interapta). Ukoliko nisu, mehanicki bi mogao da se prilagodi odnos signal/pauza pomeranjem senzora blize osovini.
Kako vrsiti testiranje? U glavnom programu NEPREKIDNO testirati stanja, i po PROMENI stanja inkrementovati poseban registar (ili mozda po dva registra - sesnaestobitnim brojanjem) za svaki ulaz.
Ukoliko se pretpostavi da su na pinovima porta B svo vreme stabilni logicki nivoi, i da su senzori povezani za pinove RB0, RB1, RB2, RB3, RB4 i RB5 (namerno stavljam PORTB jer je lakse odjednom testirati ceo port, nego ceo port A i jos jedan pin sa porta B), i (takodje pretpostavi) da senzori naizmenicno salju logicku 0 i 1 na ove pinove pri svakom obrtaju, algoritam za testiranje mogao bi izgledati ovako:
Code:
clrf RAZLIKA
Start
movf PORTB,W ; Uzimanje stanja sa porta B
xorwf RAZLIKA,F ; Poredjenje sa prethodnim stanjem
btfsc RAZLIKA,0 ; Da li se promenilo stanje na senzoru 1?
call Inc_Sen_1 ; Jeste. Pozovi potprogram za inkrementaciju registra senzora 1.
btfsc RAZLIKA,1 ; Da li se promenilo stanje na senzoru 2?
call Inc_Sen_2 ;
btfsc RAZLIKA,2 ; ...
call Inc_Sen_3
btfsc RAZLIKA,3
call Inc_Sen_4
btfsc RAZLIKA,4
call Inc_Sen_5
btfsc RAZLIKA,5
call Inc_Sen_6
goto Start ; Nastavi sa testiranjem iz pocetka.
U potprogramima Inc_Sen1 (do Inc_Sen_6) bi se inkrementovali registri senzora (0x00 do 0xFF) ili par registara po senzoru (0x0000 do 0xFFFF).
Onda je potrebno iz interapta izazvanih tajmerom testirati prekoracenje (unapred zadate) granice inkrementovanih vrednosti, i na osnovu toga postaviti odgovarajuce stanje LED. Na primer, ugasena za vrednosti do 0x02 (za svaki slucaj je ostavljen mali histerezis), i zelena preko ove vrednosti. Naravno, mora se voditi racuna da ne dodje do prekoracenja (zato pominjem sesnaestobitnu inkrementaciju) pre nove vrednosti interapta, kao i izabrati odgovarajuce vreme izazivanja interapta. Ovakav pristup pruza jednostavno kasnije dobijanje realne brzine.
Dalje je potrebno proveriti ima li registara senzora cije se stanje nije promenilo od prethodnog interapta (i dalje je 0x00 do 0x02). Ukoliko ima, pokrenula bi se inkrementacija dodatnog (interapt) registra samo za taj senzor. Odmah zatim, obrisati sve registre senzora.
Zatim je potrebno proveriti je li ijedan od interapt registara svih senzora presao unapred zadatu granicu (koju je potrebno proracunati za taj rok od 3-4 sekunde), i ukoliko jeste ukljuciti crvenu LED. Pri bilo kakvoj promeni registra senzora (obicnog, a ne dodatnog), resetovao bi se dodatni (interapt) registar tog senzora. Tek onda se moze izaci iz interapta.
A ukoliko bas zelite da promenom osvetljenosti zelene LED imate ikakvu predstavu o trenutnoj brzini, mozete umesto ukljucenja zelene LED iz interapta staviti da se ona ukljucuje odmah po ulasku u potprogram za inkrementaciju, i da se iskljucuje pre izlaska iz njega.
Komplikovano? Mozda. Ali, kompletan algoritam je tu. Ostalo je na Vama. Da ne ispadne da favorizujem PIC, isti algoritam se moze implementirati u bilo kom mikrokontroleru sa bar 12 U/I pinova, bar jednim tajmerom i mogucnoscu dobijanja interapta po prekoracenju tajmera (tesko da se uopste moze naci mikrokontroler sa 12 I/O pinova bez ovih mogucnosti).