Bascom Auslesen eines Messschiebers Bascom Glcd

Ich verlinke mal frecherweise auf das Roboternetz, da gabs mal jemanden, der sich mit sowas beschäftigt hatte...
Jetzt noch 'ne kurze Info zu mir: Ich bin hier derzeit voll im Umzugsstreß (soll noch diesen Monat über die Bühne gehen), dewegen hab ich erstens nicht viel Zeit, zweitens wandert mein Equipment so langsam in diverse Kisten... insofern bitte nicht böse sein, wenn von mir wenig Reaktionen kommen...
Wie anfangs schon gesagt: ich finde das ganze Projekt durchaus interessant. Werds auch weiter verfolgen.

Jetzt zu Deinen Fragen: Ein Display (insbesondere ein GLCD) in Assembler miteinzubeziehen ist nicht ohne - besonders nicht für'n "Anfänger" - das würd ich mir selbst jetzt nicht so ohne weiteres antuen wollen. Deswegen ja damals auch der Vorschlag "Controller für LCD und so mit Bascom" und über ein noch zu definierendes Kommunikationsnetz je einen Tiny für jeden MS, den dann in Assembler. Dann hast Du nie das Problem zu behandeln, daß alle MS (zufällig) zur selben Zeit mit dem senden loslegen. So'n Interrupt unterbricht (deswegen der Name) ja das laufende Programm. Die Unterbrechung dauert (normalerweise) bis die ISR verlassen wird. bei Bascom kommt beim Ein- und Austritt noch ein ordentlicher Overhead dazu (ok, da kann man dann selbst Hand anlegen (Stichwort "nosafe")). Wenn da jetzt mehrere (annähernd) gleichzeitig zuschlagen...
 
Hi,

uhhh Umzüge sind das schlimmste, da verstehe ich dich vollkommen, und ich hab es auch nicht eilig, ich muss sowiso noch ein paar Hardwareänderungen vornehmen an der Fräse (Kugelrollspindel muss noch verbaut werden Gasdruckfedern hab ich jetzt drin , dann müssen die MS mechanisch angepasst werden) und da die grosse Fräse in Metall nicht die schnellste ist hat es alle zeit der Welt - ist ja ein Hobby und kein Auftrag :D

Ja das denke ich auch , ich glaube ich als anfänger darf mich Glücklich schätzen das ich überhaupt etwas sehe auf dem Glcd. Und die AVR´s Kosten ja auch nicht die Welt, muss halt nur noch ein bissel testen wie das mit dem Carry rotieren funktioniert und wie ich ein Interupt auslöse und ihn in der Isr gleich wieder Scharf mache, also das was du oben beschrieben hattest, und wenn ich das auf die Reihe bekomme kann ich mir daraus auch sicher eine Routine ableiten die erkennt ob ein Messschieber angeschlossen ist.

Danke und viel "Spass" beim Umzug ;)



Edit:
Ich habe mir gerade den Link angeschaut also das ist ja genau das was ich gesucht habe und sollte hier vllt in die FAQ, Danke - super

gruss Matthias
 
