Forum: Mikrocontroller und Digitale Elektronik SCK durchgehend erzeugen


von Andreas H. (andreas1993)


Lesenswert?

Hallo,

ich versuche schon seit Tagen ein durchgehendes Clock-Signal an meinem 
Arduino UNO zu erzeugen. Ich arbeite mit SPI und an PIN 13 ist mein SCK 
angschlossen.

Wenn ich das Programm Uploade, dann bekomme ich für eine Kurzezeit ein 
Clock-Signal aber nicht durchgehen.

Was ist an meinem Code flasch, bzw. was muss ich machen,damit ich ein 
durchgehendes Signal bekomme?

Wäre für jede Hilfe sehr DANKBAR...

Gruß
Andreas

Hier ist mein Code:
1
#include <SPI.h>
2
3
int cs = 8;
4
unsigned int adcValueLSB;
5
unsigned long adcValueMSB;
6
unsigned long adcValue;
7
8
void setup(){
9
  pinMode(cs, OUTPUT);                     // Pin cs (chip select) als Ausgang definiert
10
  digitalWrite(cs, HIGH);                  // cs auf 1 setzen
11
  SPI.begin();                             // Startet die SPI-Bibliothek          
12
  SPI.setDataMode(SPI_MODE0);              // Setzt den SPI-Modus
13
  SPI.setClockDivider(SPI_CLOCK_DIV2);     // Stellt die Geschwindigkeit ein
14
  //SPI.setBitOrder(LSBFIRST);               // Setzt die Bit-Reihenfolge Most-Significant-Bit, scheint Standart zu sein!!!
15
  Serial.begin(9600);
16
}
17
18
void loop()
19
{
20
  digitalWrite(cs, LOW);
21
  delay(500);
22
  //delayMicroseconds(500);
23
  SPI.transfer(0x90);
24
  //SPI.transfer(0x00);
25
  delay(500);
26
  //delayMicroseconds(500);
27
  adcValueLSB = SPI.transfer(0x00);        // niederwertiges Byte zuerst, D15...D8
28
  adcValueMSB = SPI.transfer(0x00);        // höherwertiges Byte zum Schluss, D7...D0
29
  digitalWrite(cs, HIGH);
30
  adcValue = adcValueMSB << 8;
31
  adcValue = adcValue | adcValueLSB;      
32
  
33
  Serial.print("analog value = ");
34
  Serial.println(adcValue);
35
  Serial.print('\n');
36
  delay(1000);
37
}

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Andreas Hoffmann schrieb:
> Was ist an meinem Code flasch, bzw. was muss ich machen,damit ich ein
> durchgehendes Signal bekomme?

ich denke Zeile 42 muss angepasst werden.

von Philipp (Gast)


Lesenswert?

Der Takt wird nur erzeugt wenn du sendest. Während dem delay sendest du 
ja nichts, weshalb auch kein Takt vorhanden ist.

von Max H. (hartl192)


Lesenswert?

Für jedes bit das du sendest erzeugt der uC genau eine Taktflanke.

: Bearbeitet durch User
von Uwe Bonnes (Gast)


Lesenswert?

Beim STM32 gibt es RX_ONLY und BIDIMODE Flags, die dann dauerhaft SCK 
erzeugen.  Vielleicht hat die betroffene CPU etwas aehnliches.

von Rudolph (Gast)


Lesenswert?

Die Frage ist doch, wofür überhaupt ein durchgehendes Clock-Signal?

von Andreas H. (andreas1993)


Lesenswert?

Ich hab ein Arduino und hab ein externen ADC angeschlossen, über den ADC 
will ich meine Spannung verändern können.

Wenn ich jetzt die Spannung verändere, dann will ich am Monitor die 
Werte für die geänderte Spannung sehen.
Dann muss doch mein Clock durchgehend Daten senden, oder nicht?

von -- (Gast)


Lesenswert?

lol

welche Spannung?
ADC oder DAC?

oder möchtest du ein von deinen ADC Werten abhängiges PWM Signal?

von Max H. (hartl192)


Lesenswert?

Andreas Hoffmann schrieb:
> über den ADC
> will ich meine Spannung verändern können.
Das klingt mir eher nach einen DAC. Welchen Baustein hast du?

Ich gehe mal davon aus, dass es ein DAC ist: Normalerweise gibt ein DAC 
so lange die Eingestellte Spannung aus, bis er neuer Werte über SPI 
bekommt.

: Bearbeitet durch User
von Rudolph (Gast)


Lesenswert?

Andreas Hoffmann schrieb:
> Dann muss doch mein Clock durchgehend Daten senden, oder nicht?

Nein, der ADC braucht den Takt ja nicht zwischen den Transfers.

von Max H. (hartl192)


Lesenswert?

Andreas Hoffmann schrieb:
> Wenn ich jetzt die Spannung verändere, dann will ich am Monitor die
> Werte für die geänderte Spannung sehen.
> Dann muss doch mein Clock durchgehend Daten senden, oder nicht?

Unabhängig ob es ein ADC oder DAC ist, ist es für dich egal, ob du 
dauern Daten sendest/empfängst oder nicht. Die paar Millisekunden 
zwischen den Datenblöcken wirst du auf dem Monitor sicher nicht sehen.

