You are on page 1of 16

February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

Лаб 2. Пинови за генерална намена (GPIO)

Пиновите на микроконтролерот STM32F303VCT6 имаат можност да бидат


конфигурирани за различна намена, со цел да се овозможи интеракција на големиот
број на периферии на микроконтролерот кон надворешниот свет преку редуциран број
на пинови. Со други зборови, се врши мултиплексирање на пристапот на внатрешните
периферии кон пиновите на микроконтролерот. Основната структура на еден 5 волти
толерантен пин е дадена на слика 1.

Слика 1. Основна структура на еден 5 волти толерантен пин.


Секој бит од било која порта за генерална намена може индивидуално да се
конфигурира од страна на софтверот во повеќе модови:

 Влезен пин floating


 Влезен пин со pull-up отпорник
 Влезен пин со pull-down отпорник
 Аналоген пин
 Излезен open-drain пин со pull-up или pull-down отпорник
 Излезен push-pull пин со pull-up или pull-down отпорник
 Пин со алтернативна функција open-drain пин со pull-up или pull-down отпорник
 Пин со алтернативна функција push-pull пин со pull-up или pull-down отпорник

Влезна конфигурација

Кога влезно/излезната порта е конфигурирана (програмирана) да биде влезна


хардверската структура на портата е следна:

 Излезниот бафер е исклучен

1 Лаб 2. Пинови за генерална намена (GPIO) | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

 Влезното шмитово коло е активно


 Pull-up и pull-down отпорниците се активни (еден е секако активен) во
зависност од поставената вредност во GPIOx_PUPDR регистарот
 Нивото кое се појавува на влезно/излезниот пин се чита во влезниот податочен
регистер на секој AHB1 такт циклус
 Читањето од влезниот податочен регистар ни ја дава состојбата на
влезно/излезниот пин

Слика 2. Влезна конфигурација на портата.

Излезна конфигурација

Кога влезно/излезната порта е конфигурирана (програмирана) да биде излезна


хардверската структура на портата е следна:

 Излезниот бафер е активен


 Open drain mode: Нула во излезниот податочен регистар го активира N
каналниот мосфет, додека пак единица односно високо ниво во
излезниот податочен регистар ја остава портата во состојба на висока
импеданса (Во оваа конфигурација P каналниот мосфет никогаш не се
активира).
 Push-pull mode: Нула во излезниот податочен регистар го активира N
каналниот мосфет, додека пак единица во излезниот податочен регистар
го активира P каналниот мосфет.
 Влезното шмитово коло е активно
 Pull-up и pull-down отпорниците се активни или не во зависност од вредноста
во GPIOx_PUPDR регистарот
 Нивото кое се појавува на влезно/излезниот пин се чита во влезниот податочен
регистер на секој AHB1 такт циклус
 Читањето од влезниот податочен регистар ни ја дава состојбата на
влезно/излезниот пин

2 Излезна конфигурација | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

 Читањето од излезниот податочен регистар ни ја дава последно запишаната


состојба на влезно/излезниот пин

Слика 3. Излезна конфигурација на портата.

Алтернативна функција

Слика 4. Конфигурација на алтернативна функција.


Кога влезно/излезната порта е конфигурирана (програмирана) за алтернативна
функција хардверската структура на портата е следна:

 Излезниот бафер може да се конфигурира како open-drain или како push-pull


 Излезниот бафер е контролиран од сигналот кој што доаѓа од периферијата
 Влезното шмитово коло е активирано
 Pull-up и pull-down отпорниците се активни или не во зависност од вредноста
во GPIOx_PUPDR регистарот

3 Алтернативна функција | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

 Нивото кое се појавува на влезно/излезниот пин се чита во влезниот податочен


регистер на секој AHB1 такт циклус
 Читањето од влезниот податочен регистар ни ја дава состојбата на
влезно/излезниот пин

Аналогна конфигурација

Кога влезно/излезната порта е конфигурирана (програмирана) да биде аналогна