Nein nein, Interrupts gleich in der ISR scharfmachen ist nur was für Exoten - da kann einiges schiefgehen, wenn man nicht aufpaßt (normalerweise kann ja immer nur ein Int gleichzeitig ausgelöst werden, da beim Eintritt automatisch das I-Flag in SREG gelöscht wird (also Interrupts global disabled), somit kann also von den Interrupts her immer nur einmal die Adresse auf dem Stack landen. Die ISR wird, statt mit RET (Return from Subroutine) mit RETI (Return from Interrupt) beendet. Beide Befehle lassen das Programm in der "Programmzeile" (Program counter) weiterlaufen, deren Adresse dabei vom Stack gepoppt wird. Der Unterschied ist der, daß RETI nebenbei die Interrupts global freigibt. (Wenn man zB eine irgendeine sensible Subroutine (keine ISR) hat, und dafür die Ints temporär immer deaktiviert, kann man da auch die Ints beim Return automatisch scharfschalten lassen, indem man statt RET RETI verwendet - solche Tricks sind halt mit Assembler machbar).
Zurück zum Thema: Man kann also direkt nach dem Eintritt in die ISR das I-Flag wieder setzen (SEI (Set global interrupt Flag) zB) - dann kann sich der Interrupt aber immer wieder selbst unterbrechen - verschachtelt sozusagen. Dabei wird aber jedesmal die Adresse gepusht. Vorerst kein Problem, wenn sauber programmiert, ABER es besteht das Risiko, daß der Stack jetzt unkontrolliert in irgendwelche Daten, und erst recht in die I/O-Register hineinwächst. Oder bis hin zum Stacküberlauf.


Ich habe ja oben grosszügig geschätzt, effizient in ASM programmiert braucht man nur ein paar Takte, um nach einem flankengetriggerten IRQ an der Clock-Leitung des MS die Datenleitung zu lesen. Und dann nochmal ein paar Takte für die Schieberei. Da darf die Clock dann aber auch wieder hochgehen, und sich der Datenpin bereits ändern - wir haben ihn ja bereits ausgelesen. wir müssen halt nur rechtzeitig wieder aus der ISR raus sein, für die nächste abzufangende clock-Flanke.
Für die Kommunikation mit dem Master ist in den Pausen zwischen den Doppelpaketen mehr als genug Zeit. Dank vorhandener Hardware-USI (für SPI oder TWI verwendbar) hält sich der Aufwand da auch in Grenzen.
 
Hi,

also mit sauber Prog ist dann also gemeint das wenn ich in einer sub bzw. Isr bin und sie "anders" verlassen möchte als vorgesehen, müsste ich vorher in dem Unterprogramm den stapel aufräumen, sprich die rücksprung adresse überschreiben push - ldi - pop

gruss Matthias
 
müsste ich vorher in dem Unterprogramm den stapel aufräumen, sprich die rücksprung adresse überschreiben push - ldi - pop
Nein. Nicht überschreiben sondern vom Stapel runternehmen. Wenn du sie nur überschreibst dann steht der Stackpointer auf nem Eintrag mit ner "Mülladresse" und beim nächsten Return wird dann zu dieser Mülladresse gesprungen.

Gruß
Dino
 
Hi Matthias,

Überschreiben wollte ich wenn ich dann jene neue Adresse brauche. Aber danke , ich sehe Assambler ist wirklich sehr Flexibel
mit Manipulation des Stacks und dem Befehl RETurn könnte man sogar dynamische Sprungtabellen anlegen. Das wär dann so als wenn du in Bascom nen Goto zu ner Adresse machst die durch eine Variable geliefert wird. Also ähnlich ...
Basisadresse = &H3453
Sprungadresse = Basisadresse + (Subnummer * 150)
GOTO Sprungadresse
Man könnte also sogar mit Sprungadressen rechnen. Aber wenn du so ein Programm nicht sauber dokumentierst dann bekommst du nach ner Woche graue Haare beim Verständnis des Quelltextes.

Gruß
Dino
 
Nein. Nicht überschreiben sondern vom Stapel runternehmen. Wenn du sie nur überschreibst dann steht der Stackpointer auf nem Eintrag mit ner "Mülladresse" und beim nächsten Return wird dann zu dieser Mülladresse gesprungen...
Genau genommen könnte (!) man dazu einfach den Stackpointer um eins erhöhen - allerdings sind dazu mehr Instruktionen (Flash und Takte) nötig, als ein einfaches "pop rechenregister". Und da man zum Inkrementieren auch ein Rechenregister braucht, sehe ich keinen Sinn bei so einer Vorgehensweise.

Fang erstmal mit den normalen Sachen an.
Frage an Dino: Schluckt der Assembler denn 'ne Instruktion wie:
Code:
LDI XL, low(labelname)
LDI XH, high(labelname)
? Eigentlich sollte er - labelname wird ja in die Flashadresse der entsprechenden (folgenden) Instruktion übersetzt, also eine Zahl (Word). Und low/high() macht daraus dann das entsprechende low/high-Byte, welches zackzack in die Rechenregister geladen werden kann.

Jetzt noch was zu der Sache mit dem fehlenden MS:
Man könnte zB einfach überprüfen, ob alle 300ms (oder wie immer auch das Zeitfenster war) 'ne gültige Messung erfolgte. Wie? Indem man einen Timer nach 300ms oder mehr überlaufen läßt, und in dessen Überlauf-ISR die entsprechende Fehlermeldung für den Master generiert. Da Du in der clock-flanken-ISR eh auf ein komplett empfangenes Paket überprüfst, kannst Du da auch gleich den Timer zurücksetzen. Geschieht dieses nicht (weil keine Clock-Flanken oder so), läuft der Timer irgendwann über, und setzt die Fehlermeldung ab - Timeout eben.
Wenn der Tiny einen interruptfähgen Watchdog hat (also einen, der nicht nur Reset kann), vereinfacht sich das Zurücksetzen auf die eine Instruktion (WDR). Vorrausgesetzt, man will den Hund nicht anders einsetzen.
Da hier inzwischen ziemlich viel OT zusammengekommen ist (ja, im wesentlichen auch meine Schuld), würde ich Dir jetzt vorschlagen, hier nochmal die ganzen Eckdaten zu diskutieren/zu entscheiden (liegt ja letzten Endes bei Dir), und wenn dann alles zusammen ist einen neuen Thread dazu zu starten (und ggf hierher verweisen).
 
Hi,

Frage an Dino: Schluckt der Assembler denn 'ne Instruktion wie:
Code:
LDI XL, low(labelname)
LDI XH, high(labelname)
? Eigentlich sollte er - labelname wird ja in die Flashadresse der entsprechenden (folgenden) Instruktion übersetzt, also eine Zahl (Word). Und low/high() macht daraus dann das entsprechende low/high-Byte, welches zackzack in die Rechenregister geladen werden kann.
tja ... das müßte der Assembler ausrechnen. Ich glaube der wird motzen. Ist aber nur so eine Vermutung. Ich habs auf die Art noch nicht getestet.

Gruß
Dino
 
Hi,

also mit sauber Prog ist dann also gemeint das wenn ich in einer sub bzw. Isr bin und sie "anders" verlassen möchte als vorgesehen...
das mit dem Stackpointer korrigieren hat Dino ja schon gesagt. Ich meinte eigentlich "trotz sauberer Programmierung kann es zu diesen Überläufen bzw Berechsüberschneidungen kommen"
Was meine ich dann mit "unsauber"?
Nun, man kann den Stack ja auch zur Parameter-/Ergebnisübergabe für irgendwelche Subroutinen verwenden.
-Parameter auf den Stack pushen
-call subroutine
(-dabei wird die Rücksprungadresse auf den Stack gepusht)
-in der Subroutine die Adresse vom Stack poppen
-Parameter in umgekehrtet Reihenfolge vom Stack poppen
-hier die Aufgabe der Routine abarbeiten, ggf Ergebnis/se pushen
-Rücksprungadresse pushen
-Return
(-dabei wird die Adresse gepoppt)
-eventuelle Ergebnisse poppen
Wenn jetzt aus irgendeinem Grund die Push's und Pop's aus der Waage kommen, ist irgendwann Zwangsläufig 'ne Bereichsüberschneidung und 'n Speicherüberlauf da. Wenn die Reihenfolge (LiFo) nicht eingehalten wird, kommt auch Mist raus. Besonders anfällig wirds, wenn man da jetzt mit bedingten Verzweigungen in der sub arbeitet. Ok, wenn man gleich zu Beginn der sub alle Parameter sauber vom Stack nimmt... - aber dann kann man dafür ja auch gleich Rechenregister oder SRAM zur Übergabe verwenden.
 
Hi,

sicher werd ich erstmal mit einfachen sachen anfangen, hab so etwas nur mal in ne Forum gelesen und ist ja auch nicht schlecht das schon mal im Hinterkopf zu haben.

So ganz Grob ohne viel auf details einzugehen würde das dann in etwa so aussehen:

ISRxx:
push r16 ;benutzte Reg. retten (r16 = Zwischenspeicher)
in r16,SREG ;Statusregister einlesen
push r16 ;Statusregister retten

instruktionen

pop r16 ;Werte der geretteten Register wieder-
out SREG,r16 ;herstellen
pop r16

- und an dieser stelle könnte! man sicher die rücksprungadresse manipulieren, da diese ja als nächste vom Stapel genommen wird oder?

reti

aber soweit bin ich noch nicht ;), heut war erstmal wieder Handwerkliches dran


