#include <16F819.h>
#zero_ram
#device adc=8 *=16
#fuses HS,NOWDT,NOPROTECT,NOMCLR,NOPUT,BROWNOUT,NOLVP,NOCPD
#use delay(clock=8000000)
#use fast_io( A ) //a compiler nem ellenőrzi, hogy valóban kimenetnek
//van-e állítva a TRISX regiszter, ha ír a PORTX-be.
#use fast_io( B )
#define SERVO PIN_B0 //szervó jel
#define KEY_SET PIN_B1 //egy nyomógomb
#byte T1CON = 0x10 //pointer a TIMER1 beállító regiszterére
#byte TMR1L = 0x0E //TIMER1 alsó 8 bit
#byte TMR1H = 0x0F //TIMER1 felső 8 bit
enum interr { lowtohigh=0, hightolow=1 } edge=hightolow;
// két állapot, ez kell az élfelismeréshez
enum states { left=1, off=0, right=2 } index=off;
// index lámpák állapota (nem kerülnek kiadásra)
int16 time_ellapsed; //16 bites integer az idő méréséhez
int16 temp4eeprom; //16 bites integer az EEPROM adat ki- és beviteléhez
float MIDDLE; //lebegőpontos változó, a "középállás" megjegyzésére.
//nem minden szervó áll középállásban egy pl. 1,3ms pulzusszélességű jeltől
int wtoeepromH,wtoeepromL; //EEPROMBA írás változói
//===========================================================================
#int_EXT
void int_EXT_isr() {
//===========================================================================
if (edge == hightolow){
bit_set(T1CON,0); //T1CON.TMR1ON on
ext_int_edge(L_TO_H);
edge = lowtohigh;
}
else {
bit_clear(T1CON,0); //T1 off
time_ellapsed = make16(TMR1H,TMR1L);
set_timer1(0);
ext_int_edge(H_TO_L);
edge = hightolow;
}
}
//===========================================================================
void init(void){
//===========================================================================
set_tris_a(0xFF);
set_tris_b(0b00000111);
output_b(0x00);
port_b_pullups(true);
temp4eeprom = (int16)(read_eeprom(0x2101)&0xff) *
0x100+(read_eeprom(0x2100)&0xff);
MIDDLE = (float)temp4eeprom;
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
// 8,192 ms-on belül túlcsordulna, de kell az 1:1-es előosztó a jó
// felbontás miatt
set_timer1(0); //elvileg elhanyagolható
enable_interrupts( GLOBAL );
}
//===========================================================================
void main() {
//===========================================================================
init();
for(;;){ //ugyan az mint a while(1),
//csak így nem ad figyelmeztetést a compiler
if (!input(KEY_SET)){
output_b(0x00);
delay_ms(100);
if (!input(KEY_SET)){ //aktív állapotban alacsony szintű,
// mert pull-up ellenállás van rajta.
delay_ms(1000); //várunk egy kicsit
if (!input(KEY_SET)){ //biztos hosszan nyomja a gombot?
wtoeepromH = make8(time_ellapsed,1); //1 byte-ot shiftelünk, MSB
wtoeepromL = time_ellapsed-(wtoeepromH*0x100); //LSB
write_eeprom (0x2100, wtoeepromL); //EEPROM-ba írás
write_eeprom (0x2101, wtoeepromH);
temp4eeprom = (int16)(read_eeprom(0x2101)&0xff) *
0x100+(read_eeprom(0x2100)&0xff);
//EEPROM-ból kiolvasás, és konverzió először 16 bites integerre, majd
MIDDLE = (float)temp4eeprom; //float számmá alakítás
}
}
}
if (edge == hightolow){
/* Itt történik a pulzus hosszának a kiértékelése. Ekkor már a
time_ellapsed változóban van az érték, amit TIMER1 mért. A következő
logikával pl. egy jobbra (index.right) vagy egy balra (index.left)
indexet lehet vezérelni.
A megfelelő PIN-ek állítása a program egy későbbi részében történhet. */
if ((time_ellapsed > (0.56*MIDDLE)) && (time_ellapsed < (0.92*MIDDLE)))
//0,8-1,1ms
index = left;
else if ((time_ellapsed > (1.08*MIDDLE)) && (time_ellapsed < (1.43*MIDDLE)))
//1,3-1,6ms
index = right;
else index = off;
}
}//end of while
}//end of main