Egen bygg display har uppdaterings problem (PIC)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

Har ett problem med uppdateringen på den elektromekaniska displayen jag har byggt.
Det är 10-dels siffran som ”ibland” inte blir rätt när måltiden skall vissas.
Har mina misstankar till att det har med delayen, som körs för att siffrorna skall kunna uppdateras.
Detta fel uppstår inte på den LED model jag byggde tidigare.

Här kommer en liten förklaring om hur allt fungerar.

Det är så att jag har en Tidtagningsklocka=klocka som skickar ut sekvenser med data för vad som skall visas på displayen.

Sekvenserna kan se ut så här hexadecimalt.
Ex. 1B 21 35 31 32 mer om sekvenserna se länk till protokoll Det börjar med 1B som är ”Esc” där efter kommer ”21 eller 22”om det är ”åkarens tid” eller ”bästa tid”.
Där efter kommer indexpekaren som talar om vilken ”digit” som nästa tecken skall in på och nästa tecken till nästa digit.
Index är som följer TT:MM:SS,DD T=timmar M= minuter S= sekunder D=delar (tiondel hundradel) Så är ser exemplet ovan ut: 1,2 sekunder.
Vid t.ex. målgång sänds hela sekvensen ex. 1B 21 33 31 30 31 34 38 visas som 1:01,48

Det är som sagt vid målgång som problemet kan uppstå och vissas som 1:01,38 istället för 1:01,48.
Kan även nämna att under rullande tid visas minuter, sekunder och tiondel
Så klockan skickar ut alla 10 siffrorna per sekund för tiondelen under rullande tid.

Eftersom klockan skickar ut en loop repeterar den datat och då tar displayen emot och ändrar siffran till rätt.
Men det gör att till en början är tiden missvisande.

Som sagt jag mistänker att siffran inte blir uppdaterad under någon delay, va tror ni.
Kan förklara mer i detalj hur koden jobber om ni vill.

Här är koden.

Kod: Markera allt

                    
;**********************************************************************
;Electro 7seg display
;**********************************************************************
;
 list      p=16f886             ; Val av processor
 #include <p16f886.inc>         ; Definitions fil för processor
; 
 __CONFIG _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC
 __CONFIG _CONFIG2, _WRT_OFF & _BOR21V
;
    errorlevel -302 
;
	#define		Dig_0		PORTA, 0
	#define		Dig_1		PORTA, 1
	#define		Dig_2		PORTA, 2		
	#define		Dig_3		PORTA, 3		
	#define		Seg_7		PORTB, 7
	#define		Seg_6		PORTB, 6
	#define		Seg_5		PORTB, 5
	#define		Seg_4		PORTB, 4
	#define		Seg_3		PORTB, 3
	#define		Seg_2		PORTB, 2
	#define		Seg_1		PORTB, 1
	#define		Seg_0		PORTB, 0
	#define		In1			PORTC, 0
	#define		In2			PORTC, 1
	#define		In3			PORTC, 2
	#define		In4			PORTC, 3
	#define		Set_digit	PORTC, 4
	#define		Clr_digit	PORTC, 5
	#define 	ESC				0x1B
	#define 	CURRENT_TIME	0x22
	#define 	STX				0x02
	#define 	Clock 			0x20
;   
;
;**********************************************************************
RESET_VECTOR    CODE    0x000   ; processor reset vector
	goto    start               ; Gå till början av program
;
;
INT_VECTOR      CODE    0x004   ; interrupt vector location
	goto    isr_routine       	; Gå till "interrupt service routine".
;        
RS232_VAR		UDATA_SHR       ; ISR buffert
RX_DATA     	RES 1           ; Data som motagits från RS232 port. 
chk_number		RES 1			; Här sparas tecknet, för avkodning till displayen.
rx_buffer		RES 4			; Motagningsbuffer på upp till 4 byte
Trigger			RES 1			; Trigger lagrings plats för att trigga olika funktioner
Trigger2		RES 1			; Trigger2 lagrings plats för att trigga olika funktioner
Trigger3		RES 1			; Trigger3 lagrings plats för att trigga olika funktioner
Trigger4		RES 1			; Trigger4 lagrings plats för att trigga olika funktioner
Trigger5		RES 1			; Trigger5 lagrings plats för att trigga olika funktioner
w_temp			RES	1			; Här sparas program vaiabler, när vi går in i ISR. 
status_temp		RES	1			; Här sparas program vaiabler, när vi går in i ISR. 
pclath_temp		RES	1			; Här sparas program vaiabler, när vi går in i ISR. 
		