von Rudolph (Gast)


Lesenswert?

Vom Code her müsste es ein ADC sein, es werden Null-Bytes gesendet und 
zwei Byte eingelesen um einen 16-Bit Wert an die serielle Schnittstelle 
übergeben zu können.

von Peter D. (peda)


Lesenswert?

Andreas Hoffmann schrieb:
> hab ein externen ADC angeschlossen, über den ADC
> will ich meine Spannung verändern können.

Spannung ausgeben kann ein ADC nicht, sondern ein DAC.

Poste mal ein Link aufs Datenblatt, damit das Rätselraten endlich 
beendet werden kann.
Es gibt hier keinen Preis für größtmöglichen Informationsgeiz.

von Andreas H. (andreas1993)


Lesenswert?

-- schrieb:
> lol
>
> welche Spannung?
> ADC oder DAC?
>
> oder möchtest du ein von deinen ADC Werten abhängiges PWM Signal?

Ich hab ein externen ADC, ich geben an diesen ADC eine Spannung z.B 1V 
und möchte den digitalen Wert dazu haben.

von Andreas H. (andreas1993)


Lesenswert?

Max H. schrieb:
> Andreas Hoffmann schrieb:
>> über den ADC
>> will ich meine Spannung verändern können.
> Das klingt mir eher nach einen DAC. Welchen Baustein hast du?
>
> Ich gehe mal davon aus, dass es ein DAC ist: Normalerweise gibt ein DAC
> so lange die Eingestellte Spannung aus, bis er neuer Werte über SPI
> bekommt.

Ich hab ein ADC 1302!!!

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Vom Code her müsste es ein ADC sein, es werden Null-Bytes gesendet und
> zwei Byte eingelesen um einen 16-Bit Wert an die serielle Schnittstelle
> übergeben zu können.

Genau das ist richtig...! Aber ich bekomme nicht den Wert, denn ich am 
Netzgerät einstelle. Deswegen wollte ich mit einem Oszilloskop nach 
messen ob meine Signal auch ankommen. Die Signale für den SCK bekomme 
ich nur, wenn ich das Programm starte bzw. reset drücke.

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Ich kenne den ADC nicht, aber mit an Sicherheit grenzender 
Wahrscheinlichkeit braucht dieser nur ein Clock Signal, wenn auch Daten 
transferiert werden. Und die Pausen zwischen den Datenpaketen wirst du 
auf dem Bildschirm nicht sehen.

von Andreas H. (andreas1993)


Lesenswert?

Peter Dannegger schrieb:
> Spannung ausgeben kann ein ADC nicht, sondern ein DAC.
>
> Poste mal ein Link aufs Datenblatt, damit das Rätselraten endlich
> beendet werden kann.
> Es gibt hier keinen Preis für größtmöglichen Informationsgeiz.

Hier ist mein Datenblatt: 
http://datasheets.maximintegrated.com/en/ds/MAX1302.pdf

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Andreas Hoffmann schrieb:
> Die Signale für den SCK bekomme
> ich nur, wenn ich das Programm starte bzw. reset drücke.
Also nur einmal an Anfang und danach hängt das Programm irgendwo fest?

> Aber ich bekomme nicht den Wert, denn ich am
> Netzgerät einstelle.
Welchen Wert bekommst du?
Weißt du, dass der Wert nicht direkt die Spannung ist? Die Spannung 
erhältst du, wenn du den ADC-Wert mit 4096mV/2^16 multiplizierst.

von Andreas H. (andreas1993)


Lesenswert?

Max H. schrieb:
> Andreas Hoffmann schrieb:
>> Die Signale für den SCK bekomme
>> ich nur, wenn ich das Programm starte bzw. reset drücke.
> Also nur einmal an Anfang und danach hängt das Programm irgendwo fest?

Genau, ich weiss aber nicht wo!
Meine Frage wäre jetzt aber auch, muss der SCK die ganze Zeit Daten 
senden? Oder muss er nur Daten senden, wenn ich das Programm starte? 
Aber dann könnte ich ja am Netzgeräte die Spannung ändern, die Digitalen 
Werte würden sich dann aber erst ändern, wenn ich das Programm wieder 
neu Starte, vorher würde nichts passieren oder...?



>> Aber ich bekomme nicht den Wert, denn ich am
>> Netzgerät einstelle.
> Welchen Wert bekommst du?

Wenn ich z.B eine Spannung von 2V gebe, dann bekomme ich eine Spannung 
von 3,25V oder wenn ich 0V einstelle, dann bekomme ich 2V!

> Weißt du, dass der Wert nicht direkt die Spannung ist? Die Spannung
> erhältst du, wenn du den ADC-Wert mit 4096mV/2^16 multiplizierst.

Ja, dass weiss ich...

von Rudolph (Gast)


Lesenswert?

Du schickst dem Ding aber im Moment nur drei Byte, oder?

---
  SPI.transfer(0x90);
  //SPI.transfer(0x00);
  delay(500);
  //delayMicroseconds(500);
  adcValueLSB = SPI.transfer(0x00);        // niederwertiges Byte
