; rev 28-09-2024 pour passer en 16F84A ; rev 15/01/2012 ; Freqar_5_16F84_2012.asm ; modif hardware : RA0* as input for CAL mode ; rajout "Freq=" et "CAL " en tete de mesures ; rappel : IC-PROG105d.exe pour transferer le *.hex dans POK508 ; rev 10/01/2012 avec MPLAB 8.63.00.00 Certified ; Freqar_4_16F84_2012.asm ; with LCD 16x1 ; 12 sept 04 ; Freqar_3.asm rajout Messages d'invite en EEPROM ; 10 juin 03 ; Freqar_1.asm ; OK avec LCD 1 ligne de 16 car ; resolution 0.01Hz en BF ; TITLE "auto-ranging frequency meter @4.000MHz" LIST p=16F84A ERRORLEVEL 0, -302 ; File: fmeter.asm; Created: Feb-1999, P. Strebel ; Measures 0.900Hz to 30.00MHz with a PIC16F84 and 50% duty cycle. ; The frequency display is rounded to four decimal digits to get a ; maximum tolerance of 1 last digit without oscillator adjustement. ; ********** ********** ; * *** * ; NC A2 ** 1 18 ** A1 NC ; * * ; NC A3 ** 2 17 ** A0 --/ -- calib * (with versus 5) ; * * ; input A4 ** 3 16 ** Xin X1 ; * * ; reset MCLR ** 4 15 ** Xout X0 ; * * ; GND ** 5 14 ** VCC ; * * ; B0 ** 6 13 ** B7 D7 ; * * ; ENA B1 ** 7 12 ** B6 D6 ; * * ; R/W B2 ** 8 11 ** B5 D5 ; * * ; D/C B3 ** 9 10 ** B4 D4 ; * PIC16F84 * ; *********************** ; VCC = 5V (2-6V for controller, 4.5-5.5V for display) ; input: cmos schmitt-trigger (pulled up with 10k) ; reset: pulled up with 10k to VCC ; B0 utilisé pour mode test calbiration ; --------------------------------- 1 = GND ; | | 2 = VCC ; | | 3 = V0 ; | 16-Char LCD-Module | 4 = D/C ; | | 5 = R/W ; | 14............1 | 6 = ENA ; --------------------------------- 7-14 = D0-D7 ; V0: VCC-4.5V, D0..D3 not used in 4-bit mode ; display LM054 DL1414T update interval ; 0.900 Hz .. 9.999Hz 0.90 .. 9.99 ca. 250ms .. 1.2s ; 10.00 Hz .. 99.99Hz 10.0 .. 99.9 ca. 250ms ; 100.0 Hz .. 999.9Hz 100. .. 999. ca. 250ms ; 1.000kHz .. 9.999kHz 1K00 .. 9.99 ca. 250ms ; 10.00kHz .. 99.99kHz 10K0 .. 99K9 ca. 250ms ; 100.0kHz .. 999.0kHz 100K .. 999K ca. 250ms ; 1.000MHz .. 9.999MHz 1M00 .. 9M99 ca. 250ms ; 10.00MHz .. 99.99MHz 10M0 .. 99M9 ca. 250ms ; Higher frequencies use the prescaler and measuring time is 200ms ; Lower frequencies use no prescaler, measuring time is 200ms..1.1s ; Determination of prescaler: TMR0 input frequency should be below ; 1/4 of oscillator clock. We set the prescaler to get a maximum ; frequency of 1/8 of the oscillator speed (4Mhz/8 = 500 kHz). ; A test is done for 512us with a prescaler of 256 and then TMR0 ; is read to see what prescaler is needed. ; prescaler input frequency TMR0 (after test) prsc ; 1 (off) < 500kHz 0 off ; 2 > 500kHz >1 0 ; 4 > 1MHz >2 1 ; 8 > 2MHz >4 2 ; 16 > 4MHz >8 3 ; 32 > 8MHz >16 4 ; 64 > 16MHz >32 5 ; 128 > 32MHz >64 6 ; 256 > 64MHz >128 7 __IDLOCS H'FFFF' __CONFIG H'3FF1' ; WDT off, XT osc TMR0 EQU 1 PC EQU 2 STATUS EQU 3 FSR EQU 4 PORTA EQU 5 PORTB EQU 6 RP1 EQU H'0006' RP0 EQU H'0005' PCLATH EQU H'0A' INTCON EQU H'0B' _OPTION EQU H'81' ; OPTION register in page 1 _TRISA EQU H'85' ; TRISA in page 1 _TRISB EQU H'86' ; TRISB in page 1 EEDATA EQU H'0008' EEADR EQU H'0009' PCLATH EQU H'000A' INTCON EQU H'000B' OPTION_REG EQU H'0081' TRISA EQU H'0085' TRISB EQU H'0086' EECON1 EQU H'0088' EECON2 EQU H'0089' EEIF EQU H'0004' WRERR EQU H'0003' WREN EQU H'0002' WR EQU H'0001' RD EQU H'0000' C EQU 0 DC EQU 1 Z EQU 2 P EQU 5 ; DSPLY EQU 1 ; 1=LCD=LM054, 2= not impemented in this versus #define bank0 bcf STATUS,RP0 #define bank1 Bsf STATUS,RP0 #define PORT_DATA PORTB #define PORT_DIR_DATA TRISB #define PORT_CTRL PORTB #define BP_CAL PORTA,0 #define LCD_E PORTB,1 ; Enable #define LCD_RW PORTB,2 ; 1=Read / 0=Write #define LCD_RS PORTB,3 ; 1=Commande / 0=data cblock 0x0C ; start of RAM tmp0 ; temporary storage tmp1 tmp2 tmp3 tim0 ; software timer tim1 tim2 tim3 cnt0 ; wave counters cnt1 cnt2 cnt3 prsc ; prescaler setting quot ; quotient (division) dign ; number of decimal digits digo ; digits out to display digs :12 ; decimal digits MMkkk111mmmu Pointer_Msg count1 count2 count3 dummy endc ;======================================= ORG H'000' ; reset GOTO main ;======================================== ORG H'004' ; interrupt intserv BCF INTCON,2 ; [3] reset int flag INCFSZ cnt1,F ; [4] no status or W change GOTO intend ; [6] always same nr of cycles INCF cnt2,F ; [6] intend RETFIE ; [8] ; main program main CLRF PORTA ; port A low CLRF PORTB ; port B low bank1 MOVLW B'00010001' ; A4 input, A3..A1 outputs A0 input MOVWF _TRISA MOVLW B'00000000' ; B7..B0 outputs MOVWF _TRISB MOVLW B'11111111' ; no pu, risi, A4, hilo, presc to WDT MOVWF _OPTION ; bank0 call delay_1s CALL initlcd call delay_1s CALL loadcgr call delay_1s CALL home movlw 0 movwf Pointer_Msg Call AffNumMsgEeprom call delay_3s movlw 1 movwf Pointer_Msg Call AffNumMsgEeprom call delay_3s CALL home movlw 2 movwf Pointer_Msg Call AffNumMsgEeprom call delay_3s CALL home movlw 3 movwf Pointer_Msg Call AffNumMsgEeprom call delay_3s movlw 4 ; efface movwf Pointer_Msg Call AffNumMsgEeprom call delay_3s call home CALL Check_Calibr ; mode calibration timer si B0=0 au reset timeout MOVLW H'0C' ; debut RAZ des variables MOVWF FSR initvar CLRF 0 INCF FSR,F MOVLW H'30' XORWF FSR,W BTFSS STATUS,Z GOTO initvar ; fin RAZ display CALL round ; efface zero inutiles,arrondi CALL home ; au debut MOVLW 'F' call Display_char MOVLW 'r' call Display_char MOVLW 'e' call Display_char MOVLW 'q' call Display_char MOVLW '=' call Display_char MOVLW ' ' call Display_char ; affichage valeurs des comteurs MOVLW D'11' ; point to first (10MHz) digit MOVWF dign CLRF digo displ MOVF dign,W ; digit out ADDLW digs MOVWF FSR CALL dispdig DECF dign,F ; 11,10,9,8..until 0 BTFSS dign,7 ; negatif ? GOTO displ newm MOVLW 7 ; prescaler to 256 MOVWF prsc CALL setprsc ; init Tmr0 MOVLW D'171' ; test timer (*3 cycles) soit 512µS MOVWF tmp0 CLRF TMR0 ; clear timer and prescaler (inhalt) tstp DECFSZ tmp0,F ; wait while TMR0 counts up GOTO tstp MOVF TMR0,W ; read timer after tempo MOVWF tmp0 MOVLW 8 ; init future valeur prescaler à 00001000 MOVWF prsc BSF STATUS,C ; see what prescaler to use chkp DECF prsc,F RLF tmp0,F ; shift out leftmost bit BTFSS STATUS,C GOTO chkp donp CALL setprsc ; no prescaler needed: prsc=255 CLRF tim0 ; reset software timer CLRF tim1 CLRF tim2 CLRF tim3 CLRF TMR0 ; clear timer and prescaler CALL phase ; synchronize with signal edge CLRF TMR0 ; clear timer and prescaler BTFSC tim2,7 ; [1] timeout? GOTO timeout ; [2] CLRF cnt0 ; [3] reset counters CLRF cnt1 ; [4] CLRF cnt2 ; [5] CLRF cnt3 ; [6] MOVLW B'10100000' ; [7] enable timer interrupt MOVWF INTCON ; [8] MOVLW D'250' ; [9] wait for 200000 cycles (200ms) MOVWF tmp1 ; | tmp1 * (tmp0+1) * 4 cycles wait1 MOVLW D'199' ; | MOVWF tmp0 ; | | tpm0 * 4 cycles wait0 NOP ; | | DECFSZ tmp0,F ; | | GOTO wait0 ; | | DECFSZ tmp1,F ; | GOTO wait1 ; | CLRF tim3 ; [10] preset software timer CLRF tim2 ; [11] MOVLW H'30' ; [12] 200016/16 MOVWF tim1 ; [13] MOVLW H'D5' ; [14] MOVWF tim0 ; [15] CALL phase ; synchronize with signal edge XORWF TMR0,F ; (W=0) stop timer for 2 cycles MOVF TMR0,W ; read timer CLRF INTCON ; stop interrupt MOVWF cnt0 ; waves/presc now in cnt3:cnt2:cnt1:cnt0 BTFSC tim2,7 ; timeout? GOTO timeout BCF tim2,6 ; clear flag (maybe set) MOVF cnt1,W ; interrupt time = int count/2 MOVWF tmp0 MOVF cnt2,W MOVWF tmp1 CLRF tmp2 CLRF tmp3 BCF STATUS,C RRF tmp3,F RRF tmp2,F RRF tmp1,F RRF tmp0,F MOVLW tim0 ; tim += interrupt time MOVWF FSR CALL add32 BCF STATUS,C ; tim *= 16 to get [us] RLF tim0,F RLF tim1,F RLF tim2,F RLF tim3,F BCF STATUS,C RLF tim0,F RLF tim1,F RLF tim2,F RLF tim3,F BCF STATUS,C RLF tim0,F RLF tim1,F RLF tim2,F RLF tim3,F BCF STATUS,C RLF tim0,F RLF tim1,F RLF tim2,F RLF tim3,F ; time [us] now in tim3:tim2:tim1:tim0 BTFSC prsc,3 ; prescaler off? GOTO mulx INCF prsc,F mulp BCF STATUS,C ; multiply with prescaler RLF cnt0,F RLF cnt1,F RLF cnt2,F RLF cnt3,F DECFSZ prsc,F GOTO mulp mulx NOP ; waves in cnt3:cnt2:cnt1:cnt0 ; cnt range is from 0x00 00 01 to 0xFF FF FF (at ca.75MHz) ; tim range is about 0x03 0D 00 to about 0x10 F0 00 us ; 200mS à 1,1Sec ; frequency (MHz)=cnt/tim; following digit=reminder*10/tim MOVLW tim0 ; to get 10MHz digit MOVWF FSR ; multiply tim by 10 CALL mul10 MOVLW D'11' ; point to 10MHz digit MOVWF dign calc MOVF tim0,W ; tim to tmp (divisor) MOVWF tmp0 MOVF tim1,W MOVWF tmp1 MOVF tim2,W MOVWF tmp2 MOVF tim3,W MOVWF tmp3 ; division is looped sub: expected result < 10 (ca. 50-300 cycles) CLRF quot ; count loops divil INCF quot,F MOVLW cnt0 ; dividend MOVWF FSR CALL sub32 BTFSC STATUS,C GOTO divil divix MOVLW cnt0 ; point to cnt MOVWF FSR CALL add32 ; rebuild reminder DECF quot,F ; result MOVF dign,W ; store result (0..9) ADDLW digs MOVWF FSR MOVF quot,W MOVWF 0 DECF dign,F BTFSC dign,7 ; all digits ready? GOTO display MOVLW cnt0 ; reminder * 10 MOVWF FSR CALL mul10 GOTO calc ; next digit mul10 BCF STATUS,C ; [FSR] *= 10 RLF 0,F ; * 2; copy to tmp3:tmp2:tmp1:tmp0 MOVF 0,W MOVWF tmp0 INCF FSR,F RLF 0,F MOVF 0,W MOVWF tmp1 INCF FSR,F RLF 0,F MOVF 0,W MOVWF tmp2 INCF FSR,F RLF 0,F MOVF 0,W MOVWF tmp3 DECF FSR,F DECF FSR,F DECF FSR,F BCF STATUS,C ; * 4 RLF tmp0,F RLF tmp1,F RLF tmp2,F RLF tmp3,F BCF STATUS,C ; * 8 RLF tmp0,F RLF tmp1,F RLF tmp2,F RLF tmp3,F add32 MOVF tmp0,W ; [FSR] += tmp3:tmp2:tmp1:tmp0 ADDWF 0,F INCF FSR,F MOVF tmp1,W BTFSC STATUS,C INCFSZ tmp1,W ADDWF 0,F INCF FSR,F MOVF tmp2,W BTFSC STATUS,C INCFSZ tmp2,W ADDWF 0,F INCF FSR,F MOVF tmp3,W BTFSC STATUS,C INCFSZ tmp3,W ADDWF 0,F RETLW 0 ; carry set at overflow sub32 MOVF tmp0,W ; [FSR] -= tmp3:tmp2:tmp1:tmp0 SUBWF 0,F INCF FSR,F MOVF tmp1,W BTFSS STATUS,C INCFSZ tmp1,W SUBWF 0,F INCF FSR,F MOVF tmp2,W BTFSS STATUS,C INCFSZ tmp2,W SUBWF 0,F INCF FSR,F MOVF tmp3,W BTFSS STATUS,C INCFSZ tmp3,W SUBWF 0,F RETLW 0 ; carry cleared at overflow round MOVLW digs+D'11' ; point to first (10MHz) digit MOVWF FSR roun0 MOVF 0,W ; search for digit > 0 BTFSS STATUS,Z GOTO roun1 MOVF FSR,W XORLW digs+4 ; at digit 4 BTFSC STATUS,Z GOTO roun1 DECF FSR,F GOTO roun0 roun1 MOVLW 4 SUBWF FSR,F ; point to last digit - 1 MOVLW 5 ; add 1/2 last digit roun2 ADDWF 0,W MOVLW D'10' ; decimal carry? SUBWF 0,W BTFSS STATUS,C RETLW 0 ; no: done MOVLW D'10' SUBWF 0,F MOVLW 1 ; carry INCF FSR,F GOTO roun2 ;;; wait for signal edge or timeout (loops*16 + 3 cycles) phase MOVF TMR0,W ; [3] wait for signal edge MOVWF tmp0 ; [4] phas0 INCFSZ tim0,F ; [1] inc software timer GOTO phas1 ; [3] always same nr of cycles INCFSZ tim1,F ; [3] GOTO phas2 ; [5] always same nr of cycles INCF tim2,F ; [5] MOVLW H'01' ; [6] if tim2 matches timeout XORWF tim2,W ; [7] BTFSC STATUS,Z ; [8] BSF tim2,6 ; [9] flag this with bit6 NOP ; [10] phas4 MOVF TMR0,W ; [11] TMR0 changed? XORWF tmp0,W ; [12] BTFSS STATUS,Z ; [13] RETLW 0 ; [15] edge detected GOTO phas0 ; [16] next loop phas1 BTFSS tim2,6 ; [4] if tim2 timeout GOTO phas3 ; [6] MOVLW H'0F' ; [6] check tim1 (01 0F 01 = ca 1.11s) XORWF tim1,W ; [7] BTFSS STATUS,Z ; [8] GOTO phas4 ; [10] BSF tim2,7 ; flag timeout with bit 7 RETLW 0 ; no edge detected phas2 NOP ; [6] phas3 NOP ; [7] NOP ; [8] GOTO phas4 ; [10] ;;; prescaler in _OPTION to prsc (prescaler to WDT if bit3 is set) setprsc MOVF prsc,W ; prepare new option in W ANDLW B'00001111' IORLW B'11110000' ; no pu, risi, A4, hilo CLRF TMR0 ; clear timer and prescaler CLRWDT ; clear WDT and prescaler bank1 MOVWF _OPTION bank0 RETLW 0 initlcd MOVLW B'00110000' ; bit3..0,dat/cmd,rd/wr,ena,0 MOVWF PORTB ; command, write, ena low bank1 MOVLW B'00000000' ; 7..1 outputs, 0 output MOVWF _TRISB bank0 MOVLW D'20' CALL delay_Xms CALL Pulse_E_ MOVLW D'5' CALL delay_Xms CALL Pulse_E_ MOVLW D'1' CALL delay_Xms CALL Pulse_E_ CALL Pool_Busy MOVLW B'00100000' ; 4-Bit interface MOVWF PORTB CALL Pulse_E_ MOVLW H'20' ; 4 bit, 1 line, 5x7 matrix CALL outcmd MOVLW H'08' ; display off CALL outcmd MOVLW H'01' ; display on CALL outcmd MOVLW H'06' ; increment, no shift CALL outcmd MOVLW H'0C' ; display on, cursor off CALL outcmd MOVLW H'01' ; clear display, cursor home CALL outcmd RETLW 0 Pulse_E_ BSF PORTB,1 ; ena high BCF PORTB,1 ; ena low RETLW 0 Pool_Busy bank1 MOVLW B'11110000' MOVWF _TRISB ; Port B en lecture sur B4..B7 bank0 MOVLW B'00000100' ; command : RW=1=read, En=low MOVWF PORTB pollbs0 BSF PORTB,1 ; En= high (higher nibble) MOVF PORTB,W ; lecture portB MOVWF tmp0 BCF PORTB,1 ; ena low BSF PORTB,1 ; Pulse_E_ lower nibble BCF PORTB,1 ; ena low BTFSC tmp0,7 ; test busy flag du LCD GOTO pollbs0 CLRF PORTB ; ena low, write, command bank1 MOVLW B'00000000' MOVWF _TRISB ; remt PortB data en sorties bank0 RETLW 0 ;;; binary 0..63 to bcd 00..99 binbcd CLRF tmp0 DECF tmp0,F binbc0 INCF tmp0,F ADDLW D'246' ; subtract 10 BTFSC STATUS,C GOTO binbc0 ADDLW D'10' ; done: undo subtract SWAPF tmp0,F ; upper digit ADDWF tmp0,W ; plus lower digit RETURN hexchr ANDLW H'0F' ; 0..15 to '0'..'F' MOVWF tmp0 ; store SUBLW D'09' ; check if >= 10 (carry clr) MOVLW D'48' BTFSS STATUS,C ; add 7 if carry clr ADDLW D'07' ADDWF tmp0,W RETURN disphex MOVWF tmp2 ; display as two hex chars, save SWAPF tmp2,W CALL hexchr CALL Display_char MOVF tmp2,W CALL hexchr CALL Display_char MOVF tmp2,W ; restore RETURN home1 MOVLW H'88' goto outcmd home MOVLW H'80' ; cursor to begining of line 1 ; fall through to outcmd outcmd MOVWF tmp1 ; tmp0 is used by Pool_Busy CALL Pool_Busy ; command, write, ena low GOTO outbyte Display_char MOVWF tmp1 ; tmp0 is used by Pool_Busy CALL Pool_Busy MOVLW B'00001000' ; data, write, ena low outbyte MOVWF PORTB MOVF tmp1,W ; high nibble first ANDLW H'F0' IORWF PORTB,F BSF PORTB,1 ; Ena= high BCF PORTB,1 ; Ena= low MOVLW H'0F' ANDWF PORTB,F SWAPF tmp1,W ; low nibble ANDLW H'F0' IORWF PORTB,F BSF PORTB,1 ; Ena high BCF PORTB,1 ; Ena low MOVF tmp1,W ; restore W RETURN dispdig dispdi1 MOVLW H'0F' ; digit at FSR ANDWF 0,F BTFSC digo,2 ; 4 digits out? RETLW 0 MOVF digo,F ; 0 digits out? BTFSS STATUS,Z GOTO dispd0 MOVF dign,W ; digit nr 4? XORLW 4 BTFSC STATUS,Z GOTO dispd0 MOVF 0,F ; digit > 0? BTFSC STATUS,Z RETLW 0 dispd0 MOVF 0,W ; write digit ADDLW '0' CALL Display_char INCF digo,F BTFSC digo,2 ; 4 digits out? GOTO dispd4 CALL getdot ; decimal point XORLW 0 BTFSS STATUS,Z CALL Display_char RETLW 0 dispd4 CALL getun0 ; unit (Hz, kHz, MHz) CALL Display_char CALL getun1 CALL Display_char CALL getun2 CALL Display_char RETLW 0 dspd0 MOVF 0,W ; write digit ADDLW '0' CALL dspch CALL getdp ; decimal point / unit XORLW 0 BTFSS STATUS,Z CALL dspch RETLW 0 dspch MOVWF tmp0 ; to DL1414T at digo MOVF PORTA,W ANDLW H'F6' BTFSC tmp0,5 IORLW H'01' BTFSC tmp0,6 IORLW H'08' MOVWF PORTA MOVF tmp0,W ANDLW H'1F' BTFSS digo,0 IORLW H'80' BTFSS digo,1 IORLW H'40' IORLW H'20' ; wr high MOVWF PORTB ANDLW H'DF' ; wr low MOVWF PORTB IORLW H'20' ; wr high MOVWF PORTB INCF digo,F RETLW 0 ;;; clock display for xtal adjustment Check_Calibr BTFSS BP_CAL ; PORTA,0 if pin pulled to gnd: GOTO cali ; clock for xtal adjustment RETLW 0 cali bank1 MOVLW B'11011111' ; no pu, risi, mclk, hilo, presc to WDT MOVWF _OPTION ; BCF _TRISB,0 ; B0 output bank0 CLRF tim1 ; seconds CLRF tim2 ; minutes CLRF tim3 ; hours CLRF TMR0 ; reset timer and prescaler MOVLW B'10100000' ; enable timer interrupt MOVWF INTCON cali0 MOVLW H'BE' ; load -3906 (-1s) to cnt MOVWF cnt1 MOVF tim0,W ; -3907 every 4th second ANDLW H'03' BTFSC STATUS,Z DECF cnt1,F MOVLW H'F0' MOVWF cnt2 CALL home ; clock display MOVLW ' ' CALL Display_char MOVLW 'C' CALL Display_char MOVLW 'A' CALL Display_char MOVLW 'L' CALL Display_char MOVLW ' ' CALL Display_char MOVF tim3,W ; display hours CALL binbcd CALL disphex MOVLW ':' CALL Display_char MOVF tim2,W ; display minutes CALL binbcd CALL disphex MOVLW ':' CALL Display_char MOVF tim1,W ; display seconds CALL binbcd CALL disphex INCF tim1,F ; inc seconds MOVLW D'60' XORWF tim1,W BTFSS STATUS,Z GOTO cali1 CLRF tim1 INCF tim2,F ; inc minutes MOVLW D'60' XORWF tim2,W BTFSS STATUS,Z GOTO cali1 CLRF tim2 INCF tim3,F ; inc hours MOVLW D'24' XORWF tim3,W BTFSC STATUS,Z CLRF tim3 cali1 MOVF cnt1,W ; wait for a new second BTFSS STATUS,Z GOTO cali1 MOVF cnt2,W BTFSS STATUS,Z GOTO cali1 GOTO cali0 ;------------------------------------- delay_Xms MOVWF tmp1 ; delay ca. w * 1000 cycles dlyw1 MOVLW D'149' MOVWF tmp0 dlyw0 NOP DECFSZ tmp0,F GOTO dlyw0 DECFSZ tmp1,F GOTO dlyw1 RETLW 1 delay_100us movlw 0x001 movwf count1 movlw 0x001 movwf count2 movlw 0x020 movwf count3 delay1 decfsz count3,f goto $-1 decfsz count2,f goto $-3 decfsz count1,f goto $-5 return delay_1s movlw 4 movwf count1 movlw 14 movwf count2 movlw 56 movwf count3 goto delay1 ;==================================== delay_3s call delay_1s call delay_1s call delay_1s return ORG H'300' ; rom tables getdp MOVLW B'00011' ; PCLATH to this segment MOVWF PCLATH MOVF dign,W ; digit count ANDLW H'0F' ; 0..15 ADDWF PC,F ; jump to table RETLW 0 ; 0 RETLW 'm' ; 1 RETLW 0 ; 2 RETLW 0 ; 3 RETLW '.' ; 4 RETLW 0 ; 5 RETLW 0 ; 6 RETLW 'K' ; 7 RETLW 0 ; 8 RETLW 0 ; 9 RETLW 'M' ; 10 RETLW 0 ; 11 RETLW 0 ; 12 RETLW 'G' ; 13 RETLW 0 ; 14 RETLW 0 ; 15 getdot MOVLW B'00011' ; PCLATH to this segment MOVWF PCLATH MOVF dign,W ; digit count ANDLW H'0F' ; 0..15 ADDWF PC,F ; jump to table RETLW 0 ; 0 RETLW '.' ; 1 RETLW 0 ; 2 RETLW 0 ; 3 RETLW '.' ; 4 RETLW 0 ; 5 RETLW 0 ; 6 RETLW '.' ; 7 RETLW 0 ; 8 RETLW 0 ; 9 RETLW '.' ; 10 RETLW 0 ; 11 RETLW 0 ; 12 RETLW '.' ; 13 RETLW 0 ; 14 RETLW 0 ; 15 getun0 MOVLW B'00011' ; PCLATH to this segment MOVWF PCLATH DECF dign,W ; digit count ANDLW H'07' ; 0..15 ADDWF PC,F ; jump to table RETLW 0 ; 0 (Hz) RETLW 0 ; 1 (Hz) RETLW 0 ; 2 (Hz) RETLW 2 ; 3 (kHz) RETLW 2 ; 4 (kHz) RETLW 2 ; 5 (kHz) RETLW 5 ; 6 (MHz) RETLW 5 ; 7 (MHz) getun1 MOVLW B'00011' ; PCLATH to this segment MOVWF PCLATH DECF dign,W ; digit count ANDLW H'07' ; 0..15 ADDWF PC,F ; jump to table RETLW 1 ; 0 (Hz) RETLW 1 ; 1 (Hz) RETLW 1 ; 2 (Hz) RETLW 3 ; 3 (kHz) RETLW 3 ; 4 (kHz) RETLW 3 ; 5 (kHz) RETLW 6 ; 6 (MHz) RETLW 6 ; 7 (MHz) getun2 MOVLW B'00011' ; PCLATH to this segment MOVWF PCLATH DECF dign,W ; digit count ANDLW H'07' ; 0..15 ADDWF PC,F ; jump to table RETLW ' ' ; 0 (Hz) RETLW ' ' ; 1 (Hz) RETLW ' ' ; 2 (Hz) RETLW 4 ; 3 (kHz) RETLW 4 ; 4 (kHz) RETLW 4 ; 5 (kHz) RETLW 7 ; 6 (MHz) RETLW 7 ; 7 (MHz) loadcgr MOVLW B'00011' ; PCLATH to pattern MOVWF PCLATH MOVLW H'40' ; character generator rom CALL outcmd CLRF tmp2 ; byte counter loadcg0 MOVF tmp2,W XORLW D'64' ; test if all 64 bytes out BTFSC STATUS,Z RETLW 0 ; return if so MOVF tmp2,W CALL pattern ; get byte from table, write to cgr CALL Display_char INCF tmp2,F ; point to next byte GOTO loadcg0 pattern ADDWF PC,F ; return char from table below cgrtb0 RETLW B'01001' ; H RETLW B'01001' RETLW B'01001' RETLW B'01111' RETLW B'01001' RETLW B'01001' RETLW B'01001' RETLW B'00000' cgrtb1 RETLW B'00000' ; z RETLW B'00000' RETLW B'01111' RETLW B'00010' RETLW B'00100' RETLW B'01000' RETLW B'01111' RETLW B'00000' cgrtb2 RETLW B'01000' ; k RETLW B'01000' RETLW B'01001' RETLW B'01010' RETLW B'01100' RETLW B'01010' RETLW B'01001' RETLW B'00000' cgrtb3 RETLW B'01001' ; H RETLW B'01001' RETLW B'01001' RETLW B'01111' RETLW B'01001' RETLW B'01001' RETLW B'01001' RETLW B'00000' cgrtb4 RETLW B'00000' ; z RETLW B'00000' RETLW B'01111' RETLW B'00010' RETLW B'00100' RETLW B'01000' RETLW B'01111' RETLW B'00000' cgrtb5 RETLW B'01000' ; M RETLW B'01101' RETLW B'01010' RETLW B'01010' RETLW B'01000' RETLW B'01000' RETLW B'01000' RETLW B'00000' cgrtb6 RETLW B'10100' ; MH RETLW B'10100' RETLW B'10100' RETLW B'10111' RETLW B'10100' RETLW B'10100' RETLW B'10100' RETLW B'00000' cgrtb7 RETLW B'10000' ; Hz RETLW B'10000' RETLW B'10111' RETLW B'10001' RETLW B'10010' RETLW B'10100' RETLW B'10111' RETLW B'00000' ;======================= ; affiche Num Msg en eeprom ; terminaison par caractere null ou taille de 16 cars ;============================== AffNumMsgEeprom movf Pointer_Msg,w movwf cnt2 bcf STATUS,C rlf cnt2,f rlf cnt2,f rlf cnt2,f rlf cnt2,f ; pointeur = NøMsg * 16 clrf cnt3 affMsg_ movf cnt3,w addwf cnt2,w MOVWF EEADR bank1 BSF EECON1,RD ; bit 0 bank0 MOVF EEDATA,W XORLW 0 ; Is this the terminating char? BTFSC STATUS,Z GOTO EndAffNum call Display_char incf cnt3,f btfss cnt3,4 ; 16em car ? goto affMsg_ EndAffNum return ;--------------------- org 0x2100 signature ;1234567890123456 DT "FreqAR_6.ASM " DT "16F84A Q=4 Mhz " DT "28 Sept 2024 " DT " ",0 END; ---------------------------------------------------------------------- Release build of project `C:\_Mplab8\_Mesprojets_ASM\_Freq\Freqencemetre.mcp' started. Language tool versions: MPASMWIN.exe v5.39, mplink.exe v4.38, mplib.exe v4.38 Sun Jan 15 14:35:46 2012 ---------------------------------------------------------------------- Clean: Deleting intermediary and output files. Clean: Deleted file "C:\_Mplab8\_Mesprojets_ASM\_Freq\freqar_5_16F84_2012.o". Clean: Deleted file "C:\_Mplab8\_Mesprojets_ASM\_Freq\freqar_5_16F84_2012.err". Clean: Deleted file "C:\_Mplab8\_Mesprojets_ASM\_Freq\freqar_5_16F84_2012.hex". Clean: Deleted file "C:\_Mplab8\_Mesprojets_ASM\_Freq\freqar_5_16F84_2012.lst". Clean: Deleted file "C:\_Mplab8\_Mesprojets_ASM\_Freq\freqar_5_16F84_2012.xrf". Clean: Deleted file "C:\_Mplab8\_Mesprojets_ASM\_Freq\freqar_5_16F84_2012.cof". Clean: Done. Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F84 "freqar_5_16F84_2012.asm" /l"freqar_5_16F84_2012.lst" /e"freqar_5_16F84_2012.err" /x"freqar_5_16F84_2012.xrf" /w2 /aINHX8M Message[308] C:\_MPLAB8\_MESPROJETS_ASM\_FREQ\FREQAR_5_16F84_2012.ASM 19 : Warning level superseded by command line value. (2) Executing: "C:\Program Files\Microchip\MPASM Suite\mplink.exe" /p16F84 /l"C:\Program Files\Microchip\MPLAB ASM30 Suite\lib" /k"C:\Program Files\Microchip\MPASM Suite\LKR" "freqar_5_16F84_2012.o" /z__MPLAB_BUILD=1 /w /o"C:\_Mplab8\_Mesprojets_ASM\_Freq\freqar_5_16F84_2012.cof" /x MPLINK 4.38, Linker Copyright (c) 1998-2010 Microchip Technology Inc. Errors : 0 Loaded C:\_Mplab8\_Mesprojets_ASM\_Freq\freqar_5_16F84_2012.cof. ---------------------------------------------------------------------- Release build of project `C:\_Mplab8\_Mesprojets_ASM\_Freq\Freqencemetre.mcp' succeeded. Language tool versions: MPASMWIN.exe v5.39, mplink.exe v4.38, mplib.exe v4.38 Sun Jan 15 14:35:51 2012 ---------------------------------------------------------------------- BUILD SUCCEEDED