;
Buffert_var		UDATA			; Display buffert (kräver minnes plats lokalisering i LKR fil. "SECTION    NAME=Buffert_var  RAM=gpr1")
digit_0			RES 1   		; lagrings plats för display 0, räknat från höger
digit_1			RES 1			; lagrings plats för display 1, räknat från höger
digit_2			RES 1			; lagrings plats för display 2, räknat från höger
digit_3			RES 1			; lagrings plats för display 3, räknat från höger
digit_4			RES 1			; lagrings plats för display 4, räknat från höger
digit_5			RES 1			; lagrings plats för display 5, räknat från höger
digit_6			RES 1			; lagrings plats för display 6, räknat från höger
digit_7			RES 1			; lagrings plats för display 7, räknat från höger
digit_8			RES 1			; lagrings plats för display 8, räknat från höger
Ind_check		RES 1			; Här sparas index pekaren, för vilken display som skall uppdateras.
TX_DATA			RES 1           ; Data att skicka till RS232 port.
temp			RES 1			; Temporär lagrings plats 1
temp2			RES 1			; Temporär lagrings plats 2
temp3			RES 1			; Temporär lagrings plats 3
;
Digit_var		UDATA
ch_d0			RES 1			; Om värdet som sparas i ch_d0 inte är samma som digit_0, sätts T0 till h'FF'
ch_d1			RES 1			; Om värdet som sparas i ch_d1 inte är samma som digit_1, sätts T1 till h'FF'
ch_d2			RES 1			; Om värdet som sparas i ch_d2 inte är samma som digit_2, sätts T2 till h'FF'
ch_d3			RES 1			; Om värdet som sparas i ch_d3 inte är samma som digit_3, sätts T3 till h'FF'
ch_d4			RES 1			; Om värdet som sparas i ch_d4 inte är samma som digit_4, sätts T4 till h'FF'
ch_d5			RES 1			; Om värdet som sparas i ch_d5 inte är samma som digit_5, sätts T5 till h'FF'
T0				RES 1			; Om värdet som sparas i T0 är högre än h'00' uppdateras display 0
T1				RES 1			; Om värdet som sparas i T1 är högre än h'00' uppdateras display 1
T2				RES 1			; Om värdet som sparas i T2 är högre än h'00' uppdateras display 2
T3				RES 1			; Om värdet som sparas i T3 är högre än h'00' uppdateras display 3
T4				RES 1			; Om värdet som sparas i T4 är högre än h'00' uppdateras display 4
T5				RES 1			; Om värdet som sparas i T5 är högre än h'00' uppdateras display 5

;**********************************************************************
;**********************************************************************
; Huvudkoden.
; Här hamnar vi vid reset eller power-on (från RESET_VECTOR)
;
;
MAIN    CODE
start
;		
	banksel ANSEL               ; Stäng av alla analoga funktioner
		clrf    ANSEL
		clrf    ANSELH
	banksel TRISA               ; Port A alla pinnar utgångar 
       	clrf    TRISA
	banksel	TRISB				; Port B alla pinnar utgångar 	
		clrf    TRISB
	banksel PORTC				
       	clrf	PORTC
	banksel	TRISC
		movlw	b'11001111'		; RC 0-3,6-7 ingångar RC 4-5 Utgångar
		movwf	TRISC
	banksel PIE1
		clrf 	PIE1
		bsf	PIE1, RCIE
	banksel	PIR1
		clrf	PIR1
	banksel	PIR2
		clrf	PIR2
	banksel PIE2
		clrf	PIE2	
	banksel	INTCON
		bsf INTCON, GIE
		bsf	INTCON, PEIE
	banksel porta
;
;****************************************************
;Hego 7000 In1=1 In2=0
;****************************************************             
Hego							; Koll på vilken sort tid som skall visas.
	movlw	h'76'
	movwf	portb
	bsf		DIG_0
	bcf		Dig_1
	bcf		Dig_2
	bcf		Dig_3
	CALL	send_to_display ; Skicka H till display 5
	CALL	send_to_display 
	movlw	h'79'
	movwf	portb
	bcf		DIG_0
	bsf		Dig_1
	bcf		Dig_2
	bcf		Dig_3
	CALL	send_to_display ; Skicka E till display 4 
	movlw	h'7D'
	movwf	portb
	bsf		DIG_0
	bsf		Dig_1
	bcf		Dig_2
	bcf		Dig_3
	CALL	send_to_display ; Skicka G till display 3 
	movlw	h'3F'
	movwf	portb
	bcf		DIG_0
	bcf		Dig_1
	bsf		Dig_2
	bcf		Dig_3
	CALL	send_to_display ; Skicka O till display 2 
	movlw	h'00'
	movwf	portb
	bsf		DIG_0
	bcf		Dig_1
	bsf		Dig_2
	bcf		Dig_3
	CALL	send_to_display ; Skicka _ till display 1
	btfss	In3				; Om In3 = 0, hoppa över nästa (Åktid).
	goto	Hego2			; Om In3 = 1, gå till Besttime (Bästatid).
	movlw	h'06'
	movwf	portb								
	bcf		DIG_0
	bsf		Dig_1
	bsf		Dig_2
	bcf		Dig_3
	CALL	send_to_display ; Skicka 1 till display 0 
	call	delay_5s
		call	zero
		banksel	TXSTA
		bcf	TXSTA, TX9		;Sätt 8 bits sändning		
		bsf	TXSTA, TXEN		;Sätt data sändning
		bcf	TXSTA, SYNC		;Async kommunikation
		bcf	TXSTA, BRGH		;Låg klock hastighet
	banksel	SPBRG
		movlw	d'119'		;Sätt Baudrate till 2400 eller 9600 beroende på BRGH, SPBRG värde = 25
		movwf	SPBRG
	banksel RCSTA		
		bsf RCSTA, SPEN		;Starta serie port
		bcf	RCSTA, RX9		;Sätt 8 bits mottagning
		bsf	RCSTA, CREN		;Sätt konstant motaggning
		bcf	RCSTA, FERR	
	goto	loop
Hego2						
	movlw	h'5b'
	movwf	portb								
	bcf		DIG_0
	bsf		Dig_1
	bsf		Dig_2
	bcf		Dig_3
	CALL	send_to_display ; Skicka 2 till display 0 
	call	delay_5s
	call	zero
		banksel	TXSTA
		bcf	TXSTA, TX9		;Sätt 8 bits sändning		
		bsf	TXSTA, TXEN		;Sätt data sändning
		bcf	TXSTA, SYNC		;Async kommunikation
		bcf	TXSTA, BRGH		;Låg klock hastighet
	banksel	SPBRG
		movlw	d'119'		;Sätt Baudrate till 2400 eller 9600 beroende på BRGH, SPBRG värde = 25
		movwf	SPBRG
	banksel RCSTA		
		bsf RCSTA, SPEN		;Starta serie port
		bcf	RCSTA, RX9		;Sätt 8 bits mottagning
		bsf	RCSTA, CREN		;Sätt konstant motaggning
		bcf	RCSTA, FERR
	goto	loop