zuerst, D15...D8
  adcValueMSB = SPI.transfer(0x00);        // höherwertiges Byte zum
---

0x90 - Kanal 0, single-ended
0x00
0x00

Da fehlt doch ein Byte, nach Figure 2 im Datenblatt ist der komplette 
Frame 32 Bit lang und mit dem 3. und 4. Transfer erhält man das 
Ergebnis.

Und Du bekommst auch das höherwertige Byte zuerst zurück geliefert,
der Kommentar ist seltsam.
D15...D8 sind nicht niedriger als D7...D0.

--
  SPI.transfer(0x90);
  SPI.transfer(0x00);
  adcValueMSB = SPI.transfer(0x00);
  adcValueLSB = SPI.transfer(0x00);
--

?

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Du schickst dem Ding aber im Moment nur drei Byte, oder?
>
> ---
>   SPI.transfer(0x90);
>   //SPI.transfer(0x00);
>   delay(500);
>   //delayMicroseconds(500);
>   adcValueLSB = SPI.transfer(0x00);        // niederwertiges Byte
> zuerst, D15...D8
>   adcValueMSB = SPI.transfer(0x00);        // höherwertiges Byte zum
> ---
>
> 0x90 - Kanal 0, single-ended
> 0x00
> 0x00
>
> Da fehlt doch ein Byte, nach Figure 2 im Datenblatt ist der komplette
> Frame 32 Bit lang und mit dem 3. und 4. Transfer erhält man das
> Ergebnis.
>
> Und Du bekommst auch das höherwertige Byte zuerst zurück geliefert,
> der Kommentar ist seltsam.
> D15...D8 sind nicht niedriger als D7...D0.
>
> --
>   SPI.transfer(0x90);
>   SPI.transfer(0x00);
>   adcValueMSB = SPI.transfer(0x00);
>   adcValueLSB = SPI.transfer(0x00);
> --

Ich sende 2 Byte. Aber laut Oszilosskop nur 3 Byte, ich weiss auch nicht 
wie das sein kann. Nach dem Code sende ich zwei Byte.

Ich hab das so verstanden , dass man 4 Byte senden kann aber nicht muss, 
oder?

SPI.transfer(0x90) => Für Kanal 1 (CH1), weil mein Netzgerät an Kanal 1 
angeschlossen ist.

: Bearbeitet durch User
von Rudolph (Gast)


Lesenswert?

Andreas Hoffmann schrieb:
> Ich sende 2 Byte.

3, das 0x90 zählt auch.

> Ich hab das so verstanden , dass man 4 Byte senden kann aber nicht muss,
> oder?

Also im Mode 0 zumindest muss man 4 Byte senden, das erste ist Kommando, 
das zweite um weiter Takt zu schicken, das 3. und 4. um an die Daten 
ranzukommen.

Bei Mode 1 und Mode 2 muss man SSTRB nach dem ersten Byte auf 1 setzen,
da Du das nicht machst ist es wohl Mode 0 Du den möchtest.

Mode 0 darf nicht schneller als 3,67MHz sein.

Je nachdem wie schnell der Controller auf dem Uno getaktet ist, sollte 
SPI_CLOCK_DIV2 4 oder 8 MHz ergeben.
Wenn der Uno mit 16 MHz getaktet sein sollte, versuch mal SPI_CLOCK_DIV8 
falls es das so gibt.

Hab keinen Uno und benutze kein Arduino...

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Andreas Hoffmann schrieb:
>> Ich sende 2 Byte.
>
> 3, das 0x90 zählt auch.
>
>> Ich hab das so verstanden , dass man 4 Byte senden kann aber nicht muss,
>> oder?
>
> Also im Mode 0 zumindest muss man 4 Byte senden, das erste ist Kommando,
> das zweite um weiter Takt zu schicken, das 3. und 4. um an die Daten
> ranzukommen.
>
> Bei Mode 1 und Mode 2 muss man SSTRB nach dem ersten Byte auf 1 setzen,
> da Du das nicht machst ist es wohl Mode 0 Du den möchtest.
>
> Mode 0 darf nicht schneller als 3,67MHz sein.
>
> Je nachdem wie schnell der Controller auf dem Uno getaktet ist, sollte
> SPI_CLOCK_DIV2 4 oder 8 MHz ergeben.
> Wenn der Uno mit 16 MHz getaktet sein sollte, versuch mal SPI_CLOCK_DIV8
> falls es das so gibt.
>
> Hab keinen Uno und benutze kein Arduino...

Ok, super eine Frage hätte ich noch. SPI.transfer(0x00) ist doch ein 
Byte  und der zweite wäre doch in meinem fall SPI.transfer(0x90)!?

Ja, SPI_CLOCK_DIV8 gibt es. Es gibt 2,4,8,16,32!

von Rudolph (Gast)


Lesenswert?

Rudolph schrieb:
> Bei Mode 1 und Mode 2 muss man SSTRB nach dem ersten Byte auf 1 setzen,

