Forum: Mikrocontroller und Digitale Elektronik AD7793 Referenz Code von AD


von Mario EDUARDO (Gast)


Lesenswert?

Hallo alle,

Ich hab ein Problem mit dem Verständis des Refenz Code von AD zum 
AD7793,
und zwar mit dem SPI_Read() Call und dessen Interface.

So wie ich das verstanden habe bzw vermute, wird im übergebenen Array im 
ersten Byte codiert, ob CS angelegt werden muß.

Im 2ten Byte wird jener Wert übergeben, der ins Communications Register 
geschrieben werden soll. Daraus ergibt sich dann, wie es weiter geht.

Was bedeuten dann folgende Kommentare zur SPI_Read() Routine:
>> * @param bytesNumber - Number of bytes to write. <<

An AD7793_GetRegisterValue() wird beim Lesen der ID als size=1 
übergeben.
im Code geht es dann weiter bei AD7793_GetRegisterValue(), zuerst wird 
das CS gebastelt, dann AD7793_COMM_READ |  AD7793_COMM_ADDR(regAddress) 
als Befehl ans Communications Register erzeugt.

Dann wird an SPI_Read() plötzlich 1+size, also der Wert 2 übergeben.
Was soll das ??? Es soll ja genau 1 Byte geschrieben werden und eines 
gelesen werden.

Wie würde ich ein byte senden und dann 3 Byte lesen ?

Also letztendlich: ich verstehe das Interface nicht ganz.

PS: Noch eine Frage: Wie muß man beim AtMega das SPI konfigurieren?
CPOL = High ist ja klar, wie muß das CPHA Bit gesetzt werden ?

Danke, Mario

von Arc N. (arc)


Lesenswert?

Mario EDUARDO schrieb:
> Dann wird an SPI_Read() plötzlich 1+size, also der Wert 2 übergeben.
> Was soll das ??? Es soll ja genau 1 Byte geschrieben werden und eines
> gelesen werden.

Was steht denn im Datenblatt zum Communications Register?
Danach sollte es klarer sein...
1
// Das folgende ist für AD7794.
2
// Beim AD7793 sind die Register-Adressen gleich zum AD7794, 
3
// aber die Inhalte nicht vollständig...
4
5
#define AD7794_IDREG_READ  0b01100000
6
#define AD7794_MODEREG_WRITE  0b00001000
7
#define AD7794_DATAREG_READ  0b01011000
8
9
static uint8_t AdRead8BitReg(uint8_t reg) {
10
    SpiTransceive(reg);
11
    return SpiTransceive(0x00);
12
}    
13
14
static void AdWrite16BitReg(uint8_t reg, uint8_t high, uint8_t low) {
15
    SpiTransceive(reg);
16
    SpiTransceive(high);
17
    SpiTransceive(low);
18
}    
19
20
static uint32_t AdRead24BitReg(uint8_t reg) {
21
    uint8_t high, mid, low;
22
    SpiTransceive(reg);
23
    high = SpiTransceive(0x00);
24
    mid = SpiTransceive(0x00);
25
    low = SpiTransceive(0x00);
26
    return ((uint32_t)high << 16UL) | ((uint32_t)mid << 8UL) | (uint32_t)low;
27
}    
28
29
static void AdWriteMode(uint8_t modeHigh, uint8_t modeLow) {
30
    AdWrite16BitReg(AD7794_MODEREG_WRITE, modeHigh, modeLow);
31
}    
32
33
static uint8_t AdReadId() {
34
    return AdRead8BitReg(AD7794_IDREG_READ);
35
}
36
37
static uint32_t AdReadData() {
38
    return AdRead24BitReg(AD7794_DATAREG_READ);
39
}

: Bearbeitet durch User
von Mario EDUARDO (Gast)


Lesenswert?

Hallo ARC,

Ich sehe zwar

static uint8_t AdRead8BitReg(uint8_t reg) {
    SpiTransceive(reg);
    return SpiTransceive(0x00);
}

dass du erst die ID sendest und dann eine 0x00 sendest, die Stelle im 
Datenblatt , die das beschreibt, finde ich leider nicht. Bin blind ...

Das wird doch wohl nicht jene 0x00 sein, um den Takt zu erzeugen ...

Mario

von Arc N. (arc)


Lesenswert?

Mario EDUARDO schrieb:
> Hallo ARC,
>
> Ich sehe zwar
...
> dass du erst die ID sendest und dann eine 0x00 sendest, die Stelle im
> Datenblatt , die das beschreibt, finde ich leider nicht. Bin blind ...

