Forum: Mikrocontroller und Digitale Elektronik AD9833(DDS) - STM32 - Programmierung mittels HAL_SPI-Treiber


von Sebastian B. (sebastian_b837)


Angehängte Dateien:

Lesenswert?

Guten Abend,

ich habe die letzten Tage fast alle zum Thema passende Foreneinträge 
durchgelesen, leider ohne Erfolg. Deshalb wollte ich mein Problem 
nochmals direkt schildern. Ich bin auch noch relativ unerfahren auf dem 
Gebiet der yC-Programmierung, also seid bitte nachsichtig, wenn ich 
offensichtliche Sachen falsch gemacht habe.

Ich versuche seit einigen Tagen mittels STM32 (L476RG) den DDS AD9833 
über SPI anzusprechen, um ein Sinussignal zu generieren. Dies sollte 
theoretisch (Datenblatt AD9833) nach folgendem Muster ablaufen:
STM sendet via SPI 5 16-Bit lange Befehle in Folge. Ein Word für einen 
allgemeinen Reset zu Beginn, dann 3 Words mit Informationen zur 
gewünschten Frequenz und Phasenlage und zum Schluss einen Ausgabebefehl 
mit der gewünschten Signalform,...

Das ganze über 3 GPIO-Pins mittels Bit Banging realisiert funktioniert 
auch problemlos. Ich kann die 5 Befehle aus dem Programming Manual 
(https://www.analog.com/media/en/technical-documentation/application-notes/AN-1070.pdf) 
auf Seite 3 problemlos senden und erhalte auch den geforderten 400 Hz 
Sinus.

Jetzt möchte ich jedoch das Teil statt über meiner simplen 
GPIO-Ansteuerung mittels der HAL-SPI-Treiber ansteuern, um das ganze 
etwas professioneller zu machen (Habe auch ein paar Delays zum Timing 
bei der Bit Banging Methodik verwendet, welche ich so eigentlich simpel 
los werden wollte).
Mein Problem wie bei einigen anderen im Forum ist jedoch, dass der 
AD9833 gar nicht bis rein zufällig auf die ihm übertragenen Daten 
reagiert, was ich mir persönlich nicht erklären kann. Meist erzeugt er 
trotz Übertragung der Befehlsfolge gar keinen Output, manchmal völlig 
andere Frequenzen oder sogar andere Signalformen (wie als ob ein Bit 
verrutscht wäre).

Im Anhang habe ich 2 Oszi-Screenshots. 1x die Chip-Select Leitung, 
welche die 16 Bits umrahmt, 1x die gesendeten Datenbits des 
1.Reset-Befehls (0010 0001 0000 0000) (0x2100). Die Serial Clock ist in 
beiden Bildern in rot dargestellt.
Die Amplituden sind gleich groß, habe zur Übersichtlichkeit CH1 nur 
vergrößert dargestellt.

Aus dem Datenblatt 
(https://www.analog.com/media/en/technical-documentation/data-sheets/AD9833.pdf) 
konnte ich folgende Anforderungen an die Kommunikation übernehmen (S4, S 
20,S 13FF):
- Zwischen Befehlen soll die SCLK auf High, auch bevor die CS-Leitung 
auf High geschaltet wird
- Datenaufnahme bei fallenden Flanken der SCLK
- nicht mehr als 16 fallende Flanken zwischen dem CS-Rahmen
- Allgemeine Timing-Informationen wie minimale High und Low-Zeiten (ca 
10ns)

Meiner Meinung nach erfüllen meine ausgegebenen Bitwörter (Screenshot) 
jedoch alle Bedingungen korrekt. Trotzdem streikt die Kommunikation. 
Kann jemand einen Fehler erkennen? Hat vielleicht schon mal jemand in 
dieser Konstellation mit dem AD9833 gearbeitet? Vielen Dank für eure 
Hilfe.

Weiter noch mein Code, welcher die Übertragung generieren soll:
1
static void MX_SPI1_Init(void)
2
{
3
  /* SPI1 parameter configuration*/
4
  hspi1.Instance = SPI1;
5
  hspi1.Init.Mode = SPI_MODE_MASTER;
6
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
7
  hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
8
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
9
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
10
  hspi1.Init.NSS = SPI_NSS_SOFT;
11
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
12
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
13
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
14
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
15
  hspi1.Init.CRCPolynomial = 7;
16
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
17
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
18
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
19
  {
20
    Error_Handler();
21
  }
22
  /* USER CODE BEGIN SPI1_Init 2 */
23
24
  /* USER CODE END SPI1_Init 2 */
25
26
}
27
28
//Simple Übertragung der 5 Befehle aus dem Programming Manual (in Hex)
29
  
30
uint16_t data[1];
31
32
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
33
    data[0] = 0x2100;
34
    HAL_SPI_Transmit(&hspi1, (uint8_t*)data, 1, 100);
35
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
36
37
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
38
    data[0] = 0x50C7;
39
    HAL_SPI_Transmit(&hspi1, (uint8_t*)data, 1, 100);
40
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
41
42
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
43
    data[0] = 0x4000;
44
    HAL_SPI_Transmit(&hspi1, (uint8_t*)data, 1, 100);
45
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
46
47
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
48
    data[0] = 0xC000;
49
    HAL_SPI_Transmit(&hspi1, (uint8_t*)data, 1, 100);
50
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
51
52
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
53
    data[0] = 0x2000;
54
    HAL_SPI_Transmit(&hspi1, (uint8_t*)data, 1, 100);
55
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);

Ich weiß die Übertragung ist nicht schön gelöst, aber wollte erst mal 
generell so meinen IC zum laufen bekommen.

Vielen Dank für alle Hilfen und Sorry für die längere Erklärung!

von TK (Gast)


Lesenswert?

Hallo,
wenn Du per Bitbanging eine Kommunikation hin bekommst, die auch 
funktioniert, dann mach mal davon Oszi Aufnahmen und vergleiche die dann 
mal mit denen, die per HAL Ansteuerung rauskommen - ich nehme mal an, 
dass dort ein Unterschied zu sehen sein wird.

(Kann man die Zeitachse auf den Ausdrucken nicht irgendwie normieren - 
also 10us(25us)(50us)/DIV oder so?)

Und auch einmal groß reinzoomen in nur eine Taktperiode um die Zeiten 
zwischen CLK und DAT Versatz zu sehen.

Gruß
TK

von Andrea Trevisan (Gast)


Angehängte Dateien:

Lesenswert?

Il file allegato è frutto anche del suo articolo.
Grazie

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.