Das war quatsch, SSTRB ist ein Ausgang der vom ADC gesetzt wird wenn die 
Daten abgeholt werden können.

Was ich jetzt noch nicht verstanden habe ist wie man die 
unterschiedlichen Control-Bytes sendet.

Also was muss man machen damit der ADC zwischen Conversion-Start, 
Analog-Input Configuration und Mode-Control Byte unterscheidet?

von Rudolph (Gast)


Lesenswert?

Andreas Hoffmann schrieb:
> SPI.transfer(0x00) ist doch ein
> Byte  und der zweite wäre doch in meinem fall SPI.transfer(0x90)!?

Das sind zwei verschiedene, ja. :-)
Aber SPI.transfer(0x00) brauchst Du insgesamt drei mal.

Am Scope sieht man die zwei Null-Bytes die Du jetzt sendest natürlich 
nur an den 16 Takten auf dem SPI-Clock dazu.

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Andreas Hoffmann schrieb:
>> SPI.transfer(0x00) ist doch ein
>> Byte  und der zweite wäre doch in meinem fall SPI.transfer(0x90)!?
>
> Das sind zwei verschiedene, ja. :-)
> Aber SPI.transfer(0x00) brauchst Du insgesamt drei mal.
>
> Am Scope sieht man die zwei Null-Bytes die Du jetzt sendest natürlich
> nur an den 16 Takten auf dem SPI-Clock dazu.

Ok, aber Du meintest ja gerade, dass ich 3 Byte sende, das tue ich aber 
laut mein Code nicht. Ich sende nur zwei Byte bzw. gerade nur 1 Beyte 
(SPI.transfer(0x90), weil ich SPI.transfer(0x00) ausgeklammert habe.

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Rudolph schrieb:
>> Bei Mode 1 und Mode 2 muss man SSTRB nach dem ersten Byte auf 1 setzen,
>
> Das war quatsch, SSTRB ist ein Ausgang der vom ADC gesetzt wird wenn die
> Daten abgeholt werden können.
>
> Was ich jetzt noch nicht verstanden habe ist wie man die
> unterschiedlichen Control-Bytes sendet.
>
> Also was muss man machen damit der ADC zwischen Conversion-Start,
> Analog-Input Configuration und Mode-Control Byte unterscheidet?

Ich glaube Analog-Input Configuration und Mode-Controle Byte kann ich 
ignorieren, weil ich Mode0 arbeite. Diese wären nur zur berücksichtigen, 
wenn ich im Mode1 arbeiten würde.

von Rudolph (Gast)


Lesenswert?

SPI.transfer(0x90);
  //SPI.transfer(0x00);
  adcValueLSB = SPI.transfer(0x00);
  adcValueMSB = SPI.transfer(0x00);

Also ich sehe hier drei, 0x90, 0x00, 0x00. :-)
Und ja, das auskommentierte zähle ich nicht mit. :-)


Und? Ändert sich denn was mit

  SPI.setClockDivider(SPI_CLOCK_DIV8);

  SPI.transfer(0x90);
  SPI.transfer(0x00);
  adcValueMSB = SPI.transfer(0x00);
  adcValueLSB = SPI.transfer(0x00);

?

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:

> Und? Ändert sich denn was mit
>
>   SPI.setClockDivider(SPI_CLOCK_DIV8);
>
>   SPI.transfer(0x90);
>   SPI.transfer(0x00);
>   adcValueMSB = SPI.transfer(0x00);
>   adcValueLSB = SPI.transfer(0x00);

Ich hab es noch nicht getestet, weil ich gerade das Board nicht habe. 
Bekomme es heute Abend wieder, dann sag ich Dir bescheid ob es geklappt 
hat oder nicht.

von Andreas H. (andreas1993)


Lesenswert?

Andreas Hoffmann schrieb:
> Rudolph schrieb:
>
>> Und? Ändert sich denn was mit
>>
>>   SPI.setClockDivider(SPI_CLOCK_DIV8);
>>
>>   SPI.transfer(0x90);
>>   SPI.transfer(0x00);
>>   adcValueMSB = SPI.transfer(0x00);
>>   adcValueLSB = SPI.transfer(0x00);

Ich hab es mal jetzt getestet aber nichts was ich sehen will.

#include <SPI.h>

int cs = 8;
unsigned int adcValueLSB;
unsigned long adcValueMSB;
unsigned long adcValue;

void setup(){
  pinMode(cs, OUTPUT);                     // Pin cs (chip select) als 
Ausgang definiert
  digitalWrite(cs, HIGH);                  // cs auf 1 setzen
  SPI.begin();                             // Startet die SPI-Bibliothek
  SPI.setDataMode(SPI_MODE0);              // Setzt den SPI-Modus
  SPI.setClockDivider(SPI_CLOCK_DIV8);     // Stellt die Geschwindigkeit 
ein
  SPI.setBitOrder(MSBFIRST);               // Setzt die Bit-Reihenfolge 
Most-Significant-Bit, scheint Standart zu sein!!!
  Serial.begin(9600);
}

