Hur nollställer man en STM32?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Hur nollställer man en STM32?

Inlägg av Al_Bundy »

Jag håller på att få en utgång att blinka med STM32. Här använder jag inte mig av någon CubeMX32 eller något annat. Jag tänkte använda register för att styra hela epikaget.

Jag har en STM32F401RE på ett Nucleo-kort och jag ska få D13 att blinka. Det är en LED där.
Bild

Jag börjar med att plocka fram databladet

Där efter söker jag på RCC AHB1 peripheral clock enable register (RCC_AHB1ENR, där jag ska sätta GPIOA register aktiv.

Kod: Markera allt

RCC->AHB1ENR |= (1<<0);
Nu söker jag på att sätta vilken inställning D13 ska ha på GPIOA. I detta fall vill jag att D13 ska vara OUTPUT. Då hittar jag GPIO port mode register (GPIOx_MODER) (x = A..E and H)

Kod: Markera allt

GPIOA->MODER |= (0<<27) | (1<<26);
Nu vill jag tända och släcka LED. Då söker jag efter GPIO port bit set/reset register (GPIOx_BSRR) (x = A..E and H)

Kod: Markera allt

GPIOA->BSRRH |= (1<<13); // Tänd
GPIOA->BSRRL |= (1<<29); // Släck
Men då har jag ett litet problem. Det fungerar utmärkt att bränna in koden, tills jag glömde | i denna kod

Kod: Markera allt

GPIOA->BSRRH = (1<<13); // Tänd
GPIOA->BSRRL = (1<<29); // Släck
Jag brände in koden och sedan fick STM32 något fnatt och jag "loggades" ut från den. Jahapp, tänkte jag. Nu får jag bara detta meddelande när jag försöker bränna in kod

Kod: Markera allt

STMicroelectronics ST-LINK GDB server. Version 5.1.0
Copyright (c) 2018, STMicroelectronics. All rights reserved.

Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 1
        Listen Port Number         : 61234
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled

Target no device found

Error in initializing ST-LINK device.
Reason: No device found on target.
Datorn känner utav min ST-Link och annars verkar det inte vara något problem. Men finns det något sätt att nollställa min uC?
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur nollställer man en STM32?

Inlägg av Mr Andersson »

nucleo-pinout.png
Ändra koden så du inte pillar på SWD-pinnarna. (läs databladet och kolla vad PA13 gör)
Bygla BOOT0 till VDD.
Flasha om.
Ta bort bygling.

Notera att arduinos D13 är PA5.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur nollställer man en STM32?

Inlägg av Al_Bundy »

Hej! Det är PA5 jag håller på att blinka med, dvs D13 i bilden ovan i post #1.

Jag testade bygla VDD till BOOT0 och bränna över ett helt tomt projekt.

Kod: Markera allt

STMicroelectronics ST-LINK GDB server. Version 5.1.0
Copyright (c) 2018, STMicroelectronics. All rights reserved.

Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 1
        Listen Port Number         : 61234
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled

Waiting for debugger connection...
Debugger connected
      -------------------------------------------------------------------
                        STM32CubeProgrammer v1.3.0                  
      -------------------------------------------------------------------



Log output file:   /tmp/STM32CubeProgrammer_XhufaR.log
ST-LINK SN  : 066EFF363732594D43183143
ST-LINK FW  : V2J32M22
Voltage     : 3.25V
SWD freq    : 4000 KHz
Connect mode: Under Reset
Reset mode  : Hardware reset
Device ID   : 0x433
Device name : STM32F401xD/E
Device type : MCU
Device CPU  : Cortex-M4



Memory Programming ...
Opening and parsing file: /
  File          : /
  Size          : 4804 Bytes
  Address       : 0x08000000 


Erasing memory corresponding to segment 0:
Erasing internal memory sector 0
Download in Progress:


File download complete
Time elapsed during download operation: 00:00:00.655



Verifying ...




Download verified successfully 


Debugger connection lost.
Shutting down...
:) Tack! Nu fungerar den igen.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur nollställer man en STM32?

