Bascom Auslesen eines Messschiebers Bascom Glcd

Hi Cassio,

na da war ja einer schneller;) In PNG hab ich sie bereits konvertiert. Hochgeladen waren sie auch schon. Ich hab nur nochmal kurz den Thread ansehen wollen. :p
Egal .. da sind sie nun in PNG ...
MAP011.png MAP022.png MAP033.png MAP044.png MAP055.png

Doppelt gemoppelt hält besser :cool:

EDIT: Ha ! Die PNG-Komprimierung ist man besser ;) Die Dateien sind kleiner :D

Gruß
Dino
 
GIF statt BMP

Hallo ,

OK , werd ich das nächste mal berücksichtigen !
BMP bringt mein Oszi gleich so raus und die Auflösung ist auch nicht so toll .
Aber für den "Anfänger" reicht es vorerst aus ....

einen schönen Abend


Sven
 
Hab den Zettel gefunden - will das jetz aber heute nicht mehr abtippen. Problem ist, daß eine ISR (also ein Kanal) auf mindestens 47 Takte kommt (mir fällt zum Optimieren nichts mehr ein) - und da ist die letzte fallende Flenke noch nicht berücksichtigt gewesen - das werden dann wohl noch mindestens 2 weitere Takte.) Und der Einsprung in die ISR kostet auch ein paar Takte - 7 (?) wenn ich mich recht erinner. Aber schon die 47 Takte brauchen bei 20MHz 2,35µs. Bei 3, quasi gleichzeitig sendenden MS würden also die ersten beiden IRQs nach (frühestens) 4,7µs abgearbeitet sein - der dritte dann also erst in Angriff genommen. Mir ist grad (doch) noch eingefallen, daß ich das eigentliche Auslesen des Data-Pins in der ISR weiter nach vorn optimieren könnte - trotzdem mindestens 8 Takte (0,4µs) nach dem ISR-Einsprung in die dritte ISR. Wie Du gezeigt hast, können sich die Data-Pins aber bereits ca 6,5 µs nach der fallenden clock-Flanke wieder ändern. Wenn ich jetzt die angenommenen 7 Takte pro ISR-Einsprung und die 2 für die letzte Flanke draufrechne, komme ich schon auf 6,45µs - das wäre verdammt knapp, und selbst wenn das stimmen würde, dürfte da nix mehr dazwischenfunken - keine anderen Interrupts, keine kurzzeitige globale Deaktivierung der Interrupts (zB um mit mehr-Byte-Zahlen zu rechnen) usw.

Ohne Bascom könnte man natürlich noch deutlich optimieren - zB einige der 32 Rechenregister für bestimmte Sachen reservieren (und damit Registerretungsoperationen (Push/Pop), und Transferoperationen zwischen Registern und SRAM (LD/ST) bzw laden von Konstanten (LDI)) einsparen. Meines Wissens nach kann man in Bascom aber keine Register für Bascom "sperren" - Vielleicht wäre es drin, einen Controller für die Datenerfassung in ASM zu proggen (3 Kanäle), und mit einem 2ten Controller für Display, Userinterface etc, dann eben in Bascom programmiert, zu verbinden - über irgendeine Schnittstelle, meinetwegen auch RS232/485 etc?
 