gruss Matthias
 
... und an dieser stelle könnte! man sicher die rücksprungadresse manipulieren, da diese ja als nächste vom Stapel genommen wird oder?...
Im Prinzip schon. Würde dann auch in :
-2x pop (Adresse ist ein word)
-Manipulation
-2x push
zerfallen. Man könnte zwar die Adresse im Stack auch direkt überschreiben (zu Fuß quasi, der liegt ja im SRAM), aber kürzer ist das auch nicht (SPL/SPH laden, ggf 2x alte Adresse laden (indirekt, also LD), Manipulation, neue Adresse schreiben (auch 2 bytes) - und du brauchst dafür ein Pointer-Doppelregister).

Zum Register retten: Wenn man den ganzen Krempel weitgehend in den Registern abwickelt, und das ganze möglichst in die entsprechenden ISRs packt, minimiert sich auch der Rettungsaufwand. Ich selbst habe mal einen Poti-gesteuerten (ADC) Phasenanschnittsdimmer (Int0, Timer0 mit OC) mit serieller Kommunikation (UART) komplett in ISRs umgesetzt - nach dem ganzen Initialisierungskrempel war dann der einzige Befehl in der main-loop ein sleep. Vom SRAM wurden (abgesehen vom I/O) nur die letzten beiden Register von der Rücksprungadresse der grad aktiven ISR verwendet - sonst gar nichts gepusht/-popt.

