display knippert

Hoi ik zit met het volgende probleem.
Voor een pic 16f690 heb ik in asm een "programmatje" geschreven.
De bedoeling is dat op iedere 2e puls die op ingang RA,1 binnenkomt mijn 7 segment display een cijfer hoger aangeeft.Hij telt door t/m 75 waarna hij stopt.

Tot hier lijkt het goed te werken.Maar de displays knipperen licht.
Weet iemand hoe dit te verhelpen ?

pic asm code:



#include <p16F690.inc>

    __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
	
	ERRORLEVEL -302
	ERRORLEVEL -305
	ERRORLEVEL -224

;------------------------------------------
;	VARIABLE	DEFINITION        -
;------------------------------------------
        
;INPUTS

	

cntr1   	EQU	H'20'    	; adress voor delay
cntr2   	EQU	H'21'           ;    "          "


#define		DISPL1	PORTB,6		; DISPLAY 1  TALLEN
#define		DISPL2	PORTB,5		; DISPLAY 10 TALLEN

     		org 	0
		
		GOTO	RST

;--------------------------------------------
;	CREATE A LITTLE MULTIPLEX TEMPO	    - 
;--------------------------------------------


delay	movlw	0x01			; delay loop voor multiplexing
KILL	movwf	cntr2			; delay timer voor reset / stop effect
delay1	movlw	0xff
	movwf	cntr1
delay2	BTFSC	PORTA,0			; is PORTA,0 hoog ( reset knop )
	GOTO	E_RESET			; ga naar E_RESET 
	BTFSC	PORTA,2			; is PORTA,2 hoog ( stop knop )
	GOTO	E_OFF			; ga naar E_OFF
	decfsz	cntr1, f 		; anders vervolg routine
	goto	delay2
	decfsz	cntr2, f
        goto	delay1
	return				; ga terug naar laatste commando


;---------------------------------------------
;  ***  RESET : MAIN BOOT ROUTINE  ***	     -
;---------------------------------------------

RST		BSF	STATUS,RP1	;BANK2
		MOVLW	B'00000000'
		MOVWF	CM1CON0
		MOVLW	B'00000000'
		MOVWF	CM2CON0
		CLRF	ANSEL		;I/O'S DIGITAL
		;	
		BSF	STATUS,RP0	;BANK1
		MOVLW	B'11010111'
		MOVWF	OPTION_REG	;SET PIC OPTIONS

		MOVLW	B'00000111'
		TRIS	PORTA
		MOVLW	B'00000000'
		TRIS	PORTB
		MOVLW	B'00000000'	;I/O'S DIRECTION
		TRIS	PORTC
		;
		BCF	STATUS,RP0	;BACK TO BANK 0
				
		CLRF	PORTA
		CLRF	PORTB
		CLRF	PORTC

		GOTO	E_ON


;--------------------------------------------------
;	START 		OF 		PROGRAM	  -
;--------------------------------------------------



E_ON	CLRF	PORTC
	BTFSC	PORTA,0		; is RA,0 hoog ga naar E_RESET 
	GOTO	E_ON		; is RA,0 laag vervolg routine
		
E_AAN	MOVLW	H'CF'
	CALL	SEG2
	MOVLW	H'CB'
	CALL	SEG1		; power attention / displays shows : ON
	BTFSC	PORTA,0
	GOTO	E_RESET		; start teller --> E_RESET
	GOTO	E_AAN		
;--------------------------------------------------------------


E_RESET	CLRF	PORTC
	CLRF	PORTB		; wis displays
	BTFSC	PORTA,0
	GOTO	E_RESET		; wacht tot resetknop wordt losgelaten
	BTFSC	PORTA,1
	GOTO	E_1		; wacht op startpuls van RA,1 en ga dan naar E_1
	GOTO	E_RESET		; anders blijf wachten op startpuls

;	*************************
;	*   DISPLAY BESTURING   *
;	*************************


E_1	CLRF	PORTC
	CLRF	PORTB		; wis "ON" op displays
	BTFSC	PORTA,1		; kijk naar een puls op input RA,1
	GOTO	E_1		; wacht tot PORTA,1 laag is en ga dan verder