void loop()
{
  digitalWrite(cs, LOW);
  delay(500);
  //delayMicroseconds(500);
  SPI.transfer(0x90);
  SPI.transfer(0x00);
  delay(500);
  //delayMicroseconds(500);
  adcValueMSB = SPI.transfer(0x00);        // höherwertiges Byte zum 
Schluss, D7...D0
  adcValueLSB = SPI.transfer(0x00);        // niederwertiges Byte 
zuerst, D15...D8
  digitalWrite(cs, HIGH);
  adcValue = adcValueMSB << 8;
  //adcValue = adcValue | adcValueLSB;

  Serial.print("analog value = ");
  Serial.println(adcValue);
  Serial.print('\n');
  delay(1000);
}

Ich gebe dem ADC 2V und erhalte 3,19V. Den SCK sehe ich auf dem Oszi 
auch nicht mehr. Nur einmal ganz kurz beim Start.

Laut Oszi liegt die Frequenz jetzt bei 3,33 HZ

Mir ist auch noch aufgefallen, dass ich jeweils nur 3 Bit sende als 3 
Taktzyklen.

: Bearbeitet durch User
von Sebastian W. (wangnick)


Lesenswert?

Hallo Andreas,

ich glaube so geht das nicht.

Schau dir im Datenblatt mal "Figure 2. External Clock-Mode Conversion 
(Mode 0)" genau an. Danach wird DIN auf steigender SCLK-Flanke gesetzt 
und ist auf fallender Flanke stabil, DOUT aber wird auf fallender Flanke 
vom ADC gesetzt und ist auf steigender stabil. Dasselbe steht noch 
einmal genau so auf Seite 19: "Data is clocked into the device from DIN 
on the rising edge of SCLK, and data is clocked out of DOUT on the 
falling edge of SCLK.

Die Arduino-SPI-Bibliothek verwendet aber bei SPI_MODE0 laut 
http://arduino.cc/de/Reference/SPI jetzt CPOL=0/CPHA=0 so wie auf 
Wikipedia http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus. 
Dort wird bei CPOL=0/CPHA=0 aber bei fallender Flanke von SCK sowohl 
gesendet als auch empfangen.

Es gibt da ja noch diesen Hinweis in der Wikipedia, der hier wohl 
zutrifft: "Some devices even have minor variances from the CPOL/CPHA 
modes described above. Sending data from slave to master may use the 
opposite clock edge as master to slave."

Versuch mal das erste Byte mit SPI_MODE1 zu senden und dann auf 
SPI_MODE0 umzuschalten.

Und dann nimm auch diese ewigen delay(500) mal raus. Und korrigiere 
deine verwirrenden Kommentare (das höherwertige Byte mit D15..D8 kommt 
zuerst).

LG, Sebastian

: Bearbeitet durch User
von holger (Gast)


Lesenswert?

>Den SCK sehe ich auf dem Oszi
>auch nicht mehr. Nur einmal ganz kurz beim Start.

Dann nimm statt 8 mal 10 für CS.

von Sebastian W. (wangnick)


Lesenswert?

... und dann wollen wir mal sehen, ob das arduinoforum.de 
(http://www.arduinoforum.de/arduino-Thread-Wie-programmiere-ich-ein-externen-AD-Wandler) 
schneller ist als wir ...

LG, Sebastian

von Rudolph (Gast)


Lesenswert?

Vielleicht mal mit weniger Delays um auch mal was zu sehen?

  digitalWrite(cs, LOW);
  delayMicroseconds(1);
  SPI.transfer(0x90);
  SPI.transfer(0x00);
  adcValueMSB = SPI.transfer(0x00);        // höherwertiges Byte zum
  adcValueLSB = SPI.transfer(0x00);        // niederwertiges Byte
  digitalWrite(cs, HIGH);
//  adcValue = adcValueMSB << 8;
//  adcValue = adcValue | adcValueLSB;
//  Serial.print("analog value = ");
//  Serial.println(adcValue);
//  Serial.print('\n');
  delay(10);

Dabei auf CS triggern.

Und funktioniert sowas wie
  adcValue = 12345;
  Serial.println(adcValue);
korrekt?

von Sebastian W. (wangnick)


Lesenswert?

... und ändere den Typ von adcValueLSB und adcValueMSB in uint8_t oder 
byte, und den von adcValue in uint16_t oder word. Deine Typen sind viel 
zu groß.

LG, Sebastian

von Andreas H. (andreas1993)


Lesenswert?

Hallo Sebastian,

stimmt darauf bin ich nicht gekommen, ich hoffe das es jetzt klappen 
wird.
Danke...!

Und auch herzlichsten Danke an die anderen für euren Tipps und 
Hilfestellungen.

von Andreas H. (andreas1993)


Lesenswert?

holger schrieb:
>>Den SCK sehe ich auf dem Oszi
>>auch nicht mehr. Nur einmal ganz kurz beim Start.
>
> Dann nimm statt 8 mal 10 für CS.

Ist es aber nicht egal, wo mein CS angeschlossen ist?

von Andreas H. (andreas1993)


Lesenswert?

Sebastian Wangnick schrieb:
> ... und dann wollen wir mal sehen, ob das arduinoforum.de
> 
(http://www.arduinoforum.de/arduino-Thread-Wie-programmiere-ich-ein-externen-AD-Wandler)
> schneller ist als wir ...
>
> LG, Sebastian

;)

von Rudolph (Gast)


Lesenswert?

Du arbeitest nicht zufällig in GF? Wir haben einen Andreas Hoffmann im 
Telefonbuch in der Firma und die Welt ist ja sonst auch ein Dorf... :-)

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Du arbeitest nicht zufällig in GF? Wir haben einen Andreas Hoffmann im
> Telefonbuch in der Firma und die Welt ist ja sonst auch ein Dorf... :-)

