PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zwei Word Variablen in einer anderen verpacken Schieberegist



Fabi1234
08.12.2007, 16:25
Hallo, liebe Forengemeinde.

Hab gerade ein Problem bei der Programmierung meines Atmega16.

Ich benötige zum Ansteuern eines seriellen Schieberegisters, LM7001
eine 24Bit lange Zahlenfolge.

Ich würde nun gerne die Teilerinfo 14Bit (Dezimalzahlenwert, Word) und die Steuerinfo 10Bit (Bitfolge, auch Word) zusammen in einer Variable "verpacken" und dann auf dem Schieberegister ausgeben.

Welchen Befehl gibt es dafür in Bascom?

Makeint geht doch nur für Bytes, wenn ich das richtig sehe.

Danke schonmal für eure Antworten

stefan_Z
08.12.2007, 16:57
Also in der Bascom Hilfe steht zu MAKEINT:
...The equivalent code is: varn = (256 * MSB) + LSB...

Entsprechend könntest du ja deine
Ausgabevariable = (65536 * MSB) + LSB machen.

Die Ausgabevariable sollte dann eine LONG sein (4 Byte).

Versuchs mal, würde mich auch interessieren...

PicNick
08.12.2007, 17:51
Die Ecke daran sind die zwei Bit, die du erstmal überlappen mußt.
Welche Bits von der Steuerinfo sollen denn nach bit 14, 15 von der Teilerinfo ?
Und in welcher Reihenfolge sollen die Bits dann ausgegeben werden ?

Fabi1234
08.12.2007, 18:12
Hi,

@stefan_z

habs gerade getestet.

Es klappt nicht, sondern man erhält Fehlermeldungen, also wäre dankbar für weitere Tipps.

@Picnick

Also mit der Teilerzahl dass sind die 14Bits, fängt die Übertragung an, danach kommen dann die Steuerinfos, das ganze fängt laut DB mit dem LSB an, daran sollen dann die Steuerinfos gehängt werden. Die Steuerinfo die dann nach der Teilerzahl aus dem Port dann rauskommt soll die Folge 0000000101 haben.

Wass mach ich eigentlich wenn mein derzeitiger Teilerwert nicht die ganzen 14Bit lang ist, was muss ich dann in das Schieberegister schreiben, damit der ganze Rest dann an die richtige Stelle wandert?

Ich häng mal das Datenblatt vom LM an.

PicNick
08.12.2007, 18:38
Ah, ja, alles klar.
Also: die zwei fraglichen Bits sind sowieso immer 0, als kein Problem
Du hast also:


DIM DWort as WORD ' das sind die Bits D0 --- D13
' T0 u. T1 sind da automatisch als 0 dabei
DIM Sinfo as WORD ' B0, B1, B2, TB R0, R1, R2, S

' eine möglichkeit, wenn du die 3 Bytes einzeln ausgeben willst

DIM sendebytes(4) as byte at DWort OVERLAY
DIM index as Byte

FOR index = 1 TO 3
*sende Sendebytes(Index)
NEXT

' andere möglichkeit, ganz einfach z.B.

Printbin Sendebytes(1) ; 3

stefan_Z
08.12.2007, 18:41
Hmm das kann natürlich daran liegen, dass LONG einen Zahlenbereich von -2147483648 bis 2147483647 abdeckt - es kann also keine positive Zahl von 32 Bit Größe enthalten. Das eigentliche Bitmuster kann aber was du brauchst.
Versuchs dann mal mit SHIFT oder ROTATE.
Erste Variable in die LONG rein, dann verschieben und 2. Variable mit AND drüberlegen... sowas in der Art...

Fabi1234
08.12.2007, 21:02
Hi,

danke für eure Tipps.

Hier mal Codeausschnitte im Anhang, dürfte es nun so gehen?

Hat jemand vielleicht notfalls auch noch nen Testprogramm, wenn es nicht geht?

stefan_Z
09.12.2007, 01:41
Na, obs geht würde ich mal am Objekt testen.
Oder zumindest im Simulator die Ausgabe-Variable begutachten...

Fabi1234
09.12.2007, 10:33
Hi theoretisch müsste es aber klappen oder?

Habs jetzt schon öfters probiert und musste halt jedesmal den Atmega ausbauen, um ihn dann beschreiben zu können, das nervt halt etwas und dem Flash-Speicher tut ständig schreiben ja auch nicht so gut...

Edit:

Hat leider natürlich nicht geklappt :-s

Was mach ich noch falsch?

Noch nen bisschen Offtopic,

Wie lang sollten denn die Leitungen vom MC zum Ic maximal sein??

PicNick
09.12.2007, 13:40
Das könnte die Sende-routine sein (nicht elegant, sollte aber funzen)



dim xx as byte


'..........................Steuerinfos und Frequenz übertragen ......
Initialisieren: 'Control und Frequenzword übertragen
'Squelch = 1 'Squelch einschalten
Controlw = &B00000101
Gosub Senden
Return

Senden:
Dat = 0 'Dat
Dlen = 0 'CE
Clb = 0 'Cl
' start sending-------------------------------------
Dlen = 1
For Index = 1 To 3
Controls = Sendebytes(index)
For I = 0 To 7 'Bits 0-7 ausgeben
xx = Controls And 1 ' daten pin setzen
Dat = Xx.0
Clb = 1 ' Clock 1
Shift Controls , right , 1
Clb = 0 ' Clock 0
Next
Next I
' stop sending-------------------------------------
Dlen = 0
Return




Die Waitms Befehle wirst du nicht brauchen, denk ich, die ganze sache ist langsam genug

Fabi1234
09.12.2007, 17:26
Hi, danke erstmal für den Code,

Leider ist mir noch etwas nicht ganz klar,

Du schriebst:



For I = 0 To 7 'Bits 0-7 ausgeben
xx = Controls And 1 ' daten pin setzen Dat = Xx.0
Clb = 1 ' Clock 1
Shift Controls , right , 1
Clb = 0 ' Clock 0
Next
Next I



sind da auchschon die restlichen 17 bits enthalten, oder muss ich die noch extra dazu rausschieben?

Außerdem muss ich jetzt noch die Frequenz dazufügen oder?

Bis jetzt ist nur das Controlword drinnen oder?

Sorry bin wie du siehst noch relativ frisch...

Danke schonmal für deine Antwort

so siehts im Moment aus.
Aber mir ist noch nicht ganz klar wie das mit dem Overlay klappt.

So wie ich das sehe, hab ich das Controlword in dem Code unten noch garnicht mit der Frequenz in einer neuen Variable zusammengeführt oder?




dim Frequenz As Word 'Frequenzvariable für PLL
Dim Sendebytes(4) As Byte At Frequenz Overlay

Dim Controlw As Word 'Controlword für PLL
Dim Controls As Word 'Var für Controlword
Dim Controls1 As Long 'Variable Control+Frequenz

Dim Index As Byte

Dim Speicher As Eram Integer 'Senderspeicher

Dim I As Byte

Tunerstart:

Frequenz = 4060 'Teilerwert von 90,8 MHz
laden

Gosub Initialisieren ' In den LM7001 transfer

Cls

Locate 1 , 2

Lcd "Tuner" 'Lcd Tuner anzeigen

Muting = 1 'Audiomuting aus

Return


'..........................Steuerinfos und Frequenz übertragen ......

Initialisieren: 'Control und Frequenzword

Squelch = 1 'Squelch einschalten

Gosub Frequenzanzeige

Controlw = &B00000101

Gosub Senden

Return


Senden:

Dat = 0 'Dat
Dlen = 0 'CE
Clb = 0 'Cl

'Übertragung beginnt........................................... .

Dlen = 1 'CE ein

For Index = 1 To 3

Controls = Sendebytes(index) 'Bits 0-24 ausgeben

For I = 0 To 24

Controls1 = Controls And 1 'Datenpin setzen

Dat = Controls1.0

Clb = 1 'Clock 1

Shift Controls , Right , 1 ' Bits nach rechts

Clb = 0 'Clock 2

Next

Next I

'übertragung beenden........................................... ............

Dlen = 0 'Übertragung beenden

Return

PicNick
09.12.2007, 18:58
Overlay:


Dim Frequenz As Word addresse &H0060 länge 2 Byte
Dim Controlw As Word addresse &H0062 länge 2 Byte
Dim Controls As Byte addresse &H0064 länge 1 Byte
Dim Controls1 As Long addresse &H0065 länge 4 Byte

Dim Sendebytes(4) As Byte AT FREQUENZ OVERLAY -->
' d.h. das ist auch auf addresse &H0060 länge 4 x 1 Byte

Vor dem Senden muss man in Controlw die Bits
B0, B1, B2 , TB , R0, R1, R2, S
enthalten sein bzw. zusammengemischt werden

*grübel*

Eigentlich ist das ein unnötiges Gefummel. Vorschlag: Einfacher



DIM Frequenz as Word
DIM Control1 As Byte ' mit B0, B1, B2 , TB
DIM Control2 As Byte ' mit R0, R1, R2, S

' das schreibst du nach Herzenslust was rein

SENDEN:

DIM Sendewort AS Word

Clb = 0
Dlen = 1

Sendewort = Frequenz
for i = 1 to 16
XX = Sendewort AND &H01
Dat = XX.0
CLB = 1
shift Sendewort, right, 1
CLB = 0
NEXT

Sendewort = Control1
for i = 1 to 4
XX = Sendewort AND &H01
Dat = XX.0
CLB = 1
shift Sendewort, right, 1
CLB = 0
NEXT

Sendewort = Control2
for i = 1 to 4
XX = Sendewort AND &H01
Dat = XX.0
CLB = 1
shift Sendewort, right, 1
CLB = 0
NEXT

Dlen = 0



Das sieht zwar im ersten moment nach Spaghetti aus, auf es ist effektiv, wenn man das Gewurstel betrachtet, das man sonst machen muss, um die Daten zusammenzuschippern.

Könnte man noch mit subroutinen eleganter machen, aber was soll's

Fabi1234
09.12.2007, 20:47
Hi habs gerade noch getestet,

tut leider immernochnicht.

Vielleicht braucht er ja die Pausen?

Oder es ist nen Hardwareproblem, ich häng mal mein gesamtes Programm an, ist aber recht umfangreich

stefan_Z
10.12.2007, 12:32
ändert er denn die Ausgabevariable zumindest richtig?

Fabi1234
10.12.2007, 19:13
Wo finde ich denn die Ausgabevariable im Simulator?

stefan_Z
10.12.2007, 22:26
Eintragen ;-)
Den Simulator aufmachen und dann zeigt er dir ne leere Liste wo du vorne den Namen reinschreibst.
Wunderlicherweise macht er das für lokale Variablen (also in Subs) automatisch (2. Liste hinter der 1.), aber für die globalen nicht.
Da kannst du dann den Binär- / Hex- / Dezimalwert sehen

Fabi1234
11.12.2007, 16:46
Hi,

also im Simulator ändern sich die Variablen, aber sowohl Control 1 als auch 2 haben mehr ja beide 8 bit wegen Byte, das müsste doch eigentlich zu lang sein. oder ist das egal?

Irgendwo in der Hilfe hab ich gelesen, das man auch eigene Datentypen definieren kann, war mir aber noch nicht ganz klar, wie das jetzt genau geht. Vielleicht ginge es ja damit.

stefan_Z
11.12.2007, 17:44
also Bytes können keine 16 Bit oder so fassen, klar, aber ein Word schon. Da sollen die ja rein...