PDA

View Full Version : PIC newbie - took ages to program and i still have bugs



Trickae
- 25th September 2007, 05:00
Heres the error log


Clean: Deleting intermediary and output files.
Clean: Deleted file "C:\Documents and Settings\\My Documents\speedtemp.mcs".
Clean: Done.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPAsmWin.exe" /q /p16F84 "SPEED254.ASM" /l"SPEED254.lst" /e"SPEED254.err"
Warning[207] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 140 : Found label after column 1. (SVNSEG) Warning[207] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 167 : Found label after column 1. (INTER) Error[113] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 319 : Symbol not previously defined (z) Error[113]
C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 323 : Symbol not previously defined (z) Error[113]
C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 362 : Symbol not previously defined (c) Error[113]
C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 373 : Symbol not previously defined (c) Message[302]
C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 501 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 503 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 505 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 707 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 709 : Register in operand not in bank 0. Ensure that bank bits are correct.
Error[113] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 729 : Symbol not previously defined (z) Error[113] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 732 : Symbol not previously defined (z) Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 953 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 955 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 957 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 958 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 960 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 961 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 963 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 968 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 970 : Register in operand not in bank 0. Ensure that bank bits are correct.
Error[113] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 975 : Symbol not previously defined (z) Error[113] C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 1045 : Symbol not previously defined (c) Halting build on first failure as requested.
BUILD FAILED: Tue Sep 25 12:53:21 2007


and my code's attached

Programming language: ASM PIC instruction set
PIC: PIC16F84

Any help would be greatly appreciated

Archangel
- 25th September 2007, 05:57
Hi Trickae,
Welcome, looks like you just joined today, Not too many people will open a zip file from someone they do not know well, so how about you break up that program and let us look at it in pieces if you cannot post it all in one without zipping it.
JS

paul borgmeier
- 25th September 2007, 06:48
>>took ages to program and i still have bugs

Interesting .... I found your code here with google

http://www.siliconchip.com.au/cms/attachments/show.html?year=1999&month=November

Trickae
- 25th September 2007, 10:09
you've got me -

the code is legit no malware

the code is available with current kit based speed alert devices but I need to modify it for a personal project. I just Downloaded MPLAB today and ran the first couple of instructions and found a list of errors. I was expecting everything to be in order:

Heres the code in full:

part 1:


; File SPEED254.ASM changes from SPEED.ASM to allow speed readings up to 254km/h
; Uses assembly code for PIC16F84 microcontroller
; This program is for a car speed alarm. It utilises three 7-segment displays
; which show the set speed. The speed setting can be altered with up and down pushbutton
; switches from 0 to 255km/h in 5km/h steps. When the speed of the vehicle reaches the set speed,
; the alarm sounds and an LED lights up. The alarm is a short beep beep sound while the LED
; remains lit until the speed is reduced below the alarm speed or the alarm speed is increased
; above the vehicles speed.
;
; A rotating magnet or magnets installed on the vehicles tail shaft or drive shaft
; trigger an inductive (coil) sensor to detect vehicle speed and this signal is detected via
; an interrupt in the processor.
;
; Calibration can be made by setting an alarm speed on the display and then bringing the
; vehicle speed up to the alarm speed as shown on the vehicles speedometer.
; The Calibrate switch is then pressed. The display will show CAL until
; calibrated. Display will show Err (error) if too few pulses or none are present while calibrating.
; No calibration allowed in speedometer mode.
;
; Each pressing the Mode switch will cycle between alarm speed indication, speedometer
; and off which disables the speed alarm.
;
; Alarm indication occurs for speedometer and alarm speed modes.
;
; Pressing the Up switch at power up will set the speed alarm for either a
; repeat warning of overspeed or single alarm. The repeat alarm will produce a tone every
; 10-seconds until the speed goes below the setting or the speed setting is increased above
; the speed.
;
; When pressing the Up switch at power up, a 'r' on the right display indicates repeat
; alarm and a '-' indicates no-repeat alarm option.
;
; Pressing the Mode switch at power up will toggle the speed alarm with the speedometer on or off
; If the display shows an 'S' then the speedometer function will operate and a '-' indicates that
; the speedometer is off.
;
; Pressing the Down switch at power up will set the speed alarm threshold point either high or
; low. The low threshold means that the alarm will sound at the set speed and switch off
; when the speed goes 1km/h or less below this speed. The high threshold will set the alarm
; when the speed is 1km/h or more above the set speed and go off for speeds at or below the
; set speed. A high setting will be indicated by an 'H' and a low setting by an 'L'as shown during
; power up with the down switch pressed.
;
; Processor pin allocations are as follows:
; RA0 Output disp1 driving transistor for common anode display
; RA1 Output disp2
; RA2 Output disp3
; RA3 Output for alarm
; RA4 Input from switches

; RB0 Input for wheel sensor (interrupt)
; RB1 c segment drive for seven segment LED display
; RB2 d segment drive
; RB3 e segment drive
; RB4 f segment drive
; RB5 a segment drive
; RB6 b segment drive
; RB7 g segment drive

; CPU configuration
;
list P=16F84
#include "p16f84.inc"
__config _XT_OSC & _WDT_OFF & _PWRTE_ON

; Define variables at memory locations

; EEPROM DATA

EEPROM1 equ H'00' ; non-volatile storage for display1
EEPROM2 equ H'01' ; non-volatile storage for display2
EEPROM3 equ H'02' ; non-volatile storage for display3
EEPROM4 equ H'03' ; non-volatile storage to toggle repeat alarm feature and mode
EEPROM5 equ H'04' ; non-volatile storage of LS byte of calibration number
EEPROM6 equ H'05' ; non-volatile storage of MS byte of calibration number

; RAM