Nein, ich arbeite nicht in GF(???). Ich glaube dieser Name ist sehr 
geläufig! :)

: Bearbeitet durch User
von Martin (Gast)


Lesenswert?

es gibt  auch  einen internal clock mode

von Rudolph (Gast)


Lesenswert?

Andreas Hoffmann schrieb:
> Nein, ich arbeite nicht in GF

Schade auch. :-)


Ist denn inzwischen mehr zu sehen auf dem Oszi?

von Andreas H. (andreas1993)


Lesenswert?

Sebastian Wangnick schrieb:
> Hallo Andreas,
>
> ich glaube so geht das nicht.
>
> Schau dir im Datenblatt mal "Figure 2. External Clock-Mode Conversion
> (Mode 0)" genau an. Danach wird DIN auf steigender SCLK-Flanke gesetzt
> und ist auf fallender Flanke stabil, DOUT aber wird auf fallender Flanke
> vom ADC gesetzt und ist auf steigender stabil.

Was meinst Du eingendlich mit "stabil"???

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Andreas Hoffmann schrieb:
>> Nein, ich arbeite nicht in GF
>
> Schade auch. :-)
>
>
> Ist denn inzwischen mehr zu sehen auf dem Oszi?

Bin gerade dabei das auszuprobieren.

Mit "delayMicroseconds(1);" sehe ich immer nur noch 3 Bit, aber nur beim 
Start.

von Rudolph (Gast)


Lesenswert?

Andreas Hoffmann schrieb:
> Mit "delayMicroseconds(1);" sehe ich immer nur noch 3 Bit, aber nur beim
> Start.

Das macht keinen Sinn, der Takt sollte rausgehen.
Die "3,33 Hz" von oben sind auch seltsam, am Oszi "Auto" gedrückt und 
extrem weit rausgezoomt? :-)

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Andreas Hoffmann schrieb:
>> Mit "delayMicroseconds(1);" sehe ich immer nur noch 3 Bit, aber nur beim
>> Start.
>
> Das macht keinen Sinn, der Takt sollte rausgehen.
> Die "3,33 Hz" von oben sind auch seltsam, am Oszi "Auto" gedrückt und
> extrem weit rausgezoomt? :-)

Ja, jetzt hab ich das mal wieder ausprobiert. Hab eine Frequenz von 
1,667Hz...

von Rudolph (Gast)


Lesenswert?

Andreas Hoffmann schrieb:
> Hab eine Frequenz von
> 1,667Hz...

16MHz / 8 sind aber 2MHz.

void loop()
{
  SPI.transfer(0x55);
  delay(1);
}

Probier das mal.

von Sebastian W. (wangnick)


Lesenswert?

Andreas Hoffmann schrieb:
> Was meinst Du eingendlich mit "stabil"???

Na ja, der Sender ändert das Signal immer zum Zeitpunkt der einen Flanke 
von SCK, und der Empfänger liest das Signal immer zum Zeitpunkt der 
anderen Flanke, wenn das Signal stabil ist.

Das ist immer so. Wenn der Empfänger zum selben Zeitpunkt lesen würde, 
zu dem der Sender das Signal ändert (das Signal also nicht stabil ist), 
wäre ja unklar ob der Empfänger noch den vorherigen Signalwert, den 
neuen Signalwert, oder irgend etwas dazwischen lesen würde.

LG, Sebastian

: Bearbeitet durch User
von holger (Gast)


Lesenswert?

>>>Den SCK sehe ich auf dem Oszi
>>>auch nicht mehr. Nur einmal ganz kurz beim Start.
>>
>> Dann nimm statt 8 mal 10 für CS.
>
>Ist es aber nicht egal, wo mein CS angeschlossen ist?

Da hast du schon recht. Es ist aber nicht egal was mit dem
(Arduino) Pin10 = SS gemacht wird. Für SPI Master muss
das ein Ausgang sein. Deshalb kann man den immer
gleich als CS benutzen. Wenn der auf Eingang bleibt
und floatet kann das dazu führen das der Master
irgendwann einfach so auf Slave umgeschaltet wird.

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:
> Andreas Hoffmann schrieb:
>> Hab eine Frequenz von
>> 1,667Hz...
>
> 16MHz / 8 sind aber 2MHz.
>
> void loop()
> {
>   SPI.transfer(0x55);
>   delay(1);
> }
>
> Probier das mal.

Ich hab es ausprobiert aber es tut sich nicht...

von Andreas H. (andreas1993)


Lesenswert?

