Forum: Mikrocontroller und Digitale Elektronik STM32 Probleme mit einem GPIO Pin und SPI NOR-FLASH


von Felix N. (felix_n888)



Lesenswert?

Guten Morgen,

In meinen neuen Projekt setzte ich ein STM32F103C8T6 als Mikrocontroller 
ein. Den Chip habe ich von einem Nulceo-446RE Board runter 
gelötet(Programmierteil).

Im Moment überprüfe ich alle Funktionen der Platine bevor ich das 
eigentlich Programm schreibe. Dabei macht mir ein GPIO Pin und das SPI 
FLASH Probleme.

Bei dem GPIO Pin handelt es sich um den Pin PB4. Ich kann diesen einfach 
nicht als Ausgang konfigurieren. In meinem Fall übernimmt PB4 die Chip 
Select Funktion des SPI FLASHs. Ich habe ihn folgendermaßen versucht als 
Ausgang zu konfigurieren:
1
//Flash CS PB4 50 MHz
2
GPIOB->CRL |= GPIO_CRL_MODE4;
3
GPIOB->CRL &= ~GPIO_CRL_CNF4;
4
GPIOB->BSRR |= GPIO_BSRR_BS4;  //CS HIGH

Aber auch wenn ich das BR4 Bit setzte wird der Pin nicht auf Low 
gezogen. Und ja die Clock für GPIOB ist aktiv da dort zB. der I2C1 Bus 
mit drauf ist und der ohne Probleme fürs EEPROM funktioniert.

Ich muss sagen ich kenne mich mit dem STM32 Debugger noch nicht wirklich 
aus. Ist es möglich den Debugger so einzustellen das mir die Bits von 
MODE4 und CNF4 im GPIOB->CRL Register angezeigt werden? So das ich sehen 
kann welcher Codeabschnitt diesen Teil evtl. ändert?

Den alle anderen I/Os die ich so initialisiere funktionieren auf Anhieb 
auch bei GPIOB. Nur dieser eine nicht.

Desweitern habe ich noch ein SPI NOR-FLASH Baustein auf der Platine. 
Dieser hängt am SPI1 Bus des Mikrocontroller zusammen mit einer 
SD-Karte. Die SD-Karte mit der elm-chan FATFs Lib funktioniert am SPI1 
problemlos. Also sind die Pins und der Bus richtig konfiguriert.

