Sida 8 av 26

Postat: 7 februari 2008, 10:48:48
av Icecap
Nja... 1:27.691 blir faktisk:
1 st minut-paket.
1 st sekund-paket.
1 st 1/100-sekund paket.
1 st 1/10k-sekund paket.

Sedan visning på display.

När alla data i en tid är inhämtat är Rx_Buffer likgiltig, de aktuella siffor står i de avsatta minneslokationer (byte Timmar[2], Minuter[2], Sekunder[2], Sek100[2], Sek10k[2];) som ren text, alltså (vi skippar timmarna) kommer 1:27.691 att stå som:
' ', '1' i Minuter,
'2', '7' i Sekunder,
'6', '9' i Sek100 och
'1', ' ' i Sek10k.

Dessa siffror ska sedan slängas ut på displayen.
Obs. att INGET hindrar dig från att lägga minnet så att du får en "sträng" att lägga ut, om du lägger det såhär:
h10, h01, ':', m10, m01, ':', s10, s01, ',', 'x', 'x', 'x', '(x)' där
h10 är tiotimmar
h01 är 1-timmar
':' och ',' är RAM-lokationer som du fyller upp med just dessa tecken vid uppstart.
'x'... är 100-del + 10k-dels sekunder, dock verkar (x)-platsen alltid vara mellanslag pga. tidtagningens upplösning.

Resultatet är att du, när "Utskrift" signaleras, har en sträng:
"hh:mm:ss,xxx(x)" som du kan skriva ut i ett svep, helt eller delvist.

Postat: 7 februari 2008, 11:44:28
av Stewal
>'x'... är 100-del + 10k-dels sekunder, dock verkar (x)-platsen alltid vara mellanslag pga. tidtagningens upplösning.

Som det är idag skickar inte tidtagningen ut 1000-delen, på grund av att den inte är programmerad att göra det.
Tanken är att försöka få den att göra det, men det är en senare grej.
Därför kan koden för displayen göras enligt följande och kodas om senare:
MM:SS.xx

>Resultatet är att du, när "Utskrift" signaleras, har en sträng:

"mm:ss.xx" som du kan skriva ut i ett svep, helt eller delvist.
Vet inte om man kan skriva hela stängen till displayen, tror man måste dela upp det.

Postat: 7 februari 2008, 11:56:53
av sodjan
Icecap, det är ingen HD44780 LCD. Det är två st 4-pos LED matriser.
Så "skriva u ti ett svep" går inte. Däremot kan det finnas andra fördelar
rent kod-mässigt med att värderna ligger tillsammans...

Postat: 7 februari 2008, 12:16:18
av Stewal
Kommer nog göra ett labb efter det här med en HD44780 LCD.
Då med Start nr. Bästa tid, RAD 2 Start nr. Åkarens tid, men det är senare.

>Däremot kan det finnas andra fördelar rent kod-mässigt med att värderna ligger tillsammans...
Ja det måste vara enklare att hämta från buffern och skicka till displayen.

Postat: 7 februari 2008, 13:17:26
av Stewal
Ha knackat lite kod nu, men det känns mer som det förslaget jag hade från början.
Har plockat bort en del kod för att det skall bli enklare att läsa.

Kod: Markera allt

datain	
	btfss	PIR1, RCIF	;Väntar på att tecken skall tas emot
	goto	datain	;om ej klar,vänta...
	movf	RCREG, w	;Ta emot data från UART port, spara i w.
	movwf	RX_DATA	;Spara w, i RX_DATA	
	goto	send
send
	movf	RX_DATA, w
	sublw	h'1B'	; Om RX_DATA = 1B, så blir Z nu = 0
	btfsc	STATUS, Z	; D.v.s skippa nästa inst om Z = 0
	goto	datain	; Z=1, hoppa till datain.
	sublw	h'21'	; Om RX_DATA = 21, så blir Z nu = 0
	btfsc	STATUS, Z	; D.v.s skippa nästa inst om Z = 0
	goto	datain	; Z=1, hoppa till datain.
	sublw	h'32'	; Om RX_DATA = 32, så blir Z nu = 0
	btfsc	STATUS, Z	; D.v.s skippa nästa inst om Z = 0
	goto	s00	;Z=1, hoppa till s00.
	movwf	RX_BUFFER
	movf	RCREG, w	
	movwf	RX_BUFFER
	goto	datain