;
Zero
	movlw	h'20'			;Spara "Space" i w
	movwf	digit_0			;Kopiera w till digit_0
	movwf	digit_1			;Kopiera w till digit_1
	movwf	digit_2			;Kopiera w till digit_2
	movwf	digit_3			;Kopiera w till digit_3
	movwf	digit_4			;Kopiera w till digit_4
	movwf	digit_5			;Kopiera w till digit_5
	clrf	ch_d0			;"Clear" värdet i ch_d0
	clrf	ch_d1			;"Clear" värdet i ch_d1
	clrf	ch_d2			;"Clear" värdet i ch_d2
	clrf	ch_d3			;"Clear" värdet i ch_d3	
	clrf	ch_d4			;"Clear" värdet i ch_d4
	clrf	ch_d5			;"Clear" värdet i ch_d5
	call	d_0				;Anropa D_0
	call	d_1				;Anropa D_1
	call	d_2				;Anropa D_2
	call	d_3				;Anropa D_3
	call	d_4				;Anropa D_4
	call	d_5				;Anropa D_5
	return
; **************************************************
; Loop
; **************************************************
loop 
	movf	T0, w			; Kopiera T0 till w
	sublw	h'00'			; Om T0 = 0x00, så blir Z nu = 0
	btfsc	STATUS, Z		; D.v.s skippa nästa inst om Z = 1	
	call 	D_0				; Anropa Sänd till D_0	
	movf	T1, w			; Kopiera T1 till w
	sublw	h'00'			; Om T1 = 0x00, så blir Z nu = 0
	btfsc	STATUS, Z		; D.v.s skippa nästa inst om Z = 1	
	call 	D_1				; Anropa Sänd till D_1	
	movf	T2, w			; Kopiera T2 till w
	sublw	h'00'			; Om T2 = 0x00, så blir Z nu = 0
	btfsc	STATUS, Z		; D.v.s skippa nästa inst om Z = 1	
	call 	D_2				; Anropa Sänd till D_2	
	movf	T3, w			; Kopiera T3 till w
	sublw	h'00'			; Om T3 = 0x00, så blir Z nu = 0
	btfsc	STATUS, Z		; D.v.s skippa nästa inst om Z = 1	
	call 	D_3				; Anropa Sänd till D_3	
	movf	T4, w			; Kopiera T4 till w
	sublw	h'00'			; Om T4 = 0x00, så blir Z nu = 0
	btfsc	STATUS, Z		; D.v.s skippa nästa inst om Z = 1	
	call 	D_4				; Anropa Sänd till D_4	
	movf	T5, w			; Kopiera T5 till w
	sublw	h'00'			; Om T5 = 0x00, så blir Z nu = 0
	btfsc	STATUS, Z		; D.v.s skippa nästa inst om Z = 1	
	call 	D_5				; Anropa Sänd till D_5		
	goto 	Loop			; Gå till Loop
;
; **************************************************
; ISR_ROUTINE
; **************************************************
ISR_ROUTINE  	CODE
;
isr_routine
	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
	movwf	pclath_temp
	clrf	PCLATH		; Be sure that wer'e home alone
datain1
		btfsc	RCSTA, OERR
		goto	overerror		; om 'overflow error'...
		btfsc	RCSTA, FERR
		goto	frameerror		; om 'framing error'...
;
uart_gotit
		movf	RCREG, w		; Ta emot data från UART port, spara i w.
		movwf	RX_DATA			; Spara w, i RX_DATA	
		movf	rx_data, w
		andlw 	h'7F' 			; Lägg på sista biten, så att 7 bits blir 8 bits data. 
		movwf	rx_data
		goto	Hego_7000			; Om In2 = 0, gå till Hego.
;
overerror
		banksel RCSTA
		bcf		RCSTA, CREN		; Stäng av pulse cren
		movf	rcreg,w			; Rensa FIFO
		movf	rcreg,w			; är tre steg 
		movf	rcreg,w
		bsf		RCSTA, CREN		; Sätt cren och oerr blir låg.¨
		goto	datain1			; försök igen...
;
frameerror 				
		movf	rcreg,w			; Att läsa av RCREG gör att FERR blir låg.
		goto	datain1			; Försök igen..
;
;****************************************************
;Hego 7000 In1=1 In2=0
;****************************************************             
Hego_7000
esc_check
		movf	RX_DATA, w		; Kopiera rx_data till w
		sublw	ESC				; Subtrahera ESC med RX_DATA
		btfsc	STATUS, Z		; D.v.s skippa nästa inst om Z = 1
		goto	clear			; Gåt till clear om ESC, återställ allt.
if_0x21
		movf	rx_data, w		; Kopiera rx_data till w
		btfsc	In3				; Om In3 = 0, hoppa över nästa (läser av sekvenser med 0x22).
		addlw	h'01'			; Om In3 = 1, add 1 (läser av sekvenser med 0x21).
		movwf	temp			; Spara i temp, f
		movf	temp, w			; Kopiera temp till w
		sublw	CURRENT_TIME	; Om inkommet tecken = 0x22, så blir Z nu = 0
		btfss	STATUS, Z		; D.v.s skippa nästa inst om Z = 1
		goto	index			; Gå till Index
		movf	rx_data,w		; Kopiera rx_data till w
		movwf	INDF			; Spara w i Rx_buffer
		incf	FSR,f			; hoppa till Rx_buffer+1
		goto	Done