Bei Dir wäre als erstes zu klären, welches Protokoll der MS denn nun genau hat. Und in welcher Form der Messwert an den Master bereitgestellt werden soll. Daraus ergeben sich dann Anforderungen an den Slave-AVR.
 
Hallo Matthias,

wie siehts denn bei dir so aus. Schon ein wenig weitergekommen mit deinem DRO (Digital Read Out) für die Messschieber ?

Gruß
Dino
 
Hallo,

Danke euch beiden.

@Lotadac
Und das sind so kleinigkeiten die ich erstmal ausführlich verinnerlichen muss - wie , das eine Adresse als wort angelegt ist.

Was für ein Protokoll das ist weiss ich nicht, es ist auf jedenfall anders als die Standartprotokolle.
Beim Standart werden ja 2*24 Bit übermittelt von dem die ersten 24 Bit verworfen werden, die zahl stellt sich als Positive Zahl dar, und die "0mm" hat einen bestimmten Zahlenwert alles was unter diesem wert gesendet wird sind dann Negative Werte
darüber Positiv.
Exoten senden wohl BCD-Code mehrere Pakete.

Bei mir mache ich es so das ich 24Bit auslese, ich nehme gleich die ersten 24Bit(ich weiss nichtmal ob es da ein Zweites gibt) ich habe festgestellt das die mir genau die werte liefern die der MS anzeigt, und mehr will ich ja nicht.
Mein Glück ist halt das ich meine Werte fast auf direktem weg bekomme, lediglich das erste (LSB)Bit muss ich entfernen, das gibt an ob es inch oder mm sind. Und ich muss das 22 bit auswerten, da ist die Information über das vorzeichen. Bit 2 - Bit 21 geben mir die Binzahl meines wertes in mm(wenn mm am MS eingestellt ist sonst halt den inch wert).
Das macht die Rechnerrei weniger kompliziert als bei anderen MS.
An den AVR hatte ich dann vor die fertigen Strings zu senden.