хардверската структура на портата е следна:

 Излезниот бафер е исклучен


 Влезното шмитово коло е исклучено обезбедувајќи нула потрошувачка за секоја
аналогна вредност на влезно/излезниот пин. Излезот од шмитовото коло е
форсиран кон константна вредност нула.
 Pull-up и pull-down отпорниците се оневозможени
 Читањето од влезниот податочен регистар дава вредност нула

Слика 5. Аналогна конфигурација на порта.

Контролни регистри за работа со влезно/излезните порти

Секоја влезно/излезна порта за генерална намена има четири 32-битни


мемориски мапирани контролни регистри (GPIOx_MODER, GPIOx_OTYPER,
GPIOx_OSPEEDR и GPIOx_PUPDR), два 32-битни податочни регистри (GPIOx_IDR и
GPIOx_ODR), еден 32-битен сет/ресет регистар (GPIOx_BSRR), еден 32-битен locking
регистар (GPIOx_LCKR) и два 32-битни регистри за селектирање на алтернативна
функција на пинот (GPIOx_AFRH и GPIOx_AFRL).
GPIOx_MODER регистарот се користи за селекција на влезно излезниот мод на
пинот (влез, излез, аналоген, алтернативна функција). За секоја порта имаме посебен
MODER регистар. Така на пример за порта A MODER регистарот е GPIOA_MODER
Изгледот на овој регистар е даден на Слика5. Ако сакаме пинот 0 од порта А да го

4 Аналогна конфигурација | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

направиме излезен за генерална намена потребно е во GPIOA_MODER регистарот на


бит 0 да запишеме 1, а на бит 1 потребно е да запишеме 0. Кодот во CooCox за правење
на пинот 0 од порта A излезен за генерална намена е:
GPIOA -> MODER |= 0x1;
GPIOA -> MODER &= ~(1<<1); //1 siftame vo levo za edna pozicija na toa
//pravime komplement pa logicka AND operacija
//so vrednosta na registarot GPIOA -> MODER,
//a rezultatot go zapisuvame vo istiot registar
Истиот код напишан на малку поинаков начин:

GPIOC -> MODER |= 0x00000001;


GPIOC -> MODER &= 0xFFFFFFFD;
Доколку сакаме пинот 11 од порта C да го направиме аналоген тогаш потребно е на
битовите 22 и 23 од регистарот GPIOC_MODER да запишеме единици. Кодот во
CooCox за оваа цел е следен:
GPIOC -> MODER |= (1 << 22);
GPIOC -> MODER |= (1 << 23);
или истото напишано во еден ред:
GPIOC -> MODER |= (1 << 22) | (1 << 23);

Слика 6. Изглед на GPIOx_MODER регистарот.


GPIOx_OTYPER и GPIOx_OSPEEDR регистрите се користат за селекција на
типот на излезот (push-pull или open-drain) и селекција на брзината. GPIOx_PUPDR се
користи за селекција на pull-up, pull-down во зависност од избраната насока на пинот.
Изгледот на GPIOx_OTYPER е даден на слика 7, а изгледот на GPIOx_OSPEEDR
регистарот е даден на слика 8. Ако сакаме пинот 5 од порта B да го направиме од тип
push-pull потребно е да запишеме 0 на бит 5 од регистарот GPIOB_OTYPER. Кодот во
CooCox за оваа цел е следен:
GPIOB -> OTYPER &= ~(1 << 5);

5 Контролни регистри за работа со влезно/излезните порти | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

Ако сакаме пинот 2 од порта E да го направиме од тип open drain потребно е да


запишеме 1 на битот 2 од регистарот GPIOE_OTYPER. Кодот во CooCox за оваа цел е
следен:
GPIOB -> OTYPER |= (1 << 2);

Слика 7. Изглед на GPIOx_OTYPER регистарот.


