LIST p=16f628A
errorlevel -302 ; ???
__CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON
ORG 0x00
GOTO INIT
ORG 0x04 ; Interrupt vector
BCF INTCON, INTF ; Yes, clear interrupt flag
BCF INTCON, GIE ;
CALL IntRupt ; Interrupt routine
RETFIE
INIT:
Counter EQU 0x20 ; Delay counter
SaveW EQU 0x40 ; To save W register
DHexVal EQU 0x28 ; Hex value to display
Tens EQU 0x41 ; Dec value to display LCD
Ones EQU 0x42 ; Dec value to display LCD
count1 EQU 0x34 ; used in delay routine
counta EQU 0x35 ; used in delay routine
countb EQU 0x36 ; used in delay routine
Disp10 EQU 0x30 ; Displ 1:0
Disp11 EQU 0x31 ; Displ 1:1
BANKSEL TRISA
MOVLW b'00000000' ; Set 0 to input
MOVWF TRISA
BANKSEL 0x5 ;
CLRF 0x5 ; Set All B pins to 0
BANKSEL TRISB
MOVLW b'00000001' ; Set 0 to input
MOVWF TRISB
BANKSEL 0x6 ;
CLRF 0x6 ; Set All B pins to 0
movlw 0x07 ; Turn comparators off and enable
movwf 0x1f ; pins for I/O functions
MOVLW b'00110000' ; xx------ unimplemented
; --11---- prescaler 1:8
; ----0--- Timer1 osc = off
; -----x-- ignored when Timer1 osc = off
; ------0- Clock source = internal (Fosc/4)
; -------0 Stop timer1
MOVWF 0x10 ; Set timer
BSF OPTION_REG, INTEDG ; interrupt on positive
BCF INTCON, INTF ; clear interrupt flag
BSF INTCON, INTE ; mask for external interrupts
BSF INTCON, GIE ; enable interrupts
; 1 Sec delay routine using Timer1
; With current Timer1 setting (Prescaler 1:8, Reload 3036)
; a timer overflow happen each 500mSec, so we just
; repeat it twice
MOVLW .8 ;
MOVWF Counter ; Counter = 4
CALL InitTmr1 ; Init timer1
START: ; Main loop
CALL CheckTmr1 ; Check if tmr1 is done
movwf 0x22 ; Move returnvalue to register
btfsc 0x22,0 ; Is it 0, jump next line.
CALL CheckCounter ; Is it 1, Check counter.
CALL DispLCD ; Display values on LCDs
goto START
CheckTmr1
BTFSS PIR1, TMR1IF ; Timer1 Overflow?
RETLW 0x0 ; Still going, return 0
RETLW 0x1 ; Time's up!
CheckCounter:
DECFSZ Counter, F ; Decrease CounterA * 500ms
GOTO Jump1 ; If not zero Jump1
GOTO Jump2 ; If zero Jump2
Jump1: CALL InitTmr1 ; Restart timer
RETURN ; Return
Jump2: MOVLW .8 ; Reset Counter = 4
MOVWF Counter ; Counter = 2
CALL TimesUp ; Do the thingy
CALL InitTmr1 ; Restart timer
RETURN ; Return
DispLCD
; Display part 0/1 on displ 1
MOVF Ones, W ; Put Ones into W
CALL LCD10 ; Translate W into display10
MOVWF Disp10 ; Save
MOVF Tens, W
CALL LCD20
IORWF Disp10, W ; Add together
BCF PORTA, 0
BSF PORTA, 1 ; Turn on part 0 for disp 1,2
MOVWF PORTB ; Display part 0 on disp 1,2
MOVF Ones, W ; Put Ones into W
CALL LCD11 ; Translate W into display11
MOVWF Disp11 ; Save
MOVF Tens, W
CALL LCD21
IORWF Disp11, W ; Add together
BCF PORTA, 1
BSF PORTA, 0 ; Turn on part 1 for disp 1,2
MOVWF PORTB ; Display part 1 on disp 1,2
RETURN ; Done
LCD10
ADDWF 0x2, F
RETLW b'00010110' ; 0:0
RETLW b'00001100' ; 1:0
RETLW b'00011100' ; 2:0
RETLW b'00001100' ; 3:0
RETLW b'00001010' ; 4:0
RETLW b'00001110' ; 5:0
RETLW b'00011110' ; 6:0
RETLW b'00000000' ; 7:0
RETLW b'00011110' ; 8:0
RETLW b'00001010' ; 9:0
LCD11
ADDWF 0x2, F
RETLW b'00001110' ; 0:1
RETLW b'00000000' ; 1:1
RETLW b'00001010' ; 2:1
RETLW b'00001110' ; 3:1
RETLW b'00001100' ; 4:1
RETLW b'00000110' ; 5:1
RETLW b'00000110' ; 6:1
RETLW b'00001110' ; 7:1
RETLW b'00001110' ; 8:1
RETLW b'00001110' ; 9:1
LCD20
ADDWF 0x2, F
RETLW b'11100000' ; 0:0
RETLW b'01100000' ; 1:0
RETLW b'11000000' ; 2:0
RETLW b'11100000' ; 3:0
RETLW b'01100000' ; 4:0
RETLW b'10100000' ; 5:0
RETLW b'10100000' ; 6:0
RETLW b'11100000' ; 7:0
RETLW b'11100000' ; 8:0
RETLW b'11100000' ; 9:0
LCD21
ADDWF 0x2, F
RETLW b'10110000' ; 0:1
RETLW b'00000000' ; 1:1
RETLW b'01110000' ; 2:1
RETLW b'01100000' ; 3:1
RETLW b'11000000' ; 4:1
RETLW b'11100000' ; 5:1
RETLW b'11110000' ; 6:1
RETLW b'00000000' ; 7:1
RETLW b'11110000' ; 8:1
RETLW b'11000000' ; 9:1
TimesUp
MOVF 0x21, W ; RPM
MOVWF DHexVal ; Display value
CLRF 0x21 ; Clear out, start over
CALL HexToDec ; Convert Hex to Dec
RETURN
HexToDec ; Convert Hex to dec
CLRF Ones
CLRF Tens
movf DHexVal, W ; Get hex value to convert
movwf Ones
repeat: movlw .10
subwf Ones, W
btfss STATUS, C
RETURN ; Done converting
movwf Ones
incf Tens, f
goto repeat
InitTmr1
BCF T1CON, TMR1ON ; Stop Timer1
BCF PIR1, TMR1IF ; Clear Timer1 overflow flag
MOVLW b'11011100' ; Load
MOVWF TMR1L ; Timer1
MOVLW b'00001011' ; with
MOVWF TMR1H ; Reload Value
BSF T1CON, TMR1ON ; Start Timer1
RETURN
IntRupt
MOVWF SaveW ; Save what's in W
INCF 0x21, f ; Increase RPM counter
MOVF SaveW, W ; Restore W
RETURN ; And return
End
wp100!
Here's my current code for the PIC16F628A..
Code:LIST p=16f628A errorlevel -302 ; ??? __CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON ORG 0x00 GOTO INIT ORG 0x04 ; Interrupt vector BCF INTCON, INTF ; Yes, clear interrupt flag BCF INTCON, GIE ; CALL IntRupt ; Interrupt routine RETFIE INIT: Counter EQU 0x20 ; Delay counter SaveW EQU 0x40 ; To save W register DHexVal EQU 0x28 ; Hex value to display Tens EQU 0x41 ; Dec value to display LCD Ones EQU 0x42 ; Dec value to display LCD count1 EQU 0x34 ; used in delay routine counta EQU 0x35 ; used in delay routine countb EQU 0x36 ; used in delay routine Disp10 EQU 0x30 ; Displ 1:0 Disp11 EQU 0x31 ; Displ 1:1 BANKSEL TRISA MOVLW b'00000000' ; Set 0 to input MOVWF TRISA BANKSEL 0x5 ; CLRF 0x5 ; Set All B pins to 0 BANKSEL TRISB MOVLW b'00000001' ; Set 0 to input MOVWF TRISB BANKSEL 0x6 ; CLRF 0x6 ; Set All B pins to 0 movlw 0x07 ; Turn comparators off and enable movwf 0x1f ; pins for I/O functions MOVLW b'00110000' ; xx------ unimplemented ; --11---- prescaler 1:8 ; ----0--- Timer1 osc = off ; -----x-- ignored when Timer1 osc = off ; ------0- Clock source = internal (Fosc/4) ; -------0 Stop timer1 MOVWF 0x10 ; Set timer BSF OPTION_REG, INTEDG ; interrupt on positive BCF INTCON, INTF ; clear interrupt flag BSF INTCON, INTE ; mask for external interrupts BSF INTCON, GIE ; enable interrupts ; 1 Sec delay routine using Timer1 ; With current Timer1 setting (Prescaler 1:8, Reload 3036) ; a timer overflow happen each 500mSec, so we just ; repeat it twice MOVLW .8 ; MOVWF Counter ; Counter = 4 CALL InitTmr1 ; Init timer1 START: ; Main loop CALL CheckTmr1 ; Check if tmr1 is done movwf 0x22 ; Move returnvalue to register btfsc 0x22,0 ; Is it 0, jump next line. CALL CheckCounter ; Is it 1, Check counter. CALL DispLCD ; Display values on LCDs goto START CheckTmr1 BTFSS PIR1, TMR1IF ; Timer1 Overflow? RETLW 0x0 ; Still going, return 0 RETLW 0x1 ; Time's up! CheckCounter: DECFSZ Counter, F ; Decrease CounterA * 500ms GOTO Jump1 ; If not zero Jump1 GOTO Jump2 ; If zero Jump2 Jump1: CALL InitTmr1 ; Restart timer RETURN ; Return Jump2: MOVLW .8 ; Reset Counter = 4 MOVWF Counter ; Counter = 2 CALL TimesUp ; Do the thingy CALL InitTmr1 ; Restart timer RETURN ; Return DispLCD ; Display part 0/1 on displ 1 MOVF Ones, W ; Put Ones into W CALL LCD10 ; Translate W into display10 MOVWF Disp10 ; Save MOVF Tens, W CALL LCD20 IORWF Disp10, W ; Add together BCF PORTA, 0 BSF PORTA, 1 ; Turn on part 0 for disp 1,2 MOVWF PORTB ; Display part 0 on disp 1,2 MOVF Ones, W ; Put Ones into W CALL LCD11 ; Translate W into display11 MOVWF Disp11 ; Save MOVF Tens, W CALL LCD21 IORWF Disp11, W ; Add together BCF PORTA, 1 BSF PORTA, 0 ; Turn on part 1 for disp 1,2 MOVWF PORTB ; Display part 1 on disp 1,2 RETURN ; Done LCD10 ADDWF 0x2, F RETLW b'00010110' ; 0:0 RETLW b'00001100' ; 1:0 RETLW b'00011100' ; 2:0 RETLW b'00001100' ; 3:0 RETLW b'00001010' ; 4:0 RETLW b'00001110' ; 5:0 RETLW b'00011110' ; 6:0 RETLW b'00000000' ; 7:0 RETLW b'00011110' ; 8:0 RETLW b'00001010' ; 9:0 LCD11 ADDWF 0x2, F RETLW b'00001110' ; 0:1 RETLW b'00000000' ; 1:1 RETLW b'00001010' ; 2:1 RETLW b'00001110' ; 3:1 RETLW b'00001100' ; 4:1 RETLW b'00000110' ; 5:1 RETLW b'00000110' ; 6:1 RETLW b'00001110' ; 7:1 RETLW b'00001110' ; 8:1 RETLW b'00001110' ; 9:1 LCD20 ADDWF 0x2, F RETLW b'11100000' ; 0:0 RETLW b'01100000' ; 1:0 RETLW b'11000000' ; 2:0 RETLW b'11100000' ; 3:0 RETLW b'01100000' ; 4:0 RETLW b'10100000' ; 5:0 RETLW b'10100000' ; 6:0 RETLW b'11100000' ; 7:0 RETLW b'11100000' ; 8:0 RETLW b'11100000' ; 9:0 LCD21 ADDWF 0x2, F RETLW b'10110000' ; 0:1 RETLW b'00000000' ; 1:1 RETLW b'01110000' ; 2:1 RETLW b'01100000' ; 3:1 RETLW b'11000000' ; 4:1 RETLW b'11100000' ; 5:1 RETLW b'11110000' ; 6:1 RETLW b'00000000' ; 7:1 RETLW b'11110000' ; 8:1 RETLW b'11000000' ; 9:1 TimesUp MOVF 0x21, W ; RPM MOVWF DHexVal ; Display value CLRF 0x21 ; Clear out, start over CALL HexToDec ; Convert Hex to Dec RETURN HexToDec ; Convert Hex to dec CLRF Ones CLRF Tens movf DHexVal, W ; Get hex value to convert movwf Ones repeat: movlw .10 subwf Ones, W btfss STATUS, C RETURN ; Done converting movwf Ones incf Tens, f goto repeat InitTmr1 BCF T1CON, TMR1ON ; Stop Timer1 BCF PIR1, TMR1IF ; Clear Timer1 overflow flag MOVLW b'11011100' ; Load MOVWF TMR1L ; Timer1 MOVLW b'00001011' ; with MOVWF TMR1H ; Reload Value BSF T1CON, TMR1ON ; Start Timer1 RETURN IntRupt MOVWF SaveW ; Save what's in W INCF 0x21, f ; Increase RPM counter MOVF SaveW, W ; Restore W RETURN ; And return End
It seems to work fine when I was testing it on the 16F.
Regards
/ Morgan
;**********************************************************************
; This file is a basic code template for assembly code generation *
; on the PIC16F628A. This file contains the basic code *
; building blocks to build upon. *
; *
; Refer to the MPASM User's Guide for additional information on *
; features of the assembler (Document DS33014). *
; *
; Refer to the respective PIC data sheet for additional *
; information on the instruction set. *
; *
;**********************************************************************
; *
; Filename: xxx.asm *
; Date: *
; File Version: *
; *
; Author: *
; Company: *
; *
; *
;**********************************************************************
; *
; Files Required: P16F628A.INC *
; *
;**********************************************************************
; *
; Notes: *
; *
;**********************************************************************
list p=16f628A ; list directive to define processor
#include <p16F628A.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.
;***** VARIABLE DEFINITIONS
w_temp EQU 0x7E ; variable used for context saving
status_temp EQU 0x7F ; variable used for context saving
;**********************************************************************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program
ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
; isr code can go here or be located as a call subroutine elsewhere
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
main
; remaining code goes here
goto main ;loop forever, remove this instruction, for test only
; initialize eeprom locations
ORG 0x2100
DE 0x00, 0x01, 0x02, 0x03
END ; directive 'end of program'
Counter EQU 0x20 ; Delay counter
DHexVal EQU 0x28 ; Hex value to display
Tens EQU 0x41 ; Dec value to display LCD
Ones EQU 0x42 ; Dec value to display LCD
Disp10 EQU 0x30 ; Displ 1:0
Disp11 EQU 0x31 ; Displ 1:1
w_temp EQU 0x7E ; variable used for context saving
status_temp EQU 0x7F ; variable used for context saving
ORG 0x00 ; Reset vector
GOTO INIT
ORG 0x04 ; Interrupt vector
MOVWF w_temp ; save off current W register contents
MOVF STATUS, W ; move status register into W register
MOVWF status_temp ; save off contents of STATUS register
BCF INTCON, INTF ; Yes, clear interrupt flag
BCF INTCON, GIE ;
INCF 0x21, f ; Increase RPM counter
MOVF status_temp, W ; retrieve copy of STATUS register
MOVWF STATUS ; restore pre-isr STATUS register contents
SWAPF w_temp,F
SWAPF w_temp,W ; restore pre-isr W register contents
RETFIE
INIT:
BCF STATUS, RP1 ; Clear if it's set.
BSF STATUS, RP0 ; Select bank 1
MOVLW b'00000100' ; PORTA ext. interrupt on RA2
MOVWF TRISA
MOVLW b'00000000' ; Set PORTB to output.
MOVWF TRISB
MOVLW b'00000000' ; Set PORTC to output LCD.
MOVWF TRISC
BCF STATUS, RP0 ; Select bank 0
CLRF PORTA ; Clear port A
CLRF PORTB ; Clear port B
CLRF PORTC ; Clear port C
MOVLW b'00110000' ; xx------ unimplemented
; --11---- prescaler 1:8
; ----0--- Timer1 osc = off
; -----x-- ignored when Timer1 osc = off
; ------0- Clock source = internal (Fosc/4)
; -------0 Stop timer1
MOVWF T1CON ; Set timer 1
BSF STATUS, RP1 ; Select bank 2
CLRF ANSEL ; We want all PortA pins digit
BANKSEL INTCON
MOVLW B'10010000' ; Set RA2 to external int.
MOVWF INTCON ; And global int. Bit 7, 4
BCF STATUS, RP0 ; Select..
BCF STATUS, RP1 ; bank 0
CLRF Ones ; Clear Ones
CLRF Tens ; And Tens
MOVLW .8 ; Timing part
MOVWF Counter ; Counter = 8
CALL InitTmr1 ; Init timer1
START: ; Main loop
CALL CheckTmr1 ; Check if tmr1 is done
MOVWF 0x22 ; Move returnvalue to register
BTFSC 0x22,0 ; Is it 0, jump next line.
CALL CheckCounter ; Is it 1, Check counter.
CALL DispLCD ; Display values on LCDs
GOTO START
CheckTmr1
BTFSS PIR1, TMR1IF ; Timer1 Overflow?
RETLW 0x0 ; Still going, return 0
RETLW 0x1 ; Time's up!
CheckCounter:
DECFSZ Counter, F ; Decrease CounterA * 500ms
GOTO Jump1 ; If not zero Jump1
GOTO Jump2 ; If zero Jump2
Jump1: CALL InitTmr1 ; Restart timer
RETURN ; Return
Jump2: MOVLW .8 ; Reset Counter = 8
MOVWF Counter ; Counter = 4
CALL TimesUp ; Do the thingy
CALL InitTmr1 ; Restart timer
RETURN ; Return
DispLCD
MOVF Ones, W ; Put Ones into W
CALL LCD10 ; Translate W into display11
MOVWF Disp10 ; Save
MOVF Tens, W
CALL LCD20
IORWF Disp10, W ; Add together
MOVWF PORTC ; Display part 1 on disp 1,2
MOVLW b'00010000'
MOVWF PORTB
MOVF Ones, W ; Put Ones into W
CALL LCD11 ; Translate W into display11
MOVWF Disp11 ; Save
MOVF Tens, W
CALL LCD21
IORWF Disp11, W ; Add together
MOVWF PORTC ; Display part 1 on disp 1,2
MOVLW b'00100000'
MOVWF PORTB
RETURN ; Done
LCD10
ADDWF 0x2, F
RETLW b'00010110' ; 0:0
RETLW b'00000000' ; 1:0
RETLW b'00011100' ; 2:0
RETLW b'00001100' ; 3:0
RETLW b'00001010' ; 4:0
RETLW b'00001110' ; 5:0
RETLW b'00011110' ; 6:0
RETLW b'00000000' ; 7:0
RETLW b'00011110' ; 8:0
RETLW b'00001010' ; 9:0
LCD11
ADDWF 0x2, F
RETLW b'00001110' ; 0:1
RETLW b'00001100' ; 1:1
RETLW b'00001010' ; 2:1
RETLW b'00001110' ; 3:1
RETLW b'00001100' ; 4:1
RETLW b'00000110' ; 5:1
RETLW b'00000110' ; 6:1
RETLW b'00001110' ; 7:1
RETLW b'00001110' ; 8:1
RETLW b'00001110' ; 9:1
LCD20
ADDWF 0x2, F
RETLW b'11100000' ; 0:0
RETLW b'01100000' ; 1:0
RETLW b'11000000' ; 2:0
RETLW b'11100000' ; 3:0
RETLW b'01100000' ; 4:0
RETLW b'10100000' ; 5:0
RETLW b'10100000' ; 6:0
RETLW b'11100000' ; 7:0
RETLW b'11100000' ; 8:0
RETLW b'11100000' ; 9:0
LCD21
ADDWF 0x2, F
RETLW b'10110000' ; 0:1
RETLW b'00000000' ; 1:1
RETLW b'01110000' ; 2:1
RETLW b'01100000' ; 3:1
RETLW b'11000000' ; 4:1
RETLW b'11100000' ; 5:1
RETLW b'11110000' ; 6:1
RETLW b'00000000' ; 7:1
RETLW b'11110000' ; 8:1
RETLW b'11000000' ; 9:1
TimesUp
MOVF 0x21, W ; RPM
MOVWF DHexVal ; Display value
CLRF 0x21 ; Clear out, start over
CALL HexToDec ; Convert Hex to Dec
RETURN
HexToDec ; Convert Hex to dec
CLRF Ones
CLRF Tens
MOVF DHexVal, W ; Get hex value to convert
MOVWF Ones
repeat: MOVLW .10
SUBWF Ones, W
BTFSS STATUS, C
RETURN ; Done converting
MOVWF Ones
INCF Tens, f
GOTO repeat
InitTmr1
BCF T1CON, TMR1ON ; Stop Timer1
BCF PIR1, TMR1IF ; Clear Timer1 overflow flag
MOVLW b'11011100' ; Load
MOVWF TMR1L ; Timer1
MOVLW b'00001011' ; with
MOVWF TMR1H ; Reload Value
BSF T1CON, TMR1ON ; Start Timer1
RETURN
END
;Counter EQU 0x20 ; Delay counter
;DHexVal EQU 0x28 ; Hex value to display
;Tens EQU 0x41 ; Dec value to display LCD
;Ones EQU 0x42 ; Dec value to display LCD
;Disp10 EQU 0x30 ; Displ 1:0
;Disp11 EQU 0x31 ; Displ 1:1
;w_temp EQU 0x7E ; variable used for context saving
;status_temp EQU 0x7F ; variable used for context saving
cblock 0x20 ; ********** USER MEMORY BANK 0
Counter ; Delay counter
DHexVal ; Hex value to display
Tens ; Dec value to display LCD
Ones ; Dec value to display LCD
Disp10 ; Displ 1:0
Disp11 ; Displ 1:1
ENDC
cblock 0x7E
w_temp ; variable used for context saving
status_temp ; variable used for context saving
endc
ORG 0x00 ; Reset vector
GOTO INIT
ORG 0x04 ; Interrupt vector
MOVWF w_temp ; save off current W register contents
MOVF STATUS, W ; move status register into W register
MOVWF status_temp ; save off contents of STATUS register
BCF INTCON, INTF ; Yes, clear interrupt flag
BCF INTCON, GIE ;
INCF 0x21, f ; Increase RPM counter ???????????????? 0x21 register specifed where ?
MOVF status_temp, W ; retrieve copy of STATUS register
MOVWF STATUS ; restore pre-isr STATUS register contents
SWAPF w_temp,F
SWAPF w_temp,W ; restore pre-isr W register contents
RETFIE
INIT:
; BCF STATUS, RP1 ; Clear if it's set.
; BSF STATUS, RP0 ; Select bank 1
banksel TRISA
MOVLW b'00000100' ; PORTA ext. interrupt on RA2
MOVWF TRISA
MOVLW b'00000000' ; Set PORTB to output.
MOVWF TRISB
MOVLW b'00000000' ; Set PORTC to output LCD.
MOVWF TRISC
; BCF STATUS, RP0 ; Select bank 0
banksel PORTA
CLRF PORTA ; Clear port A
CLRF PORTB ; Clear port B
CLRF PORTC ; Clear port C
MOVLW b'00110000' ; xx------ unimplemented
; --11---- prescaler 1:8
; ----0--- Timer1 osc = off
; -----x-- ignored when Timer1 osc = off
; ------0- Clock source = internal (Fosc/4)
; -------0 Stop timer1
MOVWF T1CON ; Set timer 1
; BSF STATUS, RP1 ; Select bank 2
banksel ANSEL
CLRF ANSEL ; We want all PortA pins digit
BANKSEL INTCON
MOVLW B'10010000' ; Set RA2 to external int.
MOVWF INTCON ; And global int. Bit 7, 4
; BCF STATUS, RP0 ; Select..
; BCF STATUS, RP1 ; bank 0
banksel 0
CLRF Ones ; Clear Ones
CLRF Tens ; And Tens
MOVLW .8 ; Timing part
MOVWF Counter ; Counter = 8
CALL InitTmr1 ; Init timer1
START: ; Main loop
CALL CheckTmr1 ; Check if tmr1 is done
MOVWF 0x22 ; Move returnvalue to register ???????????????? 0x22 specifed where ?
BTFSC 0x22,0 ; Is it 0, jump next line.
CALL CheckCounter ; Is it 1, Check counter.
CALL DispLCD ; Display values on LCDs
GOTO START
CheckTmr1
BTFSS PIR1, TMR1IF ; Timer1 Overflow?
RETLW 0x0 ; Still going, return 0
RETLW 0x1 ; Time's up!
CheckCounter:
DECFSZ Counter, F ; Decrease CounterA * 500ms
GOTO Jump1 ; If not zero Jump1
GOTO Jump2 ; If zero Jump2
Jump1: CALL InitTmr1 ; Restart timer
RETURN ; Return
Jump2: MOVLW .8 ; Reset Counter = 8
MOVWF Counter ; Counter = 4
CALL TimesUp ; Do the thingy
CALL InitTmr1 ; Restart timer
RETURN ; Return
DispLCD
MOVF Ones, W ; Put Ones into W
CALL LCD10 ; Translate W into display11
MOVWF Disp10 ; Save
MOVF Tens, W
CALL LCD20
IORWF Disp10, W ; Add together
MOVWF PORTC ; Display part 1 on disp 1,2
MOVLW b'00010000'
MOVWF PORTB
MOVF Ones, W ; Put Ones into W
CALL LCD11 ; Translate W into display11
MOVWF Disp11 ; Save
MOVF Tens, W
CALL LCD21
IORWF Disp11, W ; Add together
MOVWF PORTC ; Display part 1 on disp 1,2
MOVLW b'00100000'
MOVWF PORTB
RETURN ; Done
LCD10
ADDWF 0x2, F
RETLW b'00010110' ; 0:0
RETLW b'00000000' ; 1:0
RETLW b'00011100' ; 2:0
RETLW b'00001100' ; 3:0
RETLW b'00001010' ; 4:0
RETLW b'00001110' ; 5:0
RETLW b'00011110' ; 6:0
RETLW b'00000000' ; 7:0
RETLW b'00011110' ; 8:0
RETLW b'00001010' ; 9:0
LCD11
ADDWF 0x2, F
RETLW b'00001110' ; 0:1
RETLW b'00001100' ; 1:1
RETLW b'00001010' ; 2:1
RETLW b'00001110' ; 3:1
RETLW b'00001100' ; 4:1
RETLW b'00000110' ; 5:1
RETLW b'00000110' ; 6:1
RETLW b'00001110' ; 7:1
RETLW b'00001110' ; 8:1
RETLW b'00001110' ; 9:1
LCD20
ADDWF 0x2, F
RETLW b'11100000' ; 0:0
RETLW b'01100000' ; 1:0
RETLW b'11000000' ; 2:0
RETLW b'11100000' ; 3:0
RETLW b'01100000' ; 4:0
RETLW b'10100000' ; 5:0
RETLW b'10100000' ; 6:0
RETLW b'11100000' ; 7:0
RETLW b'11100000' ; 8:0
RETLW b'11100000' ; 9:0
LCD21
ADDWF 0x2, F
RETLW b'10110000' ; 0:1
RETLW b'00000000' ; 1:1
RETLW b'01110000' ; 2:1
RETLW b'01100000' ; 3:1
RETLW b'11000000' ; 4:1
RETLW b'11100000' ; 5:1
RETLW b'11110000' ; 6:1
RETLW b'00000000' ; 7:1
RETLW b'11110000' ; 8:1
RETLW b'11000000' ; 9:1
TimesUp
MOVF 0x21, W ; RPM ???????????????? 0x21 specifed where ?
MOVWF DHexVal ; Display value
CLRF 0x21 ; Clear out, start over
CALL HexToDec ; Convert Hex to Dec
RETURN
HexToDec ; Convert Hex to dec
CLRF Ones
CLRF Tens
MOVF DHexVal, W ; Get hex value to convert
MOVWF Ones
repeat: MOVLW .10
SUBWF Ones, W
BTFSS STATUS, C
RETURN ; Done converting
MOVWF Ones
INCF Tens, f
GOTO repeat
InitTmr1
BCF T1CON, TMR1ON ; Stop Timer1
BCF PIR1, TMR1IF ; Clear Timer1 overflow flag
MOVLW b'11011100' ; Load
MOVWF TMR1L ; Timer1
MOVLW b'00001011' ; with
MOVWF TMR1H ; Reload Value
BSF T1CON, TMR1ON ; Start Timer1
RETURN
END
#DEFINE cRPMCounter .8 ; Startvalue in Counter
CBLOCK 0x20 ; Local memory Bank 0
RPMCounter ; Counting interrupts.
Counter ; Delay counter
DHexVal ; Hex value to display
Tens ; Dec value to display LCD
Ones ; Dec value to display LCD
Disp10 ; Temp mem displ 1:0
Disp11 ; Temp mem displ 1:1
TempRet ; Temporary returnvalue holder
ENDC
CBLOCK 0x7E ; Global memory
w_temp ; variable used for context saving
status_temp ; variable used for context saving
ENDC
ORG 0x00 ; Reset vector
GOTO INIT
ORG 0x04 ; Interrupt vector
MOVWF w_temp ; save off current W register contents
MOVF STATUS, W ; move status register into W register
MOVWF status_temp ; save off contents of STATUS register
BCF INTCON, INTF ; Yes, clear interrupt flag
BCF INTCON, GIE ;
INCF RPMCounter, F ; Increase RPM counter
MOVF status_temp, W ; retrieve copy of STATUS register
MOVWF STATUS ; restore pre-isr STATUS register contents
SWAPF w_temp,F
SWAPF w_temp,W ; restore pre-isr W register contents
RETFIE
INIT:
BANKSEL TRISA ; Bank 1 where TRISA, B and C exists.
MOVLW b'00000100' ; PORTA ext. interrupt on RA2
MOVWF TRISA
MOVLW b'00000000' ; Set PORTB to output.
MOVWF TRISB
MOVLW b'00000000' ; Set PORTC to output LCD.
MOVWF TRISC
BANKSEL PORTA ; Bank 0 where PORTA, B and C exists.
CLRF PORTA ; Clear port A
CLRF PORTB ; Clear port B
CLRF PORTC ; Clear port C
MOVLW b'00110000' ; xx------ unimplemented
; --11---- prescaler 1:8
; ----0--- Timer1 osc = off
; -----x-- ignored when Timer1 osc = off
; ------0- Clock source = internal (Fosc/4)
; -------0 Stop timer1
MOVWF T1CON ; Set timer 1
BANKSEL ANSEL ; Bank 2..
CLRF ANSEL ; We want all PortA pins digit
BANKSEL INTCON
MOVLW B'10010000' ; Set RA2 to external int.
MOVWF INTCON ; And global int. Bit 7, 4
BANKSEL 0 ; Go to bank 0
CLRF Ones ; Clear Ones
CLRF Tens ; And Tens
MOVLW cRPMCounter ; Timing part
MOVWF Counter ; Counter = 8
CALL InitTmr1 ; Init timer1
START: ; Main loop
CALL CheckTmr1 ; Check if tmr1 is done
MOVWF TempRet ; Move returnvalue to register
BTFSC TempRet, 0 ; Is it 0, jump next line.
CALL CheckCounter ; Is it 1, Check counter.
CALL DispLCD ; Display values on LCDs
GOTO START
CheckTmr1
BTFSS PIR1, TMR1IF ; Timer1 Overflow?
RETLW 0x0 ; Still going, return 0
RETLW 0x1 ; Time's up!
CheckCounter:
DECFSZ Counter, F ; Decrease CounterA * 500ms
GOTO Jump1 ; If not zero Jump1
GOTO Jump2 ; If zero Jump2
Jump1: CALL InitTmr1 ; Restart timer
RETURN ; Return
Jump2: MOVLW cRPMCounter ; Reset Counter = 8
MOVWF Counter ; Counter = 8
CALL TimesUp ; Do the thingy
CALL InitTmr1 ; Restart timer
RETURN ; Return
DispLCD
MOVF Ones, W ; Put Ones into W
CALL LCD10 ; Translate W into display11
MOVWF Disp10 ; Save
MOVF Tens, W
CALL LCD20
IORWF Disp10, W ; Add together
MOVWF PORTC ; Display part 1 on disp 1,2
MOVLW b'00010000'
MOVWF PORTB
MOVF Ones, W ; Put Ones into W
CALL LCD11 ; Translate W into display11
MOVWF Disp11 ; Save
MOVF Tens, W
CALL LCD21
IORWF Disp11, W ; Add together
MOVWF PORTC ; Display part 1 on disp 1,2
MOVLW b'00100000'
MOVWF PORTB
RETURN ; Done
LCD10
ADDWF PCL, F
RETLW b'00010110' ; 0:0
RETLW b'00000000' ; 1:0
RETLW b'00011100' ; 2:0
RETLW b'00001100' ; 3:0
RETLW b'00001010' ; 4:0
RETLW b'00001110' ; 5:0
RETLW b'00011110' ; 6:0
RETLW b'00000000' ; 7:0
RETLW b'00011110' ; 8:0
RETLW b'00001010' ; 9:0
LCD11
ADDWF PCL, F
RETLW b'00001110' ; 0:1
RETLW b'00001100' ; 1:1
RETLW b'00001010' ; 2:1
RETLW b'00001110' ; 3:1
RETLW b'00001100' ; 4:1
RETLW b'00000110' ; 5:1
RETLW b'00000110' ; 6:1
RETLW b'00001110' ; 7:1
RETLW b'00001110' ; 8:1
RETLW b'00001110' ; 9:1
LCD20
ADDWF PCL, F
RETLW b'11100000' ; 0:0
RETLW b'01100000' ; 1:0
RETLW b'11000000' ; 2:0
RETLW b'11100000' ; 3:0
RETLW b'01100000' ; 4:0
RETLW b'10100000' ; 5:0
RETLW b'10100000' ; 6:0
RETLW b'11100000' ; 7:0
RETLW b'11100000' ; 8:0
RETLW b'11100000' ; 9:0
LCD21
ADDWF PCL, F
RETLW b'10110000' ; 0:1
RETLW b'00000000' ; 1:1
RETLW b'01110000' ; 2:1
RETLW b'01100000' ; 3:1
RETLW b'11000000' ; 4:1
RETLW b'11100000' ; 5:1
RETLW b'11110000' ; 6:1
RETLW b'00000000' ; 7:1
RETLW b'11110000' ; 8:1
RETLW b'11000000' ; 9:1
TimesUp
MOVF RPMCounter, W ; RPM
MOVWF DHexVal ; Display value
CLRF RPMCounter ; Clear out, start over
CALL HexToDec ; Convert Hex to Dec
RETURN
HexToDec ; Convert Hex to dec
CLRF Ones
CLRF Tens
MOVF DHexVal, W ; Get hex value to convert
MOVWF Ones
repeat: MOVLW .10
SUBWF Ones, W
BTFSS STATUS, C
RETURN ; Done converting
MOVWF Ones
INCF Tens, F
GOTO repeat
InitTmr1
BCF T1CON, TMR1ON ; Stop Timer1
BCF PIR1, TMR1IF ; Clear Timer1 overflow flag
MOVLW b'11011100' ; Load
MOVWF TMR1L ; Timer1
MOVLW b'00001011' ; with
MOVWF TMR1H ; Reload Value
BSF T1CON, TMR1ON ; Start Timer1
RETURN
END
#include P16F690.INC
;-------- START WIND MEASURING ------------------------------------
errorlevel -302 ; ???
__CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _WDT_OFF & _PWRTE_ON
#DEFINE cRPMCounter .6 ; Startvalue in Counter
#DEFINE cRPMMax .12 ; Max wind for Counter
CBLOCK 0x20 ; Local memory Bank 0
RPMCounter ; Counting interrupts.
Counter ; Delay counter
DHexVal ; Hex value to display
DHexMax ; Hex max value to display
Tens ; Dec value to display LCD
Ones ; Dec value to display LCD
Disp10 ; Temp mem displ 1:0
Disp11 ; Temp mem displ 1:1
TempRet ; Temporary returnvalue holder
ENDC
CBLOCK 0x7E ; Global memory
w_temp ; variable used for context saving
status_temp ; variable used for context saving
ENDC
ORG 0x00 ; Reset vector
GOTO INIT
ORG 0x04 ; Interrupt vector
MOVWF w_temp ; save off current W register contents
MOVF STATUS, W ; move status register into W register
MOVWF status_temp ; save off contents of STATUS register
BCF INTCON, INTF ; Yes, clear interrupt flag
BCF INTCON, GIE ;
INCF RPMCounter, F ; Increase RPM counter
MOVF status_temp, W ; retrieve copy of STATUS register
MOVWF STATUS ; restore pre-isr STATUS register contents
SWAPF w_temp,F
SWAPF w_temp,W ; restore pre-isr W register contents
RETFIE
INIT:
BANKSEL TRISA ; Bank 1 where TRISA, B and C exists.
MOVLW b'00010100' ; PORTA ext. interrupt on RA2
MOVWF TRISA
MOVLW b'00000000' ; Set PORTB to output.
MOVWF TRISB
MOVLW b'00000000' ; Set PORTC to output LCD.
MOVWF TRISC
BANKSEL PORTA ; Bank 0 where PORTA, B and C exists.
CLRF PORTA ; Clear port A
CLRF PORTB ; Clear port B
CLRF PORTC ; Clear port C
MOVLW b'00110000' ; xx------ unimplemented
; --11---- prescaler 1:8
; ----0--- Timer1 osc = off
; -----x-- ignored when Timer1 osc = off
; ------0- Clock source = internal (Fosc/4)
; -------0 Stop timer1
MOVWF T1CON ; Set timer 1
BANKSEL ANSEL ; Bank 2..
CLRF ANSEL ; We want all PortA pins digit
BANKSEL INTCON
MOVLW B'10010000' ; Set RA2 to external int.
MOVWF INTCON ; And global int. Bit 7, 4
BANKSEL 0 ; Go to bank 0
CLRF Ones ; Clear Ones
CLRF Tens ; And Tens
CLRF DHexVal ; ..
CLRF DHexMax
CLRF RPMCounter
CLRF Counter
CLRF Disp10
CLRF Disp11
CLRF TempRet
MOVLW cRPMCounter ; Timing part
MOVWF Counter ; Counter = 6
CALL InitTmr1 ; Init timer1
START: ; Main loop
BTFSC PORTA, 4 ; Max wind button pressed?
GOTO Step ; No, Jump over next part.
MOVLW cRPMMax ; Timing part
MOVWF Counter ; Counter = 12
MOVF DHexMax, W
MOVWF DHexVal
CALL HexToDec ; Convert Max values instead
CALL DispLCD ; Display values on LCDs
GOTO START
Step:
CALL CheckTmr1 ; Check if tmr1 is done
MOVWF TempRet ; Move returnvalue to register
BTFSC TempRet, 0 ; Is it 0, jump next line.
CALL CheckCounter ; Is it 1, Check counter.
CALL DispLCD ; Display values on LCDs
GOTO START
CheckTmr1
BTFSS PIR1, TMR1IF ; Timer1 Overflow?
RETLW 0x0 ; Still going, return 0
RETLW 0x1 ; Time's up!
CheckCounter:
DECFSZ Counter, F ; Decrease CounterA * 500ms
GOTO Jump1 ; If not zero Jump1
GOTO Jump2 ; If zero Jump2
Jump1: CALL InitTmr1 ; Restart timer
RETURN ; Return
Jump2: MOVLW cRPMCounter ; Reset Counter = 6
MOVWF Counter ; Counter = 6
CALL TimesUp ; Do the thingy
CALL InitTmr1 ; Restart timer
RETURN ; Return
DispLCD
MOVF Ones, W ; Put Ones into W
CALL LCD10 ; Translate W into display11
MOVWF Disp10 ; Save
MOVF Tens, W
CALL LCD20
IORWF Disp10, W ; Add together
MOVWF PORTC ; Display part 1 on disp 1,2
MOVLW b'00010000'
MOVWF PORTB
MOVF Ones, W ; Put Ones into W
CALL LCD11 ; Translate W into display11
MOVWF Disp11 ; Save
MOVF Tens, W
CALL LCD21
IORWF Disp11, W ; Add together
MOVWF PORTC ; Display part 1 on disp 1,2
MOVLW b'00100000'
MOVWF PORTB
RETURN ; Done
LCD10
ADDWF PCL, F
RETLW b'00010110' ; 0:0
RETLW b'00000000' ; 1:0
RETLW b'00011100' ; 2:0
RETLW b'00001100' ; 3:0
RETLW b'00001010' ; 4:0
RETLW b'00001110' ; 5:0
RETLW b'00011110' ; 6:0
RETLW b'00000000' ; 7:0
RETLW b'00011110' ; 8:0
RETLW b'00001010' ; 9:0
LCD11
ADDWF PCL, F
RETLW b'00001110' ; 0:1
RETLW b'00001100' ; 1:1
RETLW b'00001010' ; 2:1
RETLW b'00001110' ; 3:1
RETLW b'00001100' ; 4:1
RETLW b'00000110' ; 5:1
RETLW b'00000110' ; 6:1
RETLW b'00001110' ; 7:1
RETLW b'00001110' ; 8:1
RETLW b'00001110' ; 9:1
LCD20
ADDWF PCL, F
RETLW b'11100000' ; 0:0
RETLW b'01100000' ; 1:0
RETLW b'11000000' ; 2:0
RETLW b'11100000' ; 3:0
RETLW b'01100000' ; 4:0
RETLW b'10100000' ; 5:0
RETLW b'10100000' ; 6:0
RETLW b'11100000' ; 7:0
RETLW b'11100000' ; 8:0
RETLW b'11100000' ; 9:0
LCD21
ADDWF PCL, F
RETLW b'10110000' ; 0:1
RETLW b'00000000' ; 1:1
RETLW b'01110000' ; 2:1
RETLW b'01100000' ; 3:1
RETLW b'11000000' ; 4:1
RETLW b'11100000' ; 5:1
RETLW b'11110000' ; 6:1
RETLW b'00000000' ; 7:1
RETLW b'11110000' ; 8:1
RETLW b'11000000' ; 9:1
TimesUp
MOVF RPMCounter, W ; RPM
MOVWF DHexVal ; Display value
CLRF RPMCounter ; Clear out, start over
CALL HexToDec ; Convert Hex to Dec
MOVF DHexVal, W ; Check if we have a
SUBWF DHexMax, W ; new max value?
BTFSS STATUS, C ; Yes? No?
CALL NewMaxVal ; New max value to store
RETURN
NewMaxVal ; New max value since startup
MOVF DHexVal, W
MOVWF DHexMax
RETURN
HexToDec ; Convert Hex to dec
CLRF Ones
CLRF Tens
MOVF DHexVal, W ; Get hex value to convert
MOVWF Ones
repeat: MOVLW .10
SUBWF Ones, W
BTFSS STATUS, C
RETURN ; Done converting
MOVWF Ones
INCF Tens, F
GOTO repeat
InitTmr1
BCF T1CON, TMR1ON ; Stop Timer1
BCF PIR1, TMR1IF ; Clear Timer1 overflow flag
MOVLW b'11011100' ; Load
MOVWF TMR1L ; Timer1
MOVLW b'00001011' ; with
MOVWF TMR1H ; Reload Value
BSF T1CON, TMR1ON ; Start Timer1
RETURN
END
Just a few comments Morgan.
There is a risk of damage if the variable resistor is set to minimum value. If the opto transistor turns on and the resistor is 0 Ohms, the full supply voltage is across it and it might be damaged. I would suggest a resistor to limit the current, perhaps 470 Ohms in series with the control to establish a minimum resistance.
You have no decoupling capacitors on the schematic or PCB. You should add capacitors of not less than 1uF and preferably 10uF or more between pin 1 and 2 and between pin 3 and 2 of the regulator and also add a capacitor of say 100nF directly across the PIC supply pins. Without these you risk it not behaving reliably.
Brian.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?