Zu den 2*24 Bit könnte ich mir vorstellen das der erste Wert nicht genullt werden kann also wie er auch beschrieben wird in anderen Foren als absolutwert.

@Dino

Erlich gesagt bin ich noch nicht weiter, ich habe wie gesagt getestet das ich mit einem AVR/MS eine ausreichende Rate hätte und die Werte komplett berechnet genauso schnell Darzustellen wie der MS auf seinem eigenen Display.
Aber irgendwie lässt mich jetzt Assabler nicht mehr los und ich habe jetzt mit ganz einfachen dingen angefangen zu lernen Led, Schalter und so.

Was benutzt ihr um mit Asm zu arbeiten, ich habe AVR-Studio4 komme aber noch nicht damit zurecht, habs auch noch nicht wirklich verfolgt weil mein USBASP nicht mit Studio funktioniert.
Hab bis jetzt ein wenig mit ASM in Bascom rumgespielt aber das ist nicht das wahre oder?

gruss Matthias
 
...tja ... das müßte der Assembler ausrechnen. Ich glaube der wird motzen. Ist aber nur so eine Vermutung. Ich habs auf die Art noch nicht getestet...
Ok, mal fix etwas Code zusammengestrickt:
Code:
.include "m8Adef.inc"
;*************Register umbenennen********************
.def hell=r17
.def dunkel=r18
;*************Konstanten / Variablen*****************
.equ ledport=portc
.equ ledddr=ddrc
;*****************Interruptvektoren******************
rjmp init						;Reset
rjmp int0_isr					;Int0
rjmp int1_isr					;Int1
;*****************Init*******************************
init:
	ldi r16, high(ramend)
	out sph, r16
	ldi r16, low(ramend)
	out spl, r16				;Stackpointer eingerichtet

	ser dunkel					;=0b11111111 alles aus
    clr hell					;=0b00000000 alles an

	out ledddr, dunkel			;LEDs sind Ausgang
	out ledport, dunkel			;alle aus, PortC fertig

    ldi r16, 0x00
    out ddrd, r16				;Taster sind Eingang
	ldi r16, (1<<portd2)|(1<<portd3)
	out portd, r16				;pullups aktiviert

	ldi r16, (1<<isc01)|(1<<isc11)
	out mcucr, r16				;fallende Flanken an Int0/1, sleep aus

	ldi r16, (1<<int0)|(1<<int1)
	out gicr, r16				;int0/1 enabled, IntVectors bleiben default

;******************main******************************
loop:
	sei							;interrupts scharf
	rjmp loop
;******************main******************************

int0_isr:
	pop r16
	pop r16						;Rücksprungadresse verworfen
	ldi r16, low(leds_an)
	push r16
	ldi r16, high(leds_an)
	push r16					;neue Adresse aus label -> Stack
	ret							;und hopp

int1_isr:
	pop r16
	pop r16						;Rücksprungadresse verworfen
	ldi r16, low(leds_aus)
	push r16
	ldi r16, high(leds_aus)
	push r16					;neue Adresse aus label -> Stack
	ret							;und hopp

leds_an:
	out ledport, hell			;leds an
	rjmp loop					;zurück ins HP

leds_aus:
	out ledport, dunkel			;leds aus
	rjmp loop					;zurück ins HP
Ergebnis:
Code:
		"ATmega8A" memory use summary [bytes]:
		Segment   Begin    End      Code   Data   Used    Size   Use%
		---------------------------------------------------------------
		[.cseg] 0x000000 0x00004e     78      0     78    8192   1.0%
		[.dseg] 0x000060 0x000060      0      0      0    1024   0.0%
		[.eseg] 0x000000 0x000000      0      0      0     512   0.0%
		Assembly complete, 0 errors. 0 warnings
klingt doch schon mal ganz gut...
Ans STK gesteckt...
dyntst1.jpg
nach drücken von SW0:
dyntst2.jpg
SW1 bringt einen wieder zum ersten Bild...
 