Излезната брзината на секој влезно излезен пин можеме да ја поставиме преку
GPIOx_OSPEEDR регистарот. Па така ако сакаме излезната брзина на пинот 12 од
порта D да ја поставиме на 10MHz потребно е да запишеме 1 на 24 бит и да запишеме 0
на 25 бит од GPIOD_OSPEEDR регистарот. Кодот за оваа цел во CooCox е следен:
GPIOD -> OSPEEDR |= (1 << 24);
GPIOD -> OSPEEDR &= ~(1 << 25);

Слика 8. Изглед на GPIOx_OSPEEDR регистарот.


Секоја GPIO порта има два 16-битни податочни регистри: влезен и излезен
податочен регистар (GPIOx_IDR и GPIOx_ODR). Во GPIOx_ODR се запишуваат
податоците кои треба да се јават на излез. Во овој регистар може и да се запишува
новата состојба на пиновите и да се чита последно поставената состојба на пиновите.
Изгледот на GPIOx_ODR регистарот е даден на слика 9. Ако сакаме пинот 9 од порта А
да го поставиме на високо ниво потребно е да запишеме 1 на битот 9 од регистарот
GPIOA_ODR. Кодот за сетирање на пинот 9 од портата A во CooCox е следен:

6 Контролни регистри за работа со влезно/излезните порти | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

GPIOA -> ODR |= (1 << 9);


Ако сакаме пинот 9 од портата A да го ресетираме потребно е да запишеме 0 на
битот 9 од GPIOA_ODR регистарот. Кодот за оваа цел во CooCox е следниот:
GPIOA -> ODR &= ~(1 << 9);

Слика 9. Изглед на GPIOx_ODR регистарот.


Податоците кои се појавуваат на пиновите односно состојбата на пиновите се
чита преку влезниот податочен регистар (GPIOx_IDR). Од овој регистaр може само да
се чита. Изгледот на GPIOx_IDR е даден на слика 10. Ако на пинот 4 од портата A на
влез имаме високо ниво тогаш битот 4 од регистарот GPIOA_IDR ќе има вредност 1.
Во спротивно ако на влез на пинот 4 од порта A имаме ниско ниво тогаш битот 4 од
GPIOA_IDR ќе има вредност 0. Со следниот код во CooCox би провериле дали на влез
од пинот 7 од портата B имаме високо ниво (се разбира ова не е единствен начин):
If(GPIOB -> IDR & (1 << 7))
{
//Kod za sostojba koga pinot PB7 e na visoko nivo
}

Слика 10. Изглед на GPIOx_IDR регистарот.


Со следниот код во CooCox би провериле дали на влез од пинот 7 од портата B
имаме ниско ниво (се разбира ова не е единствен начин):

7 Контролни регистри за работа со влезно/излезните порти | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

If(!(GPIOB -> IDR & (1 << 7)))


{
//Kod za sostojba koga pinot PB7 e na visoko nivo
}

Bit set/reset регистарот (GPIOx_BSRR) e 32-битен регистар што му овозможува


на апликацијата да се сетираат и ресетираат сите индивидуални битови во излезниот
податочен регистар (GPIOx_ODR). Bit set/reset регистарот има дупло поголема
должина во однос на GPIOx_ODR.
На секој бит од GPIOx_ODR одговараат два контролни битови во
GPIOx_BSRR(i): BS(i) и BR(i). Кога запишуваме 1 на BS(i) се сетира соодветниот бит
од ODR регистарот. Кога запишуваме 1 на битот BR(i) се ресетира ODR(i) соодветниот
бит. Запишување на 0 во GPIOx_BSRR не предизвикува никаков ефект на соодветниот
бит на GPIOx_ODR регистарот. Ако се случат истовремено и сетирање и ресетирање на
соодветниот бит на GPIOx_BSRR сетирањето има приоритет. Нема потреба за
софтверско исклучување на прекините кога се работи со GPIOx_ODR на битски нивоа
бидејќи е возможно да се модифицира еден или повеќе битови во единечен атомичен
AHB (Advance High Peripheral Bus) пристап на запишување. На AHB се поврзани GPIO
портите. Ако сакаме да го сетираме пинот 12 од портата A преку GPIOx_BSRR
регистарот потребно е да запишеме 1 на бит 12 од GPIOA_BSRR регистарот. Кодот за
оваа цел во CooCox е следниот:
GPIOA -> BSRR |= (1 << 12);
Ако сакаме да го ресетираме истиот пин потребно е да запишеме 1 на 12 + 16 =
28 бит од GPIOA_BSRR регистарот. Кодот за оваа цел во CooCox е следен:
GPIOA -> BSRR |= (1 << 28);