index
		movf	rx_buffer,w		; Kopiera rx_buffer till w
		btfsc	In3				; Om In3 = 0, hoppa över nästa (läser av sekvenser med 0x21).
		addlw	h'01'			; Om In3 = 1, add 1 (läser av sekvenser med 0x22).
		movwf	temp			; Spara i temp
		movf	temp, w			; kopiera temp till w
		sublw	CURRENT_TIME	; Om RX_BUFFER+1 = 0x21 eller 0x22 beroende på In3 , så blir Z nu = 0
		btfss	STATUS, Z		; D.v.s skippa nästa inst om Z = 1
		goto	clear			; Gå till clear
		movf	Trigger, w		; Kopiera Trigger till w
		sublw	h'00'			; Om Trigger = 0x00, så blir Z nu = 0
		btfss	STATUS, Z		; D.v.s skippa nästa inst om Z = 0
		goto	index_0			; Om Trigger =1, gå till Index_0	
		movf	rx_data,w		; kopiera till rx_data i w
		movwf	INDF			; Spara i rx_buffer+1
		incf	FSR,f			; Hoppa till Rx_buffer+2
		movlw	h'ff'
		movwf	Trigger			; Sätt Trigger hög
		goto 	Done			; Gå till Done
Index_0
		movf	digit_2, w		; Kopiera digit_4 till w
		movwf	temp			; spara w i temp
		movf	temp, w			; kopiera temp till w
		sublw	Clock			; Subtrahera w med clock	
		btfss	STATUS, Z		; D.v.s skippa nästa inst om Z = 0	
		goto	Index_1_0		; Gå till Index_1_0
		movlw	h'20'			; Sätt värde 0x20 i w
		movwf	digit_6			; Spara w i digit_6
;
index_1_0
		movf	digit_6, w		; kopiera digit_6 till w
		sublw	Clock			; Subtrahera w med clock	
		btfsc	STATUS, Z		; D.v.s skippa nästa inst om Z = 0
		goto 	index_1_1
		movf	rx_buffer+1, w	; kopiera rx_buffer+1 till w 
		movwf	Ind_check		; Spara w i Ind_check
		movlw	h'30'			; Sätt värde 0x30 i w 
		subwf	ind_check,f		; Subtrahera w med Ind_check
		btfss	STATUS, Z		; Om Z = 0 hoppa över nästa.
        goto	index_4			; Nej, gå till Index_1
		movf	rx_data, w		; Kopiera rx_data till w
		movwf	digit_3			; Spara w i Digit_5
		incf	rx_buffer+1,f	; Addera rx_buffer+1 med 1
		movf	ch_d3,w			; Spara i temp, f
		movwf	temp2			; Kopiera temp till w
		Movf	digit_3,w		; Kopiera digit_0 till w
		subwf	temp2,f			; Subtrahera w med Ind_check
		btfsc	STATUS, Z		; Om Z = 0 hoppa över nästa.
		goto	done			; gå till done
		movlw	h'00'
		movwf	T3				; Sätt T5 låg
		goto	Done			; gå till done;			; gå till done
index_1_1
		movf	rx_buffer+1, w	; kopiera rx_buffer+1 till w 
		movwf	Ind_check		; Spara w i Ind_check
		movlw	h'30'			; Sätt värde 0x30 i w 
		subwf	ind_check,f		; Subtrahera w med Ind_check
		btfss	STATUS, Z		; Om Z = 0 hoppa över nästa.
        goto	index_2			; Nej, gå till Index_1
		movf	rx_data, w		; Kopiera rx_data till w	
		movwf	digit_7			; Spara w i Digit_7
		incf	rx_buffer+1,f	; Addera rx_buffer+1 med 1
		goto	done			; gå till done
;
index_2							; Index pekare =31  ?
		decfsz	Ind_check, f	; Subtrahera Ind_check med 1, om Ind_check blir 0 hoppa över nästa.	
        goto	index_3			; Nej, gå till Index_2	
		movf	rx_data, w		; Kopiera rx_data till w
		movwf	digit_6			; Spara w i Digit_6
		incf	rx_buffer+1,f	; Addera rx_buffer+1 med 1
		goto 	done			; gå till done
;
index_3							; Index pekare =32  ?
		decfsz	Ind_check, f	; Subtrahera Ind_check med 1, om Ind_check blir 0 hoppa över nästa.	
		goto	index_4			; Nej, gå till Index_3
		incf	rx_buffer+1,f	; Addera rx_buffer+1 med 1
		goto	Done			; gå till done;
index_4							; Index pekare =33  ?
		decfsz	Ind_check, f	; Subtrahera Ind_check med 1, om Ind_check blir 0 hoppa över nästa.		
        goto	index_5			; Nej, gå till Index_4		
		movf	rx_data, w		; Kopiera rx_data till w
		movwf	digit_5			; Spara w i Digit_4
		incf	rx_buffer+1, f	; Addera rx_buffer+1 med 1
		movf	ch_d5,w			; Spara i temp, f
		movwf	temp2			; Kopiera temp till w
		Movf	digit_5,w		; Kopiera digit_4 till w
		subwf	temp2,f			; Subtrahera w med Ind_check
		btfsc	STATUS, Z		; Om Z = 0 hoppa över nästa.
		goto	done			; gå till done
		movlw	h'00'
		movwf	T5				; Sätt T4 låg
		goto	Done			; gå till done;