@Lotadac

Also deinen Aufbau und Code hab ich verstanden, bis auf zwei Sachen wieso leuchten da nur 6(bit) anstatt 8, oder ist das jetzt Hardware bedingt vom STK.
Heisst das, das ich egal in welcher form eine Adresse vorliegt sie immer auf ein High und Low Register schreiben kann( also nicht vorher zerlegen muss für den High- und Low- Teil der adresse)
Das Board gefällt mir immer mehr ich glaub das hol ich mir auch obwohl ich momentan mein eigenes in Planung hab was von der aufmachung einem "EasyPic v7" gleichkommt.

Es ist ja erschreckend einfach einen Interupt scharf zu machen, damit werd ich gleich mal experimentieren.

gruss Matthias
 
Hi,

ich hab heute mal den Meßschieber ans SpeicherScope gelegt den ich von den drei Lidl-Teilen mit Leitungen versehen habe. Der spricht auch 2x24Bit. Aber die Daten zappeln ganz schön rum. Selbst wenn er still steht. Bei YADRO steht aber auch folgendes ...
Die letzten Bits zittern recht instabil. Durch Filterung und Mittelwertbildung lässt sich aber die Genauigkeit erhöhen. Soweit ich es erkennen konnte, ist der "Jitter" +/-5 Stellen.
Na mal sehen wann ich Lust dazu hab ;)

Gruß
Dino
 
Hi,

Ich habe jetzt mal folgendes versucht:

erstmal noch ein AVR mit zwei Realen MS(vorher hatte ich immer vom selben MS gelesen und im AVR verzweigt)

Und schon sieht man das das so nicht funktioniert.
Ich hatte vorher Quasi nur eine Clock und Data leitung gelesen und die Ausgabe war immer gleich für "X,Y und Z" aber auch Richtig.
Jetzt hab ich zwei Clock und Data und frage mit Shiftin nacheinander ab. Die Werte werden zwar richtig berechnet und angezeigt aber alle 3 - 5 sec steht kurzeitig "Misst" auf meinem Display.

Aber nur wenn beide Messschieber abgefragt werden und etwas anderes Anzeigen als 0mm.
Ist ein MS abgeklemmt oder steht auf 0mm tritt der Fehler nicht auf. Kam zu dem schluss das noch alte Werte bei dem berechnen standen, darauf hin hab ich nach jeder Rechnung die Variablen auf 0 gesetzt aber der Fehler bleibt.

Komischerweise wird mir auch in der Variablen "Ergebn" die eigentlich nichts macht(später für Drehzahlanzeige) ausser das ich sie mit anzeigen lasse, etwas angezeigt und ändert sich immer wenn der Fehler alle 3-5sec auftritt.

Das sieht für mich aus wie ein überlaufen der Longvariable mit der ich die MS auslese (komisch nur das sich das auf "Ergebn" auswirkt)

Kann ich warscheinlich davon ausgehen das ich jetzt störungen auf der Clock und Dataleitung habe, denn den zweiten MS habe ich mit ca. 80cm langer leitung drann und den ersten mit ca 20cm.
Oder das ich jetzt die Clocks abfragen muss das nicht mittendrinn angefangen wird auszulesen.(ist auch noch ne vermutung)



Wenn ihr noch lust habt und ideen - ich würde mich freuen.



Es hat sich nicht viel geändert aber zum Probieren verwende ich den Code:
Code:
$regfile = "m16def.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32
'$baud = 38400
'$sim

Const Xa = " X = "
Const Ya = " Y = "
Const Za = " Z = "
Const E = " mm    "
Const F = "nicht Belegt"
Dim A As String * 5
Dim Zeile As Byte
Dim S As Byte
Dim Z As Byte
Dim X As Byte
Dim Y As Byte
Dim M As Long
Dim V As Long
Dim Mes As Single
Dim Ergeb As String * 6
Dim Ergebn As Integer
Ergebn = 0                                                  ' wert für drehzahl _  wird noch nicht erfasst
Ddrc = 0
Portc = &HFF
Ddra = 0
Porta = &HFF