Слика 11. Изглед на GPIOx_BSRR регистарот.


Два регистри се обезбедени за селектирање една од алтернативните функции
кои се достапни за секој I/O пин. Ова значи дека бројот на возможни периферни
функции се мултиплексирани на секој пин за генерална намена користејќи ги
GPIOx_AFRL и GPIOx_AFRH регистрите. Со овие регистри можеме да поврземе

8 Контролни регистри за работа со влезно/излезните порти | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

алтернативна функција на било кој пин во зависност од потребите на конкретната


апликација. Апликацијата на овој начин може да ја селектира било која од возможните
алтернативни функции за секој I/O пин. Сигналот за селекција на алтернативната
функција е заеднички и за влезната алтернативна функција и за излезната алтернативна
функција. Единечен канал е селектиран за алтернативната функција влез/излез за еден
I/O пин. На слика 12 е даден изгледот на GPIOx_AFRL регистарот, додека пак на слика
13 е даден изгледот на GPIOx_AFRH регистарот.

Слика 12. Изглед на GPIOx_AFRL регистарот.


Достапните алтернативни функции се дадени во datasheet за нашиот
микроконтролер почнувајќи од страна 44 па натаму. Дел од табелата за алтернативните
функции на порта A е дadeна во продолжение означена како табела 1.

Табела 1. Дел од табелата за алтернативни функции на портата A

9 Контролни регистри за работа со влезно/излезните порти | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

За избор на алтернативната функција USART2_TX на пинот 2 од порта A


потребно е да запишеме комбинација 0111 на битовите од 11 до 8 соодветно во
GPIOx_AFRL регистарот. Кодот за оваа цел во CooCox е следниот:

GPIOA -> AFRL |= (1<<10) | (1 << 9) | (1 << 8);


GPIOA -> AFRL &= ~(1 << 11);

Слика 13. Изглед на GPIOx_AFRH регистарот.

Задачи

1. Да се напише програма во CooCox развојната околина за STM32F3 Discovery


развојната плоча која ќе ја пали и гасни диодата LD4 со некое доцнење. Поврзаноста на
диодите на плочата F3 е дадена на слика 14.
#include "cmsis_lib/include/stm32f30x_gpio.h"
#include "cmsis_lib/include/stm32f30x_rcc.h"

int main(void)
{
int i;
RCC->AHBENR |= RCC_AHBENR_GPIOEEN; //Vklucuvanje na taktot za GPIOE
GPIOE -> MODER |= 0x00010000; //Konfiguriranje na pin
//PE8 (LD4) kako
//izlezen pin za generalna namena
GPIOE -> OTYPER &= 0xFFFFFEFF; //Konfiguriranje na pin PE8 (LD4)
//kako izlezen push pull pin
GPIOE -> OSPEEDR |= 0x00030000; //Postavuvanje na brzinata na pin
//PE8 (LD4) na high speed
GPIOE -> PUPDR &= 0xFFFCFFFF; //Konfiguriranje na pin PE8 (LD4) no
//pull-up no pull-down

10 Задачи | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

while(1)
{
GPIOE -> ODR |= 0x00000100; //Postavi visoko nivo na pinot PE8
for(i = 0; i < 1000000; i++ ); //Ednostavna jamka za docnenje
GPIOE -> ODR &= 0xFFFFFEFF; //Postavi nisko nivo na pinot PE8
for(i = 0; i < 1000000; i++ ); //Ednostavna jamka za docnenje
}
}

2. Да се напише прогрма во CooCox која ке ги вклучува и исклучува наизменично


