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!