s00
	sublw	h'34'	; Om RX_DATA = 32, så blir Z nu = 0
	btfsc	STATUS, Z	; D.v.s skippa nästa inst om Z = 0
	goto	h00	;Z=1, hoppa till h00.
	movwf	RX_BUFFER
	movf	RCREG, w	
	movwf	RX_BUFFER
	goto	datain
h00
	sublw	h'36'	; Om RX_DATA = 32, så blir Z nu = 0
	btfsc	STATUS, Z	; D.v.s skippa nästa inst om Z = 0
	goto	data in	;Z=1, hoppa till datain.
	movwf	RX_BUFFER
	movf	RCREG, w	
	movwf	RX_BUFFER
	goto	write_data
;
write_data
o.s.v.

Postat: 7 februari 2008, 13:58:45
av sodjan
En stor skillnad är ju att du (fortfarande) ligger och väntar ("pollar") på datat.
De förslag som jag och Icecap hade var interrupt styrda.
Spelar kanske inte så där jättestor roll, även om en interrupt styrd modell
blir lite "renare" rent strukturellt.

Men, som sagt, båda metoderna går att få fungera... :-)

Postat: 7 februari 2008, 14:52:45
av Icecap
Stewal: nu kanske jag inte hänger med men din kod testar varje byte som kommer in. Efter vad jag han se från koden ska RX_DATA vara först 0x1B, sedan 0x21, därnäst 0x32 och sedan använder du värdet.... och allt i samma byte.

Duktigt.... eller alldeles fel tänkt...

Edit: Du måste självklart FÖRST samla in 5 bytes OCH synkronisera att den första byte är 0x1B och SEDAN, när alla 5 bytes i paketet är sparat i en buffer, SEDAN kan du kolla om det är rätt data och vilka data det är.

Kan det vara där det sket sig?

Postat: 7 februari 2008, 15:05:17
av sodjan
Håller med Icecap att det är enklare att "läsa" datat när man har en
komplett sekvens att bearbeta. Det blir också en tydligare kod med bättre
separation mellan inläsning av data och analys/bearbetning.

Håller dock inte med om att man *måste* göra så, men det går åt fler
flaggor m.m för att hålla reda på var man är i sekvensen om man ska göra
allt samtidigt...

Jag ser det som 3 separata funktioner, inläsning, tolkning och skrivning
till displayer. Om man blandar dessa för mycket så blir koden svårare
att förstå och underhålla. Genom att separera det lite bättre i koden så
blir det även enklare att t.ex byta ut displayerna till en LCD senare. Det är
ju bara "skriv" funktionen som behöver justeras/bytas ut, de andra två
kan vara kvar precis som de är.

Postat: 7 februari 2008, 15:05:37
av Stewal
Jag har provat koden som jag skrev men det är inte mycket som funkar.
Har ändrat koden men den loopar här oavsett vad man skickar för 1B eller 20

Kod: Markera allt

sublw	h'1B'		; Om RX_DATA = 1B, så blir Z nu = 0
btfsc	STATUS, Z	; D.v.s skippa nästa inst om Z = 0
goto	next		; Z=1, hoppa till datain.
goto          datain
next

Postat: 7 februari 2008, 15:11:31
av sodjan
Det är jättesvårt att säga något utifrån lösryckta små kodsnuttar.
Det är du som har problemet och vill att det ska lösas, så du får
göra det enkelt för oss som det inte spelar någon större roll för... :-)

Jag tror att du ska backa ett par steg, ta en funktion i taget. Börja
t.ex med inläsningen till en buffert utan att "titta" allt för mycket på
datat. Verifiera att det fungerar. Lägg sedan till analysen/tolkningen
av datat -> värden i några andra register. När det fungerar, lägg till
själva utskriften till displayerna...

Förresten, får du inga konstiga varningar/fel från den där koden ?

Postat: 7 februari 2008, 15:38:23
av Stewal
>Det är jättesvårt att säga något utifrån lösryckta små kodsnuttar.

Ja förstår det vill inte fylla varje sida med kod.