диодите LD4 и LD3. Поврзаноста на диодите на плочата F3 е дадена на слика 14.
#include "cmsis_lib/include/stm32f30x_gpio.h"
#include "cmsis_lib/include/stm32f30x_rcc.h"

int main(void)
{
int i;
RCC->AHBENR |= RCC_AHBENR_GPIOEEN; //vkluci takt za porta E
GPIOE -> MODER |= (1 << 16) | (1 << 18); //Konfiguriranje na pinovite
//PE8(LD3) i PE9(LD3)
GPIOE -> MODER &= ~((1 << 17) | (1 << 19)); //kako izlezni pinovi za
//generalna namena
GPIOE -> OTYPER &= ~((1 << 8) | (1 << 9)); //Konfiguriranje na pinovite
//PE8 i PE9 kako push-pull
//pinovi
GPIOE -> OSPEEDR |= (0xF << 16); //Postavuvanje na brzinata na
//pinovite PE8 i PE9 na high
//speed
GPIOE -> PUPDR &= ~(0xF << 16); //Konfiguriranje na pinovite
//PE8 i PE9 kako no pull-up
//no pull-down

while(1)
{
GPIOE -> BSRR |= (1 << 8); //Postavi go pinot PE8 na visoko nivo LD4
//sveti
GPIOE -> BSRR |= (1 << 25); //Postavi go pinot PE9 na nisko nivo LD3
//ne sveti
for(i = 0; i < 1000000; i++); //Ednostavna jamka za docnenje
GPIOE -> BSRR |= (1 << 24); //Postavi go pinot PE8 na nisko nivo LD4
//ne sveti
GPIOE -> BSRR |= (1 << 9); //Postavi go pinot PE9 na visoko nivo LD3
//sveti
for(i = 0; i < 1000000; i++); //Ednostavna jamka za docnenje
}
}

3. Да се напише програма во CooCox со која со притискање на тастерот B1 ќе се


вклучи диодата LD5. Поврзаноста на диодите на плочата F3 е дадена на слика 14.
Поврзаноста на тастерот B1 на плочата F3 е дадена на слика 15.
#include "cmsis_lib/include/stm32f30x_gpio.h"
#include "cmsis_lib/include/stm32f30x_rcc.h"

int main(void)
{
RCC->AHBENR |= RCC_AHBENR_GPIOEEN; //Pustanje na takt na porta E

11 Задачи | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

GPIOE -> MODER |= 0x00100000; //Konfiguriranje na pin PE10 (LD5)


//kako izlezen pin za generalna
//namena
GPIOE -> OTYPER &= 0xFFFFFBFF; //Konfiguriranje na pin PE10 (LD5)
//kako izlezen push pull pin
GPIOE -> OSPEEDR |= 0x0030000; //Postavuvanje na brzinata na pin
//PE10 (LD4) na high speed
GPIOE -> PUPDR &= 0xFFCFFFFF; //Konfiguriranje na pin PE10 (LD5)
//no pull-up no pull-down

RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //Pustanje na takt na porta A


GPIOA -> MODER &= 0xFFFFFFFC; //Konfiguriranje na pin PA0 (Button
//B1 kako vlezen pin
GPIOA -> OSPEEDR |= 0x3; //Postavuvanje na brzinata na pin
//PA0 (Button B1) na high speed
GPIOA -> PUPDR |= 0x2; //Konfiguriranje na pin PA0 (Button
//B1) pull-down

while(!(GPIOA -> IDR & 0x1)); //Cekaj dodeka ne bide pritisnato


//kopceto B1
GPIOE -> ODR |= 0x400; //Setiraj pin PE10 vkluci dioda LD5

while(1) //Beskonecna jamka


{

}
}

4. Како што е напишан кодот за претходниот пример,притиснувањето на тастерот