index_5							; Index pekare =34  ?
		decfsz	Ind_check, f	; Subtrahera Ind_check med 1, om Ind_check blir 0 hoppa över nästa.		
        goto	index_6			; Nej, gå till Index_5
		movf	rx_data, w		; Kopiera rx_data till w
		movwf	digit_4			; Spara w i Digit_3
		incf	rx_buffer+1, f	; Addera rx_buffer+1 med 1
		movf	ch_d4,w			; Spara i temp, f
		movwf	temp2			; Kopiera temp till w
		Movf	digit_4,w		; Kopiera digit_3 till w
		subwf	temp2,f			; Subtrahera w med Ind_check
		btfsc	STATUS, Z		; Om Z = 0 hoppa över nästa.
		goto	done			; gå till done
		movlw	h'00'
		movwf	T4				; Sätt T3 låg
		goto	Done			; gå till done
;
index_6							; Index pekare =35  ?
		decfsz	Ind_check, f	; Subtrahera Ind_check med 1, om Ind_check blir 0 hoppa över nästa.		
       	goto	index_7			; Nej, gå till Index_5
		movf	rx_data, w		; Kopiera rx_data till w
		movwf	digit_3			; Spara w i Digit_2
		incf	rx_buffer+1, f	; Addera rx_buffer+1 med 1
		movf	ch_d3,w			; Spara i temp, f
		movwf	temp2			; Kopiera temp till w
		Movf	digit_3,w		; Kopiera digit_2 till w
		subwf	temp2,f			; Subtrahera w med Ind_check
		btfsc	STATUS, Z		; Om Z = 0 hoppa över nästa.
		goto	done			; gå till done
		movlw	h'00'
		movwf	T3				; Sätt T2 låg
		goto	Done			; gå till done;
index_7							; Index pekare =36  ?
		decfsz	Ind_check, f	; Subtrahera Ind_check med 1, om Ind_check blir 0 hoppa över nästa.		
       	goto	index_8			; Nej, gå till Index_5
		movf	rx_data, w		; Kopiera rx_data till w
		movwf	digit_2			; Spara w i Digit_1
		incf	rx_buffer+1, f	; Addera rx_buffer+1 med 1
		movf	ch_d2,w			; Spara i temp, f
		movwf	temp2			; Kopiera temp till w
		Movf	digit_2,w		; Kopiera digit_1 till w
		subwf	temp2,f			; Subtrahera w med Ind_check
		btfsc	STATUS, Z		; Om Z = 0 hoppa över nästa.
		goto	done			; gå till done
		movlw	h'00'
		movwf	T2				; Sätt T1 låg
		goto	Done			; gå till done
;
index_8							; Index pekare =37  ?
		decfsz	Ind_check, f	; Subtrahera Ind_check med 1, om Ind_check blir 0 hoppa över nästa.		
   		goto 	done
		movf	rx_data, w		; Kopiera rx_data till w
		movwf	digit_1			; Spara w i Digit_0
		clrf	rx_buffer		; Nolla rx_buffer
		movf	ch_d1,w			; Spara i temp, f
		movwf	temp2			; Kopiera temp till w
		Movf	digit_1,w		; Kopiera digit_0 till w
		subwf	temp2,f			; Subtrahera w med Ind_check
		btfsc	STATUS, Z		; Om Z = 0 hoppa över nästa.
		goto	done			; gå till done
		movlw	h'00'
		movwf	T1				; Sätt T0 låg
		goto	Done			; gå till done
;
;
clear							;Rensa buffern m.m.
		nop
		nop
		nop
		clrf	ind_check		; Nolla ind_check	
		nop
		clrf	rx_buffer		; Nolla rx_buffer
		clrf	rx_buffer + 1	; Nolla rx_buffer+1
		clrf	rx_buffer + 2	; Nolla rx_buffer+2
		clrf	rx_data			; Nolla rx_data
		movlw	rx_buffer		; kopiera värdet i rx_buffer till w
		movwf	FSR				; Spara w i pekaren till rx_buffer
		movlw	h'00'
		movwf	Trigger			; Sätt Trigger låg
		movlw	h'00'
		movwf	Trigger2		; Sätt Trigger2 låg
		goto	done			; gå till done
	NOP
done		
	movf	pclath_temp,W		; Read copy of PCLATH
	movwf	PCLATH				; Restore to pre-ISR content
	movf	status_temp,W		; Retrieve copy of STATUS register
	movwf	STATUS				; Restore pre-isr STATUS register contents
	swapf	w_temp,F			; Restore pre-isr F register contents
	swapf	w_temp,W			; Restore pre-isr W register contents
Slut		
	retfie
;****************************************************
; Rutin för att verifiera siffra i minne och skicka till display.
; Displayerna räknas från höger
;****************************************************
Send_to_digit
D_0
	Movf	digit_0,w		; Kopiera digit_0 till w
	movwf	ch_d0			; Spara w i ch_d0
	movwf	chk_number		; chk_number
	bcf		DIG_0			; Sätt Dig_0-4 till 6 binärt 
	bsf		Dig_1
	bsf		Dig_2
	bcf		Dig_3
	CALL	Check_number	; Anropa Check_number
	movwf	portb			; Kopiera w till PortB
	CALL	send_to_display ; Anropa Send_to_display för att uppdatera display 0
	movlw	h'ff'			; Sätt värde 0xFF i w
	movwf	T0				; Kopiera w till T0 så den blir satt hög
	return
D_1
	Movf	digit_1,w		; Kopiera digit_1 till w
	movwf	ch_d1			; Spara w i ch_d1
	movwf	chk_number		; Spara w i chk_number
	bsf		DIG_0			; Sätt Dig_0-4 till 5 binärt 
	bcf		Dig_1
	bsf		Dig_2
	bcf		Dig_3
	CALL	Check_number	; Anropa Check_number
	movwf	portb			; Kopiera w till PortB
	CALL	send_to_display ; Anropa Send_to_display för att uppdatera display 1
	movlw	h'ff'			; Sätt värde 0xFF i w
	movwf	T1				; Kopiera w till T1 så den blir satt hög
	return