Inlägg av Al_Bundy »

Nu testade jag bränna över min kod och noterade felmeddelandet.

Jag följde en person på Youtube som visade hur man ska styra GPIO pinnarna. Han hade dock en annan IDE och annan uC, men jag tänkte att det ska inte vara någon skillnad. Bara andra nummer.


Skillnaden mellan hans kod och min kod är att jag använder RCC->AHB1ENR och han använder RCC->APB2ENR. Alltså skillnaden var H mot P.
Sedan använder han

Kod: Markera allt

GPIOC->CHR
när jag använder GPIOA->MODER. Hans LED är på GPIOC, medan min är på GPIOA. Men skillnaden här var CHR mot MODER.
Sista skillnaden är att jag använder GPIOA->BSRRH och GPIOA->BSRRL när han använder endast GPIOC->BSRR.

Orsaken varför jag valde MODER istället för CHR har med att det fanns inte CHR i mitt datablad. Vart tror ni jag har gjort fel någonstans?
Notera att detta är absolut första gången jag programmerar med register. Jag är oftast van att hålla på med HAL-lager.

Kod: Markera allt

#include "stm32f4xx.h"

int main(void)
{


  // Init the clock for GPIO A
  RCC->AHB1ENR |= (1<<0);

  // Config the D13 on GPIOA
  GPIOA->MODER |= (0<<27) | (1<<26);

  /* Infinite loop */
  while (1)
  {

	for(int i = 0; i < 5000000; i++)
		GPIOA->BSRRH |= (1<<13);
	for(int i = 0; i < 5000000; i++)
		GPIOA->BSRRL |= (1<<29);
	for(int i = 0; i < 5000000; i++)
		GPIOA->BSRRH = (1<<13);
	for(int i = 0; i < 5000000; i++)
		GPIOA->BSRRL |= (1<<29);

  }
}

Kod: Markera allt

STMicroelectronics ST-LINK GDB server. Version 5.1.0
Copyright (c) 2018, STMicroelectronics. All rights reserved.

Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 1
        Listen Port Number         : 61234
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled

Waiting for debugger connection...
Debugger connected
      -------------------------------------------------------------------
                        STM32CubeProgrammer v1.3.0                  
      -------------------------------------------------------------------



Log output file:   /tmp/STM32CubeProgrammer_WuG3mu.log
ST-LINK SN  : 066EFF363732594D43183143
ST-LINK FW  : V2J32M22
Voltage     : 3.25V
SWD freq    : 4000 KHz
Connect mode: Under Reset
Reset mode  : Hardware reset
Device ID   : 0x433
Device name : STM32F401xD/E
Device type : MCU
Device CPU  : Cortex-M4



Memory Programming ...
Opening and parsing file: /
  File          : /
  Size          : 1260 Bytes
  Address       : 0x08000000 


Erasing memory corresponding to segment 0:
Erasing internal memory sector 0
Download in Progress:


File download complete
Time elapsed during download operation: 00:00:00.613



Verifying ...




Download verified successfully 


Error in executing 'cont' command ... 
CM4 Failed to read all registers
FAILED to REGISTER Values from the target
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
Target is not responding, retrying...
Debugger connection lost.
Shutting down...
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur nollställer man en STM32?

Inlägg av Mr Andersson »

Al_Bundy skrev:Hej! Det är PA5 jag håller på att blinka med, dvs D13 i bilden ovan i post #1.
Nej det är PA13.
Al_Bundy skrev:

Kod: Markera allt

GPIOA->MODER |= (0<<27) | (1<<26);
stm32f4_reg_MODER.png
Men nu vet du iaf hur man startar bootloadern. :) Det är i princip omöjligt att bricka en STM32.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Nerre
Inlägg: 26705
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Hur nollställer man en STM32?

