Documente Academic
Documente Profesional
Documente Cultură
George Mois
December 7, 2021
Abstract
Luare de decizii, operat, ii pe bit, i, manipulare intrări s, i ies, iri.
1 Luarea de decizii
Când este scris un program, există ı̂ntotdeauna o parte a codului care este executată
doar atunci când sunt verificate unele condit, ii particulare. Codul trebuie să react, ioneze
corect ı̂n funct, ie de unele evenimente sau condit, ii interne sau externe. Un exemplu ar
putea fi atunci când utilizatorul apasă o tastă predefinită pentru execut, ia unui anumit set
de instruct, iuni sau efectuarea unei alte operat, ii ı̂n cazul altei taste apăsate. Un exemplu
practic ar putea fi un sistem de controlare a nivelului apei ı̂ntr-o incintă: atunci când
senzorul detectează cres, terea nivelului apei peste un anumit prag, programul execută
instruct, iuni pentru a opri motorul pompei de alimentare cu apă.
C oferă următoarele tipuri de declarat, ii de luare a deciziilor:
• Instruct, iune if – evaluează o expresie s, i execută una sau mai multe instruct, iuni
atunci când expresia este adevărată;
• Instruct, iune if ... else – o instruct, iune if poate fi urmată de o instruct, iune opt, ională
else, care se execută atunci când expresia este evaluată ca fiind falsă;
• Instruct, iunea if ... else if ... else – permite evaluarea mai multor expresii s, i
execută diferite blocuri de cod pentru mai mult de două condit, ii;
• Operatorul condit, ional – prezentat ı̂n labortorul precedent;
• Instruct, iunea switch – permite testarea unei expresii pentru egalitate fat, ă de o
listă de valori.
1
if ( expresie )
{
instructiune 1 ;
instructiune 2 ;
...
instructiune n ;
}
Expresia are următorul efect:
– Se evaluează expresia.
– Dacă rezultatul evaluării este True, atunci blocul de cod din cadrul instruct, iunii
if este executat.
– Dacă rezultatul evaluării este False, atunci se execută prima instruct, iune după
instruct, iunea if.
Programatorul trebuie să introducă ı̂ntre parantezele rotunde condit, ia pentru care
programul trebuie să execute o instruct, iune unică sau multiplă. Dacă condit, ia va fi
adevărată, programul va executa instruct, iunile, iar dacă aceasta este falsă, programul
va sări peste instruct, iunile respective. Un alt lucru de ret, inut este faptul că instruct, iunile
trebuie să fie ı̂ntotdeauna incluse ı̂ntre acolade dacă sunt mai multe. Expresia nu trebuie
să fie urmată de punct s, i virgulă.
1.1.1 Exemplu
Eroare comună la folosirea instruct, iunii if :
# i n c l u d e < s t d i o . h>
i n t main ( )
{
i n t myData = 6 0 ;
i f ( myData >= 4 0 ) ;
{
/ / nu s e va e x e c u t a
p r i n t f ( ” V a l u e − %d . \ n ” , myData ) ;
myData = 0 ;
}
/ / i n s t r . in afara i f
myData ++;
return 0;
}
2
1.1.2 Exemplu
Folosirea unei variabile ca s, i condit, ie.
# i n c l u d e < s t d i o . h>
u i n t 8 t btnApasat = 0;
i n t main ( v o i d )
{
i f ( btnApasat )
{
/ / s e e x e c u t a daca b t n A p a s a t e s t e d i f e r i t de 0
p r i n t f ( ” P o r n e s t e LED . \ n ” ) ;
btnApasat = 0;
}
return 0;
}
1.1.3 Exercit, iu
Scriet, i un program care primes, te vârsta utilizatorului s, i ı̂i spune dacă are drept de vot.
Afis, at, i mesaje corespunzătoare.
3
if ( expresie )
{
instructiune 1 1;
instructiune 1 2;
...
instructiune 1 n;
}
else
{
instructiune 2 1;
instructiune 2 2;
...
instructiune 2 n;
}
Expresia are următorul efect:
– Se evaluează expresia.
– Dacă rezultatul evaluării este True, atunci blocul de cod din cadrul instruct, iunii
if este executat.
– Dacă rezultatul evaluării este False, atunci blocul de cod corespunzător ramurii
else este executat.
1.2.1 Exercit, iu
Modificat, i exercit, iul anterior pentru a folosi instruct, iunea if ... else.
1.2.2 Exercit, iu
Scriet, i un program care afis, ează cel mai mare dintre două numere introduse de către
utilizator. Dacă cele două numere sunt egale, atunci se afis, ează un mesaj corespunzător.
Modificat, i programul pentru a accepta s, i numere reale s, i a afis, a un mesaj de atent, ionare
dacă se introduc numere cu parte zecimală. Comparat, i doar partea ı̂ntreagă.
Modificat, i programul pentru a termina execut, ia dacă se introduc caractere ı̂n loc
de numere (scanf returnează 0 dacă operat, ia de citire este terminata fără succes, s, i 1
altfel).
if ( expresie1 )
{
instructiuni ;
}
else if ( expresie2 )
{
instructiuni ;
}
4
...
else
{
instructiuni ;
}
Expresia are urmatorul efect:
– Se evaluează expresie1.
– Dacă rezultatul evaluării este True, atunci blocul de cod din cadrul instruct, iunii
if este executat.
– Dacă rezultatul evaluării este False, atunci se evaluează expresie2.
– Dacă rezultatul evaluării este True, atunci blocul de cod din cadrul instruct, iunii
if este executat.
– ....
– Dacă rezultatul evaluării este False, atunci blocul de cod corespunzător ramurii
if este executat.
1.3.1 Exemplu
# i n c l u d e < s t d i o . h>
i n t main ( )
{
int grade = 0;
p r i n t f ( ” E n t e r t h e number o f p o i n t s o b t a i n e d a t t h e exam : ” ) ;
fflush ( stdout );
s c a n f ( ”%d ” , &g r a d e ) ;
i f ( ( g r a d e >= 0 ) && ( g r a d e <= 1 0 0 ) ) {
i f ( g r a d e >= 9 0 )
p r i n t f ( ” P a s s e d w i t h A. \ n ” ) ;
e l s e i f ( g r a d e >= 8 0 )
p r i n t f ( ” Passed with B.\ n” ) ;
e l s e i f ( g r a d e >= 7 0 )
p r i n t f ( ” Passed with C.\ n” ) ;
e l s e i f ( g r a d e >= 6 0 )
p r i n t f ( ” P a s s e d w i t h D. \ n ” ) ;
else
p r i n t f ( ” Failed .\ n” ) ;
}
else {
p r i n t f ( ”You e n t e r e d an i n v a l i d g r a d e ! ” ) ;
}
fflush ( stdout );
5
wait user input ();
return 0;
}
1.3.2 Exercit, iu
Scriet, i un program care să calculeze taxele pentru utilizator, conform cu tabelul de mai
jos:
Table 1: Taxe
Venit % taxe
Până la 9525USD 0
Între 9526 s, i 38700 USD 12%
Între 38701 s, i 82500 USD 22%
Peste 82500 USD 32% + 1000 USD
6
1.4 Instruct, iunea switch
Instruct, iunea switch poate fi folosită ı̂n locul instruct, iunii if ... else if ... else. De obicei
este mai rapidă decât instruct, iuni if ... else imbricate.
Sintaxa:
switch ( expression )
{
case constant1 :
/ / statements
break ;
case constant2 :
/ / statements
break ;
.
.
.
default :
/ / default statements
}
Expresia are următorul efect:
– Se evaluează expresia.
– Rezultatul evaluării este comparat cu constant1, constant2, ... .
– Dacă rezultatul este egal cu una dintre constante, atunci este executat blocul de
cod corespunzător.
– Dacă rezultatul nu este egal cu niciuna dintre constante, atunci este executat
blocul de cod corespunzător etichetei default.
Ramura default este opt, ională. Dacă ea lipses, te s, i valoarea expresiei nu se potrives, te
cu nicio constantă, instruct, iunea switch nu are efect. De asemenea, declarat, ia break
este opt, ională. Dacă instruct, iunea break lipses, te, toate instruct, iunile care urmează sunt
executate, până când se ı̂ntâlnes, te fie o instruct, iune break, fie se termină instruct, iunea
switch. Constantele trebuie să aibă acelas, i tip de date ca s, i expresia. Tipurile de date
permise sunt ı̂ntregi s, i caractere.
1.4.1 Exemplu
# i n c l u d e < s t d i o . h>
i n t main ( ) {
int grade = 0;
p r i n t f ( ” E n t e r one o f t h e f o l l o w i n g A, a , B , b , C , c , D, d , F , f : ” ) ;
grade = getchar ( ) ;
switch ( grade ) {
case ’ a ’ :
7
c a s e ’A ’ : p r i n t f ( ” Grade b e t w e e n 90 and 1 0 0 . \ n ” ) ;
break ;
case ’b ’ :
c a s e ’B ’ : p r i n t f ( ” Grade b e t w e e n 80 and 9 0 . \ n ” ) ;
break ;
case ’ c ’ :
c a s e ’C ’ : p r i n t f ( ” Grade b e t w e e n 70 and 8 0 . \ n ” ) ;
break ;
case ’d ’ :
c a s e ’D ’ : p r i n t f ( ” Grade b e t w e e n 60 and 7 0 . \ n ” ) ;
break ;
case ’ f ’ :
c a s e ’ F ’ : p r i n t f ( ” Grade b e t w e e n 0 and 6 0 . \ n ” ) ;
break ;
d e f a u l t : p r i n t f ( ”You e n t e r e d an i n v a l i d grade ! ” ) ;
}
return 0;
}
1.4.2 Exercit, iu
Scriet, i un program care să calculeze aria diferitelor forme geometrice, conform cu
tabelul de mai jos:
Table 2: Select, ii
Cod Formă geometrică Formulă
’c’ cerc PI * r2
’t’ triunghi (b * h)/2
’d’ dreptunghi (L * l)
’p’ pătrat l2
’r’ trapezoid ((B + b)/2)*h
8
2 Operat, ii pe bit, i
Aceste operat, ii sunt utilizate ı̂n mod obis, nuit s, i pe scară largă ı̂n C pentru manipularea
datelor din regis, tri.
Este important să ret, inem că este o diferent, ă ı̂ntre operatorii logici s, i operatorii
pentru operat, ii pe bit, i:
• && – operatorul logic AND,
• k – operatorul logic OR.
2.1 Exemplu
În exemplu, rezultatul folosirii operatorului logic este zero sau diferit de zero sau
fals sau adevărat. Dacă variabila este o valoare diferită de zero, valoarea exactă nu
contează pentru calcularea rezultatului. În cazul operatorului bitwise, se va efectua S, I
pentru fiecare bit apart, inând celor doi operanzi, acest lucru ı̂nsemnând că rezultatul
nu va fi boolean. În exemplu vedem că S, I se realizează bit cu bit ı̂ntre reprezentarea
9
binară a celor doi operanzi. Această diferent, ă este valabilă s, i pentru SAU bitwise s, i
SAU logic.
10
3 Testarea, resetarea s, i setarea bit, ilor
3.1 Exemplu
Exemplu pentru determinarea parităt, ii unui număr.
Este clar că valoarea bitului LSB poate fi utilizată pentru a evalua dacă un număr
este par sau impar. Pentru numerele pare LSB este egal cu 0 ı̂n timp ce acest bit este
egal cu 1 pentru numerele impare. Principala problemă este identificarea valorii LSB
pentru un anumit număr. Aceasta problemă poate fi rezolvată folosind o tehnică numită
bit masking. Un exemplu de bit masking este prezentat pe pagina anterioară, pentru
testarea valorii LSB a unui număr. Operatorul S, I bitwise este aplicat ı̂ntre număr s, i
valoarea 0x01. Efectuând această operat, ie (S, I cu zero pentru tot, i bit, ii ı̂n afară de LSB)
tot, i bit, ii ı̂n afară de LSB vor fi zero. În cazul LSB, dacă LSB = 0, S, I va da 0 ca rezultat,
s, i 1 dacă LSB = 1.
Bit masking, care poate fi utilizată s, i pentru operatorul SAU, are două scopuri prin-
cipale:
• modificarea valorii unui bit (din 0 ı̂n 1 folosind SAU cu 1, s, i din 1 ı̂n 0 folosind
S, I cu 0),
• testarea valorii unui bit (verificarea dacă valoarea bitului de pe o anumită pozit, ie
este 0 sau 1).
11
Este de ret, inut utilitatea practică a operatorului SAU-EXCLUSIV (XOR). Acesta
poate fi folosit, de exemplu, pentru comutarea unei ies, iri (ex. conectată la un LED).
3.2 Exemplu
4.1.1 Exemplu
Exemplul ilustrează o deplasare la dreapta a variabilei a cu 4 pozit, ii. La fiecare pas
bitul din partea dreaptă va fi ı̂mpins s, i se va pierde. T, inând cont că este o deplasare
a tuturor bit, ilor spre dreapta cu o pozit, ie, este clar că pentru bitul cel mai din stânga
vom avea o pozit, ie goală. Aceasta va fi completată cu 0 ı̂n mod implicit. Dacă acest
mecanism se repetă de 4 ori, 4 bit, i din partea dreaptă se vor pierde s, i 4 bit, i de 0 vor fi
inserat, i ı̂n stânga.
12
Figure 4: Shiftare la dreapta
Operat, iile de shiftare la drepta s, i la stânga sunt folosite pentru a ı̂mpărt, i sau ı̂nmult, i
la/cu 2. Această proprietate a operat, iilor de shiftare este foarte utilă ı̂n programare.
13
Utilizări:
• bit masking a variabilelor pentru folosirea ı̂n alte operat, ii pe bit, i,
• setarea sau resetarea bit, ilor.
4.3 Exemplu
Setarea bitului al 4-lea al unui anumit număr.
14
Resetarea bitului al 4-lea al unui anumit număr.
15
4.4 Exemplu
Extragerea unui număr de bit, i dintr-un alt număr s, i salvarea lor. Extragerea bit, ilor de
la pozit, ia 9 la pozit, ia 14 s, i salvarea lor ı̂ntr-o altă variabilă.
# i n c l u d e <s t d i o . h>
i n t main ( )
{
printf ( ” 1\ n ” ) ;
printf ( ” 2\ n ” ) ;
printf ( ” 3\ n ” ) ;
printf ( ” 4\ n ” ) ;
printf ( ” 5\ n ” ) ;
printf ( ” 6\ n ” ) ;
printf ( ” 7\ n ” ) ;
printf ( ” 8\ n ” ) ;
printf ( ” 9\ n ” ) ;
printf ( ” 10\ n ” ) ;
return 0;
}
# i n c l u d e <s t d i o . h>
# i n c l u d e < s t d i n t . h>
i n t main ( )
{
16
u i n t 8 t i = 1;
w h i l e ( i <=10)
{
p r i n t f ( ”%d \ n ” , i ) ;
i ++;
}
return 0;
}
Cele două programe execută aceeas, i instruct, iune. Exemplul al doilea utilizează o
buclă. Codul arată mai eficient s, i mai compact. Este us, or să ne imaginăm că de cele
mai multe ori numărul de operat, ii de efectuat ar putea fi mult mai mult de 10 (ar fi
foarte enervantă s, i inutilă repetarea aceleias, i comenzi de atâtea ori).
C oferă următoarele tipuri de instruct, iuni pentru implementarea buclelor:
– for – execută una sau mai multe instruct, iuni de mai multe ori utilizând o vari-
abilă;
– while – repetă una sau mai multe instruct, iuni ı̂n timp ce o expresie dată este
adevărată s, i evaluează expresia ı̂nainte de a executa corpul buclei;
– do ... while – repetă una sau mai multe instruct, iuni ı̂n timp ce o expresie dată
este adevărată s, i evaluează expresia de la sfârs, itul corpului buclei.
Buclele permit executarea unor instruct, iuni repetitiv până când sunt ı̂ndeplinite an-
umite condit, ii. Setările acestor condit, ii sunt cruciale pentru funct, ionarea corectă a
buclei.
5.2 while
Sintaxa:
while ( e x p r e s i e )
{ / / s t a r t corp i n s t r while
/ / b u c l a w h i l e cu mai m u l t e i n s t r u c t i u n i
instr1 ;
instr2 ;
instr3 ;
...
instrN ;
} / / end c o r p i n s t r w h i l e
/ / b u c l a w h i l e cu o s i n g u r a i n s t r u c t i u n e
while ( e x p r e s i e )
instr ;
/ / s e p o t f o l o s i a c o l a d e l e daca s e d o r e s t e
Această instruct, iune are următorul efect:
– Expresia este evaluată.
17
– Dacă rezultatul evaluării este adevărat, atunci blocul de cod din while este exe-
cutat s, i expresia este evaluată din nou.
– Dacă rezultatul evaluării este fals, atunci prima declarat, ie după sfârs, itul while
este executată.
Este posibil ca o instruct, iune while să nu se execute deloc. Când expresia este
evaluată s, i rezultatul este fals de la ı̂nceput, blocul de cod din while este omis s, i prima
declarat, ie după while este executată.
Blocul de cod din interiorul unei instruct, iuni while trebuie să cont, ină câteva instruct, iuni
care modifică valoarea variabilelor din expresie.
5.2.1 Exemplu
# i n c l u d e < s t d i o . h>
# d e f i n e PERIOD ’ . ’
i n t main ( v o i d )
{
int character = 0 , no character = 0;
5.2.2 Atent, ie
Plasarea unui caracter ; imediat după instruct, iunea while duce la bucle infinite s, i im-
plicit la bug-uri ı̂n cod (code hangs forever). Această gres, eală nu va fi recunoscută ı̂n
timpul compilării, dar va schimba complet logica programului.
/ / b u c l a w h i l e cu o s i n g u r a i n s t r u c t i u n e
while ( e x p r e s i e ) ;
instr ;
/ / s e p o t f o l o s i a c o l a d e l e daca s e d o r e s t e
18
5.2.3 Bucle infinite
Bucla infinită este un tip special de buclă while. Aceste bucle sunt comune ı̂n progra-
marea C, ı̂n special cele care rulează pe microcontrolere.
# i n c l u d e < s t d i o . h>
i n t main ( v o i d )
{
/* Super loop */
while ( 1 )
{
readSensorData ( ) ;
processData ( ) ;
displayAcquiredData ( ) ;
}
}
5.3.1 Exemplu
# i n c l u d e < s t d i o . h>
# d e f i n e PERIOD ’ . ’
i n t main ( )
{
19
int character = 0 , no character = 0;
5.4 for
Sintaxa:
for ( expresie1 ; expresie2 ; expresie3 )
{
instructiuni ;
}
Această instruct, iune are următorul efect:
– expresie1 este executată prima s, i o singură dată. Acest pas permite programato-
rilor să definească s, i să init, ializeze orice variabilă de control al buclei.
– Se evaluează expresie2.
– Dacă rezultatul evaluării este adevărat, atunci blocul de cod din for este executat.
– Dacă rezultatul evaluării este fals, atunci se execută prima afirmat, ie după sfârs, itul
for.
– După executarea blocului de cod din for, se execută expresie3. Acest pas permite
programatorilor să actualizeze orice variabilă de control al buclei.
– expresie2 este acum evaluată din nou. Dacă este adevărat, bucla se execută s, i
procesul se repetă. După ce expresie2 devine falsă, se termină bucla for.
expresie1, expresie2 s, i expresie3 pot lipsi, dar caracterul ; trebuie sa apară.
O buclă devine infinită dacă evaluarea unei expresii este ı̂ntotdeauna adevărată.
Bucla for este utilizată ı̂n mod tradit, ional ı̂n acest scop. Deoarece niciuna dintre cele
trei expresii care formează declarat, ia for nu este necesară, se poate face o buclă fără
sfârs, it lăsând expresia2 goală.
20
5.4.1 Exemplu
# i n c l u d e < s t d i o . h>
# d e f i n e MAX SIZE 100
i n t main ( )
{
f l o a t numbers [ MAX SIZE ] = { 0 } , a v e r a g e = 0 . 0 f , sum = 0 . 0 f ;
int i = 0 , no numbers = 0 ;
p r i n t f ( ” A r i t h m e t i c avg . v a l u e o f n (<%d ) r e a l no . \ n ” , MAX SIZE ) ;
p r i n t f ( ” I n p u t t h e number o f r e a l numbers , n = ” ) ;
fflush ( stdout );
s c a n f ( ”%d ” , &n o n u m b e r s ) ;
i f ( n o n u m b e r s > 0 && n o n u m b e r s <= MAX SIZE ) {
p r i n t f ( ” I n p u t t h e r e a l numbers : \ n ” ) ;
fflush ( stdout );
f o r ( i =0 , sum = 0 ; i < n o n u m b e r s ; i ++) {
p r i n t f ( ” numbers [%3d ] = ” , i + 1 ) ;
fflush ( stdout );
s c a n f ( ”%f ” , &numbers [ i ] ) ;
sum += numbers [ i ] ;
}
a v e r a g e = sum / n o n u m b e r s ;
p r i n t f ( ” \nAVERAGE = %.2 f \ n ” , a v e r a g e ) ;
}
else
p r i n t f ( ” The number o f r e a l numbers i s i n v a l i d . ” ) ;
fflush ( stdout );
return 0;
}
21
6.1 Exercit, iu
Scriet, i un program care afis, ează toate numerele pare de la 0 la 100, inclusiv. Numărat, i
s, i cate numere pare găsit, i. Folosit, i oricare tip de buclă dorit, i. Modificat, i apoi progra-
mul pentru a accepta numerele limită de la utilizator.
7 Recomandare
10 reguli de bază pentru scrierea de cod: link1, link2.
În figură se poate vedea ca LED-ul este conectat la pinul PA5 (port A pin 5).
Numărul pinului fizic se poate găsi ı̂n manualul de referint, a (TRM) a microcontroleru-
lui, sau mai simplu, ı̂n datasheet. Controlarea acestui pin (HIGH sau LOW) controlează
LED-ul. As, adar, ceea ce vrem să realizăm este controlarea pinului I/O PA5, prin setarea
la LOW sau HIGH, de către software pentru a opri sau porni LED-ul.
22
8.2 Porturi
Porturile sunt reprezentate de regis, tri ı̂n interiorul microcontrolerului s, i permit progra-
mului (firmware-ului) să controleze starea pinilor sau, invers, să citească starea pinilor
(dacă porturile sunt configurate ca intrări).
Fiecare port din sistemele STM32Fx sunt alcătuite din 16 pini la care se pot conecta
periferice (LED, afis, aje, butoane, memorii externe, tastaturi, etc.).
PA5 este al cincilea GPIO al portului A.
23
Locat, iile adreselor mapate de memorie sunt ı̂nregistrate ı̂n TRM. De obicei, harta
memoriei se gaseste ı̂n sect, iunea 2 a manualului de referint, ă.
Table 4: Regis, trii periferici GPIOA (GPIO register map ı̂n manual)
Nr. Registru
1 GPIOA port mode register
2 GPIOA port output type register
3 GPIOA port output speed register
4 GPIOA port pull-up/pull-down register
5 GPIOA port input data register
6 GPIOA port output data register
7 GPIOA port bit set/reset register
8 GPIOA port configuration lock register
9 GPIOA port alternate function low register
10 GPIOA port alternate function high register
Regis, trii de moduri indică dacă pinul va fi unul de intrare sau de ies, ire. Registrul
de pull-up s, i pull-down permite activarea sau dezactivarea rezistent, elor de pull-up sau
pull-down.
GPIO A este controlat de un registru pe 32 de bit, i, iar pentru a seta sau s, terge bitul
dorit (controlarea unui singur pin), este necesar să se utilizeze tehnica de mascare a
bitului respectiv. De exemplu, pentru a seta bitul 0 la HIGH este suficientă o operat, ie
SAU pe registrul GPIO A cu o mască potrivită (GPIO A SAU 0x0000001).
24
8.4 Pas, i necesari
Procedura de pornire a unui LED poate fi rezumată ı̂n următorii pas, i:
– identificarea portului GPIO (periferic) utilizat pentru conectarea LED-ului (ı̂n
cazul nostru GPIO A);
– identificarea pinului GPIO la care este conectat LED-ul, ı̂n cazul nostru 5;
– identificarea perifericului GPIO A si activarea lui (activare ceas);
– până când se activează un periferic, el este inactiv, nu funct, ionează s, i nu ia
valori de configurare setate de programator;
– odată cu activarea ceasului unui periferic, acesta este gata să preia comenzi
sau argumente (valori de configurare);
– pentru unele microcontrolere, perifericul poate fi PORNIT ı̂n mod implicit
si necesită activare (RTM – read the manual);
– configurarea modului pinului GPIO ca ies, ire (se comandă un LED);
– scriere pin (scriere Output Data Register)
– 1 - HIGH pentru 3.3V;
– 0 - LOW pentru 0V.
25
Figure 13: Activare ceas pentru GPIOA
26
Address of GPIOA: 0x40020000.
GPIO port output data register pentru port A: 0x14.
As, adar, adresa registrului este: 0x40020014.
27
8.8 Codul
# i n c l u d e < s t d i n t . h>
i n t main ( v o i d )
{
u i n t 3 2 t * p C l k C t r l R e g = ( u i n t 3 2 t * ) 0 x40023830 ;
u i n t 3 2 t * pPortAModeReg = ( u i n t 3 2 t * ) 0 x40020000 ;
u i n t 3 2 t * pPortAOutReg = ( u i n t 3 2 t * ) 0 x40020014 ;
/ / E n a b l e c l o c k f o r GPIOA
/ * u i n t 3 2 t temp = * p C l k C t r l R e g ;
temp = temp | 0 x0001 ;
* p C l k C t r l R e g = temp ; * /
* p C l k C t r l R e g | = 0 x0001 ;
/ / S e t o u t p u t mode f o r PA5
/ / F i r s t c l e a r mode f o r PA5
* pPortAModeReg &= ˜ 0 x00000C00 ;
/ / S e t o u t p u t mode f o r PA5
* pPortAModeReg | = 0 x00000400 ;
/ / S e t PA5 HIGH
* pPortAOutReg | = 0 x0020 ;
/ / Super loop
for ( ; ; ) ;
}
28
Urmează codul care foloses, te shiftare pe bit, i.
# i n c l u d e < s t d i n t . h>
i n t main ( v o i d )
{
u i n t 3 2 t * p C l k C t r l R e g = ( u i n t 3 2 t * ) 0 x40023830 ;
u i n t 3 2 t * pPortAModeReg = ( u i n t 3 2 t * ) 0 x40020000 ;
u i n t 3 2 t * pPortAOutReg = ( u i n t 3 2 t * ) 0 x40020014 ;
/ / E n a b l e c l o c k f o r GPIOA
/ * u i n t 3 2 t temp = * p C l k C t r l R e g ;
temp = temp | 0 x0001 ;
* p C l k C t r l R e g = temp ; * /
/ / s e t b i t 0 of ClkCtrlReg
* p C l k C t r l R e g | = 0 x0001 << 0 ;
/ / S e t o u t p u t mode f o r PA5
/ / F i r s t c l e a r mode f o r PA5 ( c l e a r b i t s 10 and 11 o f PortAModeReg )
* pPortAModeReg &= ˜ ( 0 x03 << 1 0 ) ;
/ / S e t o u t p u t mode f o r PA5 ( s e t p i n s 11 and 10 w i t h v a l u e 0 1 )
* pPortAModeReg | = ( 0 x01 << 1 0 ) ;
for ( ; ; ) ;
}
29
8.8.1 Debug
30
8.8.2 Modificarea codului pentru a comuta LED-ul folosind ı̂ntârzieri software
# i n c l u d e < s t d i n t . h>
i n t main ( v o i d )
{
u i n t 3 2 t * p C l k C t r l R e g = ( u i n t 3 2 t * ) 0 x40023830 ;
u i n t 3 2 t * pPortAModeReg = ( u i n t 3 2 t * ) 0 x40020000 ;
u i n t 3 2 t * pPortAOutReg = ( u i n t 3 2 t * ) 0 x40020014 ;
/ / E n a b l e c l o c k f o r GPIOA
/ * u i n t 3 2 t temp = * p C l k C t r l R e g ;
temp = temp | 0 x0001 ;
* p C l k C t r l R e g = temp ; * /
/ / s e t b i t 0 of ClkCtrlReg
* p C l k C t r l R e g | = 0 x0001 << 0 ;
/ / S e t o u t p u t mode f o r PA5
/ / F i r s t c l e a r mode f o r PA5 ( c l e a r b i t s 10 and 11 o f PortAModeReg )
* pPortAModeReg &= ˜ ( 0 x03 << 1 0 ) ;
/ / S e t o u t p u t mode f o r PA5 ( s e t p i n s 11 and 10 w i t h v a l u e 0 1 )
* pPortAModeReg | = ( 0 x01 << 1 0 ) ;
for ( ; ; )
{
/ / S e t PA5 HIGH ( s e t p i n 5 o f GPIOx ODR )
* pPortAOutReg | = ( 0 x01 << 5 ) ;
/ / For l o o p w i t h NOP
f o r ( u i n t 3 2 t i = 0 ; i <100000; i + + ) ;
/ / For l o o p w i t h NOP
f o r ( u i n t 3 2 t i = 0 ; i <100000; i + + ) ;
}
}
31
Figure 18: Dissasembly buclă for
/ / For l o o p w i t h NOP
f o r ( u i n t 3 2 t i = 0 ; i <50000; i + + ) ;
}
32
9 Citirea unei intrări pe placa de dezvoltare Nucleo
Citirea stării butonului pentru utilizator de pe placa de dezvoltare Nucleo.
În figură se poate vedea că butonul este conectat la pinul PC13 (port C pin 13).
Atunci când butonul este apăsat, PC13 este LOW, iar când butonul este liber, PC13
este HIGH.
PC13 trebuie să fie ı̂n modul intrare, iar pentru a ı̂i citi starea, trebuie să citim portul
C.
33
Address of GPIOC: 0x40020800
GPIO port mode register address offset pentru port C: 0x10.
As, adar, adresa registrului este: 0x40020810.
9.5 Codul
# i n c l u d e < s t d i n t . h>
i n t main ( v o i d )
{
/ / RCC AHB1 p e r i p h e r a l c l o c k e n a b l e r e g .
u i n t 3 2 t * p C l k C t r l R e g = ( u i n t 3 2 t * ) 0 x40023830 ;
/ / GPIOA p o r t mode r e g i s t e r
u i n t 3 2 t * pPortAModeReg = ( u i n t 3 2 t * ) 0 x40020000 ;
/ / GPIOA p o r t o u t p u t d a t a r e g .
u i n t 3 2 t * pPortAOutReg = ( u i n t 3 2 t * ) 0 x40020014 ;
/ / GPIOC p o r t mode r e g .
u i n t 3 2 t * pPortCModeReg = ( u i n t 3 2 t * ) 0 x40020800 ;
/ / GPIOC p o r t i n p u t d a t a r e g i s t e r
u i n t 3 2 t * p P o r t C I n R e g = ( u i n t 3 2 t * ) 0 x40020810 ;
/ / E n a b l e c l o c k f o r GPIOA
* p C l k C t r l R e g | = ( 0 x01 <<0);
/ / E n a b l e c l o c k f o r GPIOC
* p C l k C t r l R e g | = ( 0 x01 <<2);
/ / S e t PA5 a s o u t p u t
/ / C l e a r mode b i t s f o r PA5
34
/ / * pPortAModeReg &= ˜ 0 x00000C00 ;
* pPortAModeReg &= ˜ ( 0 x03 < <10);
/ / S e t mode b i t s f o r PA5
/ / * pPortAModeReg |= 0 x00000400 ;
* pPortAModeReg | = ( 0 x01 < <10);
/ / S e t PC13 a s i n p u t
* pPortCModeReg &= ˜ ( 0 x03 < <26);
/ * Loop f o r e v e r * /
for ( ; ; )
{
/ / r e a d PC13 s t a t u s
u i n t 8 t p i n S t a t u s = ( u i n t 8 t ) ( ( * p P o r t C I n R e g & ( 0 x01 < <13)) > >13);
35