D_2
	Movf	digit_2,w		; Kopiera digit_2 till w
	movwf	ch_d2			; Spara w i ch_d2
	movwf	chk_number		; Spara w i chk_number
	bcf		DIG_0			; Sätt Dig_0-4 till 4 binärt
	bcf		Dig_1			
	bsf		Dig_2
	bcf		Dig_3
	CALL	Check_number	; Anropa Check_number
	movwf	portb			; Kopiera w till PortB
	CALL	send_to_display ; Anropa Send_to_display för att uppdatera display 2
	movlw	h'ff'			; Sätt värde 0xFF i w
	movwf	T2				; Kopiera w till T2 så den blir satt hög
	return
D_3
	Movf	digit_3,w		; Kopiera digit_3 till w
	movwf	ch_d3			; Spara w i ch_d3
	movwf	chk_number		; Spara w i chk_number
	bsf		DIG_0			; Sätt Dig_0-4 till 3 binärt
	bsf		Dig_1
	bcf		Dig_2
	bcf		Dig_3
	CALL	Check_number	; Anropa Check_number
	movwf	portb			; Kopiera w till PortB
	CALL	send_to_display ; Anropa Send_to_display för att uppdatera display 3
	movlw	h'ff'			; Sätt värde 0xFF i w
	movwf	T3				; Kopiera w till T3 så den blir satt hög
	return
D_4
	Movf	digit_4,w		; Kopiera digit_4 till w
	movwf	ch_d4			; Spara w i ch_d4
	movwf	chk_number		; Spara w i chk_number
	bcf		DIG_0			; Sätt Dig_0-4 till 2 binärt
	bsf		Dig_1
	bcf		Dig_2
	bcf		Dig_3
	CALL	Check_number	; Anropa Check_number
	movwf	portb			; Kopiera w till PortB
	CALL	send_to_display ; Anropa Send_to_display för att uppdatera display 4
	movlw	h'ff'			; Sätt värde 0xFF i w
	movwf	T4				; Kopiera w till T4 så den blir satt hög
	return
D_5
	Movf	digit_5,w		; Kopiera digit_5 till w
	movwf	ch_d5			; Spara w i ch_d5
	movwf	chk_number		; Spara w i chk_number
	bsf		DIG_0			; Sätt Dig_0-4 till 1 binärt
	bcf		Dig_1
	bcf		Dig_2
	bcf		Dig_3
	CALL	Check_number	; Anropa Check_number
	movwf	portb			; Kopiera w till PortB
	CALL	send_to_display ; Anropa Send_to_display för att uppdatera display 5 
	movlw	h'ff'			; Sätt värde 0xFF i w
	movwf	T5				; Kopiera w till T4 så den blir satt hög
	return
;****************************************************
;Rutin för att verifiera siffra i minne
;****************************************************
Check_number
;
	banksel eeadr			; Byt till rätt bank
;
	movlw	high ascii0		; Bit 8-15 av adressen att starta i tabellen.
	movwf	eeadrh
	movlw	low ascii0		; Bit 0-7 av adressen att starta i tabellen.
	movwf	eeadr
;	
	movlw	d'32'
	subwf	chk_number, w	; Hämta ascii värdet från chk_number, och minska med 48. 
	addwf	eeadr, f
	btfsc	status,c
	incf	eeadrh, f
;   
	call	Get_value       ; Hämta värde
;   
	banksel	portb           ; Byt till rätt bank
	return
;
Get_value
	banksel	eecon1
	bsf		eecon1, eepgd	; Läs från flash
	bsf		eecon1, rd		; Sätt läs-flagga
	nop						; Vänta
	nop
	banksel	eedat
	movf	eedat, w		; Lägg värdet i "w" registret
	return


;**********************************************************************
ASCII_TABLE   CODE ; Table med ASCII värden
ascii0
   	data    h'00'	;20
	data    h'01'	;21
	data    h'02'	;22
	data    h'03'	;23
	data    h'04'	;24
	data    h'05'	;25
	data    h'06'	;26
	data    h'07'	;27
	data   	h'08'	;28
	data    h'09'	;29
	data    h'0A'	;2A
	data    h'0B'	;2B
	data    h'0C'	;2C
	data    h'0D'	;2D
	data    h'0E'	;2E
	data    h'0F'	;2F
	data    h'3f'	;0
	data    h'06'   ;1
	data    h'5b'	;2
	data    h'4f'	;3
	data    h'66'	;4
	data    h'6d'	;5
	data    h'7d'	;6
	data    h'07'	;7
	data    h'7f'	;8
	data    h'6f'	;9
	data    h'06'	;:
	data    h'0E'	;;
	data    h'58'	;<	
	data    h'48'	;=
	data    h'4C'	;>
	data    h'53'	;?
	data    h'7B'	;@
	data    h'77'	;A
	data    h'7C'	;B
	data    h'59'	;C
	data    h'5E'	;D
	data   	h'79'	;E
	data    h'71'	;F
	data    h'7D'	;G
	data    h'76'	;H
	data    h'06'	;I
	data    h'0B'	;J
	data    h'00'	;
	data    h'38'	;L
	data    h'00'	;
	data    h'54'	;N
	data   	h'00'	;