Inlägg av Nerre »

Alltså...

Kod: Markera allt

GPIOA->MODER |= (0<<27) | (1<<26);
Hur är det tänkt att fungera? Det där (0<<27) fyller ju ingen funktion, en bit som OR:as med noll behåller sitt värde.

OR kan man använda för att ett-ställa en bit, men för att nollställa så måste man köra AND med inversen (d.v.s. & ~(0<<27) eller nåt sånt)
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur nollställer man en STM32?

Inlägg av Mr Andersson »

Dina BSRR är också fel.
stm32_reg_BSRR.png
Jag har strukit över bit 31-16 för STs SDK delar upp registret i två 16-bits fält, så använd bit 0-15 för bägge pseudo-registren.

För att sätta pinne 5 hög GPIOx->BSRRH = (1<<5);
För att sätta pinne 5 låg GPIOx->BSRRL = (1<<5);

Använd =, inte |=. Registret är write-only så det finns ingen gammal data att läsa tillbaka.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur nollställer man en STM32?

Inlägg av Al_Bundy »

Okej. Nu testar jag. Ger återkoppling snart!
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur nollställer man en STM32?

Inlägg av Al_Bundy »

Mr Andersson skrev:Dina BSRR är också fel.
stm32_reg_BSRR.png
Jag har strukit över bit 31-16 för STs SDK delar upp registret i två 16-bits fält, så använd bit 0-15 för bägge pseudo-registren.

För att sätta pinne 5 hög GPIOx->BSRRH = (1<<5);
För att sätta pinne 5 låg GPIOx->BSRRL = (1<<5);

Använd =, inte |=. Registret är write-only så det finns ingen gammal data att läsa tillbaka.
Jag har inga BSRR i min kod. Mitt datablad skrev BSRR, men min IDE ville visa BSRRL och BSRRH :)
Nerre skrev:Alltså...

Kod: Markera allt

GPIOA->MODER |= (0<<27) | (1<<26);
Hur är det tänkt att fungera? Det där (0<<27) fyller ju ingen funktion, en bit som OR:as med noll behåller sitt värde.

OR kan man använda för att ett-ställa en bit, men för att nollställa så måste man köra AND med inversen (d.v.s. & ~(0<<27) eller nåt sånt)
Tittar man på databladet så för att beskriva en utgång så måste man sätta 01, alltså är 0<<27 också 0. Jag bara skrev ut den bara för att följa databladet :)
Mr Andersson skrev:
Al_Bundy skrev:Hej! Det är PA5 jag håller på att blinka med, dvs D13 i bilden ovan i post #1.
Nej det är PA13.
Al_Bundy skrev:

Kod: Markera allt

GPIOA->MODER |= (0<<27) | (1<<26);
stm32f4_reg_MODER.png
Men nu vet du iaf hur man startar bootloadern. :) Det är i princip omöjligt att bricka en STM32.
Okej. Då vet man det! Tackar! Trodde 13 var utgången, men det kanske var PA5 man skulle kolla på, dvs 5:an.

Nu blinkar det för mig :)

Kod: Markera allt

#include "stm32f4xx.h"

int main(void)
{


  // Init the clock for GPIO A
  RCC->AHB1ENR |= (1<<0);

  // Config the D13 on GPIOA
  GPIOA->MODER |= (0<<11) | (1<<10);

  /* Infinite loop */
  while (1)
  {

   for(int i = 0; i < 5000000; i++)
      GPIOA->BSRRH = (1<<5);
   for(int i = 0; i < 5000000; i++)
      GPIOA->BSRRL = (1<<5);
   for(int i = 0; i < 5000000; i++)
      GPIOA->BSRRH = (1<<5);
   for(int i = 0; i < 5000000; i++)
      GPIOA->BSRRL = (1<<5);

  }
}
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur nollställer man en STM32?

Inlägg av Al_Bundy »

