Hallo Zusammen Hat jemand Erfahrungen mit dem Temp.Sensor ADT7310 ? Ich habe da probleme diesen via SPI schnittstelle zuverlässig zu programmieren ! Mit der Keil Entwicklungsumgebung (Debugging) bringe ich das Teil zwar ab und zu zum laufen. sobald ich aber den Chip alleine ohne Debugging laufen lasse funktioniert es nicht mehr ! Komischer weise geht es ab und zu auch ohne debugger, aber nur wenn ich den /CS in abhängigkeit von TXE und RXNE auf High schalte, was aber nicht den timing spezifikationnen des ADT7310 entspricht !!!!! Schalte ich den /CS genau nach timing spez. funktioniert das Teil ohne Debugger gar nie !!!! Was mache ich da blos falsch ?? Code: void DTS_readData (int8_t dtsRegisterAddress) { // Description : This function read ADT7310 Data. // Input : none // // Output : none int16_t DigitalTempDataReg16bit; // SET Chipselect ADC nSS to low IO_CLR_PIN(TSens_SPI2_GPIO, TSens_SPI2_nSS_PIN); SPI_I2S_SendData(SPI2, 0x00); while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) { } // SET Chipselect ADC nSS to High IO_SET_PIN(TSens_SPI2_GPIO, TSens_SPI2_nSS_PIN); DigitalTempDataReg16bit = SPI_I2S_ReceiveData(SPI2); Temperatur_Case = (float)DigitalTempDataReg16bit/128; } // End DTS_readData () void DTS_writeData (int8_t dtsRegisterAddress) { // Description : This function write command to ADT7310. // Input : none // // Output : none uint8_t TxCounter; SPI_InitTypeDef SPI_InitStructure; // Disable SPI SPI_Cmd(SPI2, DISABLE); // DeInit SPI SPI_I2S_DeInit(SPI2); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // Full Duplex SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Controller is SPI Master, ADC is slave SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 16 Bit Data communication SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // accept Databit at positive clock edge SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // accept Data at first clock edge SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // manual chip select set SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //(64MHz/2) /16 = 2MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // Start with MSB as first databit SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC Polynomial // Disable CRC calculation in hardware. SPI_Init(SPI2, &SPI_InitStructure); // initialise SPI with above settings SPI_CalculateCRC(SPI2, DISABLE); // no CRC is need -> disable CRC SPI_Cmd(SPI2, ENABLE); // Enable SPI2. TxCounter = 0; // SET Chipselect ADC nSS to low IO_CLR_PIN(TSens_SPI2_GPIO, TSens_SPI2_nSS_PIN); SPI_I2S_SendData(SPI2, dtsRegisterAddress); mg_u8TempSensorTxBuffer[TxCounter++] = dtsRegisterAddress; // Wait until end of transmit while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET) { } for (delay = 0; delay < 4; delay++); delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; delay = 0; // SET Chipselect ADT7310 nSS to High IO_SET_PIN(TSens_SPI2_GPIO, TSens_SPI2_nSS_PIN); for (delay = 0; delay < 16; delay++); // Disable SPI SPI_Cmd(SPI2, DISABLE); // DeInit SPI SPI_I2S_DeInit(SPI2); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // Full Duplex SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Controller is SPI Master, ADC is slave SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; // 16 Bit Data communication SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // accept Databit at positive clock edge SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // accept Data at first clock edge SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // manual chip select set SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //(64MHz/2) /8 = 4MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // Start with MSB as first databit SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC Polynomial // Disable CRC calculation in hardware. SPI_Init(SPI2, &SPI_InitStructure); // initialise SPI with above settings SPI_CalculateCRC(SPI2, DISABLE); // no CRC is need -> disable CRC SPI_Cmd(SPI2, ENABLE); // Enable SPI2. } // End DTS_writeData ()
Hi Roger, hab grad mal kurz drüber geschaut, also nicht alles im Code gelesen, aber wenn ich Dein Bild richtig interpretiere geht Dein CS zu früh auf "1". Versuch mal ein Delay auf dem CS, so dass CS deutlich nach der letzten Flanke clk auf eins geht. Ich denke wenn Du zu früh CS wegnimmst funtioniert das ganze nicht, wobei ein zu langer CS erstmal nicht schadet, kannst dann ja ausprobieren, wie viel Delay noch funktioniert. Außerdem brauchten wir teilweise einen pull up auf MISO, könnte helfen. Gruß Bjoern
Hallo Bjoern Vielen Dank für Deine Antwort ! Ich bin froh um jeden Hinweis. Trotz geballter engineering-Wissen in meiner Bude konnte mir bis jetzt noch keiner weiterhelfen. Es ist aber auch verrückt ! Genau mit dem von Dir angesprochenen unzulässiger Vorgang auf welcher der /CS zu früh auf High geschaltet wird bringt den Chip zum laufen (aber nicht zuverlässig). Wenn Du Dir auf dem PDF-File den Versuch 2 (Die nächsten 3 Plots) anschaust kannst Du sehen, dass hier der /CS korrekt erst nach dem letzten Clock hochgezogen wird. Und das ist ja genau das unverständliche in diesem Zustand bring ich das Teil nicht mal mehr zufällig zum laufen !! Aber das mit dem hinweis Pull-up auf MISO werde ich mal verfolgen. Gruss Roger
Pull up auf MISO hat leider auch nichts gebracht ! Gruss Roger
Ich meine aber einen wirklich externen 10k Ohm Widerstand an 3V, keinen programmierten auf dem STM32.
uint16 SPI2_SendWord(uint16 word) { /* Loop while DR register in not emplty */ GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET); //Reset CS while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) { } /* Send a Byte through the SPI peripheral */ SPI_I2S_SendData(SPI2, word); /* Wait to receive a Byte */ while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) { } Delay(0x0F); GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET); //Reset CS /* Return the Byte read from the SPI bus */ return (uint16)SPI_I2S_ReceiveData(SPI2); } void Delay(__IO uint32_t nCount) { while(nCount--) { } } So ist es bei uns, vielleicht hilfts ja irgendwie. Gruß Bjoern
>// Wait until end of transmit >while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET) >{ >} Auch hier solltest du auf RXNE warten, nicht auf TXE. TXE sagt nur das das Transmit Register beschreibbar ist. Es sagt nicht das der letzte Transfer beendet wurde.
bjoern schrieb: > Ich meine aber einen wirklich externen 10k Ohm Widerstand an 3V, keinen > programmierten auf dem STM32. Ich hab das auch so verstanden. Habe einen 11k Ohm zu 3.3V angeschlossen Aber eben hatte kein Wirkung. MISO geht zwar jetzt schneller auf High bei /CS to High.
Schreib doch mal das Kommunikationsregister und lies es dann zurück. Dann solltest du schon sehen ob Du z.B. bitweise verschoben interpretiert wirst. Ob Du die Bits in der richtigen Reihenfolge rausschiebst wirst Du nur auf dem Oszi sehen können. Die Mühe nachzuzählen hab ich mir jetzt nicht gemacht. Viel Erfolg Hauspapa
holger schrieb: >>// Wait until end of transmit >>while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET) >>{ >>} > > Auch hier solltest du auf RXNE warten, nicht auf TXE. > TXE sagt nur das das Transmit Register beschreibbar ist. > Es sagt nicht das der letzte Transfer beendet wurde. Danke mach ich auch mittlerweile. Aber immer noch ohne Erfolg Gruss Roger
Hab mal den Code ein wenig gereinigt und gemäss Angaben von Björn angepasst. Nütz Leider auch nichts void DTS_readData (int8_t dtsRegisterAddress) { // Description : This function read 16bit data register from ADT7310 // Input : none // // Output : none int16_t DigitalTempDataReg16bit; IO_CLR_PIN(TSens_SPI2_GPIO, TSens_SPI2_nSS_PIN); // SET Chipselect ADC nSS to low // send 16 clocks to SPI SPI_I2S_SendData(SPI2, 0x00); delay = 0; // read 16 bit data register ADT7310 while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) { if (delay < 150000) { delay++; } else { break; } } IO_SET_PIN(TSens_SPI2_GPIO, TSens_SPI2_nSS_PIN); // SET Chipselect ADC nSS to High DigitalTempDataReg16bit = SPI_I2S_ReceiveData(SPI2); Temperatur_Case = (float)DigitalTempDataReg16bit/128; } // End DTS_readData () void DTS_writeData (int8_t dtsRegisterAddress) { // Description : This function write command byte to ADT7310 // Input : dtsRegisterAddress // // Output : none uint8_t TxCounter; SPI_InitTypeDef SPI_InitStructure; // Set SPI Data Size to 8b // Disable SPI SPI_Cmd(SPI2, DISABLE); // DeInit SPI SPI_I2S_DeInit(SPI2); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // Full Duplex SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Controller is SPI Master, ADC is slave SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 16 Bit Data communication SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // accept Databit at positive clock edge SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // accept Data at first clock edge SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // manual chip select set SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //(64MHz/2) /8 = 4MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // Start with MSB as first databit SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC Polynomial // Disable CRC calculation in hardware. SPI_Init(SPI2, &SPI_InitStructure); // initialise SPI with above settings SPI_CalculateCRC(SPI2, DISABLE); // no CRC is need -> disable CRC SPI_Cmd(SPI2, ENABLE); // Enable SPI2. // for (delay = 0; delay < 23000; delay++); TxCounter = 0; IO_CLR_PIN(TSens_SPI2_GPIO, TSens_SPI2_nSS_PIN); // SET Chipselect ADC nSS to low // SPI_I2S_SendData(SPI2, dtsRegisterAddress); // Loop while DR register in not emplty while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) { } // Send a Byte (0x054) through the SPI peripheral SPI_I2S_SendData(SPI2, dtsRegisterAddress); while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) { } // for (delay = 0; delay < 4; delay++); IO_SET_PIN(TSens_SPI2_GPIO, TSens_SPI2_nSS_PIN); // SET Chipselect ADT7310 nSS to High for (delay = 0; delay < 1200; delay++); // Set SPI Data Size to 16b // Disable SPI SPI_Cmd(SPI2, DISABLE); // DeInit SPI SPI_I2S_DeInit(SPI2); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // Full Duplex SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Controller is SPI Master, ADC is slave SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; // 16 Bit Data communication SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // accept Databit at positive clock edge SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // accept Data at first clock edge SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // manual chip select set SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //(64MHz/2) /8 = 4MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // Start with MSB as first databit SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC Polynomial // Disable CRC calculation in hardware. SPI_Init(SPI2, &SPI_InitStructure); // initialise SPI with above settings SPI_CalculateCRC(SPI2, DISABLE); // no CRC is need -> disable CRC SPI_Cmd(SPI2, ENABLE); // Enable SPI2. mg_u8TempSensorTxBuffer[TxCounter++] = dtsRegisterAddress; } // End DTS_writeData ()
Das read Data funktioniert ja einwandfrei wenn ich den Chip mal in den cont.read mode bringe. Aber das schreiben der commandos (0x54 und 0x50) geht nicht. Wie habt Ihr den die SPI schnittstelle configuriert ? Oder habe ich etwa ein problem wenn ich diese für das senden des commando auf 8b (sende 1 Byte) und dann wieder zurück auf 16b (lesen 2Byte) jeweils umstelle ?? Gruss Roger
Hier noch einen Plott nach der Anpassung des Code gemäss bjoern Die Pegel stimmen es wird genau eine 0x54 gesendet gemäss diagramm vom Datenblatt Ich verstehe nicht was da noch falsch sein soll ? Gruss Roger
Du weisst ziemlich sicher das nach senden von 0x54 der Chip nicht macht was du möchtest. Status auslesen sagt Dir was er glaubt was er machen soll. Hauspapa
Was mich im Datenblatt, Page 4, irritiert: Alle Timingdiagramme zeigen Rising Edge als aktive Flanke, auch die Setup/Hold-Zeiten beziehen sich auf die steigende Flanke. Nur die Fußnote 3 sagt, dass die aktive Flanke die fallende Flanke ist. Gibt's dazu eine Erklärung? Ich würde das nochmal checken, bzw. Hirn aus und probeweise die aktive Flanke umkonfigurieren.
Page 12 zeigt contineous read mit CS dauerhat low. Evtl. musst Du nach jedem CS die Übertragung neu starten. Das macht auch Sinn wenn Du eben etwas anderes auslesen willst als die Temperatur. Allerdings ist unter diesem Gesichtspunt der entsprechende Absatz auf S. 20 missverständlich. viel Erfolg Hauspapa
Hauspapa schrieb: > Schreibfehler: Nach jedem Wechsel von CS. > > Hauspapa Also Du meinst nach jedem wechsel von CS vorab wieder ein commando (0x54) senden oder aber CS auf Low belassen und dann jeweils durch wiederholung von 16 clocks packete den 16 bit Temp. Wert auslesen ? Hab mich bis jetzt nach Seite 20 Orientiert Danke Gruss Roger
Ja, so hab ich Seite 12 verstanden. Einfach ausprobieren. Viel Erfolg Hauspapa
Hi Roger, in Deinem SPI init schreibst Du: SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; Ich nehme jetzt mal an, das das die 2te Flanke bedeuten soll, wäre wohl die negative Flanke, versuchs doch mal mit SPI_CPHA_1Edge. Gruß Bjoern
Hallo Zusammen Komme erst jetzt wieder dazu mich der Sache anzunehmen. Ich hatte gestern noch versucht dass ganze umzukrempeln und nach dem command Byte (0x54) /CS Low zu belassen um dann mit senden von zwei Bytes (0x00,0x00) die 16 clocks zum einlesen des Datenregister zu Erzeugen (gemäss Seite 20). Leider bis jetzt ohne Erfolg ! Gruss Roger PS: Das Teil bringt mich noch ins Grab !?!?!
bjoern schrieb: > Hi Roger, > > in Deinem SPI init schreibst Du: > > SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; > > Ich nehme jetzt mal an, das das die 2te Flanke bedeuten soll, wäre wohl > die negative Flanke, versuchs doch mal mit SPI_CPHA_1Edge. > > Gruß Bjoern Hallo Bjoern Hab das mal kurz ausprobiert. Ohne Erfolg ! Aber SPI_CPHA_2Edge erachte ich als korrekt da SPI_CPOL_High gesetzt ist. Bei SPI_CPOL_High muss ich ja SPI_CPHA_ auf 2Edge stellen damit auf die erste positive Flanke ein Bit gelesen werden kann ! ansonsten fällt die erste positiv Flanke ja genau auf die Flanke des Datenbits ? Siehe Plot
Hallo Bjoern Ihr scheint ja den ADT7310 mit einem STM32 zum laufen gebracht zu haben. Wie habt Ihr den die SPI Schnittstelle eingestellt ? Und wie liest Ihr das Temp Register ? Mein Ansatzt war: Zuerst ADT7310 in den cont. read mode setzten: Schnittstelle auf 8bit setzten und das 0x54 Byte senden. Schnittstelle wieder auf 16bit setzten. Auslesen der Daten: Durch senden von 0x0000 die 16bit clock erzeugen um den 16 bit Datenwert einlesen zu können. Gruss Roger
Hallo Leute Endlich Endlich es funzt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Analog Device hat mir folgendes geschrieben: 1. Power-up ADT7310 and reset the serial interface (load 32 consecutive 1s on DIN). This ensures all internal circuitry is properly initialized. Nach dem ich dies implementiert hatte, funktioniert es nun einwandfrei!! Blöd nur das dies nicht so explizit im Datenblatt steht! Es steht da nur man kann den Chip resetieren in dem man ......bla bla. Es sollte stehen man muss den Chip beim power-up unbedingt als erstes resetieren !!!! Nun was sollst hauptsache das Teil läuft jetzt. Vielen herzlichen dank an alle welche sich die Mühe gemacht hatten mir zu antworten ! Gruss Roger
Hab noch in der zwischenzeit von Analog Device folgende Antwort bekommen: I will update the datasheet to make the serial reset requirement clearer in future. Hmm hattet Ihr keine probleme mit diesem Chip ? Oder war dies für Euch klar das man den Chip nach power-on zuerst reseten muss ? Gruss Roger
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.