- De hardware gereed maken
- Inzicht in GPIO-pinouts op STM8S103F
- Pinoutbeschrijving en tips voor STM8S103F GPIO-selectie
- STM8S programmeren voor GPIO-invoer en uitvoer met behulp van SPL
- Het programma uploaden en testen
Voor microcontrollers is een knipperend LED-programma gelijk aan het programma "hallo wereld". In onze vorige tutorial hebben we geleerd hoe we aan de slag kunnen gaan met STM8S103F3 Development Board en hoe we de IDE en compiler kunnen instellen om onze STM8S-controllers te programmeren. We hebben ook geleerd hoe we de standaard perifere bibliotheken kunnen gebruiken en hoe we de code kunnen compileren en uploaden naar onze microcontroller. Nu alle basisbeginselen zijn behandeld, kunnen we beginnen met het schrijven van code. In deze zelfstudie leren we hoe we algemene GPIO-functies op STM8S-controllers kunnen uitvoeren. Het bord heeft al een ingebouwde LED aangesloten op pin 5 van poort B, we zullen leren hoe deze LED te knipperen en ook een externe LED toevoegen en deze met een drukknop bedienen. Als je helemaal nieuw bent, wordt het ten zeerste aanbevolen om de vorige tutorial te lezen voordat je verder gaat.
De hardware gereed maken
Voordat we in het programma duiken, moeten we de hardwareverbindingen gereed maken. Zoals eerder vermeld, zullen we hier twee LED's gebruiken, de ene is een ingebouwde LED die continu zal knipperen en de andere is een externe LED die wordt omgeschakeld met een drukknop. Het idee is om alle GPIO-functionaliteit te leren in een eenvoudige set-up. De on-board Led is al aangesloten op PB5 (pin5 van PORTB), dus ik heb zojuist een LED aangesloten op PA3 en een drukknop op PA2, zoals je kunt zien in het onderstaande schema.
Maar, van alle outputpinnen die beschikbaar zijn op onze gecontroleerde, waarom heb ik PA3 als output en PA2 als input geselecteerd? De vragen zijn geldig en dat zal ik later in dit artikel uitleggen. Mijn hardware-instellingen voor deze tutorial worden hieronder weergegeven. Zoals je kunt zien, heb ik mijn ST-link-programmeur ook aangesloten op programmeerpennen die niet alleen ons bord programmeren, maar ook als stroombron fungeren.
Inzicht in GPIO-pinouts op STM8S103F
Nu terugkomend op de vraag, waarom PA2 voor input en waarom PA3 voor output? Om dat te begrijpen, laten we de pin-out van de microcontroller, die hieronder wordt weergegeven, eens nader bekijken.
Volgens het pinout-diagram hebben we vier poorten op onze microcontroller, namelijk POORT A, B, C en D aangegeven door respectievelijk PA, PB, PC en PD. Elke GPIO-pin is ook voorzien van een andere speciale functionaliteit. De PB5 (pin 5 van PORT B) kan bijvoorbeeld niet alleen werken als GPIO-pin, maar ook als SDA-pin voor I2C-communicatie en als Timer 1-uitgangspin. Dus als we deze pin gebruiken voor eenvoudige GPIO-doeleinden, zoals het aansluiten van een LED, dan kunnen we I2C en de LED niet tegelijkertijd gebruiken. Helaas is de ingebouwde LED op deze pin aangesloten, dus we hebben hier niet veel keus, en in dit programma gaan we I2C niet gebruiken, dus het is niet echt een probleem.
Pinoutbeschrijving en tips voor STM8S103F GPIO-selectie
Echt, het zou geen kwaad om PA1 een input pin te gebruiken en het zou gewoon pin werken. Maar ik heb dit opzettelijk naar voren gebracht om me de kans te geven je enkele veelvoorkomende valstrikken te laten zien waar je in zou kunnen vallen bij het selecteren van GPIO-pinnen op een nieuwe microcontroller. Het beste om de valstrikken te vermijden, is door de pin-details en pin-beschrijving te lezen in het STM8S103F3P6-gegevensblad. Voor de STM8S103F3P6 microcontroller pin beschrijving details die worden vermeld in de datasheet worden getoond onder afbeeldingen.
De invoerpennen op onze microcontroller kunnen zwevend of zwak opgetrokken zijn en de uitvoerpennen kunnen Open Drain of Push-pull zijn. Het verschil tussen Open Drain en Push-Pull Output-pinnen is al besproken, daarom zullen we daar niet op in detail treden. Om het simpel te zeggen, een Open Drain output pin kan de output alleen zo laag en niet zo hoog maken, terwijl een push-pull output pin de output zowel hoog als hoog kan maken.
Afgezien van dat van de bovenstaande tabel, kunt u ook opmerken dat een outputpin ofwel snelle output (10 Mhz) of langzame output (2 MHz) kan zijn. Dit bepaalt de GPIO-snelheid, als je je GPIO-pinnen heel snel tussen hoog en laag wilt schakelen, dan kunnen we kiezen voor Snelle uitvoer.
Sommige GPIO-pinnen op onze controller ondersteunen True Open Drain (T) en High Sink Current (HS), zoals vermeld in de bovenstaande afbeelding. Een aanzienlijk verschil tussen Open Drain en True Open Drain is dat de output die is aangesloten op de open drain niet hoger kan worden getrokken dan de bedrijfsspanning van de microcontroller (Vdd), terwijl een echte open drain-outputpen hoger kan worden getrokken dan Vdd. Pinnen met High Sink-mogelijkheid betekent dat er meer stroom kan zinken. De source- en sink-stroom van elke GPIO HS-pin is 20 mA, terwijl de voedingslijn tot 100 mA kan verbruiken.
Als u de bovenstaande afbeelding van dichterbij bekijkt, zult u zien dat bijna alle GPIO-pinnen van het type High Sink Current (HS) zijn, behalve PB4 en PB5, die True Open Drain Type (T) zijn. Dit betekent dat deze pinnen niet hoog kunnen worden gemaakt, ze zullen geen 3,3 V kunnen leveren, zelfs niet als de pin hoog is gemaakt. Dit is de reden waarom de ingebouwde led is aangesloten op een 3.3V en geaard via PB5 in plaats van deze rechtstreeks vanaf de GPIO-pin te voeden.
Raadpleeg pagina 28 op het gegevensblad voor de gedetailleerde pinbeschrijving. Zoals vermeld in de bovenstaande afbeelding, wordt PA1 automatisch geconfigureerd als een zwakke pull-up en wordt het niet aanbevolen om als outputpin te worden gebruikt. Het kan in elk geval worden gebruikt als een invoerpin samen met een drukknop, maar ik besloot PA2 te gebruiken om te proberen pull-up vanuit het programma mogelijk te maken. Dit zijn slechts een paar basiszaken die handig zullen zijn als we veel gecompliceerdere programma's schrijven. Voorlopig is het oké als veel dingen van je hoofd stuiteren, we zullen er in andere tutorials op ingaan.
STM8S programmeren voor GPIO-invoer en uitvoer met behulp van SPL
Maak een werkruimte en een nieuw project zoals we in onze eerste tutorial hebben besproken. U kunt alle header- en bronbestanden toevoegen of alleen de gpio-, config- en stm8s-bestanden. Open het main.c- bestand en begin met het schrijven van uw programma.
Zorg ervoor dat u de header-bestanden hebt toegevoegd zoals weergegeven in de bovenstaande afbeelding. Open het main.c- bestand en start de code. De volledige main.c-code vindt u onderaan deze pagina en u kunt vanaf daar ook het projectbestand downloaden. De uitleg van de code is als volgt, je kunt ook de SPL-gebruikershandleiding of de video die onderaan deze pagina is gelinkt raadplegen als je niet zeker weet wat het coderingsgedeelte is.
De-initialisatie van de vereiste poort
We beginnen ons programma met de-initialisatie van de vereiste poorten. Zoals we eerder hebben besproken, heeft elke GPIO-pin vele andere bijbehorende functies dan alleen werken als een normale invoer en uitvoer. Als deze pinnen eerder voor sommige andere toepassingen zijn gebruikt, moet deze worden gedeïnitialiseerd voordat we ze gebruiken. Het is echter niet verplicht, het is een goede gewoonte. De volgende twee regels code worden gebruikt om poort A en poort B de-initialiseren. Gebruik gewoon de syntaxis GPIO_DeInit (GPIOx); en vermeld de poortnaam in plaats van x.
GPIO_DeInit (GPIOA); // bereid poort A voor op werkende GPIO_DeInit (GPIOB); // bereid poort B voor om te werken
GPIO-verklaring voor invoer en uitvoer
Vervolgens moeten we aangeven welke pinnen zullen worden gebruikt als invoer en welke als uitvoer. In ons geval wordt pin PA2 als input gebruikt, we zullen deze pin ook declareren met interne pull-up zodat we er geen extern hoeven te gebruiken. De syntaxis is GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Waar x de poortnaam is, y de pincode en z de GPIO-pin-modus.
// Verklaar PA2 als input pull-up pin GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
Vervolgens moeten we de pinnen PA3 en PB5 als uitvoer declareren. Opnieuw zijn er vele soorten output-declaratie mogelijk, maar we zullen “GPIO_MODE_OUT_PP_LOW_SLOW” gebruiken, wat betekent dat we het zullen declareren als een outputpin van het push-pull type met lage snelheid. En standaard is de waarde laag. De syntaxis is hetzelfde.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Verklaar PB5 als push-pull Output pin GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
De onderstaande momentopname van de SPL-gebruikershandleiding vermeldt alle mogelijke GPIO-modi (z).
Oneindige while-lus
Na de pin-declaratie moeten we een oneindige lus creëren waarin we de LED voor altijd blijven knipperen en de status van de drukknop controleren om de LED in of uit te schakelen. De oneindige lus kan worden gemaakt met een while (1) of met een for (;;) . Hier heb ik while (1) gebruikt.
terwijl (1) {}
De status van de invoerpin controleren
We moeten de status van de invoerpin controleren, de syntaxis om dat te doen is GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); waarbij x de poortnaam is en y de pincode. Als de pin hoog is, krijgen we '1' en als de pin laag is, krijgen we een '0'. We hebben gewend aan een if-lus om te controleren of de pin hoog of laag is.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // if knop ingedrukt
Een GPIO-pin hoog of laag maken
Om een GPIO-pin hoog of laag te maken, kunnen we GPIO_WriteHigh (GPIOx, GPIO_PIN_y) gebruiken; en GPIO_WriteLow (GPIOx, GPIO_PIN_y); respectievelijk. Hier hebben we ervoor gezorgd dat de LED gaat branden als de knop wordt ingedrukt en uitgaat als de knop niet wordt ingedrukt.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // if knop ingedrukt GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED AAN anders GPIO_WriteHigh (GPIOA, GPIO_PIN_3); //LED UIT
Omschakelen van een GPIO-pin
Om een GPIO-pin om te schakelen, hebben we GPIO_WriteReverse (GPIOx, GPIO_PIN_y); Door deze functie aan te roepen, verandert de status van de outputpin. Als de pin hoog is, wordt deze gewijzigd in laag en als deze laag is, wordt deze gewijzigd in hoog. We gebruiken deze functie om de ingebouwde LED op PB5 te laten knipperen.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Vertragingsfunctie
In tegenstelling tot Arduino heeft de kosmische compiler geen vooraf gedefinieerde vertragingsfunctie. Dus we moeten er zelf een maken. Mijn vertragingsfunctie wordt hieronder gegeven. De waarde doe de vertraging zal worden ontvangen in de variabele ms en we zullen twee gebruiken voor lus om vast te houden of programma-uitvoering. Net als _asm ("nop") is een montage-instructie die staat voor geen bewerking. Dit betekent dat de controller in de for-lus zal lussen zonder enige bewerking uit te voeren, waardoor er een vertraging ontstaat.
ongeldige vertraging (int ms) // Functie Definitie {int i = 0; int j = 0; for (i = 0; i <= ms; i ++) {for (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Voer geen bewerking uit // montagecode}}
Het programma uploaden en testen
Nu ons programma klaar is, kunnen we het uploaden en testen. Eenmaal geüpload, werkte mijn hardware zoals verwacht. De ingebouwde rode LED knipperde elke 500 milliseconden en de externe groene LED ging aan elke keer dat ik op de schakelaar drukte.
De volledige werking is te vinden in de onderstaande video. Zodra u dit punt heeft bereikt, kunt u proberen de schakelaar en LED op verschillende pinnen aan te sluiten en de code opnieuw te schrijven om het concept te begrijpen. Je kunt ook spelen met de vertragingstijd om te controleren of je de concepten goed hebt begrepen.
Als u vragen heeft, laat deze dan achter in de commentaarsectie hieronder en voor andere technische vragen kunt u onze forums gebruiken. Bedankt voor het volgen, tot ziens in de volgende tutorial.