Config Graphlcd = 240 * 128 , Dataport = Portb , Controlport = Portd , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 6


'**********************Grafik*****************************************
Cls
Cursor Off
Wait 1
Locate 1 , 1 : Lcd "         Maschinenkoordinaten           "

For X = 150 To 220
   Pset X , 90 , 255
   Waitms 1
Next
Line(215 , 87) -(220 , 90) , 255
Line(215 , 93) -(220 , 90) , 255
Locate 13 , 36 : Lcd "X"

For Y = 90 To 20 Step -1
   Pset 150 , Y , 255
   Waitms 1
Next
Line(147 , 25) -(150 , 20) , 255
Line(153 , 25) -(150 , 20) , 255
Locate 4 , 27 : Lcd "Z"

  X = 150
  Y = 90
For Z = 1 To 35
   Incr X
   Decr Y
    Pset X , Y , 255
   Waitms 1
Next
Line(178 , 59) -(185 , 55) , 255
Line(182 , 61) -(185 , 55) , 255
Locate 8 , 32 : Lcd "Y"

'********************************************************************************




Do



 If Pina.0 = 0 Then                                         'Abfrage ob Messschieber vorhanden
  Shiftin Pinc.0 , Pinc.1 , M , 6 , 24                      'Auslesen 24 bit    
    Zeile = 4                                               'zeile für Ausgabe
    A = Xa                                                  'constante xa für Ausgabe

  Gosub Ausgabe
 Else
  Locate 4 , 1 : Lcd Xa ; F
 End If


 If Pina.1 = 0 Then
  Shiftin Pinc.2 , Pinc.3 , M , 6 , 24
    Zeile = 6
    A = Ya

  Gosub Ausgabe
 Else
  Locate 6 , 1 : Lcd Ya ; F
 End If


 If Pina.2 = 0 Then
  Shiftin Pinc.2 , Pinc.3 , M , 6 , 24
    Zeile = 8
    A = Za

  Gosub Ausgabe
 Else
  Locate 8 , 1 : Lcd Za ; F
 End If

  Locate 10 , 1 : Lcd " n =       " ; Ergebn ; " U/min  "


 Loop
End


Ausgabe:

   Shift M , Right , 1
                                        ' nun den Inhalt 1 Stelle nach rechts schieben da das erste Bit nur die Info, 0 = mm bzw 1= inch= enthält

  If M < 1048576 Then                                       ' 1048576 ist der dec-wert von bit "21"
  Mes = M / 100                                                 ' ist bit21 nicht gesetzt dann positiv Berechnen
Else                                                      
   M = M - 1048576                                            'ist bit21 gesetzt dann den zahlenwert des bits abziehen und negativ Berechnen
   Mes = M / -100
   M = 0
  End If
   Ergeb = Fusing(mes , "# . ##")


 If Mes < -100 Then
  Locate Zeile , 1 : Lcd A ; Ergeb ; E                      ' Ausgabe
 Elseif Mes < -10 Then                                      ' auswertung der Potenz mit und ohne vorzeichen
  Locate Zeile , 1 : Lcd A ; " " ; Ergeb ; E                'damit die anzeige vom einer bis zur masseinheit fix ist
 Elseif Mes < 0 Then
  Locate Zeile , 1 : Lcd A ; "  " ; Ergeb ; E
 Elseif Mes > 100 Then
  Locate Zeile , 1 : Lcd A ; " " ; Ergeb ; E
 Elseif Mes > 10 Then
  Locate Zeile , 1 : Lcd A ; "  " ; Ergeb ; E
 Else
  Locate Zeile , 1 : Lcd A ; "   " ; Ergeb ; E
 End If
Return

Edit: die abfrage ob MS vorhanden ist simuliere ich nur mit einem Low auf Pina.0 - Pina.2 manuell!

gruss Matthias
 