So ich bin den besagten Zettel mal durchgegangen, und hab das ein wenig umsortiert.
Vorüberlegungen:
-je Telegramm gibt es immer 49 fallende Flanken an der clock. Uns interessieren nur die letzten 24 vor der allerletzten. (also wenn man die von 49 bis 1 runternummeriert, interessieren uns die Flanken 25 bis 2. Flanke 1 ist insofern noch interessant, als daß man dort sicher weiß, daß jetzt ein komplettes gültiges Paket empfangen wurde.
-jeder Kanal benötigt 3 Bytes, um das 24bit-Wort abzulegen. Habe grad nochmal gesehen, das als erstes das LSB gesendet wird (deswegen "nach rechtsschieben/rollen"). Kann sein, daß bei meinem folgenden Code-Schnipsel dann die Benennung der Bytes falschrum ist(*).
diese 3 Bytes müssen in Bascom angelegt (und somit dort lesbar) sein, trotzdem brauch ich die exakte SRAM-Adresse in der ISR. Außerdem sollten sie 3 aufeinanderfolgende Speicherzellen belegen. Deswegen Definition mit AT und ggf Overlay.
-Jeder Kanal braucht außerdem einen Zähler für die Flanken, Definition und so wie beim vorherigen Punkt.
Ich gehe einfachheitshalber davon aus, daß alle 12 Registeradressen dasselbe Highbyte haben, und für jeden Kanal als erstes der Flankenzähler, und dann die 3 Werteregister(Bytes) im Speicher liegen.

In der ISR wird als erstes der Flankenzähler dekrementiert (ist ja ein count down), und wenn er dabei 0 wird, wieder mit 49 geladen (Z-Flag). deswegen interessieren mich danach nur die Flanken [24..1], alle Flanken > 24 werden verworfen, die 0 wurde ausgeschlossen. Zum synchronisierten Scharfschalten kann relativ einfach in Bascom die lange Pause nach der letzten fallenden Flanke abgewartet werden. Der Flankenzähler ist also mit 49 vorzuladen.
Der Aufruf der ISR selbst sollte mit nosafe erfolgen, da die verwendeten 3 Register und das SREG in der ISR gesichert/wiederhergestellt werden. Das ganze müßte in Bascom in der entsprechenden ISR dann als ASM-Block eingebunden werden, dabei wird das Reti im ASM-Block durch ein Return nach diesem (oder schluckt Bascom eine ISR ohne abschleißendem Return (wenn in der ISR bereits das ASM-RETI steht?).

Ok, hier mal die ISR für einen Kanal:
Code:
ch1_ISR:
						;Register sichern
	push r16				;R16->Stack
	in r16, sreg
	push r16				;SREG->Stack
	push xh					;XH->Stack
	push xl					;XL->Stack
	
	ldi xh, high(BitCountAddr1)
	ldi xl, low(BitCountAddr1)		;X->BitCounter von Kanal 1
	ld r16, x				;r16=BitCounter
	dec r16					;decrementiere
	brne ch1_reloaded			;wenn =0 ***********(skip-Befehl???)
	ldi r16, 49				;reload mit 49
  ch1_reloaded:
	st x+, r16				;BitCounter gespeichert, x->highByte
	cpi r16, 25				;wenn größer 24, dann
	brsh ch1_BitVerwerfen			;springe Bit verwerfen
	cpi r16, 17				;wenn größer 16
	brsh ch1_ByteLaden			;springe ByteLaden
	inc xl					;X->middleByte
	cpi r16, 9				;wenn größer 8, dann
	brsh ch1_ByteLaden			;springe ByteLaden
	inc xl					;X->lowByte
  ch1_ByteLaden:
	;X zeigt jetzt auf die SRAM-Adresse, wo der Datapin
	;einzuschieben ist
	clc 					;Carry=0
	sbic port1, pin1			;Datapin gelesen, wenn=1
	sec					;dann Carry=1
	;Zustand des DataPins im Carry gespeichert
	ld r16, x				;Speicherzelle eingelesen
	ror r16					;Carry (Data) eingeschoben
	st x, r16				;zurückgespeichert (RMW)
  ch1_BitVerwerfen:
  						;Register wiederherstellen
	pop xl					;XL<-Stack
	pop xh					;xh<-Stack
	pop r16
	out sreg, r16				;SREG<-Stack
	pop r16					;r16<-Stack
reti
Wie gesagt scheinen das Highbyte und das lowbyte des 24bit-Ergebnisses so vertauscht zu sein, das könnte aber noch korrigiert werden.
BitCountAddr1 ist die SRAM-Adresse des Bitzählers, siehe oben. Port1 ind Pin1 sind Adresse und Bitnummer des Beinchens, an dem die entsprechende Data-Leitung des MS hängt. Die Takte hab ich jetzt noch nicht zusammengerechnet. Sieht bis jetzt schon irgendwer grobe Fehler und/oder Optimierungsmöglichkeiten? Dino?
 
hallo LotadaC ,

oh ,ha , harte Drogen ....

Nee wirklich gut , ja, das Timing ist echt kritisch , aber das das Anspringen einer ISR 7 Takte braucht ?
wußte ich nicht das das so viel ist .
Das mit den runterzählen hatte ich an anfang auch so gedacht bin dann aber davon abgekommen .
Meine Überlegung war eher in die richtung gegangen
das die eingehenden daten in eine long variable geschrieben werden .
da ja insgesammt 48 bit einkommen werden die "ersten" aus der variablen rausgeschoben .
und bei jeden clock wird ein timer neu gestartet , wen dann clock länger als 20µs low bleibt also alle 48 bit durch sind
kann die variable dann zum rechnen übergeben werden .
so war mein lösungsansatz . den ich aber bis jetzt nie gestetet habe .
sollte deine rechnung stimmen wird das aber eine ganz enge kiste .

könnte man evtl versuchen die MS zeitversetzt zu starten ?
bzw versetzt in den fastread modus bringen
Die 2x24 bit MS senden ja immer und müßen nicht extra gestartet werden .

Dein ASM code kann ich leider nicht deuten , da kann ich nicht mithalten :(.

wenn du mal einen "gebrauchsfertigen" code hast ( Hex ) kann ich ihn ja mal testen.
Ich habe hier genügend "Testhardware" ( Bilder davon lade ich demnächst mal hoch )

MFG

Sven
 
Hi Sven,

könnte man evtl versuchen die MS zeitversetzt zu starten ?
bzw versetzt in den fastread modus bringen
Da der Systemtakt der Messschieber nicht unter den einzelnen Messschiebern synchronisiert ist werden die selbst beim sauberen zeitversetzten Start langsam auseinanderlaufen (du bekommst Schwebungseffekte). Irgendwann werden die dann doch genau gleichzeitig senden. Um das zu gewährleisten müßtest du die Systemoszillatoren von zwei der Messschieber deaktivieren und von einem den Takt auf die anderen beiden übertragen. Ob sich der Aufwand lohnt ? Nur dann würden die Messchieber mit der Sendung der Datagramme nicht auseinanderdriften.

Gruß
Dino
 
Genau.
Wenn Du alle MS quasi gleichzeitig auslesen willst, muß das Programm damit klarkommen können, daß die exakt gleichzeitig senden (von der Zeit in der ISR her worst case) und total nacheinander senden können (für Prozesse außerhalb der ISRs bleibt dann am wenigsten Zeit). Der 2te Punkt sollte aber selbst im Fastmode noch zu schaffen sein.

Wenn Dir die 7 (oder warens 6?) Takte für den reinen Einsprung Sorgen machen, vergiß das Register Retten und Wiederherstellen nicht. Bascom sichert meiner Meinung nach immer (*) alle 32 Rechenregister und das SREG, und stellt sie am Ende wieder her. Das Sichern (Push) und Wiederherstellen (Pop) eines Reigsters kostet je 2 Takte. Für 33 Register sind das also schon 33*2*2=132 Takte. Das SREG kann aber als I/O-Register nicht direkt auf den Stapel geschoben werden (bzw von dort geladen) - da ist ein Umweg über ein Rechenregister nötig. Immerhin geht das noch mit In bzw Out (jeweils ein weiterer Takt). Somit bist Du also bereits bei 134 Takten, die Bascom nur fürs Registersichern und -wiederherstellen erzeugt. Das sind bei 20MHz immerhin 6,7µs, ohne in der ISR irgendwelchen Code verarbeitet zu haben.

(*) Wenn Du in Bascom die ISR mit einem angehängtem nosave (?) ... ähm ... zuweist, wird kein(!) Register gesichert. Darum mußt Du Dich dann selbst kümmern.

Meine ISR da oben manipuliert außer dem SREG noch R16 und das X-Doppelregister (als Pointer in den SRAM). Und genau diese 4 Register werden am Anfang gesichert, und am Ende wiederhergestellt.
 
So, habe nochmal einige Möglichkeiten durchprobiert - dauert alles zu lange. Die einzige Lösung, die ich habe, ist diese hier:
Code:
clockint1_ISR:			;					6
	push r16		;r16->Stack				2
	in r16, sreg		;					1
	push r16		;SREG->Stack				2
	;Register gesichert
	lds r16, adresse1	;r16<-counter				2
	subi r16, 1		;counter dekrementiert			1
	brcc reloaded1		;bei Überlauf				1 (worst case = kein Sprung)
	ldi r16, 48 		;counter zurücksetzen			1
reloaded1:
	sts adresse1, r16	;counter gespeichert			2
	cpi r16, 24		;wenn counter >23			1 <-erste 25 Flanken überspringen
	brsh restoreregs1	;springe->restoreregs1			1 (worst case = kein Sprung)
	cpi r16, 16		;wenn counter >15			1
	brsh lowestbyte1	;springe lowestbyte1 (lsb first)	1 (worst case = counter<8)
	cpi r16, 8		;wenn counter >7			1
	brsh midbyte1		;springe midbyte1			1
	clc	      		;carry löschen				1
	sbic port1, pin1	;wenn data=1				1
	sec	           	;setze carry (carry=data)		1
	lds r16, hbyte1		;r16<-hbyte				2
	ror r16			;carry (data) einrotiert		1
	sts hbyte, r16		;hbyte zurückgeschrieben		2
	rjmp restoreregs1	;fertig -> Register wiederherstellen	2
lowestbyte1:
	clc			;carry löschen
	sbic port1, pin1	;wenn data=1
	sec			;carry setzen
	lds r16, llbyte1	;lowbyte laden
	ror r16			;carry einrotieren
	sts lbyte, r16		;lowbyte zurückschreiben
	rjmp restoreregs1	;fertig -> Register wiederherstellen
midbyte1:
	clc			;carry löschen
	sbic port1, pin1	;wenn data=1
	sec			;carry setzen
	lds r16, mbyte1     	;middlebyte laden
	ror r16			;carry einrotieren
	sts hbyte, r16		;middlebyte zurückschreiben
restoreregs1:		        ;fertig, register wiederherstellen
	pop r16			;					2
	out sreg, r16	        ;SREG<-stack				1
	pop r16		     	;r16<-stack				2
reti				;					4
;--------------------------------------------------------------------
;			43 Takte*3 = 129 Takte = 6,45µs
;Auslesen des Datapins in der 3ten ISR spätestens bei Takt 113 (=5,65µs)
Leider alles andere als elegant - hab jetzt keine Zeit mehr zum Erklären, später...
(irgendwie stimmen die TABs nicht mehr...)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)