Maker Pro
Maker Pro

Weeder Freq Counter

F

Fred

Jan 1, 1970
0
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
 
N

NewsGroup

Jan 1, 1970
0
Have you turned off the comparators.

movlw 7
movwf CMCON

Mike.
 
F

Fred

Jan 1, 1970
0
Thanks for the reply Mike . yes , sorry I didnt mention that I had done so
.. Talking to a mate at work today , the direction of conversation was
tending to a fault with MpLad , with an associated assembler to hex fault .
The hammer is raising
 
J

Joe

Jan 1, 1970
0
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
;
; WWW.WEEDTECH.COM
;
; 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


--
 
F

Fred

Jan 1, 1970
0
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.
 
Top