Forum: Mikrocontroller und Digitale Elektronik 11 Byte Register beschreiben! Wie?


von H. G. (ledi)


Lesenswert?

Hallo!

Ich habe ein Problem beim Setzen eines 11-Byte großen Registers.

Für die Initialisierung eines Funkchips muss ich das Register mit der 
Adresse 14 mit folgenden Werten beschreiben:
1
const uint8 Bank1_Reg14[]=
2
{
3
  0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF
4
};

Wie kann ich nun dieses Register beschreiben bzw. wie muss ich meine 
Funktion dafür schreiben?
Kann mir da jemand ein Beispiel geben?
Vielen Dank für Eure Hilfe!

von Karl H. (kbuchegg)


Lesenswert?

Heimo G. schrieb:

> Wie kann ich nun dieses Register beschreiben bzw. wie muss ich meine
> Funktion dafür schreiben?

Wie ist denn der Chip angeschlossen.
Über welches Protokoll wird er angesprochen oder kurz gesagt in welcher 
Reihenfolge müssen den welche Leitungen mit den Bits klappern, damit der 
Chip die Daten auch übernimmt.

> Kann mir da jemand ein Beispiel geben?

Kann man nicht.
Da fehlen viel zu viele Details, die aber allesamt im Datenblatt des 
Chips stehen, bzw. unter Umständen den Schaltplänen deines Rechners zu 
entnehmen sind.

von H. G. (ledi)


Lesenswert?

Der Chip ist über die SPI-Schnittstelle des AT90PWM316 angeschlossen.

>Über welches Protokoll wird er angesprochen oder kurz gesagt in welcher
>Reihenfolge müssen denn welche Leitungen mit den Bits klappern, damit der
>Chip die Daten auch übernimmt.

