Weeder Freq Counter

I have been trying to get the weeder program to operate on a 16F628A chip in its basic form with register locations changes as appropriate . The program shows on the display / / . / / / / / MHz with a regular flash to Overflow in approximately 30 seconds.In MpLab the only noticable difference between simulations ( F84 - F628A ) is that the second run of the program does not set INDF back to its starting value of 2F. Before I smash the darn thing can anybody offer any suggestions . Signed most frustrated

Reply to
Fred
Loading thread data ...

lol sounds like my projects :-)

in

program

can

Reply to
Hopkins

Have you turned off the comparators.

movlw 7 movwf CMCON

Mike.

Reply to
NewsGroup

Reply to
Fred

Hi,

I did a conversion to a 16F628 a couple of years ago, so I'm including the code in the hope you can get something out of it.

There are two files below - the first (main.asm) with the actual code for the frequency counter and the second (delay.inc) with some delay functions.

Note: I used a 20 MHz x-tal, so you might need to change the timing in the delay routines. Also, I changed the display code to handle a HD44780 based LCD display. I think the original weeder used a similar display, but the display timing in the Peter Cousens or Terry Weeder code is way off from the timings stated in the datasheets for HD44780 based displays.

Hope this helps!

Best regards, Johnny

;****************************************************************************** ; FREQUENCY COUNTER ; Model : WTCNT ; Author : Terry J. Weeder ; Date : November 18, 1993 ; Version: 1.0 ; ;

formatting link
; ; Ported to 16f84 by ; Peter Cousens ; October 1998 ; ; ; Cleaned up and ported to 16F628 by ; Rewritten LCD output code to 1x16 display organized as 2x8 ; Johnny Norre ; March 2004 ; ;****************************************************************************** ; ;watchdog disabled ; list P=16F628 include "P16f628.inc" __CONFIG _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF

MSB equ 7h LSB equ 0h ; cnt equ 2h rs equ 2h rw equ 1h e equ 0h o equ 7h

; VAR_BASE = 0x20 ; Base of general purpose registers

gate equ 00h+VAR_BASE cnt1 equ 01h+VAR_BASE cnt2 equ 02h+VAR_BASE cnt3 equ 03h+VAR_BASE calc1 equ 04h+VAR_BASE calc2 equ 05h+VAR_BASE calc3 equ 06h+VAR_BASE sum1 equ 07h+VAR_BASE sum2 equ 08h+VAR_BASE sum3 equ 09h+VAR_BASE rtcc2 equ 0Ah+VAR_BASE Disp1 equ 0Dh+VAR_BASE Disp2 equ 0Eh+VAR_BASE Disp3 equ 0Fh+VAR_BASE Disp4 equ 10h+VAR_BASE Disp5 equ 11h+VAR_BASE Disp6 equ 12h+VAR_BASE Disp7 equ 13h+VAR_BASE Disp8 equ 14h+VAR_BASE count1 equ 20h+VAR_BASE count2 equ 21h+VAR_BASE in_reg equ 22h+VAR_BASE addcnt equ 23h+VAR_BASE DelayTmp DelayTmpLo equ 24h+VAR_BASE DelayTmpHi equ 25h CharPos equ 26h ; 0..7 = left side, 8..15 = right side LcdTmp equ 27h oflag equ 28h+VAR_BASE ; Added - original code used IRP bit in the STATUS register (not portable!)

; org 0 goto start? #include "..\MultiThermometer\delay.inc"

; LcdCtrlOut ; ; Sends a control code to the LCD ; ; Input: ; Wreg = control code to send ; Output: ; None ; Modified: ; Wreg ; STATUS - changed to bank 0 on exit LcdCtrlOut: clrf STATUS movwf PORTB ; Write to port B call Delay1Ms bcf PORTA,rs ; CLear RS flag = instruction output bsf PORTA,e ; Set E flag call Delay1Ms bcf PORTA,e ; Clear E flag = buffer data call Delay1Ms return

; LcdCharOut ; ; Sends a character to the LCD ; ; Input: ; Wreg = character to send ; Output: ; None ; Modified: ; Wreg ; STATUS - changed to bank 0 on exit LcdCharOut: clrf STATUS movwf LcdTmp ; Store character (Wreg) movf CharPos,W ; Get address addlw 0x80 ; Point to left side of display btfsc CharPos,3 ; Should it be right side? addlw 0x38 ; Point to right side of display call LcdCtrlOut movf LcdTmp,W movwf PORTB ; Write to port B call Delay1Ms bsf PORTA,rs ; Set RS flag = data out bsf PORTA,e ; Set E flag call Delay1Ms bcf PORTA,e ; Clear E flag = buffer data call Delay1Ms incf CharPos,1 ; Point to next character position return