E_01	MOVLW	H'03'
	CALL	SEG1		; zet de nieuwe output waarde op het display "1"
	BTFSC	PORTA,1		; wacht op een puls op RA,1 en ga naar E_001
	GOTO	E_001
	GOTO	E_01
E_001	BSF	DISPL1		; laat "1" op het display staan
	BTFSC	PORTA,1		
	GOTO	E_001		; en wacht tot RA,1 weer laag is
E_0001	MOVLW	H'03'		; zet "1"nogmaals op het display 
	CALL	SEG1
	BTFSC	PORTA,1		; kijk naar een puls op RA,1
	GOTO	E_2		; en ga dan naar E_2
	GOTO	E_0001


E_2	MOVLW	H'03'
	CALL	SEG1		; laat "1" op het display staan tot RA,1 
	BTFSC	PORTA,1		; weer laag is
	GOTO	E_2
E_02	MOVLW	H'9D'	
	CALL	SEG1		; zet de nieuwe output waarde op het display "2"
	BTFSC	PORTA,1		; en herhaal het voorgaande
	GOTO	E_002
	GOTO	E_02
E_002	BSF	DISPL1
	BTFSC	PORTA,1
	GOTO	E_002
E_0002	MOVLW	H'9D'
	CALL	SEG1
	BTFSC	PORTA,1
	GOTO	E_3
	GOTO	E_0002


;  *-----------------------------*
;  *-    X DISPLAY OUTPUT X     -*
;  *-----------------------------*

SEG1	MOVWF	PORTC		
	BSF	DISPL1		; zet waarde op display 1
	CALL	DELAY
	BCF	DISPL1
	RETURN
	
SEG2	MOVWF	PORTC
	BSF	DISPL2		; zet waarde op display 2
	CALL	DELAY
	BCF	DISPL2
	RETURN


Maak de volgende waarde eens kleiner: delay1 movlw 0xff
De waarde schrijf je daarna naar cntr1.

Die waarde regelt hoe lang elk display aan staan.
Als het ene display aan staat, staat het andere uit. Als je dit snel genoeg doet zie je niet meer dat ze om en om aan staan (traagheid van je oog).
Doordat de tijd dat elk display aanstaat te lang is zie je nu het geknipper.