DISP1 equ H'0C' ; working storage for Display1 value alarm speed mode
DISP2 equ H'0D' ; working storage for Display2 value alarm speed mode
DISP3 equ H'0E' ; working storage for Display3 value alarm speed mode
STATUS_TMP equ H'0F' ; temp storage for status during interrupt
W_TMP equ H'10' ; temporary storage for w during interrupt
VALUE_1 equ H'11' ; delay value storage
VALUE_2 equ H'12' ; delay value storage
FLAG_1 equ H'13' ; flag, bit 0 = flag for closed switch, bit 1 for interrupt indicator
; bit 2 for alarm tone required, bit 3 for tone duty cycle,
; bit 4 alarm off, bit 5 overspeed, bit 6 EEPROM
; write repeat number, bit 7 for calibrate flag
FLAG_2 equ H'14' ; alarm tone period settable from 00-FE
FLAG_3 equ H'15' ; alarm tone sequence 00000000=on,00000001=off,00000010=on >=00000011 off,
; use a more significant bit to set reocurrence, bit 6 or 7
REPEAT equ H'16' ; bit 0 working store repeat alarm flag stored in EEPROM4, bit 1 on/off flag
; bit 1 on/off flag, bit 2 speedo/alarm select flag, bit 3 speedo on/off flag
; bit 4 alarm threshold
SPEED_EQV equ H'17' ; storage for speed equivalent (value of 5 per 5km/h) 160km/h=160
TEMP_1 equ H'18' ; temporary working storage
TEMP_2 equ H'19' ; temp storage
TIME_CNT1 equ H'1A' ; counter for pulse count period
TIME_CNT2 equ H'1B' ; counter for pulse count period
TIME_CNT3 equ H'1C' ; working lsb calibration number stored in EEPROM5
TIME_CNT4 equ H'1D' ; working msd calibration number stored in EEPROM6
PULSE_CNT equ H'1E' ; counter for speed pulses compared with speed_eqv
ERR_FLG equ H'1F' ; bit 0 is error flag for counter overrange during calibration
SPEEDO equ H'20' ; latched value for speedometer obtained from PULSE_CNT
SPEED1 equ H'21' ; display1 value during speedometer mode
SPEED2 equ H'22' ; display2 value during speedometer mode
SPEED3 equ H'23' ; display3 value during speedometer mode
TEMP equ H'24' ; temporary register for BCD conversion
BCD_0 equ H'25' ; decimal value MSD
BCD_1 equ H'26' ; decimal packed BCD LS digits
BIN_0 equ H'27' ; binary value for BCD conversion
CNT_8 equ H'28' ; counter for BCD conversion
TEMP_X equ H'29' ; temporary register for speed equivalent calculation

; preprogram EEPROM DATA

