Inhoudsopgave:

Dus je laadt STM32duino Bootloader in je "blauwe pil" Dus wat nu? - Ajarnpa
Dus je laadt STM32duino Bootloader in je "blauwe pil" Dus wat nu? - Ajarnpa

Video: Dus je laadt STM32duino Bootloader in je "blauwe pil" Dus wat nu? - Ajarnpa

Video: Dus je laadt STM32duino Bootloader in je
Video: ⚡️ Я НЕ СДАМСЯ! AMAZON 2.0 | Интернет магазин с нуля - Часть 3 2024, Juli-
Anonim
U laadt dus STM32duino Bootloader in uw
U laadt dus STM32duino Bootloader in uw
Dus je laadt STM32duino Bootloader in je
Dus je laadt STM32duino Bootloader in je

Als je mijn instructables al hebt gelezen waarin wordt uitgelegd hoe de STM32duino-bootloader of een andere soortgelijke documentatie wordt geladen, probeer dan een voorbeeld van een laadcode en … het kan zijn dat er helemaal niets gebeurt.

Het probleem is dat veel, zo niet alle voorbeelden voor "Generieke" STM32 niet direct zullen werken. Er zullen kleine wijzigingen nodig zijn om vervolgens werken in uw STM32 "Blue Pill"-bord te krijgen.

Ik zal 4 codevoorbeelden selecteren om uit te leggen wat er moet veranderen en waarom. Codes zijn: "BlinkWithoutDelay", "Fading", "Dimmer" en "AnalogInSerial".

Opmerking ik heb niets gecodeerd. Ik geef alleen kleine wijzigingen door in codes die zijn gemaakt door:

David A. Mellis en laat gewijzigd door Tom Igoe, Marti Bolivar en enkele gevallen door Scott Fitzgerald

Tom Igoe en laat gewijzigd door Bryan Newbold

Dus ik geef er de voorkeur aan de namen van de auteurs te behouden, zelfs in codes die ik wijzig, met behoud van de creatie-tegoed.

Stap 1: pinnen en pinnen … Waarom werkt code niet?

Pins en pins … Waarom werkt code niet?
Pins en pins … Waarom werkt code niet?

Laten we een kijkje nemen in de STM32 "Blue Pill" pin-out. Opmerking pinnen zijn te identificeren als PA1 of PC2 … zoiets.

Als u bijvoorbeeld kijkt in het codevoorbeeld "BlinkWithoutDelay", wordt pin gedeclareerd als "33"…Waarom?

Ik vermoed dat dat komt omdat Mr. Marti Bolivar deze code voor MAPLE board heeft geport.

Ik denk dat het niet zijn bedoeling was om code compatibel te maken met "Blue Pill"-borden.

Maple en Maple mini board pinnen zijn numeriek gedeclareerd, zoals Arduino, hoewel ze nummers gebruiken zoals 33, 24 en sommige zoals deze.

Ik zei dat de code niet werkte? Mijn fout. Code compileert zonder fouten en upload correct naar "Blue Pill", dus naar mijn mening werkt het inderdaad, maar met een GPIO-uitvoer verwachten we niet. Misschien niet eens beschikbaar.

Er zijn dus weinig wijzigingen in de code nodig om het te laten werken zoals verwacht.

Stap 2: Laten we enkele pinnen "definiëren"

Laten we
Laten we

Het is een goede codepraktijk om bronnen te declareren als gemakkelijk te identificeren of betekenisvolle variabelen of constanten. Hiermee kunt u code gemakkelijker begrijpen en oplossen.

Ik heb Arduino-pinnen als volgt gedeclareerd:

const int ledPin =13;

…"

Als je me leuk vindt, vraag je je misschien af: "Hoe kan ik pins declareren met namen als PC13???"

Het antwoord is: Gebruik "#define" C-statement.