[Bericht gewijzigd door gizmo17110 op zondag 27 december 2009 00:25:56 (59%)

Hoi gizmo,bedankt voor je reactie.

Ik heb de waarde van delay1 kleiner gemaakt.tot 0x01
Dit is niet het gedeelte waar het probleem in zit.
Met de waarde van delay1 op 0xff bereik ik een frequentie van ongeveer 60 hertz.Dit is ruim voldoende voor het multiplexen.

In het effect waarmee het programma start, E_ON geven de displays ON aan en hier knipperen de displays nog niet.

Als nadat RA,1 hoog is geworden en het programma naar E_1 springt begint het probleem pas.Vanaf dit moment beginnen de displays heel licht te knipperen, dit doen ze op het moment dat een btfsc commando wordt gelezen.

In ieder opvolgend effect 1 t/m 75 knippert het display twee keer.

Nog enig idee hoe dit op te lossen is ?
grtz beest

Arco

Special Member

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

@arco volgens mij mist e3 t/m e75 uit het programma

Nu even wat beter gekeken.
Je display staat uit zolang de puls op poort A 1 hoog is, dit veroorzaakt waarschijnlijk het knipperen.
Display2 staat bij de eerste 3 getallen ook uit.

Als je E 1 t/m 75 hebt gebruikt in je programma, dan kan je het programma een behoorlijk stuk kleiner maken met de INCF instructie en een stukje code die je getallen omzet naar 7 segment.

Arco

Special Member

@arco volgens mij mist e3 t/m e75 uit het programma

Je gaat me toch zeker niet vertellen dat dat blok code 75 keer is gekopieerd? |:(

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

wrsch. niet 'het' probleem, maar volgens mij doe je bit operaties direct op het poort register: read-modify-write probleem!

Wouter van Ooijen: VOTI webwinkel, docent HvU (Technische Informatica); C++ on mictrocontrollers blog

Het programma is idd best groot geworden,zodra de displays goed oplichten ga ik proberen het programma op een compactere manier te schrijven.

wel heb ik nog een vraag.

De bit operatie voer ik idd direct op de poort uit.
Om ervoor te zorgen dat tijdens het inlezen van RA,1 het display aanblijft heb ik onderstaand stukje code toegevoegd.

pic asm code:



E_01	MOVLW	H'03'   ; <-
	CALL	SEG1    ; <-
BTFSC	PORTA,1		; blijf zolang RA,1 hoog is het display aansturen
	GOTO	E_001   ;
	GOTO	E_01    ;

Als dit stukje ( eerste twee regels ) wordt weggelaten gaat het display eventjes helemaal uit.Nu dit stukje code er staat. dimt het display iets op het moment dat de code wordt gelezen.

Nu heb ik geprobeerd om de bewerkingen via het TRIS register uit te voeren maar dat geeft nog steeds hetzelfde effect.
Is er een manier om het dimmen te voorkomen ?

Arco

Special Member

Iets compactere (Q&D)versie zonder knipper:

pic asm code:


#include <p16F690.inc>
 
    __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
 
pclath_temp	equ	0x70
w_temp		equ	0x71
status_temp     equ	0x72
digcount	equ	0x73
digit1		equ	0x74
digit2		equ	0x75
digit3		equ	0x76
digit4		equ	0x77

maxdigits	equ	d'2' ; d'4'
 
     		org 	0x000
 
		goto	Init
 
Irq		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
		movf	pclath,w		; move pclath register into W register
		movwf	pclath_temp		; save off contents of PCLATH register

		movf	digcount,w		

		banksel	portb			
		call	digtab			; select digit
		movwf	portb
		movlw	digit1
		movwf	fsr
		movf	digcount,w
		addwf	fsr,f
		movf	indf,w
		call	segtab			; set segment data
		movwf	portc

		incf	digcount,f
		movf	digcount,w
		xorlw	maxdigits
		btfsc	status,z
		clrf	digcount
		
		bcf	intcon,t0if
		goto	restore

segtab		addwf	pcl,f
		dt	0x3f,0x03,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
			
digtab		addwf	pcl,f
		dt	0x20,0x40,0x80,0x10

restore		movf	pclath_temp,w	        ; retrieve copy of PCLATH register
		movwf	pclath			; restore pre-isr PCLATH register contents	
		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
 
Init		
		banksel	tmr0
		clrf	tmr0
		clrf	digcount
		bsf	intcon,t0ie
		bsf	intcon,gie	
		bsf	intcon,peie
				
		banksel ansel
		clrf	ansel			;i/o digital
		clrf	anselh
		banksel option_reg
		movlw	b'10000011'
		movwf	option_reg		;Set option reg.

		banksel trisa
		movlw	b'00000111'
		movwf	trisa
		movlw	b'00000000'
		movwf	trisb
		movlw	b'00000000'		
		movwf	trisc

main		movlw	d'3'			; 
		movwf	digit1
		movlw	d'7'
		movwf	digit2
;		movlw	d'9'
;		movwf	digit3
;		movlw	d'4'
;		movwf	digit4
loop		goto	loop

		end

Display data staat in digit1 en digit2.
Voor 4 displays kun je B7 en B4 als digit select voor resp 3 en 4 gebruiken. (maxdigits dan op 4 zetten)
knoppen kun je in main zelf toevoegen.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Hey arco ingewikkeld stukje code,hier was 'k zelf nooit opgekomen.
Ben nog wel even bezig om uit te zoeken wat het precies doet.

tnks beest.

Arco

Special Member

Interrupt gestuurde multiplex van displays is eigenlijk de enige juiste manier, omdat dan de displays netjes op tijd gerefreshed worden.
(Zonder hinderlijke knipper-effecten of helderheidswisselingen, veroorzaakt door wachten op toetsen e.d...)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Turbokeu

Golden Member

Zo is het Arco, proper gedaan!

BTW, blij te horen dat er hier nog een 'die hard' ASM'er zit, ik voel me zowat verloren tussen al die 'Basic' en 'C' toestanden hier...

I love watching conspiracy theorists use the airtight logic of the argument from incredulity: "Well I don't understand how it works so it can't be real!!!"