;************************************************************************ ; Opastinhässäkkä ; ;************************************************************************ LIST P = 16F84A, R = HEX ;Prosessorityyppi, radix INCLUDE "p16f84A.inc" ;w,f,porta,portb yms. ERRORLEVEL -224 ;Estää virheilmoituksen ;"tris"-komennosta __CONFIG _PWRTE_OFF & _HS_OSC & _WDT_OFF ; Poltto Tait-polttokoneella 16C84:nä, muista: PWRTE kääntyy! ; Xtal 4 MHz => 1 us/cycle (HS/LS-oskillaattorin raja on 32kHz!) ; ; Layout St1 ; ====== /---<---- Track 1 ; / St2 ; ->------>--------<---- Track 2 ; AdvHm Hm \ St3 ; AdvSt \---<---- Track 3 ; ; +---+_+---+ ; Vaihde:Raide1/3 PORTA.2 ->|1 18|<- PORTA.1 Lähtö2("jatkoyhteys") ; Vaihde:Raide2/3 PORTA.3 ->|2 17|<- PORTA.0 Lähtö1 ; Twin-T PORTA.4 ->|3 16|-- XTAL ; Vdd --|4 15|-- XTAL ; Vss(GND)--|5 14|-- Vdd (+5V) ; St1_G/Hm_G PORTB.0 <-|6 13|<- PORTB.7 Home ; St1_R/Hm_R PORTB.1 <-|7 12|-> PORTB.6 Starter/!Home ; St2_G/AdvSt_G PORTB.2 <-|8 11|-> PORTB.5 St3_R/AdvHm_R ; St2_R/AdvSt_R PORTB.3 <-|9 10|-> PORTB.4 St3_G/AdvHm_G ; +---------+ ; ;************************ RAM ********************************************************* CBLOCK H'0C' St1_G_in ;Opastin Raide 1 Vihreä St1_G_out ;Opastin Raide 1 Vihreä St1_R_in ;Opastin Raide 1 Punainen St1_R_out ;Opastin Raide 1 Punainen St2_G_in ;Opastin Raide 2 Vihreä St2_G_out ;Opastin Raide 2 Vihreä St2_R_in ;Opastin Raide 2 Punainen St2_R_out ;Opastin Raide 2 Punainen St3_G_in ;Opastin Raide 3 Vihreä St3_G_out ;Opastin Raide 3 Vihreä St3_R_in ;Opastin Raide 3 Punainen St3_R_out ;Opastin Raide 3 Punainen Hm_G_in ;Tulo-opastin Vihreä Hm_G_out ;Tulo-opastin Vihreä Hm_R_in ;Tulo-opastin Punainen Hm_R_out ;Tulo-opastin Punainen AdvSt_G_in ;Lähtö-esiopastin Vihreä AdvSt_G_out ;Lähtö-esiopastin Vihreä AdvSt_Y_in ;Lähtö-esiopastin keltainen AdvSt_Y_out ;Lähtö-esiopastin keltainen AdvHm_G_in ;Tulo-esiopastin Vihreä AdvHm_G_out ;Tulo-esiopastin Vihreä AdvHm_Y_in ;Tulo-esiopastin keltainen AdvHm_Y_out ;Tulo-esiopastin keltainen Apu ;apumuuttuja, bittietoa: ; 0=Twin-T:n tila ; 1=Lähtö/Tulo päällä ; 2=Esiopastinvilkun tila Flasher_ramp ;Esiopastimen ramppi Out_byte ;port b:n tuleva tila Out_bit ;mitä bittiä ylläolevasta säädetään PWM_delay ;PWM:n venyttäjä PWM_Loop_Count ;PWM-laskuri ENDC #DEFINE Home_sw PORTB, 7 #DEFINE Starter_sw PORTA, 0 #DEFINE next_Starter PORTA, 1 #DEFINE Turnout1or3 PORTA, 2 #DEFINE Turnout2or3 PORTA, 3 #DEFINE TwinT_in PORTA, 4 #DEFINE TwinT_status Apu, 0 #DEFINE LT Apu, 1 #DEFINE Flasher_status Apu, 2 #DEFINE Ulos PORTB ;************************************************************************ ;RESTART/INT-START ;************************************************************************ ORG 0 ; Restart vector goto main ORG 4 ; INT vector retfie ;--------------------------------------------------------------- ; vilkun ohjaus 1/3 POIS 2/3 PÄÄLLÄ ;--------------------------------------------------------------- ; kasvata ramppia: ; jos ramppi =0 -> valo pois! ; jos ramppi >127 ja valo on pois -> valo päälle, ramppi nollaan! Flasher incfsz Flasher_ramp,f ;kasvata Flasherramppia, menikö ympäri goto Flasher_on ;ei Flasher_off bcf Flasher_status ;kyllä, (ramppi=0) ->valo pois (clear) return Flasher_on btfsc Flasher_status ;(ramppi 1..255) oliko valo pois (clear) return ;ei, jatketaan btfss Flasher_ramp,7 ;kyllä, onko rampin bitti 7 "1" (set) return ;ei (ramppi = 0 ..127), ei muutoksia bsf Flasher_status ;kyllä (ramppi = 128..255), valo päälle (set) movlw 0x0 ;nolla akkuun ja movwf Flasher_ramp ;nollataan sillä vikkkuramppi return ;--------------------------------------------------------------- ;Lookup-taulu (jäljittelee x^3-käyrää, 0..0x0F -> 0..0x20) ;--------------------------------------------------------------- Lookup addwf pcl,f retlw .0 retlw .0 retlw .0 retlw .0 retlw .1 retlw .1 retlw .2 retlw .3 retlw .5 retlw .7 retlw .9 retlw .13 retlw .16 retlw .21 retlw .26 retlw .32 ;--------------------------------------------------------------- init ;--------------------------------------------------------------- ; I/O portit kuntoon movlw b'10000000' ;RB7=sisään, RB0..6=ulos tris portb movlw b'00011111' ;RA0..4=sisään tris porta movlw .0 ;Port A lähdöt nollille movwf porta ; movlw 0x00 ;Port B ledit päälle movwf portb ; movlw 0x00 ;esiopastinvilkun tila on 0 movwf Flasher_ramp ; return ;--------------------------------------------------------------- ; Brighten OPASTINLAMPPUA ;--------------------------------------------------------------- Brighten movwf FSR ;op_in-rek w->Indirectiin incfsz INDF, W ;Brighten Sg_in ->w, ympäri? movwf INDF ;ei, akusta Sg_in-rek:iin ; call Sg_out ;kopioi Sg_in->Sg_out return ;--------------------------------------------------------------- ; HIMMENNÄ OPASTINLAMPPUA ;--------------------------------------------------------------- Dimm movwf FSR ;Sg_in-rek w->Indirectiin movf INDF, W ;kopioi akkuun, skpz ;oliko nolla decf INDF, F ;ei, himmennä Sg_in-rek:iä ; call Sg_out ;kopioi Sg_in->Sg_out return ;--------------------------------------------------------------- ; Sg_IN -> Sg_OUT ACHTUNG: FSR pitää sis. oikean IN_rekisterin ;--------------------------------------------------------------- Sg_out btfss INDF, 7 ;onko Sg_in ylätavu 1 (set)? goto Sg_out_0 ;ei ole, pidetään Sg_out pimeänä rlf INDF, f ;yläbitti pois swapf INDF, W ;swappaa ylä-alatavut, akkuun rrf INDF, f ;yläbitti takaisin incf FSR, f ;muut osoitus Sg_in->Sg_out andlw 0xF ;maskaa ylätavu pois call Lookup ;muunna x3 -käyräksi movwf INDF ;ja työnnö Sg_out:iin return Sg_out_0 incf FSR, f ;muut osoitus Sg_in->Sg_out movlw 0x0 ;opastin pimeäksi movwf INDF ;ja pimeä Sg_out:iin return ;----------------------------------------------------------------------------- ;Tarkista Twin-T ;----------------------------------------------------------------------------- ; jos lähtö ja tulo-opastin punaiset ->Twin-T pois ; jos juna -> Twin-T päälle Check_TwinT btfss Starter_sw ;onko Lahtökytkin seis (set=seis) goto Check_train ;ei, tarkista juna btfss Home_sw ;onko Tulokytkin seis (set=seis) goto Check_train ;ei, tarkista juna bcf TwinT_status ;on Twin-T: ei junaa (clear) return Check_train btfss TwinT_in ;onko Twin-T (set=ei junaa)? bsf TwinT_status ;on, Twin-T punaiseksi (set) return ;----------------------------------------------------------------------------- ;PWM-BIT-LOOP ;----------------------------------------------------------------------------- PWM_bit_loop bsf Out_byte, 0 ;tämän lampun valo oletusarv. pois tstf INDF ;onko tätä Sg_out:ia skpnz ;eihän vielä sammutettava (zero)? goto PWM_bit_next ;ei vielä decf INDF, f ;vähennetään bcf Out_byte, 0 ;ja sytytetään lamppu PWM_bit_next rlf Out_byte, f incf FSR, f ;indirect osoittamaan incf FSR, f ;seur. Sg_out:iin decfsz Out_bit, f ;joko viimeinen ulostulobitti? goto PWM_bit_loop ;ei, takaisin return ;kyllä ;--------------------------------------------------------------- ; Laske lähtöopastimet (L1..L3) ;--------------------------------------------------------------- Laske_lahto_opastimet Sg_St1 ;------------------------------------------------------- btfsc TwinT_status ;Onko raide vapaa (clear)? goto St1_halt ;ei, op->seis btfsc Starter_sw ;Onko Lähtökytkin vi(clear)? goto St1_halt ;ei, op->seis btfss Turnout2or3 ;Onko vaihteet raiteelle 2/3(set)? goto St1_halt ;on, op->seis btfsc Turnout1or3 ;Onko vaihteet raiteelle 1/3(clear)? goto St1_halt ;ei, op->seis St1_drive movlw St1_G_in call Brighten movlw St1_R_in call Dimm goto Sg_St2 St1_halt movlw St1_G_in call Dimm movlw St1_R_in call Brighten Sg_St2 ;------------------------------------------------------- btfsc TwinT_status ;Onko raide vapaa (clear)? goto St2_halt ;ei, op->seis btfsc Starter_sw ;Onko Lähtökytkin vi(clear)? goto St2_halt ;ei, op->seis btfss Turnout1or3 ;Onko vaihteet raiteelle 1/3(set)? goto St2_halt ;on, op->seis btfsc Turnout2or3 ;Onko vaihteet raiteelle 2/3(clear)? goto St2_halt ;ei, op->seis St2_drive movlw St2_G_in call Brighten movlw St2_R_in call Dimm goto Sg_St3 St2_halt movlw St2_G_in call Dimm movlw St2_R_in call Brighten Sg_St3 ;------------------------------------------------------- btfsc TwinT_status ;Onko raide vapaa (clear)? goto St3_halt ;ei, op->seis btfsc Starter_sw ;Onko Lähtökytkin vi(clear)? goto St3_halt ;ei, op->seis btfsc Turnout1or3 ;Onko vaihteet raiteelle 1/3(set)? ## goto St3_halt ;ei, op->seis btfsc Turnout2or3 ;Onko vaihteet raiteelle 2/3(set)? ## goto St3_halt ;ei, op->seis St3_drive movlw St3_G_in call Brighten movlw St3_R_in call Dimm return St3_halt movlw St3_G_in call Dimm movlw St3_R_in call Brighten return ;--------------------------------------------------------------- ; Laske tulo-opastin (Tu) ja esiopastimet ;--------------------------------------------------------------- Laske_tulo_opastimet Sg_Hm ;------------------------------------------------------- btfsc TwinT_status ;Onko raide vapaa (clear)? goto Hm_halt ;ei, op->seis btfsc Home_sw ;Onko Tulokytkin vi(clear)? goto Hm_halt ;ei, op->seis Hm_drive movlw Hm_G_in call Brighten movlw Hm_R_in call Dimm goto Sg_AdvSt Hm_halt movlw Hm_G_in call Dimm movlw Hm_R_in call Brighten Sg_AdvSt ;------------------------------------------------------- tstf Hm_R_in ;Testataan tulotolpan punaista skpz ;Onko edes häivähdys punaista (non-zero) goto AdvSt_dark ;ei, esipoastin sammutetaan btfss Flasher_status ;onko eisop.Flasher päällä (set) goto AdvSt_dark ;ei, esipoastin sammutetaan btfsc next_Starter ;onko seurLahto Vi(clear) goto AdvSt_next_halt ;ei esipoastin keltaiseksi AdvSt_next_drive movlw AdvSt_G_in call Brighten movlw AdvSt_Y_in call Dimm goto Sg_Te AdvSt_next_halt movlw AdvSt_G_in call Dimm movlw AdvSt_Y_in call Brighten goto Sg_Te AdvSt_dark movlw AdvSt_G_in call Dimm movlw AdvSt_Y_in call Dimm Sg_Te ;------------------------------------------------------- btfss Flasher_status ;onko eisop.Flasher päällä (set) goto AdvHm_dark ;ei, esipoastin sammutetaan tstf Hm_R_in ;Testataan tulotolppaa häivädys punaista? skpz ;Onko edes häivädys punaista? (non-zero) goto Te_odota_halt ;ei, esipoastin keltaiseksi Te_odota_drive movlw AdvHm_G_in call Brighten movlw AdvHm_Y_in call Dimm return Te_odota_halt movlw AdvHm_G_in call Dimm movlw AdvHm_Y_in call Brighten return AdvHm_dark movlw AdvHm_G_in call Dimm movlw AdvHm_Y_in call Dimm return ;--------------------------------------------------------------- ; Ohjataan ulostulot lähtö-opastimille Bit 6=1 ;--------------------------------------------------------------- Ulos_lahto_opastimet movlw B'01111111' ;Ulostulot oletusarvoisesti ylös(pimeä) movwf Ulos ;Ulostulot pimeäksi movlw 0x21 movwf PWM_Loop_Count Out_byte1 movlw St1_G_out ;Aletaan portin pienimmästä bitistä movwf FSR ;ja pannaan indirect-pointteriksi movlw B'01111111' ;Ulostulot oletusarvoisesti ylös(pimeä) movwf Out_byte ; movlw .6 ;kuinka monta bittiä kierretään movwf Out_bit ; call PWM_bit_loop ;Ja pannaan ulostulon bitit Out_byte:un rrf Out_byte,f ;vikan kierron jälkeen pitää palauttaa bsf Out_byte,6 ;valitaan lähtöopastimet movfw Out_byte ;ulostulotavu akkuun ja movwf Ulos ;ja ulostuloon call Viive decfsz PWM_Loop_Count,f goto Out_byte1 movlw B'00111111' ;Ulostulot oletusarvoisesti ylös(pimeä) movwf Ulos ;odottamaan tulo-opastimia (op-ampille aikaa) return ;--------------------------------------------------------------- ; Ohjataan ulostulot Tulo- ja esiopastimille (Bit 6=0) ;--------------------------------------------------------------- Ulos_tulo_opastimet movlw B'00111111' ;Ulostulot oletusarvoisesti ylös(pimeä) movwf Ulos ;Ulostulot pimeäksi movlw 0x21 movwf PWM_Loop_Count Out_byte2 movlw Hm_G_out ;Aletaan portin pienimmästä bitistä movwf FSR ;ja pannaan indirect-pointteriksi movlw B'00111111' ;Ulostulot oletusarvoisesti ylös(pimeä) movwf Out_byte ; movlw .6 ;kuinka monta bittiä kierretään movwf Out_bit ; call PWM_bit_loop ;Ja pannaan ulostulon bitit Out_byte:un rrf Out_byte,f ;vikan kierron jälkeen pitää palauttaa bcf Out_byte,6 ;valitaan tulo-opastin ja esiopastimet movfw Out_byte ;ulostulotavu akkuun ja movwf Ulos ;ja ulostuloon call Viive decfsz PWM_Loop_Count,f goto Out_byte2 movlw B'01111111' ;Ulostulot oletusarvoisesti ylös(pimeä) movwf Ulos ;odottamaan lähtö-opastimia (op-ampille aikaa) return ;--------------------------------------------------------------- ;VIIVESILMUKKA ;--------------------------------------------------------------- Viive movlw 0x01 ;kierrosmäärä ##### oli 0xFF movwf PWM_delay ;viivesilmukka Delay_loop nop nop nop decfsz PWM_delay, f ;Joko loopattu riittävästi goto Delay_loop ;ei return ;joo ;--------------------------------------------------------------- ;MAIN ;--------------------------------------------------------------- Main call Init ;aseta portit TRIS etc.... Loop call Check_TwinT ;tarkista, onko junia call Laske_lahto_opastimet call Laske_lahto_opastimet call Ulos_lahto_opastimet call Laske_tulo_opastimet call Laske_tulo_opastimet call Ulos_tulo_opastimet call Flasher call Flasher Goto Loop END