; sub: bcf oflag,o ;clear overflow bit movf calc1,w ;subtract calc1 from cnt1 subwf cnt1 ,f btfsc STATUS,C goto sb1 movlw 0x01 ;borrow from cnt2 if overflow subwf cnt2 ,f btfsc STATUS,C goto sb1 subwf cnt3 ,f ;borrow from cnt3 if cnt2 overflow btfss STATUS,C bsf oflag,o ;set overflow bit if result is negative sb1: movf calc2,w ;subtract calc2 from cnt2 subwf cnt2 ,f btfsc STATUS,C goto sb2 movlw 0x01 ;borrow from cnt3 if cnt2 overflow subwf cnt3 ,f btfss STATUS,C bsf oflag,o ;set overflow bit if result is negative sb2: movf calc3,w ;subtract calc3 from cnt3 subwf cnt3 ,f btfss STATUS,C bsf oflag,o ;set overflow bit if result is negative retlw 0x00 ; add: movf calc1,w ;add calc1 to cnt1 addwf cnt1 ,f btfss STATUS,C goto ad1 incfsz cnt2 ,f ;add to cnt2 if cnt1 overflow goto ad1 incf cnt3 ,f ;add to cnt3 if cnt2 overflow ad1: movf calc2,w ;add calc2 to cnt2 addwf cnt2 ,f btfsc STATUS,C incf cnt3 ,f ;add to cnt3 if cnt2 overflow movf calc3,w ;add calc3 to cnt3 addwf cnt3 ,f retlw 0x00 ; cnvt: movlw 0x07 ;7 digits in display movwf count1 movlw Disp1 ;set FSR for MSB in display movwf FSR movlw 0x2F ;one less that ASCII "0" cnvt0: movwf INDF incf FSR ,f decfsz count1 ,f goto cnvt0 movlw 0x0F ;load "1,000,000" in calc1-3 movwf calc3 movlw 0x42 movwf calc2 movlw 0x40 movwf calc1 cnvt1: call sub ;subtract number from count incf Disp1,f ;increment 1,000,000's register movlw 0x3A xorwf Disp1,w btfsc STATUS,Z goto overflow btfss oflag,o ;check if overflow goto cnvt1 call add ;add back last number movlw 0x01 ;load "100,000" in calc1-3 movwf calc3 movlw 0x86 movwf calc2 movlw 0xA0 movwf calc1 cnvt2: call sub ;subtract number from count incf Disp2,f ;increment 100,000's register btfss oflag,o ;check if overflow goto cnvt2 call add ;add back last number clrf calc3 ;load "10,000" in calc1-3 movlw 0x27 movwf calc2 movlw 0x10 movwf calc1 cnvt3: call sub ;subtract number from count incf Disp3 ,f ;increment 10,000's register btfss oflag,o ;check if overflow goto cnvt3 call add ;add back last number movlw 0x03 ;load "1,000" in calc1-3 movwf calc2 movlw 0xE8 movwf calc1 cnvt4: call sub ;subtract number from count incf Disp4 ,f ;increment 1,000's register btfss oflag,o ;check if overflow goto cnvt4 call add ;add back last number clrf calc2 ;load "100" in calc1-3 movlw 0x64 movwf calc1 cnvt5: call sub ;subtract number from count incf Disp5 ,f ;increment 100's register btfss oflag,o ;check if overflow goto cnvt5 call add ;add back number movlw 0x0A ;load "10" in calc1-3 movwf calc1 cnvt6: call sub ;subtract number from count incf Disp6 ,f ;increment 10's register btfss oflag,o ;check if overflow goto cnvt6 call add ;add back last number movf cnt1,w ;put remainder in 1's register addwf Disp7 ,f incf Disp7 ,f retlw 0x00 ; count: clrf STATUS bsf STATUS,RP0 ; Bank 1 errorlevel -302 movlw b'00110111' ;rtcc = ext, 1/256 movwf OPTION_REG errorlevel +302 bcf STATUS,RP0 ; Bank 0 bcf PORTA,3 bcf PORTA,2 clrf cnt3 clrf TMR0 clrf rtcc2 bsf PORTA,2 ;toggle rtcc pin bcf PORTA,2 movf gate,w ;get gate time movwf count1 bsf PORTA,3 ;start count fr4: movlw 0xFA movwf count2 goto fr6 fr5: nop nop nop nop nop nop fr6: movf TMR0,w ;test for rtcc rollover (12) subwf rtcc2 ,f btfss STATUS,Z goto fr7 nop goto fr8 fr7: btfsc STATUS,C incf cnt3 ,f fr8: movwf rtcc2 nop nop nop decfsz count2 ,f goto fr5 decfsz count1 ,f goto fr4 bcf PORTA,3 ;stop count movf TMR0,w ;get rtcc count movwf cnt2 subwf rtcc2 ,f ;test for rtcc rollover btfss STATUS,C goto fr9 btfss STATUS,Z incf cnt3 ,f fr9: clrf cnt1 ;set to get prescaler count fr10: decf cnt1 ,f bsf PORTA,2 ;toggle rtcc pin bcf PORTA,2 movf TMR0,w ;test if rtcc has changed xorwf cnt2,w btfsc STATUS,Z goto fr10 retlw 0x00

