marți, 29 iulie 2014

Scoala de vara Lectia 2 - Programare MCU in limbajul C, Modulul periferic GPIO.

Particularitati programare MCU in C.

 
    Un microcontroller, dupa cum am mai mentionat, este un microcalculator comportamentul caruia este definit de programul e care il ruleaza. Scrierea de programe presupune utilizarea unui limbaj specific pe care il poate interpreta aceasta structura inteligenta. Limbajul nativ al microcontrollerului, cel mai apropiat de codul binar care in realitate este inscris in memoria de programe al acestuia este limbajul assembler. O comanda assembler reprezentand o actiune pe care o poate realiza procesorul, prcatic limbajul asembler presupune ca programele reprezinta o secventa de actiuni la nivel cod masina pentru realiza o problema anumita. Neajunsul dezvoltarii aplicatiilor in limbajul ASM este ca fiecare arhitectura de procesor isi are setul sau de instructiuni, respectiv un program care ese scris pentru o arhitectura este putin probabil ca va rula si pe alta arhitectura daca aceasta nu este compatibila cu setul de instructiuni dat.
    Pentru a da o universalitate programelor elaborate se recomanda utilizarea unui limbaj de nivel mai inalt decat ASM, asa cum este de exemplu limbajul C. In acest limbaj se pot dezvolta aplicatii practic pentru orice arhitectura existent la momentul actual. Sintaxa acestui limbaj este standartizata si nu este dependenta de o anumita arhitectura. La moment existu foarte multe referinte pentru studiul limbajului propriu zis, respectiv acest subiect este in afara scopurilor acestui curs.
    Ceia ce intra in obiectivele acestui curs este utilizarea Limbajului C in dezvoltarea aplicatiilor pentru microcontroller.
    Specificlul programelor pentru microcontrollere este ca programul rulat nu trebuie sa se finalizeze niciodata, aceasta fiind una din proprietatile de baza pentru aplicatiile pentru MCU.

   Vim evidentia anumite generalitati a structurii programelor pentru MCU si anume
   Programul este format din doua parti principale
        a) partea de initializare - aici se initializeasa starea initiala a microcontrollerului, si se pregateste sistemul de functionare.
        b) partea de procesare -  reprezinta o bucla infinita ce mentine MCU sub control pe tot parcursul functionarii microcontrollerului. Ca regula programele scrise de incepatori sunt cuprinse integral in aceasta parte, insa in etapele mai avansate, bucla infinita este utilizata mai mult pentru rularea unor taskuri de fundal, functionalitatile principale fiind realizate pe intreruperi.
        c) subrutine de prelucrare a intreruperilor - acest subiect este relatat in mod special la una din urmatoarele lectii

    Modulul Periferic GPIO    

 
    Interfata microcontrollerului, sau mai bine sous interactiunea programului, cu mediul inconjurator al acestuia sunt modulele periferice. modulele periferice realizeaza functia de transformare a semnalelor fizice in informatie pentru a fi prelucrata de catre microcontroller, si inverspentru transformarea informatiei in semnal fizic.
Cel mai simplu si generic modul periferic al microcontrollerului este mdoulul GPIO, port generic de intrare iesire. este de fapt modulul care permite stabilirea nivelelor logice la pinii microcontrollerului, cat si citirea valorilor de pe acestea.
Pentru lucrul cu fiecare din periferiile de acest tip sunt rezervati un set de registri periferici, accesul la care din punct de vedere al limbajului C (explicaatie pentru incepatori) este similar cu acesul la variabile, adica unei structuri de date cu numele registrului se pot atribui date, si se pot citi date din ele.
Pentru arhitectura AVRm, utilizata in cadrul acestui curs, pentru fiecare port sunt rezervati a cate 3 registri.
luand ca exemplu portul A, vom avea PORTA, DDRA si PINA.
- PINA - reprezinta nivelul logic la pinul fizic. Acest registru este doar pentru citire, atribuirea catre el nu va da nici un efect.
- DDRA - registru de seare a directiei portului, setarea in "1" va reprezenta configurarea catre iesire, iar reseterea, "0"- configurarea spre intrare.
- PORTA - registru de generator de valorii logice catre pin. In cazul cand portul este spre iesire - valoarea registrului se va aplica pe pinul fizic. In cazul in care portul este spre intrare va ezista posibilitatea de activa rezitenta de pull-up, cand valoarea portului este setata in"1", in caz contrar piinul microcontrollerului se avla in stare de impenanta inalta, adica asemeni unei sarme deconectate care atarna din MCU.
De mentionat ca fiecare port GPIO in arhitectura AVR este pe 8 bit, respectiv exista posibilitatea de a configura fiecare bit in parte dupa principiul descris mai sus, adica prin configurarea registrilor periferici la nivel de bit.

Surse de informare suplimentare:  
Iniţire în programare ASM. Stiva. Subrutina, Subrutina cu parametri.
    Module periferice Modulul periferic GPIO - Port Generic de Intrare/Ieşire.
    Realizarea construcţiilor algoritmice de bază: condiţii, selecţie multiplă, cicluri.

Aplicatie practica:

Incepand studiul programarii intrul limbal de programare, aproape intotdeauna se incepe de la o aplicatie tip "Hello World!". Pntru studiul programarii pentru Microcontrollere este mai deficil de aplicat acest template de program, motivul principal fiind ca nu exista o interfata standard te intrare/iesire predefinita.
In scimbul acestui template se practica aplicatii de manipulare a pinilor microcontrollerului.cum ar fi aprinderea unui ledsau citirea starii unui buton.
Deci rimul program in C pentru MCU va fi o plicatie care va citi starea pinilor de la un port la care sunt conectati un set de butiane, si transferul valorii acestora catre alt port, la care sunt conectati un set de LEDuri. Portul pentru LEDuri va fi configurat spre iesire, DDRA = 0b11111111, iar cel pentru butoane spre intrare cu activarea rezistentei de pull-up DDRB = 0b00000000, PORTB = 0b11111111
LEDurile sunt conectate cu Anodul la sursa de alimentare, printro rezistenta de limitare a curentului, de 300 Ohm, iar catodul se conecteaza direct la pinul MCU. In asa mod, aplicare "0" la pin va aprinde LEDul, iar "1" il va stinge.
Butonul este conectat intr ground si pinul MCU. In mod deconectat pe pin se va mentine "1" fapt conditionat de rezistenta de pull up activata. la apasarea butonului, pinul se va conecta la ground, si va lua valoarea "0".
In asa mod expresia PORTA = PINB va aprinde LEDurile pe pozitiile in care butoanele sunt apasate, deoaece se transfera "0" de la butonul scurcircuitat pe ground la catodul LED-ului.

#include <avr/io.h> // includem librarie de definitie 
// a adreselor periferiilor

int main(void){
// partea de initializare programului

DDRA = 0b11111111; // setare port A spre iesire
PORTA = 0b11111111; // LED-urile stinse
DDRB = 0b11111111; // setare port B spre intrare
PORTB = 0b00000000; // Activare rezistente pull-up pe butoane

// partea de procesare a programului

while(1){ // bucla infinita pentru mentinerea 
// sub control a microcontrollerului

char value = PINB // colectarea valorii de pe pinii
// conectati la butoane

PORTA = value // aplicare valoare pe pinii
// conectati la cotodul LED-urilor
 
} // sfarsitul buclei infinite
} sfarsitul functie main