"The communications register is an 8-bit write-only register. All
communications to the part must start with a write operation to
the communications register. The data written to the
communications register determines whether the next
operation is a read or write operation..."
Seite 15

D.h. der erste SPI-Transfer geht ins Communications Register, wählt dort 
die Operation (lesen/schreiben) und das Register aus wohin/woher die 
nächsten Bytes gehen/kommen.

> Das wird doch wohl nicht jene 0x00 sein, um den Takt zu erzeugen ...

Doch, genau der Takt, um die Bits aus dem ID-Register zu 
lesen/herauszutakten ;)

von Mario EDUARDO (Gast)


Lesenswert?

Mein Problem bzw Verhalten ist folgendes:
Nach einem Reset mit 4*0xff sind alle Leitungen im Soll-Zustand.

Mit dem nächsten Kommando, genau mit dem CS davon geht die DOUT/RDY 
Leitung auf Low. Lt Datenblatt hieße das, dass da ein Messergebnis 
anliegt.

Wenn ich genau 0xEC mal ein Byte einlese, lese ich dann eine 0x03 und 
dann geht die DOUT/RDY Leitung wieder auf High.

Das verstehe ich nich ganz.

Mario

von Arc N. (arc)


Lesenswert?

Mario EDUARDO schrieb:
> Mein Problem bzw Verhalten ist folgendes:
> Nach einem Reset mit 4*0xff sind alle Leitungen im Soll-Zustand.
>
> Mit dem nächsten Kommando, genau mit dem CS davon geht die DOUT/RDY
> Leitung auf Low. Lt Datenblatt hieße das, dass da ein Messergebnis
> anliegt.
>
> Wenn ich genau 0xEC mal ein Byte einlese,

Aus welchem Register? Oder wird einmal ein Startregister ins 
Communication Register geschrieben und danach werden 0xEC Bytes gelesen?

> lese ich dann eine 0x03 und
> dann geht die DOUT/RDY Leitung wieder auf High.

Statusregister kann es dann nicht sein, da beim AD7793 dort das Bit 3 
immer gesetzt ist oder ist das ein AD7792?

>
> Das verstehe ich nich ganz.

Ich im Moment auch nicht...
Die Einstellungen Mode/Config etc. (oder ob Continuous Mode im Comm 
Register eingestellt ist) wären zur Fehlersuche ganz hilfreich.

Ansonsten: Merkwürdiges Verhalten da im Config Register REFSEL nach 
einem Reset auf 0 = ext. Referenz gesetzt ist, aber keine angeschlossen 
ist oder z.B. im Mode Register auf externen Takt umgeschaltet wurde 
(vielleicht High und Low-Byte vertauscht?), aber keiner anliegt.

von Mario EDUARDO (Gast)


Lesenswert?

Danke für deine Hilfe!
Abggesehen von möglichen Initialisierungsfehlern von mir war ein Problem 
definitiv, daß man scheinbar mit dem JTAGICE3 nicht so problemlos durch 
den SPI Code gehen kann. Am Oszi hab ich da plötzlich Signale gesehen, 
wo der Prozessor eigentlich angehalten sein sollte.

Aber die Referenzimplementierung von AD läßt schon zu wünschen übrig. 
Schleißig dokumentiert.

Dad Datenarry, das öfter mal am Stack liegt und immer data[] heißt hat 
folgenden Aufbau:

ein Register lesend:

Data[0] sagt aus, ab ein CS angelegt werden soll.
Data[1] ist das Byte ans Communication Regsiter

Der eigene Code muß dann Data[1] senden, was aussagt von wo wieviel 
gelesen werden soll.

Die an SPI_Read() übergeben Size sagt aus, wieviele Bytes insgesamt zu 
übertragen sind, also lesend und schreibend!! Bei einem ReadId wird da 2 
übergeben weil in data[1] das zu sendende Byte steht und dann in eben 
diesem data[1] das gelesene Byte erwartet wird.

beim lesen einer Single Conversion ist das analog. Es ist ein Byte ins 
Communication Register zu schreiben und dann 3 Bytes zu lesen. Daher 
wird hier 4 übergeben. (1+size) bedeutet also 1mal schreiben, size Mal 
lesen.

Man muß also letztendlich in SPI_Read(9 wieder eine 1 abziehen, dann 
weiß man wieviel man lesen muß.

Ist ja ganz einfach ....

Mario

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.