- Подготовка на хардуера
- Разбиране на GPIO Pinouts на STM8S103F
- Описание на пиновете и съвети за избор на STM8S103F GPIO
- Програмиране на STM8S за GPIO вход и изход с помощта на SPL
- Качване и тестване на програмата
За микроконтролерите, мигаща LED програма е еквивалентна на програмата „здравей, свят“. В нашия предишен урок научихме как да започнем със STM8S103F3 Development Board и как да настроим IDE и компилатора за програмиране на нашите STM8S контролери. Също така научихме как да използваме стандартните периферни библиотеки и как да компилираме и качим кода в нашия микроконтролер. С всички основни положения, нека всъщност да започнем да пишем код. В този урок ще научим как да изпълняваме общи GPIO функции на STM8S контролери. На платката вече има вграден светодиод, свързан към щифт 5 на порт B, ще научим как да мига този светодиод и също така да добавим външен светодиод и да го управляваме с бутон. Ако сте напълно нов, силно се препоръчва да прочетете предишния урок, преди да продължите по-нататък.
Подготовка на хардуера
Преди да се потопим в програмата, нека подготвим хардуерните връзки. Както споменахме по-рано, тук ще използваме два светодиода, единият е вграден светодиод, който ще мига непрекъснато, а другият е външен светодиод, който ще се превключва с бутон. Идеята е да научите цялата GPIO функционалност с проста настройка. Вграденият Led вече е свързан към PB5 (pin5 на PORTB), така че току-що свързах светодиод към PA3 и бутон към PA2, както можете да видите на диаграмата по-долу.
Но от всички изходни щифтове, налични на нашия контролиран, защо избрах PA3 за изход и PA2 за вход? Въпросите са валидни и ще обясня това по-нататък в тази статия. Моята хардуерна настройка за този урок е показана по-долу. Както можете да видите, аз също свързах моя програмист ST-link към програмиращи щифтове, които не само ще програмират нашата платка, но и ще действат като източник на енергия.
Разбиране на GPIO Pinouts на STM8S103F
Сега се връщаме към въпроса, защо PA2 за вход и защо PA3 за изход? За да разберем това, нека разгледаме по-отблизо извода на микроконтролера, който е показан по-долу.
Според диаграмата на пиновете имаме четири порта на нашия микроконтролер, а именно PORT A, B, C и D, обозначени съответно с PA, PB, PC и PD. Всеки GPIO щифт също е сглобен с някаква друга специална функционалност. Например PB5 (пин 5 на PORT B) може не само да работи като GPIO пин, но и като SDA пин за I2C комуникация и като изходен пин на таймер 1. Така че, ако използваме този щифт за прости GPIO цели като свързване на светодиод, тогава няма да можем да използваме I2C и светодиода едновременно. За съжаление вграденият светодиод е свързан към този щифт, така че тук нямаме голям избор и в тази програма няма да използваме I2C, така че не е голям проблем.
Описание на пиновете и съвети за избор на STM8S103F GPIO
Наистина погледнато, няма да навреди да се използва PA1 входен щифт и той просто ще работи. Но умишлено съм повдигнал това, за да ми предостави възможност да ви покажа някои често срещани капани, в които може да попаднете, когато избирате GPIO щифтове на нов микроконтролер. Най-доброто, за да избегнете капаните, е да прочетете подробностите за щифтовете и описанието на щифтовете, предоставени в таблицата с данни STM8S103F3P6. За STM8S103F3P6 подробности за описанието на микроконтролера подробности, които са споменати в листа с данни, са показани под изображенията.
Входните щифтове на нашия микроконтролер могат да бъдат или плаващи, или слаби набирания, а изходните щифтове могат да бъдат Open Drain или Push-pull. Разликата между Open Drain и Push-Pull Output щифтове вече е обсъдена, поради което няма да навлизаме в подробности за това. Казано по-просто, изходният щифт с отворен източник може да направи изхода само толкова нисък, колкото висок, докато изходният щифт с натискане може да направи изхода както висок, така и висок.
Освен това от горната таблица, можете също да забележите, че изходният щифт може да бъде или бърз изход (10 Mhz), или бавен изход (2 MHz). Това определя скоростта на GPIO, ако искате да превключвате вашите GPIO пинове между висока и ниска много бързо, тогава можем да изберем Бърз изход.
Някои GPIO щифтове на нашия контролер поддържат True Open Drain (T) и High Sink Current (HS), както е споменато в горното изображение. Значителна разлика между Open Drain и True Open Drain е, че изходът, свързан към отворен канал, не може да бъде изтеглен по-високо от работното напрежение на микроконтролера (Vdd), докато истинският изходен щифт с отворен канал може да бъде изтеглен по-високо от Vdd. Щифтове с висока способност на мивка означава, че може да потъне по-голям ток. Източникът и токът на потока на всеки GPIO HS щифт е 20 mA, докато електропроводната линия може да консумира до 100 mA.
Като разгледате по-отблизо горното изображение, ще забележите, че почти всички GPIO щифтове са с висок ток на мивка (HS), с изключение на PB4 и PB5, които са True Open Drain Type (T). Това означава, че тези щифтове не могат да бъдат направени високо, те няма да могат да осигурят 3.3V, дори когато щифтът е направен високо. Ето защо вграденият светодиод е свързан към 3.3V и заземен през PB5, вместо да го захранва директно от GPIO щифта.
Вижте страница 28 в листа с данни за подробното описание на щифтовете. Както бе споменато в горното изображение, PA1 се конфигурира автоматично като слабо изтегляне и не се препоръчва да се използва като изходен щифт. Във всеки случай може да се използва като входен щифт заедно с бутон, но реших да използвам PA2 само за да се опитам да активирам изтеглянето от програмата. Това са само няколко основни неща, които ще бъдат полезни, когато пишем много по-сложни програми. Засега е добре, ако много неща отскочат от главата ви, ще влезем в него в други уроци.
Програмиране на STM8S за GPIO вход и изход с помощта на SPL
Създайте работно пространство и нов проект, както обсъдихме в първия ни урок. Можете да добавите всички заглавни и изходни файлове или само да добавите файловете gpio, config и stm8s. Отворете файла main.c и започнете да пишете програмата си.
Уверете се, че сте включили заглавните файлове, както е показано на изображението по-горе. Отворете файла main.c и стартирайте кода. Пълният код main.c може да бъде намерен в долната част на тази страница и също така ще можете да изтеглите файла на проекта от там. Обяснението на кода е както следва, можете също да се обърнете към ръководството за потребителя на SPL или към видеото, свързано в долната част на тази страница, ако сте объркани относно кодиращата част.
Деинициализиране на необходимия порт
Започваме нашата програма с Деинициализиране на необходимите портове. Както обсъждахме по-рано, всеки GPIO пин ще има много други функции, свързани с него, освен просто да работи като нормален вход и изход. Ако тези щифтове преди са били използвани за някои други приложения, то трябва да бъдат деинициализирани, преди да ги използваме. Не е задължително, но е добра практика. Следните два реда код се използват за деинициализиране на порт A и порт B. Просто използвайте синтаксис GPIO_DeInit (GPIOx); и споменайте името на порта вместо x.
GPIO_DeInit (GPIOA); // подготвяме порт A за работещ GPIO_DeInit (GPIOB); // подготвяме порт B за работа
Входна и изходна декларация GPIO
След това трябва да декларираме кои щифтове ще се използват като вход и кои като изход. В нашия случай като вход ще се използва пин PA2, ние също ще декларираме този пин с вътрешно изтегляне, така че да не се налага да го използваме външно. Синтаксисът е GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Където x е името на порта, y е номерът на пина, а z е режимът GPIO Pin.
// Деклариране на PA2 като входен издърпващ щифт GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
След това трябва да декларираме изводите PA3 и PB5. Отново са възможни много видове декларация за изход, но ние ще използваме “GPIO_MODE_OUT_PP_LOW_SLOW”, което означава, че ще го декларираме като изходен щифт от тип push-pull с бавна скорост. И по подразбиране стойността ще бъде ниска. Синтаксисът ще бъде същият.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Деклариране на PB5 като издърпващ изходен щифт GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
Долната снимка от ръководството за потребителя на SPL споменава всички възможни GPIO режими (z).
Безкраен цикъл докато
След декларацията на ПИН трябва да създадем безкраен цикъл, вътре в който ще продължим да мигаме светодиода завинаги и да наблюдаваме състоянието на бутона за превключване на светодиода. Безкрайният цикъл може да създава с известно време (1) или с for (;;) . Тук използвах while (1).
докато (1) {}
Проверка на състоянието на входния щифт
Трябва да проверим състоянието на входния щифт, синтаксисът за това е GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); където x е името на порта, а y е номерът на пина. Ако щифтът е висок, ще получим „1“, а ако щифтът е нисък, ще получим „0“. Използвали сме вътре в if цикъл, за да проверим дали щифтът е висок или нисък.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // ако бутонът е натиснат
Осъществяване на GPIO Pin високо или ниско
За да направим GPIO пин High или Low, можем да използваме GPIO_WriteHigh (GPIOx, GPIO_PIN_y); и GPIO_WriteLow (GPIOx, GPIO_PIN_y); съответно. Тук сме направили светодиода да се включва, ако бутонът е натиснат и да се изключва, ако бутонът не е натиснат.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // ако бутонът е натиснат GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED ВКЛЮЧЕН, иначе GPIO_WriteHigh (GPIOA, GPIO_PIN_3); // LED ИЗКЛ
Превключване на GPIO ПИН
За да превключваме GPIO пин, имаме GPIO_WriteReverse (GPIOx, GPIO_PIN_y); извикването на тази функция ще промени състоянието на изходния щифт. Ако щифтът е висок, той ще бъде сменен на нисък, а ако е нисък, ще бъде променен на висок. Използваме тази функция, за да премигнем вградения светодиод на PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Функция за забавяне
За разлика от Arduino, космическият компилатор няма предварително зададена функция за забавяне. Така че трябва да създадем такъв сами. Моята функция за забавяне е дадена по-долу. Стойността doe the delay ще бъде получена в променливата ms и ще използваме две за цикъл за задържане или изпълнение на програмата. Подобно на _asm (“nop”) е инструкция за сглобяване, която не означава операция. Това означава, че контролерът ще зацикли в цикъла for, без да извършва никаква операция, като по този начин създава забавяне.
void delay (int ms) // Определение на функцията {int i = 0; int j = 0; за (i = 0; i <= ms; i ++) {за (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Не изпълнявайте операция // код за монтаж}}
Качване и тестване на програмата
Сега, когато нашата програма е готова, можем да я качим и тестваме. Веднъж качен, хардуерът ми работеше според очакванията. Вграденият червен светодиод мигаше на всеки 500 милисекунди и външният зелен светодиод се включваше всеки път, когато натиснах ключа.
Цялата работа може да бъде намерена във видеото, свързано по-долу. След като достигнете тази точка, можете да опитате да свържете превключвателя и светодиода към различни щифтове и да напишете отново кода, за да разберете концепцията. Можете също така да играете с времето за забавяне, за да проверите дали сте разбрали понятията ясно.
Ако имате някакви въпроси, моля, оставете ги в раздела за коментари по-долу, а за други технически въпроси можете да използвате нашите форуми. Благодаря, че последвахте, ще се видим в следващия урок.