; ;****************************************************************************** ; START ;****************************************************************************** ; start?: clrf PORTA ; Turn off comparators and enable PORTA for input/output movlw 0x07 movwf CMCON clrf STATUS bsf STATUS,RP0 ; Bank 1 errorlevel -302 movlw b'00010000' ;instruction, write, enable low movwf TRISA errorlevel +302 bcf STATUS,RP0 ; Bank 0 clrf PORTB clrf STATUS bsf STATUS,RP0 ; Bank 1 errorlevel -302 movlw b'00000000' movwf TRISB errorlevel +302 bcf STATUS,RP0 ; Bank 0 movlw .15 ; Wait 15 ms. call DelayMs movlw 0x38 ;initialize display movwf PORTB bsf PORTA,e ;toggle enable call Delay1Ms bcf PORTA,e call Delay1Ms bsf PORTA,e ;toggle enable call Delay1Ms bcf PORTA,e call Delay1Ms bsf PORTA,e ;toggle enable call Delay1Ms bcf PORTA,e call Delay1Ms movlw 0x38 ;function call LcdCtrlOut movlw b'00001100' ;display on, cursor off call LcdCtrlOut movlw b'00000001' ;clear display call LcdCtrlOut movlw b'00000110' ;entry mode call LcdCtrlOut call Welcome

; mhz: movlw 0x14 ;0.1 sec gate movwf gate call count call cnvt ;convert binary to BCD movlw 0x30 ;test if "0" xorwf Disp1,w btfss STATUS,Z goto mhz1 movlw 0x30 ;test if "0" xorwf Disp2,w btfsc STATUS,Z goto khz1 mhz1: clrf CharPos ;Output from left side movlw 0x02 ;output first 2 characters movwf count1 movlw Disp1 ;MSD of freq movwf FSR mhz2: movlw 0x30 ;test if "0" xorwf INDF,w btfss STATUS,Z goto mhz3 movlw 0x20 ;change preceeding "0's" to "space" call LcdCharOut incf FSR ,f decfsz count1 ,f goto mhz2 goto mhz4 mhz3: movf INDF,w call LcdCharOut incf FSR ,f decfsz count1 ,f goto mhz3 mhz4: movlw 0x2E ;"." call LcdCharOut movlw 0x05 ;output last 5 characters movwf count1 mhz5: movf INDF,w call LcdCharOut incf FSR ,f decfsz count1 ,f goto mhz5 movlw 0x20 ;"space" call LcdCharOut movlw 0x4D ;"M" call LcdCharOut movlw 0x48 ;"H" call LcdCharOut movlw 0x7A ;"z" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut goto mhz ; khz: movlw 0x14 ;0.1 sec gate movwf gate call count call cnvt ;convert binary to BCD movlw 0x30 ;test if 0 xorwf Disp1,w btfss STATUS,Z goto mhz1 movlw 0x32 ;test if < 2 subwf Disp2,w btfsc STATUS,C goto mhz1 movlw 0x30 ;test if "0" xorwf Disp2,w btfss STATUS,Z goto khz1 movlw 0x30 ;test if "0" xorwf Disp3,w btfsc STATUS,Z goto xkhz khz1: clrf CharPos ;Output from left side movlw 0x05 ;output first 5 characters movwf count1 movlw Disp1 ;MSD of freq movwf FSR khz2: movlw 0x30 ;test if "0" xorwf INDF,w btfss STATUS,Z goto khz3 movlw 0x20 ;change preceeding "0's" to "space" call LcdCharOut incf FSR ,f decfsz count1 ,f goto khz2 goto khz4 khz3: movf INDF,w call LcdCharOut incf FSR ,f decfsz count1 ,f goto khz3 khz4: movlw 0x2E ;"." call LcdCharOut movf INDF,w ;output last 2 characters call LcdCharOut incf FSR ,f movf INDF,w call LcdCharOut movlw 0x20 ;"space" call LcdCharOut movlw 0x4B ;"K" call LcdCharOut movlw 0x48 ;"H" call LcdCharOut movlw 0x7A ;"z" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut goto khz ; xkhz: movlw 0xC8 ;1 sec gate movwf gate call count call cnvt ;convert binary to BCD movlw 0x30 ;test if 0 xorwf Disp1,w btfss STATUS,Z goto khz movlw 0x32 ;test if < 2 subwf Disp2,w btfsc STATUS,C goto khz movlw 0x30 ;test if 0 xorwf Disp2,w btfss STATUS,Z goto xkhz1 movlw 0x30 ;test if 0 xorwf Disp3,w btfsc STATUS,Z goto hz0 xkhz1: clrf CharPos ;Output from left side movlw 0x04 ;output first 4 characters movwf count1 movlw Disp1 ;MSD of freq movwf FSR xkhz2: movlw 0x30 ;test if "0" xorwf INDF,w btfss STATUS,Z goto xkhz3 movlw 0x20 ;change preceeding "0's" to "space" call LcdCharOut incf FSR ,f decfsz count1 ,f goto xkhz2 goto xkhz4 xkhz3: movf INDF,w call LcdCharOut incf FSR ,f decfsz count1 ,f goto xkhz3 xkhz4: movlw 0x2E ;"." call LcdCharOut movf INDF,w ;output last 3 characters call LcdCharOut incf FSR ,f movf INDF,w call LcdCharOut incf FSR ,f movf INDF,w call LcdCharOut movlw 0x20 ;"space" call LcdCharOut movlw 0x4B ;"K" call LcdCharOut movlw 0x48 ;"H" call LcdCharOut movlw 0x7A ;"z" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut goto xkhz ; hz: movlw 0xC8 ;1 sec gate movwf gate call count call cnvt ;convert binary to BCD movlw 0x30 ;test if "0" xorwf Disp1,w btfss STATUS,Z goto xkhz1 movlw 0x30 ;test if "0" xorwf Disp2,w btfss STATUS,Z goto xkhz1 movlw 0x32 ;test if < 2 subwf Disp3,w btfsc STATUS,C goto xkhz1 hz0: clrf CharPos ;Output from left side movlw 0x07 ;output first 7 characters movwf count1 movlw Disp1 ;MSD of freq movwf FSR hz1: movlw 0x30 ;test if "0" xorwf INDF,w btfss STATUS,Z goto hz2 movlw 0x20 ;change preceeding "0's" to "space" call LcdCharOut incf FSR ,f decfsz count1 ,f goto hz1 goto hz3 hz2: movf INDF,w call LcdCharOut incf FSR ,f decfsz count1 ,f goto hz2 hz3: movlw 0x20 ;"space" call LcdCharOut movlw 0x48 ;"H" call LcdCharOut movlw 0x7A ;"z" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut movlw 0x20 ;"space" call LcdCharOut goto hz ; overflow: movlw 0x01 ;clear display call LcdCtrlOut movlw 0x02 movwf CharPos ;Output from char 2 movlw 0x84 ;display address call LcdCtrlOut movlw 0x4F ;"O" call LcdCharOut movlw 0x76 ;"v" call LcdCharOut movlw 0x65 ;"e" call LcdCharOut movlw 0x72 ;"r" call LcdCharOut movlw 0x66 ;"f" call LcdCharOut movlw 0x6C ;"l" call LcdCharOut movlw 0x6F ;"o" call LcdCharOut movlw 0x77 ;"w" call LcdCharOut clrf CharPos ;Output from left side goto mhz ; Welcome: movlw 0x01 call LcdCtrlOut clrf CharPos movlw "D" call LcdCharOut movlw "u" call LcdCharOut movlw "N" call LcdCharOut movlw "o" call LcdCharOut movlw " " call LcdCharOut movlw " " call LcdCharOut movlw "G" call LcdCharOut movlw "F" call LcdCharOut movlw "-" call LcdCharOut movlw "0" call LcdCharOut movlw "0" call LcdCharOut movlw "1" call LcdCharOut movlw 15 call DelayDs return