ја вклучува LED диодата еднократно. Ако ја прошириме функционалноста на кодот
така што сакаме при секое притиснување на тастерот диодата да се вклучува па
исклучува наизменично, потребно е да се внесат одредени измени. Прво, треба целата
постапка да се извршува во бесконечна јамка. Во оваа јамка можеме да направиме
еднаш проверка дали е притиснат тастерот за да ја вклучиме диодата, па откако ќе го
извршиме тоа уште една проверка дали е притиснат за да ја исклучиме, што би се
повторувало бесконечно. Тоа би го постигнале со следното парче код:
While(1)
{
while(!(GPIOA -> IDR & 0x1));
GPIOE -> ODR |= 0x400;

while(!(GPIOA -> IDR & 0x1));


GPIOE -> ODR &= 0xFFFFFBFF;
}
Иако кодот изгледа коректен, сепак нема да го извршува тоа што ни е потребно
кога микроконтролерот ќе работи во реално време. Зошто? Инструкциите се
извршуваат со голема брзина, со фреквенција во [MHz] така што едно притиснување на
тастерот од човек кое трае најмалку десетици милисекунди ќе биде исчитано како
високо логичко ниво огромен број на пати во оваа бесконечна јамка. Тоа значи дека за
ова време диодата ќе се вклучува па исклучува итн. се додека не биде пуштен тастерот,
а тоа би било случаен момент каде што диодата ќе остане во последната состојба во
која бил поставен пинот. Ова не е посакуваното однесување на системот, па затоа
треба да воведеме дополнителни проверки. Покрај проверката дали тастерот е
притиснат, откако ќе ја вклучиме/исклучиме диодата потребено е да провериме и дали

12 Задачи | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

е пуштен. Значи воведуваме нови две линии код: притиснат, откако ќе ја


вклучиме/исклучиме диодата потребено е да провериме и дали е пуштен. Значи
воведуваме нови две линии код:
while(1)
{
while(!(GPIOA -> IDR & 0x1));
GPIOE -> ODR |= 0x400;
while(GPIOA -> IDR & 0x1);

while(!(GPIOA -> IDR & 0x1));


GPIOE -> ODR &= 0xFFFFFBFF;
while(GPIOA -> IDR & 0x1);
}
На овој начин однесувањето на системот е целосно дефинирано и ја добиваме
посакуваната функционалност. Во продолжение следи целосниот изворен код на main.c
за примерот 4.
#include "cmsis_lib/include/stm32f30x_gpio.h"
#include "cmsis_lib/include/stm32f30x_rcc.h"

int main(void)
{
RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
GPIOE -> MODER |= 0x00100000; //Konfiguriranje na pin PE10
//(LD5) kako izlezen pin za
//generalna namena
GPIOE -> OTYPER &= 0xFFFFFBFF; //Konfiguriranje na pin PE10
//(LD5) kako izlezen push pull
//pin
GPIOE -> OSPEEDR |= 0x0030000; //Postavuvanje na brzinata na
//pin PE10 (LD4) na high speed
GPIOE -> PUPDR &= 0xFFCFFFFF; //Konfiguriranje na pin PE10
//(LD5) no pull-up no pull-
//down

RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA -> MODER &= 0xFFFFFFFC; //Konfiguriranje na pin PA0
//(Button B1) kako vlezen pin
GPIOA -> OSPEEDR |= 0x3; //Postavuvanje na brzinata na
//pin PA0 (Button B1) na high
//speed
GPIOA -> PUPDR |= 0x2; //Konfiguriranje na pin PA0
//(Button B1) pull-down

while(1) //Beskonecna jamka


{
while(!(GPIOA -> IDR & 0x1)); //Cekaj dodeka ne bide
//pritisnato kopceto B1

13 Задачи | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

GPIOE -> ODR |= 0x400; //Setiraj pin PE10


//vkluci dioda LD5
while(GPIOA -> IDR & 0x1); //Cekaj dodeka e
//pritisnato kopceto B1

while(!(GPIOA -> IDR & 0x1)); //Cekaj dodeka ne bide


//pritisnato kopceto B1
GPIOE -> ODR &= 0xFFFFFBFF; //Setiraj pin PE10
//vkluci dioda LD5
while(GPIOA -> IDR & 0x1); //Cekaj dodeka e
//pritisnato kopceto B1
}
}