;
; **************************************************
; Rutin för att sända ett tecken till vald display
; Bit-mönstret ska ligga i "portb" före anrop
; **************************************************;
send_to_display
;
	BcF		Clr_digit	;Pulsa "Clr_digit" för att släcka de segment som inte skall visas.
	call	Delay_70ms	;Vänta 70 ms
	BsF		Clr_digit	;Sätt "Clr_digit" hög igen.
;
	movf	PORTB, w	; Kopiera PortB till w
	sublw	h'00'		; Om PortB = 0x00, så blir Z nu = 0
	btfsc	STATUS, Z	; D.v.s skippa nästa inst om Z = 1	
	RETURN
	BcF		Set_digit	;Pulsa "Set_digit" för att sätta de segment som skall visas.
	call	Delay_70ms	;Vänta 70 ms
	BsF		Set_digit	;Sätt "Clr_digit" hög igen.
;
	RETURN
;
; *********************************************************************
; Diverse delay rutiner.
; Alla delay rutiner generade med kodgeneratorn här :
; http://www.piclist.com/techref/piclist/codegen/delay.htm
; OBS generatade för 18.432 Mhz processorhastighet. 
; *********************************************************************
;
DLY_VAR      UDATA_SHR
d1           RES 1
d2           RES 1
d3           RES 1
;
;
DLY_CODE        CODE
;
delay_5s
	movlw	0x23
	movwf	d1
	movlw	0x3A
	movwf	d2
	movlw	0x33
	movwf	d3
Delay_5s_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_5s_0
	goto $+1
 nop
    return
;
Delay_70ms
	movlw	0xFF
	movwf	d1
	movlw	0xFC
	movwf	d2
Delay_70ms_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_70ms_0
	goto	$+1
	return
;
;**********************************************************************
    end
Jag kan förklara mer ingående vad koden gör om ni vill.
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

Har inte skrivit något mer här då det kom Jul, Nyår och födelsdagsfirande i vägen.

Här är lite av vad koden gör för något.
Digit_1=hundradel
Digit_2=tiondel
Digit_3=sekund
Digit_4=sekund
Digit_5=minut
Digit_6=timme
fröken ur= för att kunna vissa klockan TT:MM på positonerna sekunder och delar

ISR tar emot inkommande RS232 data sparar i Rx_data.
Esc_check kollar om Rx_data innehåller 1B om ja så nollställs buffern och div. trigg punkter och går ur ISR.

If_0x21 söker efter t.ex. 21* om det är 21 sparas Rx_data i buffern går ur ISR. Om det är annat än 21 går den till index.

* If_0x21 och index har en funktion för att ta 21 och 22

Index hämtar upp värdet i rx_buffer och kollar om det är t.ex. 21* om annat värde så nollställs buffern och div. trigg punkter och går ur ISR.
Om det var t.ex. 21*, så kollas trigger om värde är 00 om ja så sparas rx_data i rx_buffer+1 sen sparas FF i trigger och går ur ISR.
innehåller trigger ett högre värde, gå till index_0

Index_0 kollar om Digit_2 innehåller värdet 20 om den innehåller 20 så sparas värdet 20 i Digit_6 (Denna funktion kan bort ses då den är för att släcka fröken ur.)

Index_1_0 (Denna funktion kan bort ses då den är för att visa fröken ur.)

Index_1_1 tar värdet i Rx_buffer+1 och sparar i Ind_check.
Ind_check subtraheras med värdet 30 och resultatet av ind_check kollas mot Index_1_1 till index_8 om Ind_check blir 00, så sparas Rx_data till rätt digit.

T.ex. om Index pekaren i Rx_buffer+1 är 35 så sparas värdet i Digit_3 (sekund)
Nu ökas värdet i Ind_check med 1 så när nästa inkommande kommer sparas det i Digit_2 (tiondel)

Det gör även en check om värdet i t.ex.digit_3 är samma som ch_d3 om det inte är samma, så sparas 00 i T3 som triggar en uppdatering av sekunder siffran.

Loopen kollar om det har triggats någon ändring och i så fall uppdaterar siffrorna.

Om vi säger att Digit_3 har ett nytt värde ex. 35 för en 5:a, så triggas den i ISR koden och loopen anropar D_3, som gör följande.
Sparar digit_3 i ch_d3 och i chk_number.
Sätter utgångarna till binärt en 3:a (RA0-3)
Anropar Check_number, som kollar vad värdet i chk_number blir i ASCII tabellen och får tillbaka det binära värdet satt till PORTB under D3.
Nu anropas Send_to_display, som först pulsar clr_digit för att släcka ev. satta segment.
Sen pulsas set_digit för att sätta segment för att visa en 5:a och tillbaka till D3, därefter sparas FF i T3 och sen tillbaka till loopen.
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

Som det ser ut nu är det mycket kod i ISR, vilket har varit upp i diskussion om i en tidigare tråd. Allt har funkat förutom detta uppdaterings problem att koden hinner sätta rätt siffra på tiondelen.

Är lite inne på att utöka buffern och låta allt data komma in där tills nästa 1B dyker upp och då först gå igenom datat i buffern, men vet inte riktigt hur man bäst löser det.

En fråga: Vad händer under en Delay kör ISR ändå eller hur fungerar det.
sodjan
EF Sponsor
Inlägg: 43244
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av sodjan »

Ja, så länge som interrupts inte är avstängda så körs de.
Processorn i sig har ju inte en aning om att den befinner
sig i en "delay". Allt är bara kod för processorn...
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

Hur menar du med "så länge som interrupts inte är avstängda så körs de"?
Att "Global Interrupt Enable bit" skulle vara avslagen?
sodjan
EF Sponsor
Inlägg: 43244
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av sodjan »

Ja. Eller rellevant IExx eller IFxx flagga.

Min poäng var att du frågade om interrupt fungerade när
"processorn befinner sig i en delay", och att det vet inte
processorn...
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