end

--- < CUT> -------------------------------------------------------------

; ; *** DELAY.INC (C)2003 by DuNo Electronics I/S & Johnny Norre *** ; ; This module provides various delay functions. All functions assume ; a clock speed of 20MHz! ; ; NOTE: The variable "DelayTmp, DelayTmpLo and DelayTmpHi" (2 bytes ) ; must have been defined prior to calling any functions in this ; module. The DELAYVAR define can be used in a CBLOCK to define ; these variables. ; ; ; 26.04.03 v0.0 Initial version - DelayMS implemented

; --- Defines ---

; DELAYVAR can be used in a CBLOCK to define the variables needed by this module. ; Note: DELAYVAR must be defined in Bank 0! #define DELAYVAR DelayTmp:0, DelayTmpLo, DelayTmpHi

; --- Functions ---

; DelayMs ; ; Delay for 1..256 milliseconds ; Note: The time spent in this function is not included in the ; timing, resulting in a small overhead (3 cycles per ; millisecond). ; ; Input: ; Wreg = Number of milliseconds (0 = 256) ; Output: ; None ; Modified: ; Wreg and DelayTmpLo is modified by function DelayMs: clrf STATUS ; Bank 0 bcf STATUS,RP1 movwf DelayTmpLo DelayMsLoop: call Delay1Ms decfsz DelayTmpLo,f goto DelayMsLoop return

; DelayDs ; ; Delay DeciSeconds - Delay for 1..256 * 1/10 seconds ; Note: The time spent in this function is not included in the ; timing, resulting in a small overhead. ; ; Input: ; Wreg = Number of deciseconds (0 = 256) ; Output: ; None ; Modified: ; Wreg and DelayTmpLo is modified by function DelayDs: clrf STATUS ; Bank 0 movwf DelayTmpHi DelayDsLoop: movlw .100 call DelayMs decfsz DelayTmpHi,f goto DelayDsLoop return

; Delay1Ms ; ; Delay for 1 millisecond. This is done by waiting for 5000 cycles ; as the module assumes 20MHz clock speed. ; ; Input: ; None ; Output: ; None ; Modified: ; Wreg Delay1Ms: movlw .256-.50+2 ; Burn 50*100 cycles (minus time spent by this function) Delay1MsLoop: call Delay100Cycles addlw 1 btfss STATUS,Z goto Delay1MsLoop goto $+1 return

; Delay100Cycles ; ; Delay for 100 cycles. ; Note: 2 cycles is spent by the call to the funtion and ; another 2 by returning to the caller, so 96 cycles ; is spent by the actual code in the function ; ; Input: ; None ; Output: ; None ; Modified: ; None Delay100Cycles: call Delay16Cycles call Delay16Cycles call Delay16Cycles call Delay16Cycles call Delay16Cycles call Delay16Cycles return

; Delay16Cycles ; ; Delay for 16 cycles ; Note: Call to the function takes 2 cycles and the return ; takes 2 cycles, so 12 cycles is spent by the function ; ; Input: ; None ; Output: ; None ; Modified: ; None Delay16Cycles: goto $+1 ; Spend 2 cycles goto $+1 ; spend 2 cycles goto $+1 ; Spend 2 cycles goto $+1 ; spend 2 cycles goto $+1 ; Spend 2 cycles goto $+1 ; spend 2 cycles return

--

"Fred"  wrote in message 
news:NcJvg.8079$tE5.1327@news-server.bigpond.net.au...
>I have been trying to get the weeder program to operate on a 16F628A chip 
>in its basic form with register locations changes as appropriate . The 
>program shows on the display  / / . / / / / / MHz with a regular flash to 
>Overflow in approximately 30 seconds.In MpLab the only noticable difference 
>between simulations ( F84 - F628A ) is that the second run of the program 
>does not set INDF back to its starting value of 2F. Before I smash the darn 
>thing can anybody offer any suggestions . Signed most frustrated
>
Reply to
Joe

Thanks Joe , as you noted in your conversion " original code used IRP bit in the STATUS register (not portable!)" .When I watched the program run in MPlab the program went to update its latest converted figure in the allocated FSR but the value in the INDF register just seemed to vanish . It , of course , was directed to a different bank . A smile appears , the hammer gently lowered , all is calm till the next project.

Reply to
Fred

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.