Bei dem Flash Baustein handelt es sich um ein AT25XE321D 
32Mbit(https://www.mouser.de/ProductDetail/Dialog-Semiconductor/AT25XE321D-SSHN-B?qs=IS%252B4QmGtzzoO02k6rtHgBw%3D%3D)

Schaltbild wie ich diesen angeschlossen und auch wie die SD-Karte mit 
dranhängt habe ich angehängt. Ich wollte für den Anfang nur erstmal die 
Manf. ID und Device ID vom FLASH auslesen also noch nix schreiben oder 
anderes lesen.

Doch das Problem bleibt das der FLASH keine Daten auf MISO ausgibt. Man 
könnt ja jetzt denken ok oben habe ich geschrieben das PB4 welcher FLASH 
CS ist nicht funktioniert dann ist ja klar das dass FLASH keine Daten 
raus gibt wenn es nicht selektiert wird.

Ich habe aber den Code mittels der ST Graphischen Oberfläche erzeugen 
lassen und da funktioniert der Pin sehr wohl(siehe Bild vom 
LogicAnalyzer).

Laut Datenblatt soll man den Befehl(0x90) als erstes schicken dann 
folgen 3 Dummy Bytes als Adressbytes. Und danach sollen die Daten am SO 
pin(MISO) anliegen wofür aber noch weitere 16 Clocks vom Master nötig 
sind. Aber die Daten kommen nicht aus dem SO Pin raus. Hab jetzt auch 
nix im Datenblatt gefunden das man den FLASH Baustein erst enablen oder 
aufwecken muss, bevor man lesen & schreiben kann.

Habe auch schonmal testweise den Chip gegen ein neuen getauscht aber 
auch das hat nix gebracht.

Hat jemand ne Idee woran das liegt bzw. was ich falsch gemacht habe?

Mfg

von Bauform B. (bauformb)


Angehängte Dateien:

Lesenswert?

PB4 ist nach Reset erstmal JNTRST. Damit man den als GPIO nutzen kann, 
muss man JTAG abschalten. Vielleicht geht das einfach mit den SWJ_CFG 
Bits im AFIO_MAPR? Vielleicht geht's beim F103 auch ganz anders. Warum 
ist gerade der komplizierteste STM32 der beliebteste?

von Felix N. (felix_n888)


Lesenswert?

Bauform B. schrieb:
> PB4 ist nach Reset erstmal JNTRST

Hallo,

Ach so. Ich dachte man müsste wenn man JTAG verwenden möchte das extra 
einschalten. Nun gut. Ich habe ich AFIO->MAPR die SWJ_CFG Bits so 
gesetzt das JTAG abgeschaltet ist aber SWD weiterhin erstmal aktiv 
bleibt.

Nun funktioniert der Pin PB4 auch so wie er soll danke dafür schon mal!

Mit dem FLASH Baustein mache ich auch fortschritte. Zumindestens kommen 
da jetzt mal Daten raus aber eine Sache verstehe ich noch nicht ganz.

Laut Datenblatt des SPI FLASH muss um die Device ID auszulesen der 
Befehl 0x90 gesendet werden und darauf sollen 3 Dummy Adressbytes 
folgen. Danach werden dann die Daten rausschoben. Zu mindestens habe ich 
das so erstmal verstanden also sieht mein Code dafür wie folgt aus:
1
GPIOB->BSRR |= GPIO_BSRR_BR4;  //FLASH CS LOW
2
writeSPI(SPIP1, 0x90);      //Send command first 0x90
3
writeSPI(SPIP1, 0x00);      //First dummy address byte
4
writeSPI(SPIP1, 0x00);      //Second dummy address byte
5
writeSPI(SPIP1, 0x00);      //Third dummy address byte
6
writeSPI(SPIP1, 0x00);      //???
7
uint8_t l = readSPI(SPIP1);    //Read Manufacturer ID. Should return 0x1F
8
uint8_t h = readSPI(SPIP1);    //Read Device ID. Should return 0x47
9
GPIOB->BSRR |= GPIO_BSRR_BS4;  //FLASH CS HIGH

Ich habe dort eine Zeile kommentiert mit drei ? "???". Wenn ich nur drei 
Dummybytes sende wie es das Datenblatt vorsieht das bekomme ich beim 
ersten readSPI für l ein Wert von 0xFF und beim zweiten readSPI für h 
ein Wert von 0x1F. Sende ich ein viertes Dummybyte bekomme ich beim 
ersten read 0x1F und beim zweiten 0x47 so wie es sein soll.

Woran könnte das liegen? Hier sind meine SPI write und read Funktionen

writeSPI:
1
void writeSPI(SPI_PERIPHERAL spi, uint8_t data) {
2
  SPI_TypeDef *spiUnit = SPI1;    //SPI1 by default selected
3
  if(spi == SPIP2) spiUnit = SPI2;  //Switch to SPI2 if requested
4
5
  while((spiUnit->SR & SPI_SR_BSY));  //Wait until SPI Bus is not longer busy
6
  spiUnit->DR = data;          //Load data into shift register
7
  while(!(spiUnit->SR & SPI_SR_TXE));  //Wait until data has been transmitted
8
  (void)spiUnit->DR;          //Discharge received byte
9
10
}

readSPI:
1
uint8_t readSPI(SPI_PERIPHERAL spi) {
2
  SPI_TypeDef *spiUnit = SPI1;         //SPI1 by default selected
3
  if(spi == SPIP2) spiUnit = SPI2;    //Switch to SPI2 if requested
4
5
  while((spiUnit->SR & SPI_SR_BSY));    //Wait until SPI Bus is not longer busy
6
  spiUnit->DR = 0;      //Send a dummy byte
7
  while(!(spiUnit->SR & SPI_SR_RXNE));  //Wait until data has been loaded in the RX buffer
8
  return spiUnit->DR;            //Load data from rx buffer and return it
9
}

Muss ich daran noch was ändern damit es passt?

Mfg

von Stefan F. (Gast)


Lesenswert?

Felix N. schrieb:
> Ich dachte man müsste wenn man JTAG verwenden möchte das extra
> einschalten.

In Cube MX wird das irreführend dargestellt. Warum dort sowohl JTAG als 
auch SWD Standardmäßig deaktiviert werden, obwohl beide eigentlich 
standardmäßig (nach Reset) aktiv sind, ist mir ein Rätsel.

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.