"nur 6 LEDs":
Das liegt eher am verwendeten Port und Prozessor.
Beim Mega8 (der steckte grad noch im Brett) ist PortC nur 7 bits breit. Und bit6 ist nicht als I/O, sondern als Reset verwendet (siehe RSTDSBL-Fuse - ohne wäre ISP over SPI nicht möglich).
Warum habe ich trotzdem PortC genommen?
Weil ich bei PortD die externen Interrupt-Pins nutze, und an PortB einerseits der SPI hängt (sollte zwar eigentlich keine Probleme machen, aber sicher ist sicher), andererseits hätte man da nicht so einfach den Hosenträger vom Port-Header zum LED-Header ziehen können. B6 und B7 sind nämlich nicht auf den PortD-Header gelegt, sondern auf den Aux-Header (?). Weil sie Verbindung zum Qarz/Takt bekommen können müssen (XTAL1/2).

"STK500":
Das Teil hat meiner Meinung nach einige Nachteile:
-Mit den verwendeten DIL-Sockeln ist das Wechseln des Prozessors schon ein Gewaltakt - je mehr Pins, desto schlimmer -> Nullkraftsockel wären wohl zu teuer gewesen?!
-serielle Schnittstellen (RS232 - 1xCntrl, 1x zur freien Verwendung). Inzwischen wäre 'ne USB-anbindung wohl besser. Ok, man kann statt des internen Programmers auch einen anderen anstecken (wie bei mir den AVRISP MKII). Und die Verwendung eines virtuellen Schnittstellenconverters geht eigentlich auch.
-keine Unterstützung von TPI ... wie immer das bei den XMEGAs jetzt auch hieß - da ist wohl auch in Zukunft nix vorgesehen.
-das mit dem beiden MSB von PortB beim "grünen" Sockel hab ich ja oben schon angedeutet - da hattte ich auch mal ewig nach'nem Fehler gesucht...
-Preis
-inzwischen gibts wohl den Nachfolger.

Für einfache Taster-LED-Schaltungen kann man das verwenden, für mehr brauchst Du eh mindestens 'n Breadboard (unter der HF vs. Leiterlängen/Signalführungs-Problematik leiden ja beide Ansätze).

Deine Frage mit den Adressen hab ich nicht ganz verstanden. Der Assembler rechnet immer mit den ganzen Zahlen. Die Adressen sind (als word) ganze Zahlen. LDI zB schluckt nur bytes, deswegen ja auch low bzw high(Name). Dabei mußt Du beachten, daß Name eine Konstante ist. Eine Fixe Adresse. Beim erstellen des hex-codes mach der Assembler da also ein byte draus. Eben das low- bzw high-byte des Adresswortes. Auf den Stack werden die dann als Byte gepusht, klar. Man könnte die natürlich zwischendurch in den Rechenregistern noch manipulieren, oderstatt mit LDI 'ne Konstante (byte) auch mit LD was aus dem SRAM laden.
RJMP hingegen kann als Parameter eine 12bit-Zahl bekommen. RJMP springt relativ zur derzeitigen Position, also 2K words in jede Richtung (der Flash ist ja in words organisiert). Schau Dir die instruktionen mal im Instruction Set an. Der 16bit-Opcode (deswegen ja word) von RJMP ist 1100_kkkk_kkkk_kkkk. Hinter den k's verbirgt sich die relative Adresse. Wenn Du also irgendwo im Code "RJMP blablub" stehen hast, und das assemblierst, versucht der Assembler aus blablub 'ne 12bit-Zahl zu machen. gelingt ihm das nicht, gibts'ne Fehlermeldung, gelingt es (egal, ob die Zahl in Deinem Programm jetzt auch wirklich sinn macht), wird daraus, und mit 1100 das Befehlswort gebildet, und an der entsprechenden Stelle im Hexfile geschrieben (welches dann in den Flash gebrannt werden kann).
Alles andere (also außer dem Stackpointer und den Sprunglabeln) in meinem Programm sind bytes.
 

Ü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)