Sebastian Wangnick schrieb:
> Hallo Andreas,
>
> ich glaube so geht das nicht.
>
> Schau dir im Datenblatt mal "Figure 2. External Clock-Mode Conversion
> (Mode 0)" genau an. Danach wird DIN auf steigender SCLK-Flanke gesetzt
> und ist auf fallender Flanke stabil, DOUT aber wird auf fallender Flanke
> vom ADC gesetzt und ist auf steigender stabil. Dasselbe steht noch
> einmal genau so auf Seite 19: "Data is clocked into the device from DIN
> on the rising edge of SCLK, and data is clocked out of DOUT on the
> falling edge of SCLK.

Sebastian, ich hätte mal da eine Frage. Demnach würde der ADC den 
Modi(0) folgender weise interpretieren.

Für DIN: CPHA=0 und CPOL=0
Für DOUT: CPHA=1 und CPOL=1

CPHA=0: Daten werden mit der ersten Flanke des Taktsignals übernommen 
(HIGH)

CPOL=0: Ist der Takt im Ruhezustand auf LOW-Pegel, die erste Flanke ist 
eine steigende Flanke(HIGH)

CPHA=1: Daten werden bei fallender Taktflanke eingelesen, bei steigender 
ausgegeben

CPOL=1: Takt ist invertiert, ruhe HIGH, ein Wechsel auf LOW zählt als 
steigende Taktflanke

Hab ich das soweit richtig wieder gegeben?

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:

> Mode 0 darf nicht schneller als 3,67MHz sein.

Rudolph, wie kommst Du darauf, dass der Mode 0 nicht schneller als 
3,67MHz sein darf?

Ok, ich hab es gefunden im Datenblatt auf Seite 19! :-)

: Bearbeitet durch User
von Rudolph (Gast)


Lesenswert?

Aber warum funktioniert der SPI garnicht mehr?
setup() sieht aber bis auf das SPI_CLOCK_DIV8 aus wie vorher?

von Andreas H. (andreas1993)


Lesenswert?

Guten Tag,

ich hab es jetzt hin bekommen, ich sehe mein 4 Byte auf dem Oszilloskop.
Ich danke euch für die Teilnahme meines problems.

Die Freguenz läßt sich doch folgender weisse bestimmen.

f = 1/T    f=2Mhz

T = Persiode
f = Frequenz

Somit wäre eine Periode T = 1/f

T = 1/2Mhz
T = 0,5µs

Und ich hab die ganze Zeit in einem Bereich von 500ms statt 500ns 
gemessen!
Außerdem habe ich eine Information bekommen, dass ich bei meinem 
Oszilloskop den Modus im Menü auf Normal einstellen soll, es war vorher 
auf Auto.

Kann mir vielleicht jemanden sagen, was der Modus für ein Zweck hat?

Ich hab es mal getestet, sogar wenn ich die richtige Zeit einstelle, 
aber den Modus auf Auto lasse, dann sehe ich mein Clock wieder nicht.

: Bearbeitet durch User
von Rudolph (Gast)


Lesenswert?

Hust, war doch der erste Kommentar dazu, weit rausgezoomt und so. :-)
Klingt nach Auto-Setup.

Und das "Auto" was Du jetzt meinst bezieht sich wohl auf das triggern?
Da haben beide Einstellungen ihren Sinn, auf meinem Scope bleibt bei 
"Normal" ein einzelnes Ereignis auf dem Schirm stehen auf das getriggert 
wurde.
Bei "Auto" sieht man eher den aktuellen Verlauf.

Praktisch ist wenn man gleich so die Option hat z.B. auf SPI zu 
triggern. :-)

von Andreas H. (andreas1993)


Lesenswert?

Rudolph schrieb:

> Praktisch ist wenn man gleich so die Option hat z.B. auf SPI zu
> triggern. :-)

Hat das denn jeder Oszilloskop diese Option? Wenn ja, wo finde ich das? 
;)

von Rudolph (Gast)


Lesenswert?

Andreas Hoffmann schrieb:
> Hat das denn jeder Oszilloskop diese Option? Wenn ja, wo finde ich das?

Nein, jedes sicher nicht, bei SPI ist das auch unkritisch.
Einfach Chip-Select mit anschliessen und darauf triggern.

Bei dem Agilent hier gibt es im Trigger-Block eine Taste "More", da 
finden sich dann Optionen auf verschiedene Signal-Formen zu triggern.
Etwa TV, CAN, LIN, SPI, I2C und so.

von Cyblord -. (cyblord)


Lesenswert?

Für sowas ist auch ein USB-LA mit Protokoldecoder viel besser geeignet 
als jedes Scope und sei es noch so teuer. Wenn ich ne SPI Kommunikation 
untersuchen will, würde ich jederzeit meinen 100 EUR Saleae Logic 
Analyzer einem 25k LeCroy vorziehen.

gruß cyblord

von Andreas H. (andreas1993)


Lesenswert?

Hallo,

ich bekomme jetzt zwar mein Signal und bei 0V hab ich ein Wert von 
32175.
Dieser Wert ist auch richtig, wenn man auf die Seite 22 im Datenblatt 
(Figure 12) guckt.