ORG 2100
DE 0x00, 0x06, 0x00 ; preset EEPROM1-EEPROM3 ( initial speed setting is 60)
DE 0x03 ; set EEPROM4 (repeat alarm on bit 0 and set to on/off bit 1)
; bit 2 speedo/set bit to set alarm mode, bit 3 speedo on
; bit 4 alarm threshold low
DE 0xB3, 0x11 ; set calibration EEPROM5 & EEPROM6 (set to 100Hz = 160km/h
; calibration calculated out at 1.6s update time 160km/h = 160 pulses counted.
; 3.579545MHz/4/2/(256-100+2) = 353.1175us and require 4531Decimal for 1.6 sec or 11B3Hex

; Program begins

; define reset and interrupt vector start addresses

org 0 ; start at address 0000h
goto MAIN ; normal service routines from Reset vector
org 4 ; interrupt vector 0004h, start interrupt routine here
goto INTER ; go to start of interrupt routine, bypass subroutines

; subroutine to get seven segment display data. (This is placed at front of programm to prevent computed
; goto crossing 256 bit boundary. *PCL control only over least significant 8-bits*)

SVNSEG andlw 0x0F; remove most significant bits if present prevents value >16h
addwf PCL,f ; add value of display to program counter
retlw B'10000000' ; 7-segment code 0
retlw B'10111100' ; 7-segment code 1
retlw B'00010010' ; 7-segment code 2
retlw B'00011000' ; 7-segment code 3
retlw B'00101100' ; 7-segment code 4
retlw B'01001000' ; 7-segment code 5
retlw B'01000000' ; 7-segment code 6
retlw B'10011100' ; 7-segment code 7
retlw B'00000000' ; 7-segment code 8
retlw B'00001000' ; 7-segment code 9

;************************************************* ******************************************


- if need be i'll contact the developers website on why their code is ridden with bugs. Thanks for look at it.

Trickae
- 25th September 2007, 10:10
Part 2


; INTERRUPT
; interrupt from counter used to multiplex display
; this sucessively switches on Disp1, Disp2, Disp3 in sequence plus
; blanking leading zeros on display for Disp2 and Disp3 for either
; speedometer or set alarm speed modes
; uses internal timer to initiate display update
; also updates time period counters which set period of speed pulse counting
; checks speed against alarm setting
; speed sensor update

; start interrupt by saving w and status registers before altered by interrupt routine

INTER movwf W_TMP ; w to w_tmp storage
swapf STATUS,w ; status to w
movwf STATUS_TMP ; status in status_tmp

; which interrupt (INT or TMRO)

btfsc INTCON,T0IF ; TMRO overflow interrupt flag then goto litchk
goto LITCHK ; TMRO overflow so multiplex display
SENSOR btfsc INTCON,INTF ; INT interrupt flag set then goto speed
goto SPEED ; speed sensor signal update
goto RECLAIM ; end of interrupt reclaim w and status

; multiplex display routine

LITCHK btfsc REPEAT,1 ; check if speed alarm unit on or off
goto ALM_BY ; on so skip resetting alarm (alarm bypass)

; reset alarm function

clrf PULSE_CNT ; clear pulse counter so no alarm
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
ALM_BY bcf STATUS,RP0 ; select bank 0
movlw D'100' ; speed up multiplex rate for suitable tone in piezo alarm (100
; is used in calibration number calculation and for output freq)
; freq is 3.579545MHz/2/4/(256-100+2)/2 = 1.4159kHz
addwf TMR0,f ; add to timer registerand takes 2 cycles to start counting
bcf INTCON,T0IF ; clear TMRO interrupt flag
bsf FLAG_1,0 ; indicate another interrupt has occurred
btfsc REPEAT,2 ; check if speedometer or alarm speed mode
goto SPD_LTE ; display update in speedometer mode
btfss PORTA,0 ; skip if display 1 not lit
goto LIT1 ; display 1 lit
btfss PORTA,1 ; skip if display 2 not lit
goto LIT2 ; display 2 lit
btfss PORTA,2 ; skip if display 3 not lit
goto LIT3 ; display 3 lit
movlw B'11111110' ; seven segments off
movwf PORTB
bcf PORTA,2 ; no displays lit so set disp3 (used if error in output)
goto LITCHK ; goto check which is lit now
LIT1 bsf PORTA,0 ; disp1 off
movf DISP3,w ; look at display3
xorlw 0x00 ; compare display3 with 0
btfss STATUS,Z ; skip if zero
goto NOBLNK ; do not blank display2
movf DISP2,w ; look at display2
xorlw 0x00 ; compare disp2 with 0
btfss STATUS,Z ; skip if 0
goto NOBLNK ; do not blank disp2
movlw B'11111110' ; 7-segment display off
goto BLANK ; blank disp2 when disp2 and disp3 = 0
NOBLNK movf DISP2,w ; disp2 to w
call SVNSEG ; goto subroutine to get seven segment code
BLANK btfss ERR_FLG,0 ; calibrate error
goto CAL_M ; mid display
movlw B'10000110' ; set display for 'r' (Err)
goto LIT_r ; light an r
CAL_M btfsc FLAG_1,7 ; calibrate flag skip if clear
movlw B'00000100' ; set display to show an A (for CAL)
btfss REPEAT,1 ; is speed alarm unit on or off, 1 is on 0 is off
movlw B'01111110' ; set 'g' segment on display
LIT_r movwf PORTB ; seven segment value to portB
bcf PORTA,1 ; disp2 powered
goto TIMECNT ; end of multiplex
LIT2 bsf PORTA,1 ; disp2 off
movf DISP3,w ; disp3 to w
xorlw 0x00 ; compare with 0
btfss STATUS,Z ; skip if zero
goto SHOW ; show digit on disp3
movlw B'11111110' ; 7-segment display off
goto BLNK ; value to blank display
SHOW movf DISP3,w ; look at display3
call SVNSEG ; get 7-segment value
BLNK btfss ERR_FLG,0 ; calibrate error
goto CAL_L ; Left display
movlw B'01000010' ; set display for 'E' (Err)
goto LIT_E ; light an E
CAL_L btfsc FLAG_1,7 ; calibrate flag skip if clear
movlw B'11000010' ; set display to show a C (for CAL)
btfss REPEAT,1 ; is speed alarm unit on or off, 1 is on 0 is off
movlw B'01111110' ; set 'g' segment on display
LIT_E movwf PORTB ; portB has seven-segment code
bcf PORTA,2 ; disp3 powered
goto TIMECNT ; end of multiplex
LIT3 bsf PORTA,2 ; disp3 off
movf DISP1,w ; disp1 to w
call SVNSEG
btfss ERR_FLG,0 ; calibrate error
goto CAL_R ; Right display
movlw B'10000110' ; set display for 'r' (Err)
goto LIT_rr ; light an r
CAL_R btfsc FLAG_1,7 ; calibrate flag skip if clear
movlw B'11100010' ; set display to show an L (for CAL)
btfss REPEAT,1 ; is speed alarm unit on or off, 1 is on 0 is off
movlw B'01111110' ; set 'g' segment on display
LIT_rr movwf PORTB
bcf PORTA,0 ; disp1 powered
goto TIMECNT

; display update for speedometer mode

SPD_LTE btfss PORTA,0 ; skip if display 1 not lit
goto SPD_LT1 ; display 1 lit
btfss PORTA,1 ; skip if display 2 not lit
goto SPD_LT2 ; display 2 lit
btfss PORTA,2 ; skip if display 3 not lit
goto SPD_LT3 ; display 3 lit
movlw B'11111110' ; seven segments off
movwf PORTB
bcf PORTA,2 ; no displays lit so set disp3 (used if error in output)
goto SPD_LTE ; goto check which is lit now
SPD_LT1 bsf PORTA,0 ; disp1 off
movf SPEED3,w ; look at display3
xorlw 0x00 ; compare display3 with 0
btfss STATUS,Z ; skip if zero
goto NOBLNK1 ; do not blank display2
movf SPEED2,w ; look at display2
xorlw 0x00 ; compare disp2 with 0
btfss STATUS,Z ; skip if 0
goto NOBLNK1 ; do not blank disp2
movlw B'11111110' ; 7-segment display off
goto BLANK1 ; blank disp2 when disp2 and disp3 = 0
NOBLNK1 movf SPEED2,w ; disp2 to w
call SVNSEG ; goto subroutine to get seven segment code
BLANK1 movwf PORTB ; seven segment value to portB
bcf PORTA,1 ; disp2 powered
goto TIMECNT ; end of multiplex
SPD_LT2 bsf PORTA,1 ; disp2 off
movf SPEED3,w ; disp3 to w
xorlw 0x00 ; compare with 0
btfss STATUS,Z ; skip if zero
goto SHOW1 ; show digit on disp3
movlw B'11111110' ; 7-segment display off
goto BLNK1 ; value to blank display
SHOW1 movf SPEED3,w ; look at display3
call SVNSEG ; get 7-segment value
BLNK1 movwf PORTB ; portB has seven-segment code
bcf PORTA,2 ; disp3 powered
goto TIMECNT ; end of multiplex
SPD_LT3 bsf PORTA,2 ; disp3 off
movf SPEED1,w ; disp1 to w
call SVNSEG
movwf PORTB
bcf PORTA,0 ; disp1 powered

; update time period counters for speed pulse counter

TIMECNT btfsc FLAG_1,7 ; calibrate flag skip if clear (no calibrate)
goto CALBRAT ; calibrate switch pressed so do calibration
movf TIME_CNT4,w ; MS Byte of calibration value to w
xorwf TIME_CNT2,w ; compare MS Byte counter with calibration
btfss STATUS,z ; skip if equal
goto INC_CT1 ;
movf TIME_CNT3,w ; LS Byte of calibration value
xorwf TIME_CNT1,w ; compare LS byte counter with calibration
btfss STATUS,z ; skip if equal
goto INC_CT1 ;
clrf TIME_CNT1 ; clear timer counter 1
clrf TIME_CNT2 ; and timer 2
movf PULSE_CNT,w ; look at pulse counter value
movwf SPEEDO ; speedometer value latched pulse counter value

Trickae
- 25th September 2007, 10:10
part 3


; routine to convert speedo memory to speed 1, 2 & 3 display memory

sublw 0xFF ; compare with maximum value (255km/h)
btfsc STATUS,Z ; is it at maximum
goto LIMIT ; maximum of 255 on display

; convert speedo to BCD place in Speed 3,Speed 2 and Speed1

movf SPEEDO,w ; look at speedo value
movwf BIN_0 ; to binary register
call BCD ; convert to BCD
movf BCD_0,w ; ms digit
movwf SPEED3 ; display MSD
movf BCD_1,w ; LS Digits
andlw 0x0F ; mask bits 7-4
movwf SPEED1 ; ls digit
swapf BCD_1,w ; look at ms nibble
andlw 0x0F
movwf SPEED2 ; middle digit
goto CK_SPD

LIMIT movlw 0x08 ; place 8 in speed1-3 memory so display -
movwf SPEED1 ; - shows 888 for overrange speedometer
movwf SPEED2
movwf SPEED3

; check speed against alarm setting

CK_SPD movf SPEED_EQV,w ; speed equivalent value to w
btfsc REPEAT,4 ; skip if alarm threshold low
addlw 0x01 ; increase speed equiv by hysteresis value
subwf PULSE_CNT,w ; subtract speed equivalent from pulse counter
btfsc STATUS,c ; if positive or zero (c=1) then sound overspeed alarm
goto SETALM

; add hysteresis (addition of 1 to pulse counter gives 1km/h hysteresis)

movf PULSE_CNT,w ; pulse counter value
btfss REPEAT,4 ; skip if alarm threshold high
addlw 0x01 ; increase by factor for hysteresis (on to off alarm speed)
movwf PULSE_CNT
movf SPEED_EQV,w
subwf PULSE_CNT,w ; subtract speed equivalent from new pulse counter value
btfsc STATUS,c ; if positive or zero (c=1) then leave set alarm on
goto ALM_CL ; continue alarm
goto CLRALM ; clear alarm as below overspeed

INC_CT1 incfsz TIME_CNT1,f ; increase counter 1 skip if overflowed
goto ALARM
incf TIME_CNT2,f ; increase counter 2 when counter 1 overflows
goto ALARM

; calibrate time counters

CALBRAT incfsz TIME_CNT1,f ; increase counter 1 skip if overflowed
goto CMP_PLS
incfsz TIME_CNT2,f ; increase counter 2 on overflow skip if overflowed
goto CMP_PLS ; not overrange so compare pulse count with speed equiv
bsf ERR_FLG,0 ; error flag set as counter 2 has overranged
bcf FLAG_1,7 ; calibrate off flag
goto C_ALM
CMP_PLS movf PULSE_CNT,w ; pulse counter to w
xorwf SPEED_EQV,w ; compare pulse counter with speed equivalent (display value)
btfss STATUS,Z ; skip if equal
goto C_ALM

; store time counters TIME_CNT1 & 2 into TIME_CNT3 & 4 and into EEPROM5 & 6 - new calibration

movf TIME_CNT1,w ; time counter 1 to w
movwf TIME_CNT3 ; time counter 3 = 1
movf TIME_CNT2,w ; time counter 2 to w
movwf TIME_CNT4 ; time counter 2 = 4
bcf FLAG_1,7 ; calibrate flag clear, calibrate off

; clear alarm

CLRALM clrf PULSE_CNT ; clear pulse counter for recount
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
C_ALM bcf FLAG_1,5 ; overspeed flag
bcf FLAG_1,4 ; clear alarm off flag
bsf PORTA,3 ; alarm output high
goto ALARM ; continue program

; set alarm

SETALM clrf PULSE_CNT ; clear pulse counter for recount
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
btfsc FLAG_1,5 ; is overspeed flag set. Skip if not
goto ALARM ; set so skip setting alarm again, wait till cleared
bsf FLAG_1,5 ; overspeed flag
bsf FLAG_1,2 ; set alarm tone flag
bsf FLAG_1,4 ; set alarm off flag
clrf FLAG_2 ; alarm tone period
bcf FLAG_1,3 ; clear on off flag
clrf FLAG_3 ; alarm tone sequence

; alarm tone routine generates a beep beep tone for over-speed

ALM_CL clrf PULSE_CNT
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
ALARM btfss FLAG_1,4 ; alarm off flag
goto SENSOR ; alarm not required
incf FLAG_2,f ; alarm tone period
btfss FLAG_1,2 ; skip if alarm tone required
goto RDFLG_2 ; no alarm go to check sensor interrupt
btfsc FLAG_1,3 ; alternate on and off flag for tone
goto SET_OUT ; if flag set then stop tone on RA3 output
btfsc PORTA,3 ; is alarm out low
goto SET_OUT
bsf PORTA,3 ; alarm out pin high
goto CNT_SEQ
SET_OUT bcf PORTA,3 ; alarm out pin low
CNT_SEQ bcf FLAG_1,3
btfss FLAG_3,0 ; read alarm tone sequence (bit 0 low then alarm tone)
goto RDFLG_2
bsf FLAG_1,3 ; no tone
bsf PORTA,3 ; alarm output high
btfss FLAG_3,1 ; check count
goto RDFLG_2
bcf FLAG_1,2 ; alarm off
bcf PORTA,3 ; alarm out low
goto SENSOR
RDFLG_2 movf FLAG_2,w ; read alarm tone period counter
sublw 0xFE ; alarm tone on-time (FE = max) (00 = min)
btfss STATUS,C ; skip if less than on-time
goto SET_FLG
goto SENSOR
SET_FLG incf FLAG_3,f ; next sequence
clrf FLAG_2 ; start period count
btfss FLAG_3,7 ; look at bit for repeat tone period, 7 is longest interval, 6 half the period etc
goto SENSOR ; if bit set then repeat alarm
btfss REPEAT,0 ; skip if repeat flag set
goto SENSOR
bsf FLAG_1,2 ; allow alarm again
clrf FLAG_3 ; clear repeat bit
goto SENSOR

; speed sensor update

SPEED bcf INTCON,INTF ; clear INT flag
incfsz PULSE_CNT,f ; increase pulse counter value for each speed sensor input
goto RECLAIM
movlw 0xFF ; max value
movwf PULSE_CNT ; place max count in pulse counter do not allow overrange

; end of interrupt reclaim w and status

RECLAIM swapf STATUS_TMP,w ; status temp storage to w
movwf STATUS ; w to status register
swapf W_TMP,f ; swap upper and lower 4-bits in w_tmp
swapf W_TMP,w ; swap bits and into w register
retfie ; return from interrupt

Trickae
- 25th September 2007, 10:11
;************************************************* *********************************************

; RESET
; Set ports A & B

MAIN clrf FLAG_1 ; clear flag memory
clrf ERR_FLG ; clear error flag used in calibration
clrf TIME_CNT1 ; clear time period counter for speed pulse update
clrf TIME_CNT2 ; clear time period counter
clrf PULSE_CNT ; clear speed pulse counter
clrf SPEED1 ; clear speedometer display1
clrf SPEED2 ; clear speedometer display2
clrf SPEED3 ; clear speedometer display3
bsf STATUS,RP0 ; select memory bank 1
movlw B'00000001' ; w = 00000001 binary (RB0 input, RB1-RB7 output)
movwf TRISB ; port B data direction register
movlw B'10000000' ; w = 10000000 binary
movwf OPTION_REG ; TMRO prescaler no division, PORTB pullups disabled
movlw B'00010000' ; w = 10000 binary (RA0-RA2, RA3 outputs, RA4 input)
movwf TRISA ; A port data direction register
bcf STATUS,RP0 ; select memory bank 0
movlw B'11111110' ; w is all 1's for RB7-RB1, 0 for RB0
movwf PORTB ; portB outputs high
movlw B'00001111'
movwf PORTA ; portA RA0 high, RA1,RA2 outputs high, RA3 high

; get memory in EEPROM1, EEPROM2 & EEPROM3 for speed setting, place in DISP1, DISP2, DISP3

movlw EEPROM1 ; address for EEPROM1
call EEREAD ; read EEPROM storage
sublw 0x09 ; compare with 9
btfss STATUS,C ; skip if positive therefore a 9 or less
goto CLR1 ; greater than 9 then clear to 0
movf EEDATA,w ; restore w
movwf DISP1 ; EEPROM1 to DISP1
goto EEPRM2
CLR1 clrf DISP1 ; Disp1 = 0 as disp1 was more than 9 (illegal value)

EEPRM2 movlw EEPROM2 ; address for EEPROM2
call EEREAD
sublw 0x09 ; compare with 9
btfss STATUS,C ; skip if positive therefore a 9 or less
goto CLR2
movf EEDATA,w ; restore w
movwf DISP2 ; EEPROM2 to DISP2
goto EEPRM3
CLR2 clrf DISP2 ; disp2 = 0 as disp2 was more than 9 (illegal value)

EEPRM3 movlw EEPROM3 ; address for EEPROM3
call EEREAD
sublw 0x01 ; compare with 1
btfss STATUS,C ; skip if positive therefore a 1 or less
goto CLR3
movf EEDATA,w ; restore w
movwf DISP3 ; EEPROM3 to DISP3
goto EEPRM5
CLR3 clrf DISP3 ; disp3 = 0 as disp3 was more than 1 (illegal value)

; get EEPROM5 and EEPROM6 calibration values and place in TIME_CNT3 and TIME_CNT4

EEPRM5 movlw EEPROM5 ; address for EEPROM5
call EEREAD
movwf TIME_CNT3 ; store in LS byte calibration register
movlw EEPROM6 ; address for EEPROM6
call EEREAD
movwf TIME_CNT4 ; store in MS byte calibration register

; get memory EEPROM4 and place in REPEAT. This is the indicator for
; repeat alarm on or off, bit 0. ON/OFF flag, bit 1, bit 2 is speedo, bit 3 is speedo on/off
; bit 4 is alarm threshold high or low

EEPRM4 movlw EEPROM4 ; address for EEPROM4
call EEREAD
movwf REPEAT ; store in repeat register

; check for pressed up switch

bcf PORTA,2 ; clear RA2 to check if up switch pressed
nop
nop ; allow time for levels to settle
btfsc PORTA,4 ; is up switch pressed
goto CHK_DN ; switch open so check down switch
btfsc REPEAT,0 ; test for repeat flag bit 0
goto CLRREP ; clear repeat off alarm
bsf REPEAT,0 ; set repeat for alarm
movlw B'10000110' ; 'r' on display for repeat alarm
goto SWOPEN
CLRREP bcf REPEAT,0 ; clear repeat
movlw B'01111110' ; '-' on display for no repeat alarm
SWOPEN movwf TEMP_1
SWCLSD bsf PORTA,0 ; display off
bsf PORTB,5 ; clear a segment
bsf PORTB,6 ; clear b segment
bsf PORTB,3 ; e segment
bsf PORTB,4 ; f segment
bsf PORTB,7 ; g segment
bsf PORTB,2 ; clear display at RB
bcf PORTA,2 ; clear RA2 to check if up switch pressed
call DELMO
btfsc PORTA,4 ; wait for switch to open
goto MODESTO ; store repeat setting when switch opens

; multiplex display until switch opens

bsf PORTA,2 ; RA2 high
nop
nop
nop
bcf PORTA,0 ; RA0 low so display 1 lit
movf TEMP_1,w ; retrieve temp storage value
movwf PORTB ; port B a-g segments on again
call DELMO ; more delay time
goto SWCLSD ; check for pressed switch

; check for pressed down switch

CHK_DN bsf PORTA,2 ; RA2 high so Disp3 will be off
bsf PORTA,0 ; RA0 high so disp1 off
nop
nop
bcf PORTA,1 ; clear RA1 to check if down switch pressed
nop
nop ; allow time for levels to settle
btfsc PORTA,4 ; is down switch pressed
goto CHK_MDE ; switch open so check mode switch
btfsc REPEAT,4 ; test for threshold flag bit 4
goto CLRTRS ; clear threshold flag bit
bsf REPEAT,4 ; set threshold high
movlw B'00100100' ; 'H' on display for high threshold
goto DNOPEN
CLRTRS bcf REPEAT,4 ; clear threshold flag
movlw B'11100010' ; 'L' on display for low threshold
DNOPEN movwf TEMP_1
DNCLSD bsf PORTB,6 ; clear b segment
bsf PORTB,1 ; clear c segment
bsf PORTB,3 ; e segment
bsf PORTB,4 ; f segment
bsf PORTB,7 ; g segment
bsf PORTB,2 ; d segment
bcf PORTA,1 ; clear RA1 to check if down switch pressed
call DELMO ; more delay time (multiplex)
call DELMO ; more delay time
btfsc PORTA,4 ; wait for switch to open
goto MODESTO ; store repeat setting when switch open

; multiplex display until switch opens

movf TEMP_1,w
movwf PORTB ; port B a-g segments on again
call DELMO ; more delay time
goto DNCLSD ; check for pressed switch

Trickae
- 25th September 2007, 10:12
; check for pressed Mode switch

CHK_MDE bsf PORTA,1 ; RA1 high so disp2 off
bsf PORTA,2 ; RA2 high so disp3 off
nop
nop
bcf PORTA,0 ; clear RA0 to check if mode switch pressed
nop
nop
btfsc PORTA,4 ; is mode switch pressed
goto NO_OPEN ; switch open so no change
btfss REPEAT,3 ; test for speedo on/off flag bit 3
goto CLRSPED ; clear speedo on/off
bcf REPEAT,3 ; set speedo
movlw B'01001000' ; 's' on display for speedo
movwf TEMP_1
goto MODEOPN
CLRSPED bsf REPEAT,3 ; set speedo on/off flag
movlw B'01111110' ; '-' on display for no speedo
movwf TEMP_1
bcf REPEAT,2 ; clear speedometer flag
MODEOPN bsf PORTA,2 ; display off
bsf PORTB,5 ; clear a segment
bsf PORTB,1 ; clear c segment
bsf PORTB,2 ; d segment
bsf PORTB,4 ; f segment
bsf PORTB,7 ; g segment
bcf PORTA,0 ; clear RA0 to check if mode switch pressed
call DELMO ; more delay time (multiplex time)
call DELMO ; more delay time
btfsc PORTA,4 ; wait for switch to open
goto MODESTO ; store repeat setting when switch open

; multiplex display until switch opens

bsf PORTA,0 ; RA0 high
nop
nop
nop
bcf PORTA,2 ; RA2 low so display 1 lit
movf TEMP_1,w
movwf PORTB ;
call DELMO ; more delay time (multiplex)
goto MODEOPN

; delay period for multiplex rate

DELMO movlw D'255' ; delay period
movwf TEMP_2
SMALR decfsz TEMP_2,f ; reduce temp_2
goto SMALR ; temp_2 smaller by 1
return ; end delay

; write new mode option to EEPROM4

MODESTO movlw EEPROM4 ; address for EEPROM4
movwf EEADR ; address for write
movf REPEAT,w ; flag stored
call EWRITE ; write to EEPROM

; calculate speed equivalent value

NO_OPEN call SPDEQIV ; calculate speed equivalent
goto INT_SET

; subroutine to read EEPROM memory

EEREAD movwf EEADR ; indirect special function register
bsf STATUS,RP0 ; select memory bank 1
bsf EECON1,RD ; read EEPROM
RD_RD nop
btfsc EECON1,RD ; skip if RD low (read complete)
goto RD_RD ; wait for low RD (read RD)
bcf STATUS,RP0 ; select bank 0
movf EEDATA,w ; EEPROM value in w
return

; subroutine to calculate speed equivalent of 8 per 5km/h this value is compared with
; counted pulses from speed sensor.

SPDEQIV bcf FLAG_1,5 ; overspeed flag
bcf FLAG_1,4 ; clear alarm off flag
clrf PULSE_CNT ; clear pulse counter
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
bsf PORTA,3 ; alarm output high
clrf SPEED_EQV ; clear speed equivalent store

; Convert the display readings to a binary speed equivalent value

movf DISP3,w ; look at DISP3 value
btfsc STATUS,z ; check if 0
goto ZERO
xorlw 0x01 ; check if a 1
btfsc STATUS,z ; z is 1 if a 1
goto ONE ;
movlw D'100' ; 100
movwf SPEED_EQV ; 100 in speed equivalent
ONE movlw D'100'
addwf SPEED_EQV,f ; 200 if disp3 was a 2
ZERO movf DISP2,w ; look at display 2
movwf TEMP_X ; place in temporary register
INC_SE movlw D'10' ; 10
addwf SPEED_EQV,f ; increase speed equivalent by 10
decfsz TEMP_X,f ; reduce disp2 value
goto INC_SE ; do again
movf DISP1,w ; display 1 value
addwf SPEED_EQV,f ; add display 1 value
return


; allow interrupts

INT_SET btfss REPEAT,1 ; bit 1 on/off flag
goto RB0_INT ; no RB0 interrupt if speed alarm unit in off mode
bsf INTCON,INTE ; set interrupt enable for RB0
RB0_INT bsf INTCON,T0IE ; set interrupt enable for TMR0
SWITCH bsf INTCON,GIE ; set global interrupt enable for above

; check if a switch is pressed

bcf FLAG_1,0 ; clear multiplex update flag
MULTIP btfss FLAG_1,0 ; check if multiplex update occured
goto MULTIP ; wait for new multiplex update for display
btfsc PORTA,4 ; if a switch is pressed, then bit 4 will be low
goto SWITCH ; no switch pressed so look again

; check for Cal switch

bcf INTCON,GIE ; clear interrupts
bcf ERR_FLG,0 ; clear error flag when any switch pressed
movf PORTA,w ; look at RA0-RA2

movwf TEMP_1 ; store in temporary memory
iorlw B'00000111' ; bit 0-2 high
movwf PORTA ; place in port A, displays off

movlw 0x1F ; delay period
movwf VALUE_1 ; VALUE_1 = w
DELOOP decfsz VALUE_1,f ; decrease VALUE_1, skip if zero
goto DELOOP

btfss PORTA,4 ; is the cal switch pressed
goto CALIBRT ; yes it is the cal switch
movf TEMP_1,w ; retrieve port A bit 0-2
movwf PORTA ; port A bits 0-2 as before
nop ; give time for ports to change
nop
nop
btfsc PORTA,4 ; if a switch is pressed, then bit 4 will be low
goto SWITCH ; no switch pressed so look again
btfsc PORTA,0 ; is it the mode switch
goto D_U_CHK
goto MODE
D_U_CHK btfss REPEAT,1 ; is on/off flag on
goto WAIT ; no up down selection allowed when speed alarm unit is off
btfsc PORTA,1 ; is it the Down switch
goto U_CHK
goto DOWN
U_CHK btfsc PORTA,2 ; is it the UP switch
goto SWITCH ; no switch reading
goto UP

Trickae
- 25th September 2007, 10:12
MODE btfss REPEAT,1 ; bit 1 a '1' for on (on/off flag)
goto SET_1 ; was off so turn on
btfsc REPEAT,3 ; speedo on/off flag
goto BYSPD
btfss REPEAT,2 ; speedometer or alarm set mode
goto SET_2 ; repeat1 status same, repeat2 =1
BYSPD bcf REPEAT,1 ; if set then clear on/off flag
bcf REPEAT,2 ; clear speedometer flag
bcf INTCON,INTE ; clear interrupt enable for RB0
clrf PULSE_CNT ; clear pulse counter
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
goto WAIT
SET_2 bsf REPEAT,2 ; set speedometer flag
goto NO_SET1
SET_1 bsf REPEAT,1 ; if clear then set on/off flag
NO_SET1 bsf INTCON,INTE ; set interrupt enable for RB0
goto WAIT

UP movf DISP1,w ; display1 to w register
xorlw 0x05 ; compare with decimal'5'
btfss STATUS,Z ; skip next instruction if Disp <9 decimal
goto UP_1 ; increase display1

; check for maximum on display

movf DISP2,w ; look at display 2
xorlw 0x05 ; compare with a 5
btfss STATUS,Z ; is it 5 then check DISP3
goto DISP_UP
movf DISP3,w ; look at disp3
xorlw 0x02 ; compare with a 1
btfsc STATUS,Z ; is it a 2
goto WAIT ; maximum of 255 on display so stop counting up

; digit overflow

DISP_UP clrf DISP1 ; Disp value cleared as it was beyond BCD range (0-9)
movf DISP2,w ; display2 value to w
xorlw 0x09 ; compare with decimal'9' (H'9')
btfss STATUS,Z ; skip next instruction if Disp <9 decimal
goto UP_2 ; increase display2
clrf DISP2 ; Disp value cleared as it was beyond BCD range (0-9)
goto UP_3 ; increase display3

UP_1 movlw 0x05 ; a 5 in the display (count by 5's)
movwf DISP1 ; display1 increased
goto WAIT
UP_2 incf DISP2,f ; display2 increased
goto WAIT
UP_3 incf DISP3,f ; display3 increased
goto WAIT

DOWN movf DISP1,w ; display1 to w register
xorlw 0x00 ; compare with decimal'0' to see if was zero
btfss STATUS,Z ; skip next instruction if Disp 0 decimal
goto DN_1 ; decrease display1

; check for display minimum

movf DISP2,w ; look at display 2
xorlw 0x00 ; compare with 0
btfss STATUS,Z ;
goto DISP_DN ; not 0 so can count down
movf DISP3,w ; look at display 3
xorlw 0x00 ; compare with 0
btfsc STATUS,Z
goto WAIT ; do not decrease beyond 000

DISP_DN movlw H'05' ; place a 5 in display1
movwf DISP1 ; disp1 = 5
movf DISP2,w ; display2 value to w
xorlw 0x00 ; compare with decimal'0' to see if 0
btfss STATUS,Z ; skip next instruction if Disp 0 decimal
goto DN_2 ; decrease display2
movlw H'09' ; Disp value = 9
movwf DISP2
goto DN_3 ; decrease display3

DN_1 clrf DISP1 ; display1 decreased to 0
goto WAIT
DN_2 decf DISP2,f ; display2 decreased
goto WAIT
DN_3 decf DISP3,f ; display3 decreased

; wait period (delay plus EEPROM write time)

; delay loop plus apply tone to piezo alarm as switch press acknowledgement

WAIT bsf INTCON,GIE ; allow global interrupts
movlw D'100' ; set delay period for repeat of value 2 delay (sets key
; acknowledge tone frequency)
movwf VALUE_1 ; VALUE_1 = w
movlw D'50' ; set delay period value 2 (also sets key acknowledge tone period)
LOOP_1 movwf VALUE_2 ; VALUE_2 = w
LOOP_2 decfsz VALUE_2,f ; decrease VALUE_2, skip if zero
goto LOOP_2
btfsc PORTA,3 ; alarm output check if high or low
goto CLR_T
bsf PORTA,3 ; alarm out high
DEC_V1 decfsz VALUE_1,f ; decrease VALUE_1, skip if zero
goto LOOP_1
bsf PORTA,3 ; alarm out high
goto DELTME ; delay time
CLR_T bcf PORTA,3 ; alarm out low
goto DEC_V1

; more delay time

DELTME movlw D'50' ; set delay period
movwf VALUE_1 ; VALUE_1 = w
movlw D'255' ; set delay period value 2
LP_1 movwf VALUE_2 ; VALUE_2 = w
LP_2 decfsz VALUE_2,f ; decrease VALUE_2, skip if zero
goto LP_2
decfsz VALUE_1,f ; decrease VALUE_1, skip if zero
goto LP_1

; EEPROM write. Store new display values in EEPROM

EPWRT movlw EEPROM1 ; address for EEPROM1
movwf EEADR ; address to write
movf DISP1,w ; display1 data to w
call EWRITE ; EEPROM write sequence
movlw EEPROM2 ; address for EEPROM2
movwf EEADR ; address for write
movf DISP2,w
call EWRITE
movlw EEPROM3 ; address for EEPROM3
movwf EEADR ; address for write
movf DISP3,w
call EWRITE
movlw EEPROM4 ; address for EEPROM4
movwf EEADR ; address to write to
movf REPEAT,w ; repeat values (bit 0 is alarm repeat, bit 1 is on/off)
call EWRITE

; when a new speed setting is selected recalculate speed equivalent value

bcf INTCON,GIE ; disable interrupts
call SPDEQIV ; recalculate speed equivalent value
bsf INTCON,GIE ; enable interrupts
goto CLOSED ; out from EEPROM write

; subroutine to write to EEPROM

EWRITE bcf FLAG_1,6 ; EEPROM write repeat flag
movwf TEMP_2 ; store w in temporary storage
EWRIT movf TEMP_2,w ; place value in w (used for read data sequence)
movwf EEDATA ; data register
bcf INTCON,GIE ; disable interrupts
bsf STATUS,RP0 ; select bank 1
bsf EECON1,WREN ; enable write
movlw 0x55 ; place 55H in w for write sequence
movwf EECON2 ; write 55H to EECON2
movlw 0xAA ; AAH to w
movwf EECON2 ; write AA to EECON2
bsf EECON1,WR ; set WR bit and begin write sequence
bsf INTCON,GIE ; enable interrupts
bcf EECON1,WREN ; clear WREN bit
WRITE btfsc EECON1,WR ; skip if write complete WR=0 when write complete
goto WRITE ; not written yet
bcf EECON1,EEIF ; clear write interrupt flag

; read EEPROM DATA and check if written correctly

bsf STATUS,RP0 ; select memory bank 1
bsf EECON1,RD ; read EEPROM
RD_AGN nop
btfsc EECON1,RD ; skip if RD low (read complete)
goto RD_AGN ; wait for low RD
bcf STATUS,RP0 ; select bank 0
movf EEDATA,w ; EEPROM value in w
subwf EEDATA,w ; compare read value with value stored
btfsc STATUS,z ; skip if not the same
return ; value correctly written
btfsc FLAG_1,6 ; write repeat bit, skip if clear and rewrite
return
bsf FLAG_1,6 ; set repeat flag rewrite once only
goto EWRIT ; rewrite as not written correctly

; wait for switch to open (must test for closed switch when RA0, RA1 and RA2 are low
; because switch will appear open at RA4 when switch pull down via RA0-RA2 is high)

CLOSED bcf FLAG_1,1 ; clear flag that indicates switch closed
call ON ; check for closed switch
call ON ; do three times to return to original switch closure
call ON ;
call ON ; do again just in case missed an interrupt during call
call ON ; do again just in case missed one interrupt during call
btfsc FLAG_1,1 ; was switch closed
goto CLOSED ; yes go to check again
goto SWITCH ; switch open so out

; subroutine to wait for switch to reopen

ON bcf INTCON,T0IE ; prevent multiplex update
bcf FLAG_1,0 ; clear flag that indicates update interrupt for display

RE_CHK btfsc PORTA,4 ; check if switch closed
goto OPEN
bsf FLAG_1,1 ; switch closed so set flag
bsf INTCON,T0IE ; allow multiplex interrupt
goto RE_CHK ; closed so check till open
OPEN bcf FLAG_1,0 ; clear multiplex update flag wait for next multiplex update
bsf INTCON,T0IE ; allow multiplex update
FLG_TST btfss FLAG_1,0 ; is flag set indicating a new interrupt for multiplexing
goto FLG_TST ; wait
return

; calibrate routine

CALIBRT btfss REPEAT,1 ; is on/off flag on
goto WAIT ; no calibration allowed when speed alarm unit is off
btfsc REPEAT,2 ; is speedometer on
goto WAIT ; no calibration if speedometer mode
bcf INTCON,GIE ; disable interrupts
clrf PULSE_CNT ; clear pulse counter
clrf TIME_CNT1 ; clear time counter 1
clrf TIME_CNT2 ; clear time counter 2
bsf FLAG_1,7 ; calibrate flag set
bcf INTCON,T0IF ; clear timer interrupt flag
bcf INTCON,INTF ; clear interrupt flag
bsf INTCON,GIE ; allow interrupts
FLG1_CK btfsc FLAG_1,7 ; wait for end of calibrate, skip if end
goto FLG1_CK ; recheck flag 1 bit 7 (cleared at end of calibration)

; store new calibration count numbers in EEPROM

movlw EEPROM5 ; address for EEPROM5
movwf EEADR ; address to write
movf TIME_CNT3,w ; counter 3 to w
call EWRITE ; EEPROM write sequence
movlw EEPROM6 ; address for EEPROM6
movwf EEADR ; address to write
movf TIME_CNT4,w ; counter 4 to w
call EWRITE ; EEPROM write sequence
goto SWITCH ; check for a new closed switch

; Subroutine to convert from 8-bit binary to 2-digit BCD (packed)
; Binary value is in BIN_0
; Result in BCD is in BCD_0 & BCD_1.
; BCD_0 is MSB, BCD_1 is LSB

BCD bcf STATUS,c ; clear carry bit
movlw D'8'
movwf CNT_8 ; 8 in count
clrf BCD_0
clrf BCD_1 ; set BCD registers to 0
LOOPBCD rlf BIN_0,f ; shift left binary registers
rlf BCD_1,f ; MSB shift left

rlf BCD_0,f ; LSB shift left BCD registers
decfsz CNT_8,f ; reduce count value return when 0
goto DECADJ ; continue decimal adjust
return ; completed decimal to BCD operation

; subroutine decimal adjust

DECADJ movlw BCD_1 ; BCD LSB address
movwf FSR ; pointer for BCD1
call ADJBCD ; subroutine to adjust BCD
movlw BCD_0 ; BCD MS address
movwf FSR ; pointer for BCD0
call ADJBCD
goto LOOPBCD

; subroutine adjust BCD

ADJBCD movlw 0x03 ; w has 03
addwf INDF,w ; add 03 to BCDx register (x is 0-1)
movwf TEMP ; store w
btfsc TEMP,3 ; test if >7
movwf INDF ; save as LS digit
movlw 0x30 ; 3 for MSbyte
addwf INDF,w ; add 30 to BCDx register
movwf TEMP ; store w in temp
btfsc TEMP,7 ; test if >7
movwf INDF ; save as MS digit
return ; end subroutine


end

HenrikOlsson
- 25th September 2007, 14:21
Hi,
I'm not saying that you won't get any help but since this is a forum for PicBasic you MAY not get the help you're looking for. Something like the PICList may be more suitable if you're "writing" in, or having problems with ASM.

BUT, with that being said, have you selected 16F84 in MPLAB? Configure/Select Device and then point to 16F84.

/Henrik Olsson.

paul borgmeier
- 25th September 2007, 15:40
as a starters,


C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 323 : Symbol not previously defined (z) Error[113]
C:\DOCUMENTS AND SETTINGS\\MY DOCUMENTS\SPEED254.ASM 362 : Symbol not previously defined (c) Error[113]

change commands that look like this (with c or z in them)


btfsc STATUS,z ; check if 0

to this


btfsc STATUS,Z ; check if 0

Trickae
- 25th September 2007, 22:54
Thanks for the help so far - i'll check out piclist and make the above corrections.

Regards,

Trickae
- 25th September 2007, 23:48
btw - I got a build succeeded confirmation - however I have the following error messages.



Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPAsmWin.exe" /q /p16F84 "SPEED254.ASM" /l"SPEED254.lst" /e"SPEED254.err"
Message[302] C:\PIC LAB\SPEED254.ASM 542 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 544 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 546 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 770 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 773 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1049 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1051 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1053 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1054 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1056 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1058 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1060 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1065 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PIC LAB\SPEED254.ASM 1068 : Register in operand not in bank 0. Ensure that bank bits are correct.
Loaded C:\PIC LAB\SPEED254.cod.
BUILD SUCCEEDED: Wed Sep 26 07:47:42 2007


it seems like the error occurs when accessing eeproms or clearing flags

Does anyone know how to rectify a "Register in operand not in bank 0" error/warning?

mister_e
- 26th September 2007, 01:18
As long as you're sure you did the BANK switching manually, there's no real problem. Unless you may spread some BANKSEL here and there... not sure enough it will solve the warning message so far :(

BANKSEL is a nice MPASM tool, it avoid to do the bankswitching yourself AND manually. Same thing as CHK?RP do with PBP. NO YOU DON'T WANT TO USE BANKSEL WITH PBP unless you know some tricks. Even if you know them... i don't find any advantage myself. Maybe Darrel could confirm or contradict it.

Assuming you already did it (as it seems to be), you just need to disable the warning message with the following


errorlevel -302


HTH

Trickae
- 26th September 2007, 06:41
well as long as they're only warnings i'll move on to adding to the design.

thanks