- Förbereda hårdvaran
- Förstå GPIO Pinouts på STM8S103F
- Pinout-beskrivning och tips för STM8S103F GPIO-val
- Programmering av STM8S för GPIO in- och utgång med SPL
- Ladda upp och testa programmet
För mikrokontroller motsvarar ett LED-blinkande program programmet “hej världen”. I vår tidigare handledning lärde vi oss hur man kommer igång med STM8S103F3 Development Board och hur man ställer in IDE och kompilator för att programmera våra STM8S-styrenheter. Vi har också lärt oss hur man använder de vanliga perifera biblioteken och hur man sammanställer och laddar upp koden till vår mikrokontroller. Med alla grunderna täckta kan vi faktiskt börja skriva kod. I den här handledningen lär vi oss hur man utför allmänna GPIO-funktioner på STM8S-styrenheter. Kortet har redan en inbyggd LED ansluten till stift 5 på port B, vi lär oss hur man blinkar denna LED och lägger också till en extern LED och styr den med en tryckknapp. Om du är helt ny rekommenderas det att du läser föregående handledning innan du fortsätter vidare.
Förbereda hårdvaran
Låt gör hårdvaruanslutningarna redo innan vi dyker in i programmet. Som nämnts tidigt kommer vi att använda två lysdioder här, en är en inbyggd lysdiod som blinkar kontinuerligt och den andra är en extern lysdiod som växlas med en tryckknapp. Tanken är att lära sig all GPIO-funktionalitet i en enkel installation. Den inbyggda LED-enheten är redan ansluten till PB5 (pin5 på PORTB), så jag har precis anslutit en LED till PA3 och en tryckknapp till PA2, som du kan se i diagrammet nedan.
Men av alla utgångsstift som finns tillgängliga på vår kontrollerade, varför valde jag PA3 för utgång och PA2 för ingång? Frågorna är giltiga och jag kommer att förklara det senare i den här artikeln. Min hårdvaruuppsättning för denna handledning visas nedan. Som du kan se har jag också anslutit min ST-länk-programmerare till programmeringsstift som inte bara kommer att programmera vårt kort utan också fungerar som en strömkälla.
Förstå GPIO Pinouts på STM8S103F
Kommer nu tillbaka till frågan, varför PA2 för ingång och varför PA3 för utgång? För att förstå det, låt oss titta närmare på pinout på mikrokontrollern som visas nedan.
Enligt pinout-diagrammet har vi fyra portar på vår mikrokontroller, nämligen PORT A, B, C och D betecknade med PA, PB, PC respektive PD. Varje GPIO-stift har också en annan specialfunktion. Till exempel kan PB5 (stift 5 i PORT B) inte bara fungera som en GPIO-stift utan också som en SDA-stift för I2C-kommunikation och som en Timer 1-utgångsstift. Så om vi använder denna stift för enkla GPIO-ändamål som att ansluta en LED, kommer vi inte att kunna använda I2C och LED samtidigt. Tyvärr är den inbyggda lysdioden ansluten till denna stift, så vi har inte mycket val här, och i det här programmet kommer vi inte att använda I2C, så det är inte mycket av ett problem.
Pinout-beskrivning och tips för STM8S103F GPIO-val
I själva verket skulle det inte skada att använda PA1 en ingångsstift och det skulle bara fungera. Men jag tog medvetet upp detta för att ge mig en möjlighet att visa dig några vanliga fällor som du kan hamna i när du väljer GPIO-stift på en ny mikrokontroller. Det bästa att undvika fällorna är att läsa stiftdetaljerna och stiftbeskrivningen i STM8S103F3P6-databladet. För STM8S103F3P6 mikrokontroller pin beskrivning detaljer som nämns i databladet visas nedan bilder.
Ingångsstiften på vår mikrokontroller kan antingen vara flytande eller svag uppdragbar och utgångsstiften kan antingen vara Open Drain eller Push-pull. Skillnaden mellan Open Drain och Push-Pull Output-stift har redan diskuterats, därför kommer vi inte att komma in i detaljer om det. För att uttrycka det enkelt kan en Open Drain-utgångsstift göra att utgången bara är så låg, inte så hög, medan en utdragningsstift med push-pull kan göra utgången både så hög som hög.
Bortsett från det från ovanstående tabell kan du också märka att en utgångsstift antingen kan vara snabb utgång (10 MHz) eller långsam utgång (2 MHz). Detta bestämmer GPIO-hastigheten, om du vill växla dina GPIO-stift mellan högt och lågt mycket snabbt, så kan vi välja snabb utmatning.
Vissa GPIO-stift på vår controller stöder True Open Drain (T) och High Sink Current (HS) som nämns i bilden ovan. En avsevärd skillnad mellan Open Drain och True Open Drain är att utgången som är ansluten till öppen dränering inte kan dras högt mer än mikrokontrollerns (Vdd) driftspänning medan en riktig utloppsnippel med öppen dränering kan dras högre än Vdd. Stift med hög diskbänkförmåga innebär att den kan sjunka mer ström. Källan och sänkströmmen för alla GPIO HS-stift är 20 mA, medan kraftledningen kan förbruka upp till 100 mA.
Om du tittar närmare på bilden ovan kommer du att märka att nästan alla GPIO-stift är HS-typ (High Sink Current) förutom för PB4 och PB5 som är True Open Drain Type (T). Detta innebär att dessa stift inte kan göras höga, de kommer inte att kunna ge 3,3 V även när stiften är hög. Det är därför den inbyggda ledningen är ansluten till en 3,3 V och jordad via PB5 istället för att driva den direkt från GPIO-stiftet.
Se sidan 28 på databladet för en detaljerad stiftbeskrivning. Som nämnts i bilden ovan konfigureras PA1 automatiskt som en svag pull-up och rekommenderas inte att användas som en utgångsstift. Hur som helst kan den användas som en ingångsstift tillsammans med en tryckknapp, men jag bestämde mig för att använda PA2 bara för att försöka aktivera pull up från programmet. Det här är bara några grundläggande saker som kommer att vara användbara när vi skriver mycket mer komplicerade program. För tillfället är det okej om många saker studsade av ditt huvud, kommer vi in i det lager i andra handledning.
Programmering av STM8S för GPIO in- och utgång med SPL
Skapa en arbetsyta och ett nytt projekt som vi diskuterade i vår första handledning. Du kan antingen lägga till alla rubrik- och källfiler eller bara lägga till gpio-, config- och stm8s-filerna. Öppna main.c- filen och börja skriva ditt program.
Se till att du har inkluderat rubrikfilerna som visas i bilden ovan. Öppna main.c- filen och starta koden. Den fullständiga main.c-koden finns längst ner på denna sida och du kommer också att kunna ladda ner projektfilen därifrån. Förklaringen till koden är som följer, du kan också hänvisa till SPL-användarhandboken eller den länkade videon längst ner på denna sida om du är förvirrad över kodningsdelen.
Avinitialisering av den nödvändiga porten
Vi börjar vårt program med att de-initialisera de portar som krävs. Som vi diskuterade tidigare kommer varje GPIO-stift att ha många andra funktioner associerade med det än att bara fungera som en vanlig in- och utgång. Om dessa stift har använts tidigare för andra applikationer, bör de avinitieras innan vi använder dem. Det är inte obligatoriskt, men det är en bra praxis. Följande två rader kod används för att avinitialisera port A och port B. Använd bara syntax GPIO_DeInit (GPIOx); och ange portnamnet i stället för x.
GPIO_DeInit (GPIOA); // förbereda port A för att arbeta GPIO_DeInit (GPIOB); // förbereda port B för arbete
In- och utgång GPIO-deklaration
Därefter måste vi förklara vilka stift som kommer att användas som ingång och vilka som utgång. I vårt fall kommer pin PA2 att användas som ingång, vi kommer också att deklarera denna pin med intern Pull-up så att vi inte behöver använda en externt. Syntaksen är GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Där x är portnamnet är y pin-numret och z är GPIO Pin-läget.
// Förklara PA2 som ingångsupptagningsstift GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
Därefter måste vi deklarera stiften PA3 och PB5 som utgång. Återigen är många typer av utgångsdeklaration möjliga men vi kommer att använda "GPIO_MODE_OUT_PP_LOW_SLOW" vilket innebär att vi kommer att förklara det som en utgångsstift av push-pull-typ med låg hastighet. Och som standard är värdet lågt. Syntaxen kommer att vara densamma.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Förklara PB5 som push pull Utgångsstift GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
Nedanstående ögonblicksbild från SPL-användarhandboken nämner alla möjliga GPIO-lägen (z).
Oändligt medan loop
Efter stiftdeklarationen måste vi skapa en oändlig slinga inuti vilken vi fortsätter att blinka lysdioden för alltid och övervaka tryckknappens status för att växla mellan lysdioden. Den oändliga slingan kan antingen skapa med ett tag (1) eller med en för (;;) . Här har jag använt medan (1).
medan (1) {}
Kontrollerar ingångsstiftets status
Vi måste kontrollera ingångsstiftets status, syntaxen för att göra det är GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); där x är portnamnet och y är stiftnumret. Om stiftet är högt får vi '1' och om stiftet är lågt får vi ett '0'. Vi har använt oss av en if-loop för att kontrollera om stiftet är högt eller lågt.
om (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // om knappen trycks in
Gör en GPIO-stift hög eller låg
För att göra en GPIO-stift hög eller låg kan vi använda GPIO_WriteHigh (GPIOx, GPIO_PIN_y); och GPIO_WriteLow (GPIOx, GPIO_PIN_y); respektive. Här har vi gjort att lysdioden tänds om knappen trycks in och stängs av om knappen inte trycks in.
om (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // om knappen trycktes GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED PÅ annat GPIO_WriteHigh (GPIOA, GPIO_PIN_3); // LED av
Växla en GPIO-stift
För att växla en GPIO-stift har vi GPIO_WriteReverse (GPIOx, GPIO_PIN_y); Om du ringer till den här funktionen ändras utgångsstiftets status. Om stiftet är högt ändras det till lågt och om det är lågt ändras det till högt. Vi använder den här funktionen för att blinka den inbyggda lysdioden på PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Fördröjningsfunktion
Till skillnad från Arduino har den kosmiska kompilatorn ingen fördefinierad fördröjningsfunktion. Så vi måste skapa en på egen hand. Min fördröjningsfunktion ges nedan. Värdet för fördröjningen kommer att tas emot i variabeln ms och vi använder två för loop för att hålla eller programkörning. Liksom _asm ("nop") är en monteringsinstruktion som inte står för någon operation. Detta innebär att styrenheten kommer att slinga in i for-slingan utan att utföra någon operation, vilket skapar en fördröjning.
tomrumsfördröjning (int ms) // Funktionsdefinition {int i = 0; int j = 0; för (i = 0; i <= ms; i ++) {för (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Utför ingen åtgärd // monteringskod}}
Ladda upp och testa programmet
Nu när vårt program är klart kan vi ladda upp det och testa det. Efter att ha laddats upp fungerade min hårdvara som förväntat. Den inbyggda röda lysdioden blinkade var 500: e millisekund och den externa gröna lysdioden tänds varje gång jag tryckte på strömbrytaren.
Hela arbetet finns i videon som länkas nedan. När du har nått denna punkt kan du försöka ansluta strömbrytaren och lysdioden till olika stift och skriva om koden för att förstå konceptet. Du kan också spela med fördröjningstiden för att kontrollera om du har förstått begreppen tydligt.
Om du har några frågor, vänligen lämna dem i kommentarfältet nedan och för andra tekniska frågor kan du använda våra forum. Tack för att du följde, vi ses i nästa handledning.