5. Потребно ни е да реализираме систем кој што по еднократно притиснување на


тастерот ќе ја вклучи и потоа исклучи LED диодата вкупно 5 пати, и потоа повторно би
чекал на притисок на тастерот за да го изврши истото. Јасно е дека потребно ни е да
воведеме бесконечна јамка (на пример со while(1) { ... } ), и на самиот почеток на таа
јамка да ја проверуваме состојбата на пинот. Ако утврдиме дека има високо логичко
ниво на истиот, треба да следи вклучувањето и исклучувањето на LED диодата со
соодветни паузи помеѓу, за да може човечкото око да ги забележи промените.
Потребен ни е и некаков бројач за тоа колку пати е вклучена па исклучена LED
диодата, кој ќе го проверуваме и доколку утврдиме дека изминал 5 циклуси ќе
завршиме со постапката. За таа цел во овој пример користиме локална променлива
наречена brojac која е вградена во for циклус предвиден за 5 изминувања на
внатрешниот код (вкл../искл. на диодата). За поголема флексибилност на кодот,
наместо во for циклусот да го ограничиме извршувањето до 5 како константа, го
задаваме лимитот параметарски преку #define дефиниција која ја нарековме во
случајов ODBROJUVANJE. Ако овој лимит постоеше во кодот на поголем број места,
неговата вредност ќе можеше едноставно да ја смениме во линијата #define
ODBROJUVANJE ... кога би била потребна промена во функционалноста на кодот.
Во продолжение следува изворниот код на main.c за примерот 5.
#include "cmsis_lib/include/stm32f30x_gpio.h"
#include "cmsis_lib/include/stm32f30x_rcc.h"

#define ODBROJUVANJE 5

int main(void)
{
int i,brojac;
RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
GPIOE -> MODER |= 0x00100000; //Konfiguriranje na pin PE10
//(LD5) kako izlezen pin za
//generalna namena
GPIOE -> OTYPER &= 0xFFFFFBFF; //Konfiguriranje na pin PE10
//(LD5) kako izlezen push pull
//pin
GPIOE -> OSPEEDR |= 0x0030000; //Postavuvanje na brzinata na
//pin PE10 (LD4) na high speed

14 Задачи | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

GPIOE -> PUPDR &= 0xFFCFFFFF; //Konfiguriranje na pin PE10


//(LD5) no pull-up no pull-
//down

RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA -> MODER &= 0xFFFFFFFC; //Konfiguriranje na pin PA0
//(Button B1) kako vlezen pin
GPIOA -> OSPEEDR |= 0x3; //Postavuvanje na brzinata na
//pin PA0 (Button B1) na high
//speed
GPIOA -> PUPDR |= 0x2; //Konfiguriranje na pin PA0
//(Button B1) pull-down

while(1) //Beskonecna jamka


{
while(!(GPIOA -> IDR & 0x1)); //Cekaj dodeka ne bide
//pritisnato kopceto B1
for(brojac = 0; brojac < ODBROJUVANJE; brojac++)
{ //jamka za 5 kratno povtoruvanje
//na trepkanjeto na diodata

GPIOE -> ODR |= 0x400; //Setiraj pin PE10


//vkluci dioda LD5
for(i = 0; i < 1000000; i++); //ednostavna jamka
//za docnenje
GPIOE -> ODR &= 0xFFFFFBFF; //Setiraj pin PE10
//vkluci dioda LD5
for(i = 0; i < 1000000; i++); //ednostavna jamka
//za docnenje
}

}
}

15 Задачи | Никола Јовановски


February 16, 2016 ЛАБОРАТОРИСКА ВЕЖБА 2 GPIO

Слика 14. Лед диоди на F3 плочата и нивната поврзаност со пиновите од


STM32F303 микроконтролерот.

Слика 15. USER копчето на плочата F3 и неговата поврзаност со пинот PA0 од


STM32F303 микроконтролерот.
16 Задачи | Никола Јовановски

You might also like