- Gjør maskinvaren klar
- Forstå GPIO Pinouts på STM8S103F
- Pinout-beskrivelse og tips for STM8S103F GPIO-valg
- Programmering STM8S for GPIO Input og Output ved hjelp av SPL
- Laste opp og teste programmet
For mikrokontrollere tilsvarer et LED-blinkende program programmet “hei verden”. I vår forrige opplæring lærte vi hvordan vi kommer i gang med STM8S103F3 Development Board og hvordan vi setter opp IDE og kompilator for å programmere STM8S-kontrollerne. Vi har også lært hvordan vi bruker standard perifere biblioteker, og hvordan vi kan kompilere og laste opp koden til mikrokontrolleren vår. Med alt det grunnleggende dekket, kan vi faktisk begynne å skrive kode. I denne opplæringen vil vi lære å utføre generelle GPIO-funksjoner på STM8S-kontrollere. Styret har allerede en innebygd LED koblet til pin 5 i port B, vi vil lære å blinke denne LED og også legge til en ekstern LED og kontrollere den med en trykknapp. Hvis du er helt ny, anbefales det sterkt å lese den forrige opplæringen før du fortsetter videre.
Gjør maskinvaren klar
Før vi dykker inn i programmet, la maskinvaretilkoblingene være klare. Som nevnt tidlig, vil vi bruke to lysdioder her, den ene er en innebygd LED som vil blinke kontinuerlig og den andre er en ekstern LED som vil veksles med en trykknapp. Ideen er å lære all GPIO-funksjonaliteten i et enkelt oppsett. Den innebygde LED-en er allerede koblet til PB5 (pin5 av PORTB), så jeg har nettopp koblet en LED til PA3 og en trykknapp til PA2, som du kan se i diagrammet nedenfor.
Men av alle utgangspinnene som er tilgjengelige på vår kontrollerte, hvorfor valgte jeg PA3 for utgang og PA2 for inngang? Spørsmålene er gyldige, og jeg vil forklare det senere i denne artikkelen. Min maskinvareoppsett for denne opplæringen er vist nedenfor. Som du kan se, har jeg også koblet min ST-link programmerer til programmeringspinner som ikke bare vil programmere kortet vårt, men også fungere som en strømkilde.
Forstå GPIO Pinouts på STM8S103F
Nå kommer vi tilbake til spørsmålet, hvorfor PA2 for inngang og hvorfor PA3 for utgang? For å forstå det, la oss se nærmere på pinout av mikrokontrolleren som er vist nedenfor.
I henhold til pinout-diagrammet har vi fire porter på mikrokontrolleren vår, nemlig PORT A, B, C og D betegnet med henholdsvis PA, PB, PC og PD. Hver GPIO-pin er også kledd med noen andre spesielle funksjoner. For eksempel kan PB5 (pin 5 i PORT B) ikke bare fungere som en GPIO-pin, men også som en SDA-pin for I2C-kommunikasjon og som en Timer 1-utgangsstift. Så hvis vi bruker denne pinnen til enkle GPIO-formål som å koble til en LED, vil vi ikke kunne bruke I2C og LED samtidig. Dessverre er den innebygde LED-en koblet til denne stiften, så vi har ikke så mye valg her, og i dette programmet skal vi ikke bruke I2C, så det er ikke mye av et problem.
Pinout-beskrivelse og tips for STM8S103F GPIO-valg
Sannelig, det ville ikke skade å bruke PA1 en inngangspinne, og det ville bare fungere. Men jeg tok bevisst dette opp for å gi meg en mulighet til å vise deg noen vanlige feller som du kan falle i når du velger GPIO-pinner på en ny mikrokontroller. Det beste for å unngå feller er å lese pinnedetaljer og pinbeskrivelse gitt i STM8S103F3P6-databladet. For STM8S103F3P6 mikrokontroller pin beskrivelse detaljer som er nevnt i databladet er vist nedenfor bilder.
Inngangstappene på mikrokontrolleren vår kan enten være flytende eller svakt opptrekkbare og utgangsstiftene kan enten være åpen avløp eller push-pull. Forskjellen mellom Open Drain og Push-Pull Output-pinner er allerede diskutert, derfor vil vi ikke komme i detaljer om det. For å si det enkelt, kan en Open Drain-utgangspinne gjøre utgangen bare så lav, ikke så høy, mens en push-pull-utgangspinne kan gjøre utgangen både så høy som høy.
Bortsett fra det fra tabellen ovenfor, kan du også merke at en utgangsstift enten kan være rask utgang (10 MHz) eller langsom utgang (2 MHz). Dette bestemmer GPIO-hastigheten. Hvis du vil bytte GPIO-pinner mellom høy og lav veldig raskt, så kan vi velge Rask utgang.
Noen GPIO-pinner på kontrolleren vår støtter True Open Drain (T) og High Sink Current (HS) som nevnt i bildet ovenfor. En betydelig forskjell mellom Open Drain og True Open Drain er at utgangen koblet til åpen drenering ikke kan trekkes høyt mer enn driftsspenningen til mikrokontroller (Vdd), mens en ekte åpen dreneringsutgang kan trekkes høyere enn Vdd. Pins med høy vaskeevne betyr at den kan synke mer strøm. Kilden og vaskestrømmen til en hvilken som helst GPIO HS-pin er 20mA, mens kraftledningen kan forbruke opptil 100 mA.
Når du ser nærmere på ovennevnte bilde, vil du legge merke til at nesten alle GPIO-pinner er av høy sinkstrøm (HS), bortsett fra PB4 og PB5 som er True Open Drain Type (T). Dette betyr at disse pinnene ikke kan gjøres høye, de vil ikke kunne gi 3,3V selv når pinnen er høy. Dette er grunnen til at den innebygde ledningen er koblet til en 3,3 V og jordet gjennom PB5 i stedet for å drive den direkte fra GPIO-pinnen.
Se side 28 på databladet for detaljert beskrivelse av pin. Som nevnt i bildet ovenfor blir PA1 automatisk konfigurert som en svak pull-up og anbefales ikke å brukes som en utgangsstift. Uansett kan den brukes som en inngangspinne sammen med en trykknapp, men jeg bestemte meg for å bruke PA2 bare for å prøve å aktivere pull up fra programmet. Dette er bare noen få grunnleggende ting som vil være nyttige når vi skriver mye mer kompliserte programmer. For nå er det greit hvis mange ting spretter av hodet ditt, vil vi komme inn i det laget i andre opplæringsprogrammer.
Programmering STM8S for GPIO Input og Output ved hjelp av SPL
Lag et arbeidsområde og nytt prosjekt som vi diskuterte i vår første opplæring. Du kan enten legge til alle header- og kildefilene eller bare legge til gpio-, config- og stm8s-filene. Åpne main.c- filen og begynn å skrive programmet.
Forsikre deg om at du har tatt med headerfilene som vist på bildet ovenfor. Åpne main.c- filen og start koden. Den komplette main.c-koden finner du nederst på denne siden, og du vil også kunne laste ned prosjektfilen derfra. Forklaringen på koden er som følger, du kan også se i SPL Brukerhåndbok eller videoen som er koblet nederst på denne siden hvis du er forvirret om kodingsdelen.
De-initialisere den nødvendige porten
Vi starter programmet vårt med å deinitialisere de nødvendige portene. Som vi diskuterte tidligere, vil hver GPIO-pin ha mange andre funksjoner knyttet til den, bortsett fra bare å fungere som en vanlig inngang og utgang. Hvis disse pinnene tidligere har blitt brukt til noen andre applikasjoner, bør de avinitialiseres før vi bruker dem. Det er ikke obligatorisk, men det er en god praksis. Følgende to kodelinjer brukes til å avinitialisere port A og port B. Bare bruk syntaksen GPIO_DeInit (GPIOx); og nevn portnavnet i stedet for x.
GPIO_DeInit (GPIOA); // forberede port A for å arbeide GPIO_DeInit (GPIOB); // forberede port B for arbeid
Inngang og utgang GPIO-erklæring
Deretter må vi erklære hvilke pinner som skal brukes som inngang og hvilke som utgang. I vårt tilfelle vil pin PA2 brukes som inngang, vi vil også erklære denne pin med intern Pull-up slik at vi ikke trenger å bruke en eksternt. Syntaksen er GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Hvor x er portnavnet, er y pin-nummeret, og z er GPIO Pin-modus.
// Erklær PA2 som inngangs pull up pin GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
Deretter må vi erklære pinnene PA3 og PB5 som utgang. Igjen er mange typer utgangsdeklarasjoner mulig, men vi vil bruke "GPIO_MODE_OUT_PP_LOW_SLOW", noe som betyr at vi vil erklære det som en utgangsstift av push-pull-type med lav hastighet. Og som standard vil verdien være lav. Syntaksen vil være den samme.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Erklær PB5 som push pull Utgangsstift GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
Nedenstående øyeblikksbilde fra SPL brukerhåndbok nevner alle mulige GPIO-moduser (z).
Uendelig mens løkke
Etter pin-erklæringen må vi lage en uendelig sløyfe der vi vil fortsette å blinke LED-lampen for alltid og overvåke statusen på trykknappen for å slå LED-lampen. Den uendelige sløyfen kan enten opprettes med en stund (1) eller med en for (;;) . Her har jeg brukt mens (1).
mens (1) {}
Kontrollerer statusen til inngangspinnen
Vi må sjekke statusen til inngangspinnen, syntaksen for å gjøre det er GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); hvor x er portnavnet og y er pin-nummeret. Hvis pinnen er høy, vil vi få '1' og hvis pinnen er lav, vil vi få en '0'. Vi har brukt å inne i en if-løkke for å sjekke om pinnen er høy eller lav.
hvis (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // hvis knappen trykkes
Å lage en GPIO-pin høy eller lav
For å lage en GPIO-pin høy eller lav, kan vi bruke GPIO_WriteHigh (GPIOx, GPIO_PIN_y); og GPIO_WriteLow (GPIOx, GPIO_PIN_y); henholdsvis. Her har vi fått lysdioden til å slå seg på hvis du trykker på knappen og slår av hvis du ikke trykker på knappen.
hvis (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // hvis knappen ble trykket på GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED PÅ ellers GPIO_WriteHigh (GPIOA, GPIO_PIN_3); // LED AV
Veksle en GPIO-pin
For å bytte en GPIO-pin, har vi GPIO_WriteReverse (GPIOx, GPIO_PIN_y); å ringe til denne funksjonen vil endre status på utgangspinnen. Hvis tappen er høy, vil den endres til lav, og hvis den er lav, vil den bli endret til høy. Vi bruker denne funksjonen til å blinke den innebygde LED-lampen på PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Forsinkelsesfunksjon
I motsetning til Arduino har den kosmiske kompilatoren ikke en forhåndsdefinert forsinkelsesfunksjon. Så vi må lage en på egen hånd. Min forsinkelsesfunksjon er gitt nedenfor. Verdien for forsinkelsen vil bli mottatt i variabelen ms, og vi vil bruke to for loop for å holde eller programmere kjøring. Som _asm (“nop”) er en monteringsinstruksjon som ikke står for noen operasjon. Dette betyr at kontrolleren vil løkke inn i for-løkken uten å utføre noen operasjon, og dermed skape en forsinkelse.
ugyldig forsinkelse (int ms) // Funksjonsdefinisjon {int i = 0; int j = 0; for (i = 0; i <= ms; i ++) {for (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Utfør ingen operasjon // monteringskode}}
Laste opp og teste programmet
Nå som programmet vårt er klart, kan vi laste det opp og teste det. Når maskinen var lastet opp, fungerte den som forventet. Den innebygde røde lysdioden blinket hver 500 millisekund, og den eksterne grønne lysdioden tennes hver gang jeg trykket på bryteren.
Komplett arbeid finner du i videoen som er lenket nedenfor. Når du har nådd dette punktet, kan du prøve å koble bryteren og lysdioden til forskjellige pinner og skrive koden på nytt for å forstå konseptet. Du kan også spille med forsinkelsestimingen for å sjekke om du har forstått konseptene tydelig.
Hvis du har spørsmål, kan du legge dem igjen i kommentarfeltet nedenfor, og for andre tekniske spørsmål, kan du bruke forumene våre. Takk for at du fulgte med, vi sees i neste opplæring.