Da bin ich mir nicht so sicher ob das nun LSB oder MSB first ist.
Das Register 14 ist im Datenblatt auf Seite 20 (Address 0E)zu finden.
Datenblatt des RFM70 Funkmoduls: 
[[http://www.hoperf.com/upfile/RFM70.PDF]]

Die Reihenfolge ist im Datenblatt so beschrieben:

The serial shifting SPI commands is in the following format:
<Command word: MSB bit to LSB bit
(one byte)>
<Data bytes: LSB byte to MSB byte, MSB bit in each byte first> for all 
registers at bank 0 and register 9 to
register 14 at bank 1
<Data bytes: MSB byte to LSB byte, MSB bit in each byte first> for 
register 0 to register 8 at bank 1

Da werd ich aber nicht so ganz schlau daraus.

von Purzel H. (hacky)


Lesenswert?

Der Einfachheit halber auf SPI verzichten und mit den Port befehlen 
arbeiten.

SPICS:=0;
SPIData:=0;
SPIClk:=1;
SPIClk:=0;
SPIData:=..
SPIClk:=1;
SPIClk:=0;
SPIData:=..
SPIClk:=1;
SPIClk:=0;
SPIData:=..
SPIClk:=1;
SPIClk:=0;
...
...
SPICS:=1;

oder aehnlich, gemaess datenblatt.

von H. G. (ledi)


Lesenswert?

Ich kann den Funkchip aber nur über SPI ansprechen.

Auf die Registeradresse 0x0E muss ich die Daten 0xFFFFFEF7CF208104082041 
schreiben.

Da ich aber nur Byte für Byte übertragen kann, muss ich denke ich das 
irgendwie ausmaskieren oder mit Pointer arbeiten. Da kenne ich mich aber 
noch nicht so aus.

Hier die Vorgehensweise:

1. Cipselect = low
2. Schreiben der Adresse 0x0E
3. Schreiben der Daten 0xFFFFFEF7CF208104082041
4. Cipselect = high

von Tretet den Trog (Gast)


Lesenswert?

Hab ich doch beschrieben wie's geht. Jedes bit einzeln reinschieben ...

von Rüdiger (Gast)


Lesenswert?

Tretet den Trog schrieb:
> Hab ich doch beschrieben wie's geht. Jedes bit einzeln reinschieben ...

Er versteht es nicht.

von Peter D. (peda)


Lesenswert?

A...aha Soooo. schrieb:
> Der Einfachheit halber auf SPI verzichten und mit den Port befehlen
> arbeiten.

Was ist denn daran einfach?
Es ist ein Wust an Schreibarbeit ohne Sinn und Verstand.
Ein einziger Schreibfehler und Du suchst Dich dumm und dümmer.

Mach ne SW-SPI über ein Byte, definiere ein Array und gebe es aus in 
eine Schleife bis sizeof(Array), vorn und hinten /CS klappern, fertsch.

Mit nem kleinen bischen Suchen findest Du auch haufenweise bereits 
fertige SW-SPIs.


Peter

von Purzel H. (hacky)


Lesenswert?

Ok. Man nimmt den selben Pin und deklariert ihn als Portpin. irgendwie :

SPIClk = PortB,6
SPIDataOut = PortB,5
SPICS = PortB,4

Ein Byte spult man dann ab als

 for i=1 to 8 do
  SPIDataOut = ((DataByte and 0x80)==1)
  SPIClk =1;
  SPIClk =0;
  DataByte = (DataByte << 1)

von H. G. (ledi)


Lesenswert?

Also ich hab das mal so gelöst:

Hier setze ich die Daten:
1
//************  Bank1 register 14 initialization value
2
const unsigned int Bank1_Reg14[11]=
3
{
4
  0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF,
5
};

Und hier schreibe ich zuerst die Adresse, gefolgt von den Daten:
1
  CS_low(200);
2
  SPDR = 0x0E;            // Init address Bank1 Reg.14
3
  while (!(SPSR & (1<<SPIF)));
4
  for (int k=0; k<=11; k++)
5
  {
6
    SPDR = Bank1_Reg14[k];      // Init data
7
    while (!(SPSR & (1<<SPIF)));
8
    CS_high(200);
9
  }

Ist das so ok?

von Karl H. (kbuchegg)


Lesenswert?

Heimo G. schrieb:


>   for (int k=0; k<=11; k++)

Diese Schleife wird 12 mal durchlaufen

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11

Zähl nach, sind 12 Stück

Dein Array
const unsigned int Bank1_Reg14[11]=

ist aber nur 11 Einträge groß. Ein Bank1_Reg14[11] gibt es nicht, daher 
kannst du es auch mit Bank1_Reg14[k] nicht ansprechen, wenn k gleich 11 
geworden ist.

>  for (int k=0; k<=11; k++)
>  {
>    SPDR = Bank1_Reg14[k];      // Init data
>    while (!(SPSR & (1<<SPIF)));
>    CS_high(200);
>  }

Warum schaltest du den CS gleich nach dem ersten gesendeten Byte wieder 
auf  High?
Du sollst ihn auf High schalten, nachdem alle 11 Bytes übertragen 
wurden!

> Ist das so ok?

Funktionierts denn?
Wenn ja, dann stehen die Chancen nicht so schlecht. Wenn nein, dann hast 
du auf jeden Fall noch mindestens 1 Fehler.

von Lutz (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Diese Schleife wird 12 mal durchlaufen
>
> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
>
> Zähl nach, sind 12 Stück

Ich habe momentan ziemlichen Kohldampf und liege deshalb vielleicht 
falsch, aber mit k<=11 ist doch bei 10 schon Schluß?

von Karl H. (kbuchegg)


Lesenswert?

Lutz schrieb:
> Karl heinz Buchegger schrieb:
>> Diese Schleife wird 12 mal durchlaufen
>>
>> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
>>
>> Zähl nach, sind 12 Stück
>
> Ich habe momentan ziemlichen Kohldampf und liege deshalb vielleicht
> falsch, aber mit k<=11 ist doch bei 10 schon Schluß?

Ähm.
Die Schleife wird solange wiederholt, solange die angegebene Bedingung 
wahr ist.
1
  k = 0;  k wird mit 0 initialisiert
2
  k gleich  0; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
3
  k gleich  1; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
4
  k gleich  2; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
5
  k gleich  3; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
6
  k gleich  4; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
7
  k gleich  5; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
8
  k gleich  6; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
9
  k gleich  7; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
10
  k gleich  8; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
11
  k gleich  9; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
12
  k gleich 10; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
13
  k gleich 11; Bedingung k <= 11 ist wahr; Schleifenkörper wird ausgeführt; k++
14
15
  k gleich 12; Bedingung k <= 11 ist falsch; Schleifenkörper wird NICHT
16
                                            mehr ausgeführt und es geht
17
                                            hinter der Schleife weiter

Mit welchen Werten für k wird daher der Schleifenkörper ausgeführt?

Das ist aber sowas von Basic-C Wissen, dass es mich zweifeln lässt, ob 
du dir für Funk überhaupt schon deine Sporen verdient hast.

von Lutz (Gast)


Lesenswert?

Nun ja, aus dieser Sicht betrachtet, scheint das, ... wohl ... 
tatsächlich, ... so zu sein, räusper.

War meine "Befürchtung" doch richtig. Aber es gibt ja gleich neue 
Kohlenhydrate, so daß wieder etwas mehr Glukose mit dem Blut in mein 
Hirn geschwemmt wird ...

Übrigens: Ich bin aber nicht der Funkprobleminhaber.

von Karl H. (kbuchegg)


Lesenswert?

Lutz schrieb:
> Nun ja, aus dieser Sicht betrachtet, scheint das, ... wohl ...
> tatsächlich, ... so zu sein, räusper.

Wenn eine Schleife, die über alle Elemente eines Arrays gehen soll, 
anders aussieht also so

  for( i = 0 ; i < Anzahl_Array_Elemente; i++ )
    mach was mit Array[i]

dann ist praktisch immer Feuer am Dach oder zumindest Vorsicht 
angebracht. Sieht die Schleife hingegen so aus, dann braucht man sie 
nicht groß analysieren: sie geht über alle Array-Elemente

Die Zutaten sind
* dieselbe Variable in der for-Initialisierung, der Bedinungung,
  dem Inkrement und im Index beim Array Zugriff
* Die Initialisierung erfolgt auf 0
* Die Abbruchbedingung lautet auf kleiner Anzahl Elemente (also der
  Zahl, die bei der Array-Deklaration angegeben wurde).
  Nicht kleiner gleich, nicht ungleich, nicht gleich und nicht größer.
  Kleiner ... und sonst nichts anderes
* Es wird nur um 1 inkrementiert und das Inkrement steht im for und
  nicht irgendwo im Schleifenkörper. Ob man hingegen i++ schreibt oder
  ++i bevorzugt, spielt für die for-Schleife an sich keine Rolle sondern
  hat andere Ursachen.

Sind diese Zutaten gegeben, dann muss es im Kopf klick machen und eine 
innere Stimme sagt: Aha, alle Array Elemente ... was macht er denn mit 
jedem Einzelnen, das for ist in der Analyse bereits gegessen, darüber 
brauch ich nicht länger nachdenken

Ist aber auch nur 1 Zutat nicht vorhanden, dann müssen die Alarmglocken 
zu läuten anfangen und der 'Detailed-Code-Analyse-Modus' klinkt sich ein 
und nimmt die for Schleife an sich auseinander: Welches ist der erste 
Wert der Schleifenvariable, welches ist der Letzte und in welcher 
Richtung verändert sich der Wert pro Durchlauf? Wie korreliert das mit 
dem Array-Zugriff und erfolgt da kein Out-Of-Bounds Zugriff?

> Übrigens: Ich bin aber nicht der Funkprobleminhaber.

Mein Fehler, dann nehme ich das für dich zurück.
Aber auch der Funk-Problematiker hat da offenbar so seine 
Schwierigkeiten damit, also kann er die Aussage ruhig auf sich gemünzt 
sehen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.