Nyfiken fråga? Hur vem man vilken bitoperatör man skall använda sig av? ^=, |=, = osv

Vi kan ta detta exempel. Pull-up och pull-down register. Jag vill ha en pull-down på min ADC, av ren säkerhet. Då är det 0x02 som jag måste använda för att få binärt 10.

Om jag vill skriva till PUPDR2[1:0] så måste jag väll skriva en kod som lyder:

Kod: Markera allt

GPIOx->PUPDR |= (0x02 << 4);
Alltså jag flyttar binärt 10 till 100000.

Nu är |= av en ren gissning.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Nerre
Inlägg: 26705
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Hur nollställer man en STM32?

Inlägg av Nerre »

Att skriva A |= B är samma sak som att skriva A = A | B och fungerar (som Mr Andersson säger) bara om A kan läsas.

Om det är ett register som enbart kan skrivas så måste man skriva ALLA BITAR varje gång.

Om du bara skriver med 0x02 << 4 så kommer du bara sätta en bit, alla andra bitar kommer att skrivas med noll.

Du måste alltså konfigurera allting i samma skrivning (om det inte går att läsa ut registret).
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur nollställer man en STM32?

Inlägg av Al_Bundy »

Det förklarar blinkningen.

>> Om det är ett register som enbart kan skrivas så måste man skriva ALLA BITAR varje gång.

Hur vet man om man kan endast skriva eller läsa till registret? Självklart står det i databladet. Men i vilken avdelning?

>> Om du bara skriver med 0x02 << 4 så kommer du bara sätta en bit, alla andra bitar kommer att skrivas med noll.

Japp. Bara en bit, vilket jag också vill att det ska bli :) Då sätter jag pull-down på PUPDR2.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur nollställer man en STM32?

Inlägg av Mr Andersson »

Nyfiken fråga? Hur vem man vilken bitoperatör man skall använda sig av? ^=, |=, = osv
Det beror ju helt på vad du ska göra.
a = b skriver över hela registret med valfritt värde.
a |= b sätter alla bitar som är 1 i b till 1 i a. 0:or i b ger ingen ändring i a. Kan inte ändra 1 till 0.
a &= b sätter alla bitar som är 0 i b till 0 i a. 1:or i b ger ingen ändring i a. Kan inte ändra 0 till 1.
a ^= b inverterar alla bitar i a som är 1 i b. 0:or i b ger ingen ändring i a.
Hur vet man om man kan endast skriva eller läsa till registret? Självklart står det i databladet. Men i vilken avdelning?
I registerbeskrivningarna finns det en rad med r och/eller w.
Användarvisningsbild
AndLi
Inlägg: 17127
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: Hur nollställer man en STM32?

Inlägg av AndLi »

Al_Bundy skrev:

Kod: Markera allt

GPIOx->PUPDR |= (0x02 << 4);
Det där kommer bara funka om värdet på bitarna du försöker skriva till är 0x00 eller 0x02. Du påverkar alltså bara en bit inte två som du önskar...

Så det är ingen universallösning...
Nerre
Inlägg: 26705
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Hur nollställer man en STM32?

Inlägg av Nerre »

Al_Bundy skrev: Japp. Bara en bit, vilket jag också vill att det ska bli :) Då sätter jag pull-down på PUPDR2.
Ja, om du vill att alla andra bitar ska vara noll så är det ok. Men om du vill sätta flera pull-down så måste du alltså sätta alla vid samma skrivning, annars kommer bara den sista du skriver att "ta", eftersom du skriver både ettor och nollor varje gång. Så om du bara skriver en etta så skriver du resten med nollor.

Det man normalt gör är att man "bygger upp" en variabel med det värde man vill ha och sen skriver den till registret.

Börja med att sätta variabeln till noll.
Använd sen =| för att ettställa alla de bitar som ska vara ett.
Sen skriver du variabeln till registret.
Skriv svar