Okej, då är jag me.

Det lustiga med problemet är att det fungerar på LED modellen, men inte på elektromekaniska. Å andra sidan är det lite olika uppdateringar av displayen. På LED modellen är det ett shiftregister som hela tiden uppdatera alla siffrorna, vilket inte funkar på den elektromekaniska då man måste ta en siffra i taget. Om nu ISR´n funkar under delayen borde rätt siffra lagras till digit och sen då bli rätt.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4743
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Swech »

Om man istället tittar på de grova dragen så är mitt förslag:

UART rutinen skall endast buffra inkommande data tills dess att ett end
of text dyker upp. Bäst är att köra en dubbel buffer.
Så fort som end of text kommer så bytar UART rutinen buffer och signalerar
till huvudprogrammet att avkoda den just mottagna kompletta bufferten.
UART kan ta emot data i den andra bufferten samtidigt som huvudprogrammet avkodar..

När huvudprogrammet avkodat klart så uppdateras alla siffror oavsett om det är
ändrat eller ej. Så slipper man den typ av fenomen som du har. Att någon siffra
inte hänger med....

Swech
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

Jag var inne på att köra bara en men var rädd att den blir över skriven innan man hunnit gå igenom hela buffern, så dubbla buffrar låter bra.
Nu kanske jag är ute och cyklar, men det kan bli upp till 16 bytes per buffer och vad jag förstår så är det bara 16 per minnesbank eller har jag fel?
sodjan
EF Sponsor
Inlägg: 43244
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av sodjan »

Det är väl en 886'a ?
Se "FIGURE 2-6: PIC16F886/PIC16F887 SPECIAL FUNCTION REGISTERS"
DU har minst 80 bytes per bank, och ytterligare en del...
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

Måste ha blandat ihop det problem som jag hade tidigare i Udata_shr, då jag översteg 16 byte och fick problem med att man delade på samma address.

Löstes genom att skapa en till udata i grp1, vilket alltså kan vara upp till 80 byte stor enlikt databladet.

För att nu skapa en storbuffer, är det nödvändigt att peka startadressen till en specifik adress i ram eller?
Ex.

Kod: Markera allt

Buffert_var udata 0xA0 ;Buffert data stored at locations starting at 0xA0 (bank 1)
   Buffer_1 res 16
   Buffer_2 res 16
sodjan
EF Sponsor
Inlägg: 43244
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av sodjan »

Ja, det det ger två 16 bytes buffertar. Sedan kan du t.ex ladda FSR registret med
valfri buffert via "MOVLW Buffer_1". Länkaren kommer att översätta "Buffer_1"
till en konstant ("litteral"), d.v.s den faktiska adressen där bufferten hamnade efter
allokeringen under länkningen (vilket alltså kan skilja från en build till nästa).
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

Vill bara kolla ett par saker innan jag testar att lägga in de andra två buffrarna.
Idag har jag en buffer som sparar de två första byten efter 1B, den heter Rx_buffer, jag pekar inte innan på rx_buffer jag spara data i Rx_buffer. utan skriver bara som följande.

Kod: Markera allt

		movf	rx_data,w		; kopiera till rx_data i w
		movwf	INDF			; Spara i Rx_buffer
		incf	FSR,f			; Hoppa till Rx_buffer+1
Antar att man inte behöver det för att den ligger i "Udata_shr"
Men nu när jag skapar en till buffer misstänker jag att man måste peka på Rx_buffer innan man skriver data till buffern för att inte skriva till fel buffer.

Är det då bara att skriva följande innan koden ovan?

Kod: Markera allt

banksel Rx_buffer 
eller måste jag skriva

Kod: Markera allt

movlw    Rx_buffer
movwf    FSR
sodjan
EF Sponsor
Inlägg: 43244
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av sodjan »

"Shared memory" gör att du inte behöver BANKSEL före använding
av den aktuella variablen.

Sen så är jag inte riktigt med på vad du menar...
I det nuvarande fallet så måste du ju ha "laddat" FSR någonstans
med adressen till Rx_buffer innan du accessar INDF !?
Det blir samma sak nu, fast du får växla mellan de två buffrarna.

Sedan har du rör ihop det lite med banksel och indexerad adressering.
Du ska inte göra banksel mot *bufferten*, den accessas genom
indexregistret ! Kolla "2.4 Indirect Addressing, INDF and FSR Registers"
en gång till, speciellt "FIGURE 2-8: DIRECT/INDIRECT ADDRESSING".
BANKSEL sätter RP0/RP1 och i fuguren ser du att de *inte* används
vid indexerad adressering.

Se även "4.6 bankisel - GENERATE INDIRECT BANK SELECTING CODE"
i MPASM manualen !
Stewal
Inlägg: 354
Blev medlem: 17 januari 2008, 16:38:41
Ort: Nämdö

Re: Egen bygg display har uppdaterings problem (PIC)

Inlägg av Stewal »

>I det nuvarande fallet så måste du ju ha "laddat" FSR någonstans
>med adressen till Rx_buffer innan du accessar INDF !?
Jag missade att den ligger under Clear.

Kod: Markera allt

		movlw	rx_buffer		; kopiera värdet i rx_buffer till w
		movwf	FSR		; Spara w i pekaren till rx_buffer
Säg att jag lägger Buffer_1 och Buffer_2 i Bank 1
Om jag nu skall läsa från t.ex buffer_1 måste jag välja bank 1 innan, enligt vad jag kan se i figuren under "FIGURE 2-8: DIRECT/INDIRECT ADDRESSING".
Blir det inte "INDIRECT ADDRESSING"?
Skriv svar