Meine Frage wäre jetzt, in welchen Zustand ist mein ADC wenn ich nur den 
Conversion-Start Byte betrachte. Da in CH1 mein Signal kommt, ist mein 
Conversion-Star Byte 10010000 = 90. Also ist mein Befehl für den ersten 
Byte: "SPI.transfer(0x90);"!!!

Wenn ich im Datenblatt auf Seite 20 die Tabele 6 angucken, dann ist mein 
MODE: No Range Change. Also keine bereichs Änderung.
Aber in welchen Bereich ist er denn?

Laut Ergebnis und Datenblatt, müsse ja der Zustand (MODE) des ADC bei 
keiner Änderung "Ideal Bipolar Transfer Function, Single-Ended or 
Differential Input" sein (Seite 22, Figure 12) oder...?


Liebe Grüße
Andreas

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Andreas Hoffmann schrieb:

> Wenn ich im Datenblatt auf Seite 20 die Tabele 6 angucken, dann ist mein
> MODE: No Range Change. Also keine bereichs Änderung.
> Aber in welchen Bereich ist er denn?

In derselben Tabelle ist eine Zeile mit DEFAULT markiert.

Allerdings.
Wenn du dich heute fragst, welchen Modus du bei 0000 eingestellt hast 
(No Change), dann wirst du dich das in einem halben Jahr, wenn du den 
Code das nächste mal hgeraus kramst, wieder fragen.
D.h. an dieser Stelle wäre es vernünftig, im Programm einmalig eine 
geischerten Modus konkret einzustellen und das auch zu dokumentieren.

von Andreas H. (andreas1993)


Lesenswert?

Karl Heinz schrieb:

> In derselben Tabelle ist eine Zeile mit DEFAULT markiert.

Ok, super das habe ich mir auch gedacht. Also ist es richtig, dass wenn 
ich keine Änderung vornehme, dann ist mein MODE wie Figure 12 auf Seite 
22.

Wolltes nur nochmal bestätigit haben, weil ich keine Erfahrung damit 
habe.

Super echt cool, danke Dir...

lg
Andreas

von Andreas H. (andreas1993)


Lesenswert?

Karl Heinz schrieb:

> Allerdings.
> Wenn du dich heute fragst, welchen Modus du bei 0000 eingestellt hast
> (No Change), dann wirst du dich das in einem halben Jahr, wenn du den
> Code das nächste mal hgeraus kramst, wieder fragen.
> D.h. an dieser Stelle wäre es vernünftig, im Programm einmalig eine
> geischerten Modus konkret einzustellen und das auch zu dokumentieren.

Ja, stimmt hast Recht das werde ich gleich machen...! Danke für den Tip.

lg
Andreas

von Andreas H. (andreas1993)


Lesenswert?

Ich hab mich für das Verfahren wie auf Seite 22 Figure 14 entschieden. 
Somit habe ich auf Seite 20 Figure 14 mit "Single-Ended Unipolar 0V to 
+VREF
FSR = VREF" ausgewählt.

Da meine Vref 4,096 V beträgt und mein µC 5V zulässt, habe diese Methode 
gewählt.

Somit wäre doch mein Range-Select Bit: 0110 und da ich mit CH1 arbeite. 
Ist mein "Channel Selection in Single-Ended Mode": 001.

Das bedeutet doch, wenn ich mein Analog-Input Configuration Byte jetzt 
mit den Bit setzte, dann wäre dieser doch: 10010110 in Hex = 96.

"SPI.transfer(0x96);"

Da bekomme ich aber immer den Wert 0 zurück, egal ob ich die Spannung 
auf 2V lege oder 0V.

von Andreas H. (andreas1993)


Lesenswert?

Guten Abend,

ich hab es jetzt soweit hinbekommen, dass ich das Schema von Figure 14 
auf Seite 22 im Datenblatt anwenden kann.

Aber nur, wenn ich das Programm einmal mit SPI.transfer(0x96) und dann 
schließlich wieder auf SPI.transfer(0x90) umstelle.

Dann kann ich meine Werte von 0 (0V) bie 65533 (4,096V) sehen.

Aber eigentlich müsste ich doch mein Byte-Tranfer nur mir 
SPI.transfer(0x96) lass, weil mein Analog-Input Configuration Byte 
1(Start) 001(CH1) 0110(Verfahren für Single-Ended Unipolar 0V to + Vref 
FSR=Vref; S.20 Figure 14).
Somit wäre 10010110 = 96 in Hex, oder mach ich etwas falsch?

hier ist einmal mein Programm:

  digitalWrite(ss, LOW);
  SPI.transfer(0x90); // Hier muss ich erst 0x96 festlegen und dann das 
Programm einmal laufen lassen und dann auf 0x90 umstellen!!!
  SPI.transfer(0x00);
  adcValueMSB = SPI.transfer(0x00);
  adcValueLSB = SPI.transfer(0x00);

Danke!!!

: Bearbeitet durch User
von Andreas H. (andreas1993)


Lesenswert?

Hallo hab immer noch das Problem. Hat vielleicht jemand eine Idee???

Danke Andreas...

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.