Dus, volgens pinout draw, is PC13 de pin die we aan boord hebben LED in "BluePill". Om het te gebruiken, zou ik als volgt declareren, net na de definitie van bibliotheken (#include…) en voor alles:

#definieer LedPin PC13

…"

Let op: er is GEEN ";" lijnbeëindiging, NOR "=" toewijzing.

Vergelijk beide codes. Een daarvan is het originele voorbeeld geladen vanuit IDE. Ten tweede is degene die ik heb aangepast om met "BluePill" te werken.

Ik raad ten zeerste aan om alle pinnen die u van plan bent te gebruiken in code te declareren. Zelfs degenen die van plan zijn om als ADC-ingang te gebruiken (hierover later meer).

Dit zal uw leven gemakkelijk maken.

Stap 3: PinMode()…Hoe u uw pinnen gaat gebruiken…

Laten we, voordat we verder gaan, de functie PinMode() begrijpen.

Net als Arduino hebben STM32-pins meerdere functies. De eenvoudigste manier om de ene of de andere te selecteren, is door de instructie pinMode() te gebruiken.

Arduino heeft slechts 3 modi beschikbaar, INPUT, OUTPUT of INPUT_PULLUP.

STM32 heeft daarentegen veel smaken van pinMode(). Zij zijn:

UITGANG -Basis digitale uitgang: wanneer de pin HOOG is, wordt de spanning op +3,3 V (Vcc) gehouden en wanneer deze LAAG is, wordt deze naar de grond getrokken

OUTPUT_OPEN_DRAIN -In open drain-modus geeft de pin "laag" aan door de stroom naar aarde te accepteren en "hoog" door een verhoogde impedantie te bieden

INPUT_ANALOG -Dit is een speciale modus voor wanneer de pin wordt gebruikt voor analoge (niet digitale) uitlezingen. Maakt het mogelijk om ADC-conversie uit te voeren op de spanning op de pin

INPUT_PULLUP -De status van de pin in deze modus wordt op dezelfde manier gerapporteerd als bij INPUT, maar de pinspanning wordt voorzichtig "opgetrokken" richting +3,3v

INPUT_PULLDOWN -De status van de pin in deze modus wordt op dezelfde manier gerapporteerd als bij INPUT, maar de pinspanning wordt voorzichtig "naar beneden getrokken" richting 0v

INPUT_FLOATING - Synoniem voor INPUT

PWM -Dit is een speciale modus voor wanneer de pin wordt gebruikt voor PWM-uitvoer (een speciaal geval van digitale uitvoer)

PWM_OPEN_DRAIN -Net als PWM, behalve dat in plaats van afwisselende cycli van LAAG en HOOG, de spanning op de pin bestaat uit afwisselende cycli van LAAG en zwevend (losgekoppeld)

(opmerking: geëxtraheerd uit

Ik open gewoon dit haakje, want wanneer u begint met het maken van uw eigen code, moet u ervoor zorgen dat u de juiste pinMode() gebruikt voor uw behoefte.

Stap 4: AnalogWrite() versus PwmWrite()…Analoge uitvoer in 2 smaken

AnalogWrite() versus PwmWrite()…Analoge uitvoer in 2 smaken
AnalogWrite() versus PwmWrite()…Analoge uitvoer in 2 smaken
AnalogWrite() versus PwmWrite()…Analoge uitvoer in 2 smaken
AnalogWrite() versus PwmWrite()…Analoge uitvoer in 2 smaken

Voordat u "Blue Pill" GPIO-pinnen gebruikt, moet u het gedrag ervan aangeven, d.w.z. hoe het zal werken. Dat is precies wat de functie pinMode() doet.

Dus laten we ons nu concentreren op hoe correct een analoge uitgang is ingesteld. Het kan worden gedeclareerd als OUTPUT-modus of PWM-modus.

Op dezelfde manier kunnen analoge waarden op 2 manieren aan GPIO worden toegeschreven: analogWrite() of pwmWrite(), MAAR, analogWrite() ZAL alleen werken als pinMode()= OUTPUT. Aan de andere kant zal pwmWrite() alleen werken als pinMode()=PWM.

Laten we bijvoorbeeld PA0 nemen: het is een analoge/pwm-uitgangskandidaat.

analogWrit(): dit verklaart op deze manier:

….

#define ledPin PA0

pinMode (ledPin, UITGANG);

analogWrite(ledPin, <nummer>);

……"

waarbij het getal tussen 0 en 255 moet liggen, zoals bij Arduino. Eigenlijk is het achterwaarts compatibel met Arduino.

pwmWrite(): verklaar op deze manier:

#define ledPin PA0

pinMode (ledPin, PWM);

pwmWrite(ledPin, <nummer.>);

…."

Waar het nummer tussen 0 ~ 65535 moet liggen, een resolutie die veel hoger is dan die van Arduino.

In afbeeldingen is het mogelijk om 2 codes te vergelijken. U kunt ook de originele code zien.

Stap 5: STM32 seriële communicatie

STM32 seriële communicatie
STM32 seriële communicatie

Laten we eens kijken hoe de USART-interfaces in STM32 zijn gerangschikt. Ja, interfaces in het meervoud…..

"Blue Pill" heeft 3 USART's (RX/TX 1~3), en als je een bootloader gebruikt, kun je USB gebruiken, deze is op geen van beide aangesloten.

Afhankelijk van of u wel of geen USB gebruikt, moet u de seriële poort op een of andere manier in uw code aangeven.

Geval 1: USB gebruiken:

Op deze manier worden schetsen direct gedownload via USB. Het is niet nodig om de BOOT0-jumper naar positie 1 en terug naar 0 te verplaatsen.

In dit geval betekent elke keer dat u "Serial" zonder index aangeeft, communicatie via USB.

Serial1 betekent dus TX/RX 1 (pinnen PA9 en PA10); Serial2, betekent TX/RX 2 (pinnen PA2 en PA3) en Serial 3 betekent TX/RX 3 (pinnen PA10 en PA11).

Dit is de manier waarop we werken. Ik zal wijzigingen in voorbeelden voor deze manier van coderen presenteren.

Nog iets: "Seriële USB" hoeft niet te worden geïnitialiseerd. Met andere woorden, "…Serial.begin(15200);" Is niet nodig.

Het is mogelijk om elke seriële functie (Serial.read(), Serial.write(), etc) aan te roepen zonder enige initialisatie.

Als het om de een of andere reden in de code aanwezig is, zal de compiler het negeren.

Geval 2: TTL seria-naar-USB-adapter gebruiken:

Op deze manier ondersteunt de bootloader geen native STM32 USB-communicatie, dus je hebt een USB-naar-serieel-adapter nodig die is aangesloten op TX/RX 1 (pin PA9 en PA10) om schetsen te uploaden.

In dit geval betekent elke keer dat "Serial" zonder index code is, TX/RX1 (poort die wordt gebruikt om de code te uploaden). Serial1 verwijst dus naar TX/RX 2 (pinnen PA2 en PA3) en Serial2 verwijst naar TX/RX 3 (pinnen PA10 en PA11). Geen Serial3 beschikbaar.

Stap 6: een waarde doorgeven aan microcontroller

Een waarde doorgeven aan microcontroller
Een waarde doorgeven aan microcontroller

Een voorbeeld van een dimmer is een eenvoudige manier om te laten zien hoe een waarde aan de microcontroller wordt doorgegeven.

Het veronderstelt een waarde van 0 tot 255 door te geven om de LED-helderheid te regelen.

Het zal NIET werken zoals verwacht in Blue Pill vanwege:

  1. Om de pwmWrite()-functie te gebruiken, MOET pinMode() worden gedeclareerd als PWM-modus.
  2. U krijgt nooit een geheel getal van 3 cijfers. De functie Serial.read() legt alleen bufferinhoud vast, wat een "BYTE" is. als u "100" typt en op "enter" drukt, wordt alleen de laatste "0" uit de buffer vastgelegd. En de waarde ervan is "48" (decimale ASCII-waarde voor "0"). Als u de waarde "100" wilt uitgeven, moet u "d" typen. Het is dus correct om te zeggen dat het een ASCII-symbool decimale waarde in LED-helderheid zal converteren, toch??…. Nou, een soort van…
  3. Probleem, kaartwaarden rechtstreeks vanuit de functie Serial.read() toewijzen is een truc. Het is vrijwel zeker dat u onverwachte waarden krijgt. Een betere benadering is de inhoud van de opslagbuffer in een tijdelijke variabele en DAN in kaart brengen.

Zoals ik eerder in item 2 uitleg, zal code die ik wijzigingen inbreng het mogelijk maken om een ASCII-symbool in te voeren en dit zal de LED-helderheid regelen op basis van de ASCII-decimaalwaarde … bijvoorbeeld, "spatie" is waarde 32 (in feite is dit het laagste afdrukbare teken dat u kunt invoeren) en "}" is mogelijk de hoogste (waarde 126). Andere tekens kunnen niet worden afgedrukt, dus de terminal zal het niet begrijpen of ze zijn mogelijk een samengesteld teken (zoals "~" is een dode toets op mijn toetsenbord en zal niet correct werken). Dit betekent dat dit samengestelde teken, wanneer het in de terminal wordt ingevoerd, het teken zelf en iets anders zal verzenden. Meestal een niet-afdrukbare. En is deze laatste code zal vastleggen. Houd er ook rekening mee dat uw terminal in dit geval GEEN "Carriage Return" of "Line Feed" mag verzenden. Je moet hier op letten om de code correct te laten werken.

Als je viel, is het een beetje verwarrend, het wordt het ergste …

Stap 7: En als ik drie cijfers wil typen…. of nog meer??

En als ik drie cijfers zou willen typen… of nog meer??
En als ik drie cijfers zou willen typen… of nog meer??

Meerdere tekens ontvangen van een seriële communicatie is geen eenvoudige taak.

Seriële buffer is een FIFO-bytestapel met tekens. Elke keer dat de functie Serial.read() wordt aangeroepen, wordt het eerste verzonden teken van de stapel verwijderd en ergens anders opgeslagen. Meestal een char-variabele in code. Let op, afhankelijk van de hardware is er meestal een time-out voor hoe de logbuffer informatie kan bewaren.

Als u van plan bent meer dan één cijfer via serienummer in te voeren, moet u een tekenreeks teken voor teken "componeren", aangezien ze in de UART-buffer komen.

Dit betekent dat fietsen elke buffer-char moet lezen, opslaan in een tijdelijke variabele, het in de eerste positie van een stringarray laden, naar de volgende positie gaan en opnieuw beginnen, totdat … nou ja, afhankelijk van de toepassing. Er zijn 2 manieren om de cyclus te beëindigen:

  1. Een "eindteken"-teken gebruiken, zoals "carriage Return" of "Line Feed". Zodra "end Mark" char is gevonden, eindigt de lus.
  2. Als alternatief kan het aantal karakters in de stringketen worden beperkt, evenals het aantal interactieve cycli. Wanneer het de limiet bereikt, laten we zeggen, 4, verkrijgt u zelf routine-afwerkingen.

Laten we eens kijken in een eenvoudig voorbeeld hoe dit te doen:

  • Stel een "end" char in, zoals '\n' (dit betekent line feed ASCII char).
  • looping ondertussen Serial.available() is waar
  • het opslaan van Serial.read() resulteert in een tijdelijke char-variabele. Onthoud: zodra Serial.read() de buffer daadwerkelijk "leest", is deze schoon en wordt het volgende teken erin geladen.
  • verhoog een stringvariabele met dit teken
  • Als de laatste char "end" is, verlaat u de lus.

Gewoonlijk ziet de routine voor het ophalen van een serieel tekenarray eruit als een afbeelding.

Het was gebaseerd op een uitgebreide aanpassing van de originele code van de heer David A. Mellis.

Voel je vrij om het te gebruiken en te testen. Onthoud: waarden MOETEN worden ingevoerd in een formaat van 3 cijfers.

Dit is het voor nu. Ik zal mezelf niet uitbreiden in aanvullende seriële communicatiedetails. Het is te complex om hier te behandelen en het verdient zijn eigen Intructables.

Ik hoop dat het je helpt om voorbeelden in Blue Pill te gebruiken en je wat verlichting geeft hoe de juiste code voor dit bordje is.

Zie je rond in andere instructable.

Aanbevolen: