Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Wind measuring m/s with PIC16F628, in assembler

Status
Not open for further replies.
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
 

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



Hi,


Yes it will work for now but if you start adding more complex code things will fall down.

When you enter the ISR you must properly save the key system Registers.
In MPASM folder you have whats called the Template Code files which are starter codes examples - the one below is for the 628A and shows how to properly do the Context Save - see also the datasheet for details.

Also notice the ram adresses they have used for the context save registers - they are specified as 7F - look at the datasheet memory map - you will see that this is a special common area at the bottom of each memory bank.

Although it says you can use a Call from the ISR it is probably better to keep all you code within the ISR routine. Although not a problem for you at the moment, always try and keep the ISR code short so other Interrupts are not sat waiting to be serviced.


When coding, really suggest you do not specify the system registers by their hex address like banksel 0x6, it becomes confusing with all those numbers - use the system registers label banksel PORTB - much clearer.


happy coding..

Code:
;**********************************************************************
;   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'
 

Hello again wp100

Ok, I see..

Thanks for hinting that out for me.

Soo, now I've added this to my code:

Code:
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

I hope this is better, working like i want it to.. but is it OK?
Someting that I'm doing wrong?

Thanks

By the way.. I forgot to mention that I've changed PIC to 16F690 instead!

/ Morgan
 
Last edited:

Hi,

Well you seem to be moving around chips rather fast, is this code for the 16F877A - portC used ..?
Be aware when changing chips even within the same family that memory bank sizes can change in size and system registers a differ in there location.

Its seems quite good, have not checked your program logic in any detail - just the code - a few things that I would do to make things easier in the long term.

Use Banksel instead of BSF etc.
Rather than using the EQU to specify your User Registers use the Cblock method as shown.

You should alway use Labels / Names for your User Register and the System Register othwise you end up with a jumble of numbers.
Your have 0x21 and 0x22 specifed in the code , but as you have not labelled them it so easy to mix things up.

Code:
;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
 

Re: Wind measuring m/s with PIC16F690, in assembler

wp100, I made all of these changes now. I have even put a define cRPM for the .8 used in the Counter.

Code:
	#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

I belive it's clean now, and I've made some test to the circuit.. seems stable.
Here's my electric chart too:

50463d1288822450-windmiller6rel3-jpg


Now I need to calibrate and create a calculation function or something for knots, I have decided to measure in knots instead of m/s. Will see how this will end..

Thanks again for all the help you've been giving me once again :smile:

Regards

/ Morgan
 

Attachments

  • Windmiller6Rel3.jpg
    Windmiller6Rel3.jpg
    53 KB · Views: 93
Last edited:

Re: Wind measuring m/s with PIC16F690, in assembler

For the one who wants to follow me in my work, I've added a new code here where I've included a button displaying max value of a measuring session. Every third secound I'll display the new count of rotations made and with my setup and choise of propeller (taken from a net adapter in a PC), after calibrating with a "real" anemometer I got m/s through multiplication by 0.187 and knots by multiplication by 0.36.

Code:
#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

Here's my electric chart too:

**broken link removed**

And my PCB board, bottom side:

attachment.php


I'll add pictures of the complete equipment soon..

Regards

/ Morgan
 

Attachments

  • PCB20.jpg
    PCB20.jpg
    8.9 KB · Views: 130
Last edited:

Re: Wind measuring m/s with PIC16F690, in assembler

Now the project is finished, here's the picture of the complete thing, an Anemometer..



Regards, Morgan
 

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.
 
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.

Hi Brian!

Yes, right..
Thank you for pointing that out for me, I'll add them to my cirquit immideately and to the schematic image :)

"Well, now I've made all of the changes to the images. I hope it's like it should :/"

attachment.php


attachment.php


And I've changed the interval to 1 sec, multiply with 0.23 to get m/s and with 0.447 to get knots.

Regards
Morgan
 

Attachments

  • PCB12.jpg
    PCB12.jpg
    51 KB · Views: 121
  • PCB20.jpg
    PCB20.jpg
    8.9 KB · Views: 128
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top