>Det är du som har problemet och vill att det ska lösas,
>så du får göra det enkelt för oss som det inte spelar någon större roll för...
Är jätte tacksam att ni orkar vara lärare åt mig som är nybörjare. TACK!

>Jag tror att du ska backa ett par steg, ta en funktion i taget.
Ja det är nog dags att backa bandet, börjar blandar ihop för mycket nu.

>Börja t.ex med inläsningen till en buffert utan att "titta" allt för mycket på
datat.
Var det den koden som skall ligga under interupts?
Har hittat ett ex. i databladet.

>Förresten, får du inga konstiga varningar/fel från den där koden ?
Nej! Det går hur bra som helst, som sagt all kod var ju inte med i det ex. som är ut lagt.

Postat: 7 februari 2008, 16:28:34
av sodjan
> Var det den koden som skall ligga under interupts?

Så var i alla min tanke. Och under tiden ligger main bara och väntar
i en loop (och väntar på en flagga från interrupt rutinen säger att en hel
sekvens finns färdig).

> Nej! Det går hur bra som helst,

OK, annars så får inte instruktioner och "labels" ligga i samma
position. Labels ska vara i pos 1 på raden, instruktioner måste ligga
minst en position in på reden...

Postat: 7 februari 2008, 16:51:41
av Stewal
>Under tiden ligger main bara och väntar i en loop (och väntar på en
>flagga från interrupt rutinen säger att en hel sekvens finns färdig).
Får googla lite och se om man kan hitta något om det. Har inte hunnit titta på något vad gäller interrupts.


>Labels ska vara i pos 1 på raden, instruktioner måste ligga minst en position in på reden...
Ok det blev så när jag kopierade in texten här.
Ja annars klagar programmet på det, har jag märkt.

Postat: 7 februari 2008, 17:30:48
av sodjan
Här har du ett väldigt enkelt exempel på ett program som använder interrupt.
I detta fall från Timer1, men det är samma princip. Det var inte helt klart
från ditt inlägg vad som var oklart...

Detta exempel gör allt "jobb" i ISR'en, main innehåller bara en tom loop.

Tillkommer eventuellt (sannolikt) lite kod för att spara några register
(exempel finns i databladeti interrupt kapitlet).

Fråga om något är oklart !


Kod: Markera allt

;**********************************************************************
;   Enkelt blink-a-led, 16F628A.                                       *
;                                                                     *
;**********************************************************************
;    Files required:  P16F628A.INC                                     *
;                     16F628A.LNK                                      *
;                                                                     *
;**********************************************************************

  list      p=16f628A
  #include <p16f628A.inc>
	
  __CONFIG   _DATA_CP_OFF & _CP_ON & _LVP_OFF & _BODEN_OFF & _BOREN_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _MCLRE_ON

RESET_VECTOR    CODE    0x000     ; processor reset vector
  goto    start             ; go to beginning of program


INT_VECTOR      CODE    0x004     ; interrupt vector location
  goto    isr_routine       ; goto main interrupt service routine.
        

;***************************************************************
MAIN    CODE

start

  banksel cmcon
  movlw   h'07'
  movwf   cmcon            ; Stäng av ADC.

  banksel trisa
  clrf    trisa
  clrf    trisb             ; Alla pinnar = utgångar.

  banksel t1con
  movlw   b'00110001'
  movwf   t1con             ; Se datablad...
        
  banksel pie1
  movlw   b'00000001'
  movwf   pie1              ; Enable avbrott från TMR1.

  banksel intcon	
  bsf     intcon, peie
  bsf     intcon, gie       ; Enable avbrott...

loop
  goto loop                 ; Vänta på avbrott...
 


;***************************************************************
ISR_ROUTINE  CODE

isr_routine

  banksel porta
  comf    porta            ; Blinka med hela PORTA!

  banksel pir1
  bcf     pir1, tmr1if     ; återställ avbrotts flagga.

  retfie

  end

Postat: 7 februari 2008, 20:18:25
av Stewal
Har gjort en asm fil, som kan laddas ner då blir det inte så mycket kod här.

Är det här rätt tänkt vad gäller ISR
http://rodel.se/resultat_display.asm