;************************************************************************ ; 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!) ; ; Raidekaavio L1 ; =========== /---<---- Raide 1 ; / L2 ; ->------>--------<---- Raide 2 ; Te Tu \ L3 ; Le \---<---- Raide 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) ; L1Vi/TuVi PORTB.0 <-|6 13|<- PORTB.7 Tulo ; L1Pu/TuPu PORTB.1 <-|7 12|-> PORTB.6 L/!T ; L2Vi/LeVi PORTB.2 <-|8 11|-> PORTB.5 L3Pu/TePu ; L2Pu/LePu PORTB.3 <-|9 10|-> PORTB.4 L3Vi/TeVi ; +---------+ ; ;************************ RAM ********************************************************* CBLOCK H'0C' L1Vi_in ;Opastin Raide 1 Vihreä L1Vi_out ;Opastin Raide 1 Vihreä L1Pu_in ;Opastin Raide 1 Punainen L1Pu_out ;Opastin Raide 1 Punainen L2Vi_in ;Opastin Raide 2 Vihreä L2Vi_out ;Opastin Raide 2 Vihreä L2Pu_in ;Opastin Raide 2 Punainen L2Pu_out ;Opastin Raide 2 Punainen L3Vi_in ;Opastin Raide 3 Vihreä L3Vi_out ;Opastin Raide 3 Vihreä L3Pu_in ;Opastin Raide 3 Punainen L3Pu_out ;Opastin Raide 3 Punainen TuVi_in ;Tulo-opastin Vihreä TuVi_out ;Tulo-opastin Vihreä TuPu_in ;Tulo-opastin Punainen TuPu_out ;Tulo-opastin Punainen LeVi_in ;Lähtö-esiopastin Vihreä LeVi_out ;Lähtö-esiopastin Vihreä LeKe_in ;Lähtö-esiopastin keltainen LeKe_out ;Lähtö-esiopastin keltainen TeVi_in ;Tulo-esiopastin Vihreä TeVi_out ;Tulo-esiopastin Vihreä TeKe_in ;Tulo-esiopastin keltainen TeKe_out ;Tulo-esiopastin keltainen Apu ;apumuuttuja, bittietoa: ; 0=Twin-T:n tila ; 1=Lähtö/Tulo päällä ; 2=Esiopastinvilkun tila Vilkku_ramppi ;Esiopastimen ramppi Ulos_tavu ;port b:n tuleva tila Ulos_bit ;mitä bittiä ylläolevasta säädetään Pwm_viive ;PWM:n venyttäjä Pwm_Loop_Count ;PWM-laskuri ENDC #DEFINE Tulo_Kytkin PORTB, 7 #DEFINE Lahto_Kytkin PORTA, 0 #DEFINE Seur_Lahto PORTA, 1 #DEFINE Vaihde1t3 PORTA, 2 #DEFINE Vaihde2t3 PORTA, 3 #DEFINE TwinT_in PORTA, 4 #DEFINE TwinT_tila Apu, 0 #DEFINE LT Apu, 1 #DEFINE Vilkku_tila 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! Vilkku incfsz Vilkku_ramppi,f ;kasvata vilkkuramppia, menikö ympäri goto Vilkku_paalle ;ei Vilkku_pois bcf Vilkku_tila ;kyllä, (ramppi=0) ->valo pois (clear) return Vilkku_paalle btfsc Vilkku_tila ;(ramppi 1..255) oliko valo pois (clear) return ;ei, jatketaan btfss Vilkku_ramppi,7 ;kyllä, onko rampin bitti 7 "1" (set) return ;ei (ramppi = 0 ..127), ei muutoksia bsf Vilkku_tila ;kyllä (ramppi = 128..255), valo päälle (set) movlw 0x0 ;nolla akkuun ja movwf Vilkku_ramppi ;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 Vilkku_Ramppi ; return ;--------------------------------------------------------------- ; KIRKASTA OPASTINLAMPPUA ;--------------------------------------------------------------- Kirkasta movwf FSR ;op_in-rek w->Indirectiin incfsz INDF, W ;kirkasta op_in ->w, ympäri? movwf INDF ;ei, akusta op_in-rek:iin ; call Op_out ;kopioi op_in->op_out return ;--------------------------------------------------------------- ; HIMMENNÄ OPASTINLAMPPUA ;--------------------------------------------------------------- Himmenna movwf FSR ;op_in-rek w->Indirectiin movf INDF, W ;kopioi akkuun, skpz ;oliko nolla decf INDF, F ;ei, himmennä op_in-rek:iä ; call Op_out ;kopioi op_in->op_out return ;--------------------------------------------------------------- ; OP_IN -> OP_OUT ACHTUNG: FSR pitää sis. oikean IN_rekisterin ;--------------------------------------------------------------- Op_out btfss INDF, 7 ;onko op_in ylätavu 1 (set)? goto op_out_0 ;ei ole, pidetään op_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 op_in->op_out andlw 0xF ;maskaa ylätavu pois call Lookup ;muunna x3 -käyräksi movwf INDF ;ja työnnö op_out:iin return Op_out_0 incf FSR, f ;muut osoitus op_in->op_out movlw 0x0 ;opastin pimeäksi movwf INDF ;ja pimeä op_out:iin return ;----------------------------------------------------------------------------- ;Tarkista Twin-T ;----------------------------------------------------------------------------- ; jos lähtö ja tulo-opastin punaiset ->Twin-T pois ; jos juna -> Twin-T päälle Tarkista_TwinT btfss Lahto_kytkin ;onko Lahtökytkin seis (set=seis) goto Tarkista_juna ;ei, tarkista juna btfss Tulo_kytkin ;onko Tulokytkin seis (set=seis) goto Tarkista_juna ;ei, tarkista juna bcf TwinT_tila ;on Twin-T: ei junaa (clear) return Tarkista_juna btfss TwinT_in ;onko Twin-T (set=ei junaa)? bsf TwinT_Tila ;on, Twin-T punaiseksi (set) return ;----------------------------------------------------------------------------- ;PWM-BIT-LOOP ;----------------------------------------------------------------------------- Pwm_bit_loop bsf Ulos_tavu, 0 ;tämän lampun valo oletusarv. pois tstf INDF ;onko tätä op_out:ia skpnz ;eihän vielä sammutettava (zero)? goto Pwm_bit_seur ;ei vielä decf INDF, f ;vähennetään bcf Ulos_tavu, 0 ;ja sytytetään lamppu pwm_bit_seur rlf Ulos_tavu, f incf FSR, f ;indirect osoittamaan incf FSR, f ;seur. op_out:iin decfsz Ulos_bit, f ;joko viimeinen ulostulobitti? goto Pwm_bit_loop ;ei, takaisin return ;kyllä ;--------------------------------------------------------------- ; Laske lähtöopastimet (L1..L3) ;--------------------------------------------------------------- Laske_lahto_opastimet Op_L1 ;------------------------------------------------------- btfsc TwinT_Tila ;Onko raide vapaa (clear)? goto L1_seis ;ei, op->seis btfsc Lahto_Kytkin ;Onko Lähtökytkin vi(clear)? goto L1_seis ;ei, op->seis btfss Vaihde2t3 ;Onko vaihteet raiteelle 2/3(set)? goto L1_seis ;on, op->seis btfsc Vaihde1t3 ;Onko vaihteet raiteelle 1/3(clear)? goto L1_seis ;ei, op->seis L1_aja movlw L1Vi_in call Kirkasta movlw L1Pu_in call Himmenna goto Op_L2 L1_seis movlw L1Vi_in call Himmenna movlw L1Pu_in call Kirkasta Op_L2 ;------------------------------------------------------- btfsc TwinT_Tila ;Onko raide vapaa (clear)? goto L2_seis ;ei, op->seis btfsc Lahto_Kytkin ;Onko Lähtökytkin vi(clear)? goto L2_seis ;ei, op->seis btfss Vaihde1t3 ;Onko vaihteet raiteelle 1/3(set)? goto L2_seis ;on, op->seis btfsc Vaihde2t3 ;Onko vaihteet raiteelle 2/3(clear)? goto L2_seis ;ei, op->seis L2_aja movlw L2Vi_in call Kirkasta movlw L2Pu_in call Himmenna goto Op_L3 L2_seis movlw L2Vi_in call Himmenna movlw L2Pu_in call Kirkasta Op_L3 ;------------------------------------------------------- btfsc TwinT_Tila ;Onko raide vapaa (clear)? goto L3_seis ;ei, op->seis btfsc Lahto_Kytkin ;Onko Lähtökytkin vi(clear)? goto L3_seis ;ei, op->seis btfss Vaihde1t3 ;Onko vaihteet raiteelle 1/3(set)? goto L3_seis ;ei, op->seis btfss Vaihde2t3 ;Onko vaihteet raiteelle 2/3(set)? goto L3_seis ;ei, op->seis L3_aja movlw L3Vi_in call Kirkasta movlw L3Pu_in call Himmenna return L3_seis movlw L3Vi_in call Himmenna movlw L3Pu_in call Kirkasta return ;--------------------------------------------------------------- ; Laske tulo-opastin (Tu) ja esiopastimet ;--------------------------------------------------------------- Laske_tulo_opastimet Op_Tu ;------------------------------------------------------- btfsc TwinT_Tila ;Onko raide vapaa (clear)? goto Tu_seis ;ei, op->seis btfsc Tulo_Kytkin ;Onko Tulokytkin vi(clear)? goto Tu_seis ;ei, op->seis Tu_aja movlw TuVi_in call Kirkasta movlw TuPu_in call Himmenna goto Op_Le Tu_seis movlw TuVi_in call Himmenna movlw TuPu_in call Kirkasta Op_Le ;------------------------------------------------------- tstf TuPu_in ;Testataan tulotolpan punaista skpz ;Onko edes häivähdys punaista (non-zero) goto Le_pimea ;ei, esipoastin sammutetaan btfss vilkku_tila ;onko eisop.vilkku päällä (set) goto Le_pimea ;ei, esipoastin sammutetaan btfsc Seur_Lahto ;onko seurLahto Vi(clear) goto Le_odota_seis ;ei esipoastin keltaiseksi Le_odota_aja movlw LeVi_in call Kirkasta movlw LeKe_in call Himmenna goto Op_Te Le_odota_seis movlw LeVi_in call Himmenna movlw LeKe_in call Kirkasta goto Op_Te Le_pimea movlw LeVi_in call Himmenna movlw LeKe_in call Himmenna Op_Te ;------------------------------------------------------- btfss vilkku_tila ;onko eisop.vilkku päällä (set) goto Te_pimea ;ei, esipoastin sammutetaan tstf TuPu_in ;Testataan tulotolppaa häivädys punaista? skpz ;Onko edes häivädys punaista? (non-zero) goto Te_odota_seis ;ei, esipoastin keltaiseksi Te_odota_aja movlw TeVi_in call Kirkasta movlw TeKe_in call Himmenna return Te_odota_seis movlw TeVi_in call Himmenna movlw TeKe_in call Kirkasta return Te_pimea movlw TeVi_in call Himmenna movlw TeKe_in call Himmenna 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 L1Vi_out ;Aletaan portin pienimmästä bitistä movwf FSR ;ja pannaan indirect-pointteriksi movlw B'01111111' ;Ulostulot oletusarvoisesti ylös(pimeä) movwf Ulos_tavu ; movlw .6 ;kuinka monta bittiä kierretään movwf Ulos_bit ; call Pwm_bit_loop ;Ja pannaan ulostulon bitit Ulos_tavu:un rrf Ulos_Tavu,f ;vikan kierron jälkeen pitää palauttaa bsf Ulos_tavu,6 ;valitaan lähtöopastimet movfw Ulos_tavu ;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 TuVi_out ;Aletaan portin pienimmästä bitistä movwf FSR ;ja pannaan indirect-pointteriksi movlw B'00111111' ;Ulostulot oletusarvoisesti ylös(pimeä) movwf Ulos_tavu ; movlw .6 ;kuinka monta bittiä kierretään movwf Ulos_bit ; call Pwm_bit_loop ;Ja pannaan ulostulon bitit Ulos_tavu:un rrf Ulos_Tavu,f ;vikan kierron jälkeen pitää palauttaa bcf Ulos_tavu,6 ;valitaan tulo-opastin ja esiopastimet movfw Ulos_tavu ;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_viive ;viivesilmukka Viive_loop nop nop nop decfsz pwm_viive, f ;Joko loopattu riittävästi goto Viive_loop ;ei return ;joo ;--------------------------------------------------------------- ;MAIN ;--------------------------------------------------------------- Main call Init ;aseta portit TRIS etc.... Loop call Tarkista_TwinT ;tarkista, onko junia call Laske_lahto_opastimet call Ulos_lahto_opastimet call Laske_tulo_opastimet call Ulos_tulo_opastimet call vilkku call vilkku Goto Loop END