;******************************************************************** ;* Program frekvencmetra za QRP radijsko postajo. * ;* f (Q) = 4000 kHz * ;* Prikaz na 4 cifernem 7 segmentnem LED prikazu. * ;* MC14499 7 segment LED display driver, 93C46 EEPROM. * ;******************************************************************** SUBTITL "Program merilnik frekvence za radijsko postajo" LIST P=16C71,N=40,C=132 ;******************************************************************** ;* PIC interni registri. * ;******************************************************************** indir equ 0x00 ; Use this register as source/destination for ; indirect addressing. rtcc equ 0x01 ; real time clock counter pcl equ 0x02 ; PIC programski stevec status equ 0x03 ; PIC statusni register fsr equ 0x04 ; File Select Register porta equ 0x05 ; port A data register trisa equ 0x05 ; port A data direction register portb equ 0x06 ; port B data register trisb equ 0x06 ; port B data direction register adcon0 equ 0x08 ; kontrolni register 0 A/D pretvornika adcon1 equ 0x08 ; kontrolni register 1 A/D pretvornika adres equ 0x09 ; rezultat A/D pretvorbe pclath equ 0x0A ; PC latch hi intcon equ 0x0B ; interrupt control register carry equ 0 ; Carry Flag of Status Register. zflag equ 2 ; Zero Flag of Status Register. rp0 equ 5 ; Register page select bit irp equ 7 ; General purpose bit (only 16c84) !!!!!!!! w equ 0 ; Work register f equ 1 ; file register (data RAM) rtif equ 2 ; RTCC overflow interrupt flag rtie equ 5 ; RTIF interrupt enable bit gie equ 7 ; global interrupt enable go equ 2 ; GO/DONE bit A/D pretvornika adon equ 0 ; A/D on control bit ;******************************************************************** ;* Pomnilne lokacije v file registrih. * ;******************************************************************** uni_01 equ 0x0C ; univerzalna pomnilna lokacija uni_02 equ 0x0D ; univerzalna pomnilna lokacija uni_03 equ 0x0E ; univerzalna pomnilna lokacija uni_04 equ 0x0F ; univerzalna pomnilna lokacija adr_1 equ 0x10 adr_0 equ 0x11 op0_3 equ 0x12 ; hi byte operanda 0 op0_2 equ 0x13 ; op0_1 equ 0x14 ; op0_0 equ 0x15 ; low byte operanda 0 op1_3 equ 0x16 ; hi byte operanda 1 op1_2 equ 0x17 ; op1_1 equ 0x18 ; op1_0 equ 0x19 ; low byte operanda 1 cifra_1 equ 0x1A ; najnizja cifra prikaza - enice cifra_2 equ 0x1B ; desetice cifra_3 equ 0x1C ; stotice cifra_4 equ 0x1D ; tisocice cifra_5 equ 0x1E ; desettisocice cifra_6 equ 0x1F ; stotisocice c_ofl equ 0x20 ; prepolnitev stevca frekvence c_hi equ 0x21 ; visji byte stevca frekvence c_low equ 0x22 ; nizji byte stevca frekvence c_oflex equ 0x23 ; stara vred. prepolnitve stevca frekvence c_hiex equ 0x24 ; stara vred. visji byte stevca frekvence c_lowex equ 0x25 ; stara vred. nizji byte stevca frekvence dis_mod equ 0x26 stev_t equ 0x27 ; Stevec pri delu s tipko nap_ex equ 0x28 ; Stara vrednost izmerjene napetosti portb_ex equ 0x29 ; Vrednost na portu B pri predhodnem vzorcenju. offs_h equ 0x2A ; Vrednost offseta, visji byte. offs_m equ 0x2B ; Sredni byte. offs_l equ 0x2C ; Vrednost offseta, nizji byte. flags equ 0x2F ; razne zastavice krat_p equ 0 ; Zastavica krat. prit. na tipko (flags) dolg_p equ 1 ; Zastavica dolg. prit. na tipko (flags) blokada equ 2 ; Blokada tipke ;******************************************************************** ;* Periferija. * ;******************************************************************** ; ------------------------------------------------------------------ ;| PORT B | ; ------------------------------------------------------------------ jmp_2 equ 7 ; Jumper 2 jmp_1 equ 6 ; Jumper 1 dis_en equ 5 ; Enable vhod display driverja tipka equ 4 ; Vhod za tipko ee_cs equ 3 ; Chip select EEPROMA clk equ 2 ; Clock serijskega perifernega vodila din equ 1 ; Data vhod periferije (ser. perif. vodilo) dout equ 0 ; Data izhod periferije (ser. vodilo) ; ------------------------------------------------------------------ ;| PORT A | ; ------------------------------------------------------------------ f_in equ 4 ; frekvencni vhod ... PA4/RTCC f_ov equ 3 ; impulzi za overflov precounterja ... PA3 f_en equ 2 ; freq. vhod enable ... PA2 ;******************************************************************** ;* Reset in prekinitveni vektor. * ;******************************************************************** org 0x0000 goto reset ;******************************************************************** ;* Zacetek programa. * ;******************************************************************** reset clrf pclath clrf intcon ; pobrisem vse zahteve za prekinitev clrwdt movlw b'01100111' ; bit0, bit1, bit2: RTCC prescaler rate 1:256 ; bit3: prescaler assigned to RTC ; bit4: presc. inc. on low to hi ; bit5: RTCC source: trans. on RTCC pin ; bit6: INT on rising edge ; bit7: port B pull-ups enabled option clrwdt ;******************************************************************** ;* Inicializacija vhodov/izhodov * ;******************************************************************** movlw b'11110001' ; Jp2, Jp1, EN, Key, CS, CK, DI, DO movwf portb movlw b'11111011' ; f_en=low, f_ov=hi movwf porta bsf status,rp0 ; dostop do gornje polovice file registrov movlw b'11110001' ; konfiguracija port A movwf trisa movlw b'00000010' ; PA0 analog. vhod, ostali dig I/O movwf adcon1 ; za Vref uporabljen Vdd movlw b'11010001' ; konfiguracija port B movwf trisb bcf status,rp0 ; ponovno dostop do spod. polov. file regist. ;******************************************************************** ;* Glavna zanka v rezimu delovanja. * ;******************************************************************** clrf c_ofl ; spraznim stevec prepolnitve clrf c_hi ; hi byte stevca frekvence clrf c_low ; low byte stevca frekvence clrf c_oflex ; spraznim stari stevec prepolnitve clrf c_hiex ; hi byte starega stevca frekvence clrf c_lowex ; low byte starega stevca frekvence clrf nap_ex ; stara vrednost napetosti clrf flags ; pobrisem vse mogoce zastavice clrf stev_t ; brisem stevec tipke bcf porta,f_en ; frekvencni vhod disabled bsf porta,f_ov ; ni pulza za dosego prepolnitve call read_offset ; Offset precitam iz EEPROMa btfsc portb,tipka ; Pritisnjena tipka? Da, preskoci goto ini_mode_03 ; Ne, pojdi v normalni delovni rezim. movlw 0x26 ; Mode nastavitve parametrov, nastavitev movwf dis_mod ; najvisje (6.) cifre. movf offs_l,w movwf op0_0 movf offs_m,w movwf op0_1 movf offs_h,w movwf op0_2 call hex_bcd ; Offset pretvorim iz HEX oblike v BCD. movlw 0x15 ; 21, najvecja vrednost stevca tipke movwf stev_t ; Stevec tipke dam na najvecjo vrednost bsf flags,blokada ; Blokiram tipko goto ini_mode_26 ini_mode_03 movlw 0x03 ; Privzeti nacin prikaza 1 (kkk.H) v movwf dis_mod ; "normalnem" delovnem nacinu ini_mode_26 call dis_test ; Testiranje LED prikaza zanka movf portb,w ; Vzorcim vrednosti na portb in movwf portb_ex ; shranim za kasnejso primerjavo. call meri_freq ; izvrsim meritev frekvence call freq_hist ; upostevam histerezo prikaza call freq_offset ; Pristevanje / odstevanje frek. odmika call det_pb ; Preveri pritisnjenost tipke in ukrepaj. movf dis_mod,w andlw 0xF0 ; Izlocim bite, ki odlocajo o prikazu napet. sublw 0x10 ; Prikazni nacin 1x = prikaz napetosti? btfsc status,zflag ; Ne, preskoci. goto gl_u_nap ; Da, izmeri in prikazi napetost napajanja. movf dis_mod,w andlw 0xF0 ; Izlocim bite, ki odlocajo o prikazu napet. sublw 0x20 ; Prikazni nacin 2x? btfsc status,zflag ; Ne, preskoci in prikazi izmerjeno frekvenco. goto gl_offset ; Da, prikaz offseta. movf portb,w ; Vzorcim vrednosti na portb in xorwf portb_ex,f ; Primerjam s staro vrednostjo btfsc portb_ex,jmp_1 ; Ce ni spremembe na jmp_1, potem preskoci. goto zanka_ok ; Ce je, potem v tem ciklu ne prikazi nove f. call dis_freq ; prikazi frekvenco goto zanka_ok gl_u_nap call meas_dis_u ; Podprogram izmeri in prikaze napetost napajanja. goto zanka_ok gl_offset call dis_offset ; Prikaz frekvencnega offseta goto zanka_ok zanka_ok goto zanka ;******************************************************************** ;* Podprogram preverja pritisnjenost tipke in prozi akcije. * ;******************************************************************** det_pb btfsc portb,tipka ; Ali je pritisnjena tipka? goto det_pb_t1 ; Ne movf stev_t,w ; Da. bcf status,zflag sublw 0x15 ; Ali je stanje stevca tipke 21 ? btfss status,zflag ; Da, ne povecujem. incf stev_t,f ; Se ne, povecam stanje stevca. movf stev_t,w bcf status,zflag sublw 0x14 ; Ali je stanje stevca 20 ? btfsc status,zflag ; Ne, nic ne ukrepam bsf flags,dolg_p ; Da, oznacim dolg pritisk na tipko btfsc status,zflag ; Ne, nic ne ukrepam bsf flags,blokada ; Da, oznacim blokado tipke goto det_pb_t_ok ; Koncam z opazovanjem tipke det_pb_t1 movf stev_t,w ; bsf status,carry sublw 0x01 ; Ali je stanje stevca tipke > 1? btfsc status,carry ; Da, preskocim goto det_pb_no_t ; Ne, stejem da tipka ni bila pritisnjena btfsc flags,blokada ; Tipka blokirana? Ce ne, preskocim goto det_pb_no_t ; Da, deblokiram tipko. bsf flags,krat_p ; Ne, oznacim kratek pritisk na tipko bsf flags,blokada ; Blokiram tipko do naslednjic goto det_pb_t_ok ; Koncam z opazovanjem tipke det_pb_no_t clrf stev_t ; Iznicim stevec pritisnjenosti tipke bcf flags,blokada ; Deblokiram tipko det_pb_t_ok movf dis_mod,w sublw 0x01 ; Prikazni nacin 1? btfsc status,zflag ; Ne, testiraj dalje. goto det_pb_x_xxx ; Da, prikaz frekvence v obliki M.kkk movf dis_mod,w sublw 0x02 ; Prikazni nacin 2? btfsc status,zflag ; Ne, testiraj dalje. goto det_pb_xx_xx ; Da, prikaz f v obliki MM.kk movf dis_mod,w sublw 0x03 ; Prikazni nacin 3? btfsc status,zflag ; Ne, testiraj dalje. goto det_pb_xxx_x ; Da, prikaz f v obliki kkk.H movf dis_mod,w andlw 0xF0 ; Izlocim bite, ki odlocajo o prikazu napet. sublw 0x10 ; Prikazni nacin 1x? btfsc status,zflag ; Ne, testiraj dalje. goto det_pb_u_nap ; Da, prikaz napetost napajanja. movf dis_mod,w andlw 0xF0 ; Izlocim bite, ki odlocajo o prikazu napet. sublw 0x20 ; Prikazni nacin 2x? btfsc status,zflag ; Ne, testiraj dalje. goto det_pb_n_ofst ; Da, prikaz nastavljanega parametra. goto reset ; Mozno le ob napaki. ; ------------------------------------------------------------------ ;| Mode prikaza freq X.XXX MHz, prikazni nacin 01. | ; ------------------------------------------------------------------ det_pb_x_xxx btfss flags,krat_p ; Zastavica kratkega pritiska tipke postavljena? goto det_pb_x_xxx_s1 ; Ne. movlw 0x11 ; Da, iz prikaznega nacina 1, grem v movwf dis_mod ; prikazni nacin prikaza napetosti (11). goto det_pb_x_xxx_s2 det_pb_x_xxx_s1 btfss flags,dolg_p ; Zastavica dolgega pritiska tipke postavljena? goto det_pb_x_xxx_s2 ; Ne. movlw 0x02 ; Da. movwf dis_mod ; Prehod v prikazni nacin 2. det_pb_x_xxx_s2 bcf flags,krat_p ; Akcija izvrsena, pobrisem zastavice. bcf flags,dolg_p goto det_pb_ret ; ------------------------------------------------------------------ ;| Mode prikaza freq. XX.XX MHz, prikazni nacin 02. | ; ------------------------------------------------------------------ det_pb_xx_xx btfss flags,krat_p ; Zastavica kratkega pritiska tipke postavljena? goto det_pb_xx_xx_s1 ; Ne. movlw 0x12 ; Da, iz prikaznega nacina 2, grem v movwf dis_mod ; prikazni nacin prikaza napetosti (12). goto det_pb_xx_xx_s2 det_pb_xx_xx_s1 btfss flags,dolg_p ; Zastavica dolgega pritiska tipke postavljena? goto det_pb_xx_xx_s2 ; Ne. movlw 0x03 ; Da. movwf dis_mod ; Prehod v prikazni nacin 3. det_pb_xx_xx_s2 bcf flags,krat_p ; Akcija izvrsena, pobrisem zastavice. bcf flags,dolg_p goto det_pb_ret ; ------------------------------------------------------------------ ;| Mode prikaza freq. XXX.X kHz, prikazni nacin 03. | ; ------------------------------------------------------------------ det_pb_xxx_x btfss flags,krat_p ; Zastavica kratkega pritiska tipke postavljena? goto det_pb_xxx_x_s1 ; Ne. movlw 0x13 ; Da, iz prikaznega nacina 3, grem v movwf dis_mod ; prikazni nacin prikaza napetosti (13). goto det_pb_xxx_x_s2 det_pb_xxx_x_s1 btfss flags,dolg_p ; Zastavica dolgega pritiska tipke postavljena? goto det_pb_xxx_x_s2 ; Ne. movlw 0x01 ; Da. movwf dis_mod ; Prehod v prikazni nacin 1. det_pb_xxx_x_s2 bcf flags,krat_p ; Akcija izvrsena, pobrisem zastavice. bcf flags,dolg_p goto det_pb_ret ; ------------------------------------------------------------------ ;| Mode prikaza napetosti delovanja, prikazni nacin 1x. | ; ------------------------------------------------------------------ det_pb_u_nap btfsc flags,krat_p ; Zastavica kratkega pritiska tipke postavljena? goto dis_u_nap_s1 ; Da. btfsc flags,dolg_p ; Zastavica dolgega pritiska tipke postavljena? goto dis_u_nap_s1 ; Da. goto dis_u_nap_s2 ; Nobene akcije dis_u_nap_s1 bcf dis_mod,4 ; Iz prikaznega nacina Unap grem nazaj ; v nacin prikaza napetosti. dis_u_nap_s2 bcf flags,krat_p ; Akcija izvrsena, pobrisem zastavice. bcf flags,dolg_p goto det_pb_ret ; ------------------------------------------------------------------ ;| Mode prikaza nastavljanega offseta, prikazni nacin 2x. | ; ------------------------------------------------------------------ det_pb_n_ofst btfsc flags,krat_p ; Zastavica kratkega pritiska tipke postavljena? goto dis_n_ofst_s1 ; Da. btfsc flags,dolg_p ; Zastavica dolgega pritiska tipke postavljena? goto dis_n_ofst_s2 ; Da. goto dis_n_ofst_ok ; Nobene akcije dis_n_ofst_s1 movf dis_mod,w ; Prikazni nacin andlw 0x0F ; Izlocim gornje 4 bite (2x --> 0x, x = 1..6) addlw cifra_1 ; Pristejem naslov najnizje nastavljane cifre. movwf fsr ; Lokacija za posredno naslavljanje decf fsr,f ; Naslov korigiram (cifra_1 ima odmik 0). movf indir,w ; Precitam vrednost nastavljane cifre. addlw 0x01 ; Povecam vrednost nastavljane cifre za 1. andlw 0x0F ; Omejim na 0..15. movwf indir ; Shranim nazaj. sublw 0x0A ; Preverim, ali nova vrednost = 10. btfsc status,zflag ; Ni, Vrednost OK, preskoci. clrf indir ; Je, postavim vrednost nastavljane cifre na 0. goto dis_n_ofst_ok ; Konec akcije. dis_n_ofst_s2 decf dis_mod,f ; Prikaz /nastavitev naslednje cifre offseta. movf dis_mod,w ; Preverim, ali je morda mode = 20? andlw 0x0F ; V ta namen postavim gornje 4 bite na "low". btfss status,zflag ; Ce W = 0, potem mode = 20. goto dis_n_ofst_ok ; mode <> 20, akcija zakljucena movlw 0x0E ; Izpisem -.-.-.- movwf op1_3 movwf op1_2 movwf op1_1 movwf op1_0 movlw b'00001110' movwf op0_0 ; Prizgem prve 3 decimalne pike. call display call bcd_hex ; Nastavljene cifre pretvorim v HEX. call write_offset ; Vpis offseta v EEPROM. movlw 0x03 ; Grem v normalni nacin delovanja. movwf dis_mod movlw 0x64 movwf uni_03 ; Stevec zakasnilne zanke 100 x 10ms dis_n_ofst_z1 call pavza_10 ; Pavza poskrbi za boljsi "vtis". decfsz uni_03,f goto dis_n_ofst_z1 dis_n_ofst_ok bcf flags,krat_p ; Akcija izvrsena, pobrisem zastavice. bcf flags,dolg_p goto det_pb_ret ; ------------------------------------------------------------------ ;| Vrnitev iz podprograma. | ; ------------------------------------------------------------------ det_pb_ret return ;******************************************************************** ;* Podprogram izmeri frekvenco. * ;******************************************************************** meri_freq bcf porta,f_en ; f_en <-- low (frek. vhod disabled) bsf porta,f_ov ; izhod za gener. ofl. pulzov v nevtal. stan. clrf c_ofl clrf rtcc clrf intcon movlw 0x050 ; 80x((99x10)+10)+1+korekcija od bsf do vkljuc. bcf f_en movwf uni_01 ; stevec zunanje zanke bsf porta,f_en ; zacnem s stetjem frekvence f_en <-- hi meri_f_z1z movlw 0x63 ; stevec notranje zanke (99 ciklov) movwf uni_02 nop ; 1 nop ; 1 nop ; 1 nop ; 1 nop ; 1 nop ; 1 meri_f_z1n movf intcon,w ; 1 movwf uni_03 ; 1 btfsc uni_03,rtif ; 1 (2) prepolnitev RTCC ?, ce ne, potem preskoci incf c_ofl,f ; 1 (0) ce da, povecaj stevec prepolnitve btfsc uni_03,rtif ; 1 (2) ce ne, potem preskoci bcf intcon,rtif ; 1 (0) ce da, resetiraj RTCC interrupt. flag nop ; 1 decfsz uni_02,f ; 1 (2) goto meri_f_z1n ; 2 (0) decfsz uni_01,f ; 1 (2) goto meri_f_z1z ; 2 (0) ; ------------------------------------------------------------------ ;| Morebitni popravki "casovne baze". | ; ------------------------------------------------------------------ nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. nop ; Korekcija zaradi netocnosti oscilatorja. bcf porta,f_en ; koncam s stetjem frekvence movf intcon,w ; movwf uni_03 ; btfsc uni_03,rtif ; prepolnitev RTCC ?, ce ne, potem preskoci incf c_ofl,f ; ce da, povecaj stevec prepolnitve btfsc uni_03,rtif ; ce ne, potem preskoci bcf intcon,rtif ; ce da, resetiraj RTCC interrupt. flag movf rtcc,w ; hi byte prestetih vhodnih impulzov movwf c_hi ; shranim movwf uni_03 ; rabim za primerjavo clrf c_low ; nizji byte prestetih vhodnih impulzov meri_f_z2 decf c_low,f ; manjka se en impulz do prepolnitve presc. bcf porta,f_ov ; naredim pozitivni impulz na vhod RTCC nop nop nop nop nop nop bsf porta,f_ov movf rtcc,w subwf uni_03,w btfss status,zflag ; 1 (2) inc. RTCC ? ce ne, potem preskoci goto meri_f_prsc_ok ; prescaler znova resetiran, c_low ok goto meri_f_z2 meri_f_prsc_ok return ;******************************************************************** ;* Podprogram izvrsi histerezo prikaza izmerjene vrednosti, * ;* in preracuna rezultat iz 12,5Hz resolucije na 100Hz resoluc.* ;******************************************************************** freq_hist movf c_low,w movwf op0_0 movf c_hi,w movwf op0_1 movf c_ofl,w movwf op0_2 clrf op0_3 movf c_lowex,w movwf op1_0 movf c_hiex,w movwf op1_1 movf c_oflex,w movwf op1_2 clrf op1_3 movlw op0_0 movwf adr_0 movlw op1_0 movwf adr_1 call cmp_32 btfsc status,zflag ; rezultat primerjave enak nic? ne, preskoci goto freq_hist_ceq ; da, enak prikaz kot v prejsnjem ciklu btfsc status,carry ; nova vrednost vecja od stare? ne, preskoci goto freq_hist_cgt ; da, odstej od nove vred. 1 in prikazi goto freq_hist_cls ; nova vred. manj. od stare, dodaj 1 in prikazi freq_hist_ceq nop ; prikazana vrednost enaka izmerjeni goto freq_hist_cok freq_hist_cgt movlw 0x01 movwf op1_0 clrf op1_1 clrf op1_2 clrf op1_3 movlw op0_0 movwf adr_0 movlw op1_0 movwf adr_1 call sub_32 ; prikazana vrednost za 1 manjsa od izmerjene goto freq_hist_cok freq_hist_cls movlw 0x01 movwf op1_0 clrf op1_1 clrf op1_2 clrf op1_3 movlw op0_0 movwf adr_0 movlw op1_0 movwf adr_1 call add_32 ; prikazana vrednost za 1 vecja od izmerjene goto freq_hist_cok freq_hist_cok movf op0_0,w ; shranim novo prikazano vrednost movwf c_lowex movf op0_1,w movwf c_hiex movf op0_2,w movwf c_oflex movlw 0x04 ; polovica delitelja (8) je enaka 4 movwf op1_0 clrf op1_1 clrf op1_2 clrf op1_3 movlw op0_0 movwf adr_0 movlw op1_0 movwf adr_1 call add_32 ; po deljenju z osem bo to zaokrozanje navzgor movlw op0_0 movwf fsr ; naslov lokacije, ki jo bom shiftal bcf status,carry call rrc_32 ; deljenje z 2 movlw op0_0 movwf fsr ; naslov lokacije, ki jo bom shiftal bcf status,carry call rrc_32 ; ponovno deljenje z 2 movlw op0_0 movwf fsr ; naslov lokacije, ki jo bom shiftal bcf status,carry call rrc_32 ; in se enkrat deljenje z 2, skupaj z 8 return ;******************************************************************** ;* Podprogram pristeje / odsteje frekvencni offset prikaza * ;* glede na postavljene jumperje. * ;******************************************************************** freq_offset btfss portb,jmp_2 ; Jumper 2 odprt? Da, preskoci na izracun odmika prikaza. goto freq_offs_ok ; Prikaz rezultata brez offseta. movf offs_l,w ; Nizji byte offseta. movwf op1_0 movf offs_m,w ; Srednji byte offseta. movwf op1_1 movf offs_h,w ; Visji byte offseta. movwf op1_2 clrf op1_3 movlw op0_0 ; rezultat meritve movwf adr_0 movlw op1_0 ; offset prikaza movwf adr_1 btfss portb,jmp_1 ; Jumper 1 sklenjen? Ne, preskoci. goto freq_offs_add ; Da, offset pristej k rezultatu. call sub_32 ; odstevanje offseta od rezultata btfss op0_3,7 ; Ali je razlika negativna? Da, preskoci. goto freq_offs_ok ; Ne, rezultat je ze ok. clrf op1_0 ; Razliko odst. od 0, da dobim abs. vrednost. clrf op1_1 clrf op1_2 clrf op1_3 movlw op1_0 ; na tej lokaciji se nahaja vrednost 0 movwf adr_0 movlw op0_0 ; razlika movwf adr_1 call sub_32 ; nic minus razlika movf op1_0,w movwf op0_0 ; rezultat shranim na lokacijo op0_0 movf op1_1,w movwf op0_1 ; rezultat shranim na lokacijo op0_1 movf op1_2,w movwf op0_2 ; rezultat shranim na lokacijo op0_2 movf op1_3,w movwf op0_3 ; rezultat shranim na lokacijo op0_3 goto freq_offs_ok freq_offs_add call add_32 ; sestevanje offseta in rezultata freq_offs_ok return ;******************************************************************** ;* Podprogram prikaze offset. * ;******************************************************************** dis_offset movf dis_mod,w ; Prikazni nacin andlw 0x0F ; Izlocim gornje 4 bite (2x --> 0x, x = 1..6) movwf op1_3 ; St. nastavljane cifre na 1. prikaznem mestu. addlw cifra_1 ; Pristejem naslov najnizje nastavljane cifre. movwf fsr ; Lokacija za posredno naslavljanje decf fsr,f ; Naslov korigiram (cifra_1 ima odmik 0). movf indir,w ; Precitam vrednost nastavljane cifre movwf op1_0 ; In prikazem na 4. prikaznem mestu. movlw 0x0F ; "Blank" vpisem na movwf op1_2 ; 2. prikazno mesto movwf op1_1 ; in 3. prikazno mesto. movlw b'00001110' ; Prizgem 1., 2. in 3. decimalno piko. movwf op0_0 call display ; Priprav. vrednosti prenese v prikazovalnik. return ;******************************************************************** ;* Podprogram prikaze frekvenco. * ;******************************************************************** dis_freq call hex_bcd ; pretvorim rezultat meritve frekvence v BCD movf dis_mod,w sublw 0x01 ; Prikazni nacin 1? btfsc status,zflag ; Ne, testiraj dalje. goto dis_freq_x_xxx ; Da, prikazi frekvenco v obliki M.kkk movf dis_mod,w sublw 0x02 ; Prikazni nacin 2? btfsc status,zflag ; Ne, testiraj dalje. goto dis_freq_xx_xx ; Da, prikazi f v obliki MM.kk movf dis_mod,w sublw 0x03 ; Prikazni nacin 3? btfsc status,zflag ; Ne, testiraj dalje. goto dis_freq_xxx_x ; Da, prikazi f v obliki kkk.H goto reset ; Mozno le ob napaki. ; ------------------------------------------------------------------ ;| Prikaz XXX.X kHz, prikazni nacin 3. | ; ------------------------------------------------------------------ dis_freq_xxx_x movf cifra_4,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_3 ; 1. prikazno mesto v op_1 movf cifra_3,w ; Cifra 3 gre na 2. prikazno mesto movwf op1_2 ; 1. prikazno mesto v op_1 movf cifra_2,w ; Cifra 2 gre na 3. prikazno mesto movwf op1_1 ; 1. prikazno mesto v op_1 movf cifra_1,w ; Cifra 1 gre na 4. prikazno mesto movwf op1_0 ; 1. prikazno mesto v op_1 movlw b'00000010' ; Prizgem se decimalno piko na 3. prik. mestu. movwf op0_0 movf cifra_6,f ; Ali je vrednost enaka 0? btfss status,zflag ; Da. goto dis_freq_xxx_x_ok ; Ne, OK. movf cifra_5,f ; Ali je vrednost enaka 0? btfss status,zflag ; Da. goto dis_freq_xxx_x_ok ; Ne, OK. movf cifra_4,f ; Ali vrednost 1. prik. mesta enaka 0? btfss status,zflag ; Da. goto dis_freq_xxx_x_ok ; Ne, OK. movlw 0x0F ; Da, movwf op1_3 ; brisanje vodece nicle. movf cifra_3,f ; Ali je tudi vrednost 2. prik. mesta enaka 0? btfss status,zflag ; Da. goto dis_freq_xxx_x_ok ; Ne, OK. movwf op1_2 ; Da, brisanje vodece nicle. dis_freq_xxx_x_ok goto dis_freq_wr ; ------------------------------------------------------------------ ;| Prikaz X.XXX MHz, prikazni nacin 1. | ; ------------------------------------------------------------------ dis_freq_x_xxx movf cifra_5,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_3 ; 1. prikazno mesto v op_1 movf cifra_4,w ; Cifra 3 gre na 2. prikazno mesto movwf op1_2 ; 1. prikazno mesto v op_1 movf cifra_3,w ; Cifra 2 gre na 3. prikazno mesto movwf op1_1 ; 1. prikazno mesto v op_1 movf cifra_2,w ; Cifra 1 gre na 4. prikazno mesto movwf op1_0 ; 1. prikazno mesto v op_1 movlw b'00001000' ; Prizgem se decimalno piko na 1. prik. mestu. movwf op0_0 goto dis_freq_wr ; ------------------------------------------------------------------ ;| Prikaz XX.XX MHz, prikazni nacin 2. | ; ------------------------------------------------------------------ dis_freq_xx_xx movf cifra_6,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_3 ; 1. prikazno mesto v op_1 movf cifra_5,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_2 ; 1. prikazno mesto v op_1 movf cifra_4,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_1 ; 1. prikazno mesto v op_1 movf cifra_3,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_0 ; 1. prikazno mesto v op_1 movlw b'00000100' ; Prizgem se decimalno piko na 2. prik. mestu. movwf op0_0 movf cifra_6,f ; Ali vrednost 1. prik. mesta enaka 0? btfss status,zflag ; Da. goto dis_freq_xx_xx_ok ; Ne, OK. movlw 0x0F ; Da, movwf op1_3 ; brisanje vodece nicle. dis_freq_xx_xx_ok goto dis_freq_wr ; ------------------------------------------------------------------ ;| Prenos po serijskem vodilu na MC14499. | ; ------------------------------------------------------------------ dis_freq_wr call display ; Priprav. vrednosti prenese v prikazovalnik. return ;******************************************************************** ;* Podprogram izmeri napetost. * ;******************************************************************** meas_dis_u movlw b'10000001' ; Fosc/32, kanal RA0, A/D on movwf adcon0 ; Inicializiram kontrolni register_0 A/D call pavza_1 ; 1 ms pavze (10 x acquisition time) bsf adcon0,go ; sprozim A/D konverzijo meas_u_z btfsc adcon0,go ; Ali je pretvorbe konec? Ce da, preskoci. goto meas_u_z ; Cakam na konec pretvorbe clrf intcon ; pobrisem vse zahteve za prekinitev bcf adcon0,adon ; Izkljucim A/D pretvornik movf adres,w ; preberem rezultat A/D pretvorbe sublw 0x0FF ; preverim, ali je napetost vecja od 5V btfsc status,zflag ; ce ne, potem zerro=0, normalen prikaz goto meas_u_overv ; ce da, prikazi stanje prenapetosti movf adres,w ; Ponovno preberem rezultat A/D pretvorbe. subwf nap_ex,f ; odstejem staro vrednost napetosti btfsc status,zflag ; rezultat primerjave enak nic? ne, preskoci goto meas_u_vm_hok ; da, enak prikaz kot v prejsnjem ciklu btfsc status,carry ; nova vrednost manjsa od stare? ne, preskoci goto meas_u_vm_clwr ; da, prikazi (navzdol ni histereze) goto meas_u_vm_cgt ; nova vred. vec. od stare, odstej 1 in prik. meas_u_vm_clwr goto meas_u_vm_hok ; grem na prikaz, nic ne pristevam meas_u_vm_cgt sublw 0x001 ; odstejem w od ena (1-w) sublw 0x000 ; in negiram 0-(1-w) = w-1 goto meas_u_vm_hok ; grem na prikaz meas_u_vm_hok movwf nap_ex ; novo prikazano vrednost shranim movwf op0_0 clrf op0_1 clrf op0_2 clrf op0_3 call hex_bcd ; Pretvori rezultat v BCD obliko. movlw 0x0F ; Prvo cifro nadomestim movwf cifra_4 ; z ugasnjenim mestom movf cifra_3,f ; Testiram 1. cifro, ali je enaka 0. btfsc status,zflag ; Cifra_3 ni nic -> zflag = 0, preskoci movwf cifra_3 ; Je nic, nadomestim jo z ugasnjenim mestom. goto meas_u_ret meas_u_overv ; Sem priletim, ce Uad >= 5V. movlw 0x0E ; Kodo minusa dam movwf cifra_1 ; v vse stiri cifre, da oznacim prenapetost movwf cifra_2 ; z ---.- movwf cifra_3 movwf cifra_4 meas_u_ret movf cifra_4,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_3 ; 1. prikazno mesto v op_1 movf cifra_3,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_2 ; 1. prikazno mesto v op_1 movf cifra_2,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_1 ; 1. prikazno mesto v op_1 movf cifra_1,w ; Cifra 4 gre na 1. prikazno mesto movwf op1_0 ; 1. prikazno mesto v op_1 movlw b'00000010' ; Prizgem se decimalno piko na 3. prik. mestu. movwf op0_0 call display ; Pripravljene vrednosti prenese v prikazoval. return ;******************************************************************** ;* Podprogram prebere offset iz EEPROMa. * ;******************************************************************** read_offset movlw b'10000000' ; Op. code: Read address 00hex movwf op0_3 ; 1. byte, ki gre v EEPROM (op. code) clrf op0_2 ; Ostale besede spraznim clrf op0_1 call wr_str_ee ; Prenesem v EEPROM in preberem vsebino v op1_x movf op1_2,w movwf offs_h ; 1. prebrani podatek: offs_h movf op1_1,w movwf offs_m ; 1. prebrani podatek: offs_m movlw b'10000001' ; Op. code: Read address 01hex movwf op0_3 ; 1. byte, ki gre v EEPROM (op. code) clrf op0_2 ; Ostale besede spraznim clrf op0_1 call wr_str_ee ; Prenesem v EEPROM in preberem vsebino v op1_x movf op1_2,w movwf offs_l ; 1. prebrani podatek: offs_l addwf offs_m,w ; Pristejem offs_m addwf offs_h,w ; Pristejem se offs_h in dobim kontrol. vsoto. xorlw b'10101010' ; Kontrolni vsoti invertiram vsak 2. bit. subwf op1_1,w ; V tem operandu je prebrana kontrol. vsota. btfsc status,zflag ; Ce razlika ni nic, preskoci. goto read_offset_ok ; Sicer podatki OK. movlw 0x90 ; Podatki niso OK, inicializiram na MF = 9MHz movwf offs_l movlw 0x5F movwf offs_m movlw 0x01 movwf offs_h read_offset_ok return ;******************************************************************** ;* Podprogram vpise nastavljeni offset v EEPROM. * ;******************************************************************** write_offset movlw b'00110000' ; Op. code: Erase / write enable movwf op0_3 ; 1. byte, ki gre v EEPROM clrf op0_2 ; Ostale besede spraznim clrf op0_1 call wr_str_ee ; Prenesem v EEPROM movlw b'01000000' ; Op. code: Vpis na naslov 00hex movwf op0_3 ; 1. byte, ki gre v EEPROM movf offs_h,w movwf op0_2 ; 1. podatek: offs_h movf offs_m,w movwf op0_1 ; 2. podatek: offs_m call wr_str_ee ; Prenesem v EEPROM call wait_wr_end ; Cakam na konec vpisa (max. 10ms) movlw b'01000001' ; Op. code: Vpis na naslov 01hex movwf op0_3 ; 1. byte, ki gre v EEPROM movf offs_l,w movwf op0_2 ; 1. podatek: offs_l addwf offs_m,w ; Pristejem offs_m addwf offs_h,w ; Pristejem se offs_h in dobim kontrolno vsoto. xorlw b'10101010' ; Invertiram vsak 2. bit kontrolne vsote. movwf op0_1 ; 2. podatek: kontrolna vsota call wr_str_ee ; Prenesem v EEPROM call wait_wr_end ; Cakam na konec vpisa (max. 10ms) movlw b'00000000' ; Op. code: Erase / write disable movwf op0_3 ; 1. byte, ki gre v EEPROM clrf op0_2 ; Ostale besede spraznim clrf op0_1 call wr_str_ee ; Prenesem v EEPROM return ;******************************************************************** ;* Podprogram testira delovanje prikaza in MC14499. * ;******************************************************************** dis_test movlw 0x08 ; Prizgem vse segmente. movwf op1_3 movwf op1_2 movwf op1_1 movwf op1_0 ; Na vseh 4 mestih. movlw 0x0F movwf op0_0 ; Prizgem vse decimalne pike. call display movlw 0x96 movwf uni_03 ; Stevec zakasnilne zanke 150 x 10ms dis_test_z1 call pavza_10 decfsz uni_03,f goto dis_test_z1 movlw 0x0F ; Ugasnem vse segmente movwf op1_3 movwf op1_2 movwf op1_1 movwf op1_0 ; Na vseh 4 mestih. clrf op0_0 ; Ugasnem tudi vse decimalne pike. call display movlw 0x96 movwf uni_03 ; Stevec zakasnilne zanke 150 x 10ms dis_test_z2 call pavza_10 decfsz uni_03,f goto dis_test_z2 return ;******************************************************************** ;* Podprogram pretvorbe iz BCD v HEX. * ;* Podatek dobi v cifra_x (x = 6..1), vrne v offs_h...offs_l. * ;******************************************************************** bcd_hex clrf op0_0 ; Pocistim lokacije, kjer tvorim rezultat. clrf op0_1 clrf op0_2 clrf op0_3 movlw 0x06 ; 6 BCD cifer pretvarjam v zanki v HEX. movwf uni_03 ; Stevec zanke. bcd_hex_z1 movf op0_0,w ; op0 zacasno shranim v op1 za potrebe mnozenja. movwf op1_0 movf op0_1,w movwf op1_1 movf op0_2,w movwf op1_2 movf op0_3,w movwf op1_3 movlw op0_0 ; Naslov operanda, ki ga shiftam, movwf fsr ; dam v lokacijo za posredno naslavljanje. bcf status,carry call rlc_32 ; op0 <-- 2 x op0 movlw op0_0 ; Naslov operanda, ki ga shiftam, movwf fsr ; dam v lokacijo za posredno naslavljanje. bcf status,carry call rlc_32 ; op0 <-- 4 x op0 movlw op0_0 ; 4 x op0 movwf adr_0 movlw op1_0 ; op0 movwf adr_1 call add_32 ; op0 <-- 4 x op0 + op0 movlw op0_0 ; Naslov operanda, ki ga shiftam, movwf fsr ; dam v lokacijo za posredno naslavljanje. bcf status,carry call rlc_32 ; op0 <-- 8 x op0 + 2 x op0 = 10 x op0 movf uni_03,w ; Stevec zanke uporabim za gener. naslova. addlw cifra_1 ; Pristejem naslov najnizje BCD cifre. movwf fsr ; Lokacija za posredno naslavljanje decf fsr,f ; Naslov korigiram (cifra_1 ima odmik 0). movf indir,w ; Precitam vrednost cifre, ki jo pristevam. movwf op1_0 ; K op_0 najprej pristevam najvisjo cifro. clrf op1_1 ; Ostali byte-i prazni. clrf op1_2 clrf op1_3 movlw op0_0 ; Rezultat movwf adr_0 movlw op1_0 ; Cifra, ki jo pristevam k rezultatu. movwf adr_1 call add_32 ; Izvrsim sestevanje op0 + op1 --> op0 decfsz uni_03,f ; Zanka izvrsena sestic? goto bcd_hex_z1 ; Se ne, ponovi zanko movf op0_0,w ; Rezultat shranim v lokacije z freq. odmikom. movwf offs_l movf op0_1,w movwf offs_m movf op0_2,w movwf offs_h return ;******************************************************************** ;* Podprogram pretvorbe iz hex v BCD. * ;* Podatek dobi v op0_x, vrne v cifra_x (x = 6..1). * ;******************************************************************** hex_bcd clrf op0_3 movlw 0xA0 movwf op1_0 movlw 0x86 movwf op1_1 movlw 0x01 ; 186A0 hex = 100000 dec movwf op1_2 clrf op1_3 movlw 0xFF ; ena ponovitev zanke tudi ce < 100000 movwf uni_03 hex_z0 incf uni_03,f ; tukaj se generirajo stotisocice movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call sub_32 btfsc status,carry ; ali je prislo do prenosa, da goto hex_z0 ; se ne movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call add_32 ; odstel sem malo prevec movf uni_03,w movwf cifra_6 ; shranim dekodirane stottisocice movlw 0x10 movwf op1_0 movlw 0x27 ; 2710 hex = 10000 dec movwf op1_1 clrf op1_2 clrf op1_3 movlw 0xFF ; ena ponovitev zanke tudi ce < 10000 movwf uni_03 hex_z1 incf uni_03,f ; tukaj se generirajo desettisocice movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call sub_32 btfsc status,carry ; ali je prislo do prenosa, da goto hex_z1 ; se ne movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call add_32 ; odstel sem malo prevec movf uni_03,w movwf cifra_5 ; shranim dekodirane desettisocice movlw 0xE8 movwf op1_0 movlw 0x03 ; 03E8 hex = 1000 dec movwf op1_1 clrf op1_2 clrf op1_3 movlw 0xFF ; ena ponovitev zanke tudi ce < 1000 movwf uni_03 hex_z2 incf uni_03,f ; tukaj se generirajo tisocice movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call sub_32 btfsc status,carry ; ali je prislo do prenosa, da goto hex_z2 ; se ne movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call add_32 ; odstel sem malo prevec movf uni_03,w movwf cifra_4 ; shranim dekodirane tisocice movlw 0x64 movwf op1_0 ; 064 hex = 100 dec clrf op1_1 clrf op1_2 clrf op1_3 movlw 0xFF ; ena ponovitev zanka tudi ce < 100 movwf uni_03 hex_z3 incf uni_03,f ; tukaj se generirajo stotice movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call sub_32 btfsc status,carry ; ali je prislo do prenosa, da goto hex_z3 ; se ne movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call add_32 ; odstel sem malo prevec movf uni_03,w movwf cifra_3 ; shranim dekodirane stotice movlw 0x0A movwf op1_0 ; 0A hex = 10 dec clrf op1_1 clrf op1_2 clrf op1_3 movlw 0xFF ; ena ponovitev zanka tudi ce < 10 movwf uni_03 hex_z4 incf uni_03,f ; tukaj se generirajo desetice movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call sub_32 btfsc status,carry ; ali je prislo do prenosa, da goto hex_z4 ; se ne movlw op0_0 ; odstevanec movwf adr_0 movlw op1_0 movwf adr_1 call add_32 ; odstel sem malo prevec movf uni_03,w movwf cifra_2 ; shranim dekodirane desetice movf op0_0,w ; enice movwf cifra_1 ; shranim dekodirane enice return ;******************************************************************** ;* 32 bitni string (op0_3...op0_1) prenese v EEPROM po ser. v. * ;* Sproti bere stanje z izhoda DO in spravlja v op1_3...op1_1. * ;******************************************************************** wr_str_ee bcf portb,ee_cs ; Pravilno inicializiram serijsko vodilo bcf portb,clk bcf portb,din ; Nevtralno stanje nop bsf portb,ee_cs ; Zacetek prenosa nop bsf portb,din ; start bit = 1 nop bsf portb,clk ; Prenesem v EEPROM "start bit" nop bcf portb,clk movlw 0x03 movwf uni_01 ; Stevec zunanje zanke (prenos 3 x 8 bitov) movlw op0_3 ; Naslov 1. besede s podatki za prenos (op.code + adr.) movwf fsr ; Naslov dam v register za posredno naslavljanje wr_str_ee_z1 movlw 0x08 movwf uni_02 ; Stevec notranje zanke (prenesem 8 bit-ov). wr_str_ee_z2 btfss indir,7 ; Preverjam 7. bit (MSB) bcf portb,din ; Stanje prenesem na izhod. btfsc indir,7 ; Preverjam 7. bit (MSB) bsf portb,din ; Stanje prenesem na izhod. rlf indir,f ; Pripravim za prenos naslednjega bita. bsf portb,clk ; Zacetek pozitivnega urinega impulza nop ; Dolzina impulza 2 us. bcf portb,clk ; Konec urinega impulza. movlw op1_0-op0_0 ; Naslov op1 za 4 vecji od op0 addwf fsr,f ; 4 pristejem k naslovu v fsr bsf status,carry ; predpostavim visoko stanje na DO (EE). btfss portb,dout ; Visoko stanje? Ce da, preskoci. bcf status,carry ; Na izhodu iz EEPROMa nizko stanje. rlf indir,f ; Shiftam v levo op1_x, C --> op1_x [0] subwf fsr,f ; fsr nastavim nazaj na op0 decfsz uni_02,f ; Prenesenih vseh 8 bitov tekoce besede? goto wr_str_ee_z2 ; Ne, ponovi zanko. incf fsr,f ; Naslov naslednjega byte-a decfsz uni_01,f ; Prenesene vse 3 8-bitne besede? goto wr_str_ee_z1 ; Ne, ponovi zanko. bcf portb,ee_cs ; Konec ser. komunikacije. Deaktiviram EEPROM. bcf portb,din ; Nevtralno stanje. return ;******************************************************************** ;* Caka na konec vpisa podatka v ser. EEPROM. * ;******************************************************************** wait_wr_end bcf portb,ee_cs ; Pravilno inicializiram serijsko vodilo bcf portb,clk bcf portb,din ; Nevtralno stanje bsf portb,ee_cs ; Aktiviram DO izhod 93C46 nop wait_wr_end_z1 btfss portb,dout ; Visoko stanje? goto wait_wr_end_z1 ; Se ne, cakaj. bcf portb,ee_cs ; Da, deaktiviram CS EERPOMa. return ;******************************************************************** ;* op1_3 ... op1_0 ter op0_0 (dec. pike) prenese na prikaz. * ;******************************************************************** display bsf portb,dis_en ; Pravilno inicializiram serijsko vodilo bcf portb,clk movlw 0x05 movwf uni_01 ; Stevec zunanje zanke (prenos 5 x 4 bite) movlw op0_0 ; Naslov 1. besede s podatki za prenos movwf fsr ; Naslov dam v register za posredno naslavljanje bcf portb,dis_en ; Zacetek prenosa disp_z1 movlw 0x04 movwf uni_02 ; Stevec notranje zanke (prenesem 4 bite). disp_z2 btfss indir,3 ; Preverjam 3. bit (MSB) bcf portb,din ; Stanje prenesem na izhod. btfsc indir,3 ; Preverjam 3. bit (MSB) bsf portb,din ; Stanje prenesem na izhod. rlf indir,f ; Pripravim za prenos naslednjega bita. bsf portb,clk ; Zacetek pozitivnega urinega impulza nop ; Dolzina impulza 2 us. bcf portb,clk ; Konec urinega impulza. decfsz uni_02,f ; Preneseni vsi 4 biti tekoce besede? goto disp_z2 ; Ne, ponovi zanko. incf fsr,f ; Naslov naslednjega byte-a decfsz uni_01,f ; Prenesenih vseh 5 4-bitnih besed? goto disp_z1 ; Ne, ponovi zanko. bsf portb,dis_en ; Prikaz nove vrednosti nop bcf portb,din ; Nevtralno stanje. return ;******************************************************************** ;* Rotate left through Carry 32 (16) bit (fsr) * ;******************************************************************** rlc_32 rlf indir,f decf fsr,f rlf indir,f decf fsr,f rlc_16 rlf indir,f decf fsr,f rlf indir,f return ;******************************************************************** ;* Rotate right through Carry 32 (16) bit (fsr) * ;******************************************************************** rrc_16 decf fsr,f goto rrc_16_v rrc_32 decf fsr,f decf fsr,f decf fsr,f rrf indir,f incf fsr,f rrf indir,f incf fsr,f rrc_16_v rrf indir,f incf fsr,f rrf indir,f return ;******************************************************************** ;* Compare 32 bit (adr_0) by 32 bit (adr_1) * ;******************************************************************** cmp_32 decf adr_0,f decf adr_0,f decf adr_0,f decf adr_1,f decf adr_1,f decf adr_1,f movlw 0x04 ; primerjam najvec 4 byte v zanki movwf uni_02 ; stevec zanke bcf status,carry ; ocistim carry bit goto cmp_v ; na tem mestu vstopam v zanko primerjave cmp_zan incf adr_0,f incf adr_1,f cmp_v movf adr_1,w movwf fsr movf indir,w movwf uni_01 ; 2. operand zacasno shranim v uni_01 movf adr_0,w movwf fsr ; 1. operand indirektno naslovljiv movf uni_01,w subwf indir,w ; 1. operand - 2. operand --> W file btfss status,zflag ; rezultat operacije = 0, da -> se primerjaj goto cmp_e ; ne, konec primerjave decfsz uni_02,f goto cmp_zan cmp_e return ;******************************************************************** ;* 32 bit (adr_0) + 32 bit (adr_1) -> 32 bit (adr_0) * ;******************************************************************** add_32 movlw 0x04 ; sestevam 4 byte v zanki movwf uni_02 ; stevec zanke bcf status,carry ; ocistim carry bit add_zan movf adr_1,w movwf fsr movf indir,w movwf uni_01 ; 2. operand zacasno shranim v uni_01 movf adr_0,w movwf fsr ; 1. operand indirektno naslovljiv bcf status,zflag btfsc status,carry incf indir,f bcf status,irp btfsc status,zflag bsf status,irp movf uni_01,w addwf indir,f btfsc status,irp bsf status,carry decf adr_0,f decf adr_1,f decfsz uni_02,f goto add_zan return ;******************************************************************** ;* 32 bit (adr_0) - 32 bit (adr_1) -> 32 bit (adr_0) * ;******************************************************************** sub_32 movlw 0x04 ; odstevam 4 byte v zanki movwf uni_02 ; stevec zanke bsf status,carry ; 1 --> `borrow = carry sub_zan movf adr_1,w movwf fsr movf indir,w movwf uni_01 ; 2. operand --> uni_01 (zacasno shranim) movf adr_0,w movwf fsr ; 1. operand indirektno naslovljiv btfss status,carry ; ce `borrow = 1, ne zmanjsam 1. operanda za 1 goto sub_b ; potrebno upostevati da `borrow = 0 bcf status,irp ; oznacim, da ni izposoje goto sub_nb sub_b movf indir,f ; testiram ali je vrednost nic bcf status,irp ; predpostavim, da ni nic btfsc status,zflag ; vrednost res ni nic bsf status,irp ; vrednost je nic, potrebno upostevati izposo. decf indir,f sub_nb movf uni_01,w ; 2. operand v W register subwf indir,f btfsc status,irp bcf status,carry ; 0 --> `borow (oznacim izposojo od prej) decf adr_0,f decf adr_1,f decfsz uni_02,f goto sub_zan return ;******************************************************************** ;* Podprogram zakasnitve ca. 10 ms. * ;******************************************************************** pavza_10 movlw 0x00A ; stevilo ponovitev zunanje zanke 10 movwf uni_01 ; 1 pavza_10z1 movlw 0x0F9 ; stevilo ponovitev zanke (n) = 249 1 movwf uni_02 ; 1 pavza_10z2 nop ; 1 decfsz uni_02,f ; 1 x n ... (2 cikla ob izstopu iz zanke) goto pavza_10z2 ; 2 x n ... (ob izstopu se ne izvaja) decfsz uni_01,f goto pavza_10z1 return ; nazaj od koder prihajas ;******************************************************************** ;* Podprogram zakasnitve ca. 1 ms. * ;******************************************************************** pavza_1 movlw 0xFA ; stevilo ponovitev zunanje zanke 3 movwf uni_01 ; 1 pavza_1_z1 nop ; 1 decfsz uni_01,f ; 1 (2) goto pavza_1_z1 ; 2 (0) return ; nazaj od koder prihajas ;******************************************************************** ;* That's all folks! * ;******************************************************************** end