+ All Categories
Home > Documents > web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9....

web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9....

Date post: 17-Nov-2018
Category:
Upload: ngodang
View: 220 times
Download: 0 times
Share this document with a friend
134
FACULTATEA DE AUTOMATICĂ ŞI CALCULATOARE DEPARTAMENTUL CALCULATOARE Sistem de monitorizare și comandă pentru vehicule electrice bazat pe microcontroller LUCRARE DE LICENŢĂ Absolvent: Lucian CRIȘAN Coordonator ştiinţific: S.L.Dr.Ing Radu DĂNESCU
Transcript
Page 1: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

FACULTATEA DE AUTOMATICĂ ŞI CALCULATOAREDEPARTAMENTUL CALCULATOARE

Sistem de monitorizare și comandă pentru vehicule electrice bazat pe microcontroller

LUCRARE DE LICENŢĂ

Absolvent: Lucian CRIȘAN

Coordonator ştiinţific: S.L.Dr.Ing Radu DĂNESCU

2012

jim, 06/03/11,
Scrieţi Titlul lucrării de licenţă
jim, 06/03/11,
titlul ştiintific prenumele şi numele coordonatorului. Exemplu: Prof. dr. ing. Sergiu NEDEVSCHI
Page 2: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

VIZAT,DECAN, DIRECTOR DEPARTAMENT,

Prof. dr. ing. Liviu MICLEA Prof. dr. ing. Rodica POTOLEA

Absolvent: Lucian CRIȘAN

TITLUL LUCRĂRII DE LICENŢĂ

1. Enunţul temei: Problema pe care lucrarea de față o abordează se referă la conducerea unei mașini în mod eficient, având ca și constrângeri o destinație aflată la un anumit număr de kilometri sau/și o constrângere legată de timpul maxim până la care se dorește ajungerea la destinație. Se va folosi un microcontroller pentru achiziția datelor de la senzori și trimiterea lor la o tabletă cu sistem de operare Android.

2. Conţinutul lucrării: Pagina de prezentare, Declarație, Introducere, Obiectivele proiectului, Studiu bibliografic, Analiză și fundamentare teoretică, Proiectare de detaliu și implementare, Testare și validare, Manual de instalare și utilizare, Concluzii, Bibliografie, Anexe

3. Locul documentării: Universitatea Tehnică din Cluj-Napoca, Departamentul Calculatoare

4. Consultanţi: S.L. Dr. Ing. Radu Dănescu, A.L. Dr. Ștefan Breban

5. Data emiterii temei: 1 noiembrie 2011

6. Data predării: 29 Iunie 2012

Absolvent: _____________________________

Coordonator ştiinţific: _____________________________

jim, 06/03/11,
Semnătura coordonatorului
jim, 06/03/11,
Semnătura autorului
jim, 06/03/11,
ziua luna anul
jim, 06/03/11,
ziua luna anul
jim, 06/03/11,
Exemplu: Universitattea Tehnică din Cluj-Napoca, Cateddra Calculatoare
jim, 06/03/11,
prenumele şi apoi numele de familie al autorului, ca mai sus
Page 3: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Declaraţie

Subsemnatul Lucian CRIȘAN, student al Facultăţii de Automatică şi Calculatoare, Universitatea Tehnică din Cluj-Napoca, declar că ideile, analiza, proiectarea, implementarea, rezultatele şi concluziile cuprinse în această lucrare de licenţă constituie efortul meu propriu, mai puţin acele elemente ce nu îmi aparţin, pe care le indic şi recunosc ca atare.

Declar de asemenea că, după ştiinţa mea, lucrarea în această formă este originală şi nu a mai fost niciodată prezentată sau depusă în alte locuri sau alte instituţii decât cele indicate în mod expres de mine.

Data: 29 Iunie 2012 Absolvent: Lucian CRIȘANNumăr matricol: 210842Semnătura:______________________

3

jim, 06/03/11,
Semnătura autorului
jim, 06/03/11,
data predării proiectului
jim, 06/03/11,
Prenumele şi Numele autorului proiectului
Page 4: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Cuprins1. Introducere – Contextul proiectului............................................................................1

1.1 Contextul proiectului............................................................................................11.2 Domeniul temei de licență....................................................................................1

2. Obiectivele proiectului................................................................................................22.1 Măsurarea tensiunii pe șunt și pe divizorul de tensiune.......................................2

2.1.1 Asigurarea bazei de timp pentru achiziția de date........................................22.1.2 Asigurarea voltajului de referință.................................................................22.1.3 Ameliorarea variaților consumului de curent...............................................2

2.2 Comunicarea cu tableta........................................................................................32.2.1 Protocolul Android Open Accessory............................................................32.2.2 Alimentarea tabletei......................................................................................32.2.3 Posibilitatea înlocuiri tabletei.......................................................................3

2.3 Asigurarea independenței în comunicare..............................................................32.3.1 Trimiterea parametrilor de configurație ai microcontroller-ului...................4

3. Studiu bibliografic.......................................................................................................53.1 Variante alternative de conectare la microcontroller............................................5

3.1.1 Hacking.........................................................................................................53.1.2 Bridge între USB și serial.............................................................................53.1.3 Bridge între BlueTooth și serial....................................................................5

3.2 Android Open Accessory Protocol( ADK)...........................................................63.2.1 Android@Home............................................................................................6

3.3 Sistem audio-video al mașinii conectat la Android..............................................73.4 Conducerea eficientă a vehiculelor electrice........................................................73.5 Roboți autonomi...................................................................................................8

4. Analiză și fundamentare teoretică...............................................................................94.1 MPLAB X............................................................................................................94.2 Microchip Application Library.............................................................................94.3 Componente hardware........................................................................................10

4.3.1 Circuitul de achiziție...................................................................................104.3.2 H-Bridge.....................................................................................................104.3.3 Motoarele de curent continuu.....................................................................11

4.4 Perifericele microcontroller-ului........................................................................124.4.1 Timer...........................................................................................................124.4.2 Output Compare..........................................................................................134.4.3 Input capture...............................................................................................154.4.4 I2C..............................................................................................................164.4.5 ADC............................................................................................................174.4.6 RTCC..........................................................................................................184.4.7 Controller-ul de întreruperi.........................................................................19

4.5 Protocoale folosite..............................................................................................204.5.1 I2C..............................................................................................................204.5.2 USB.............................................................................................................22

4.5.2.1 O scurtă introducere............................................................................22

4

Page 5: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

4.5.2.2 Tipuri de transfer.................................................................................234.5.2.3 Modelul de comunicație USB.............................................................234.5.2.4 Descriptorii de USB............................................................................244.5.2.5 Procesul de enumerare........................................................................244.5.2.6 USB Embedded Host Stack................................................................25

4.5.2.6.1 Target Peripheral List( TPL)......................................................254.5.2.6.2 Arhitectura stivei........................................................................264.5.2.6.3 Driver-ul client bazat pe evenimente.........................................27

4.5.3 Android Open Accessory Protocol..............................................................274.6 Algoritmii propuși..............................................................................................28

4.6.1 Conversia din analogic în digital................................................................304.6.2 Măsurarea turației.......................................................................................314.6.3 Actualizarea datelor....................................................................................324.6.4 Calibrare motoare.......................................................................................334.6.5 Înlănțuirea comenzilor pe USB .................................................................33

5. Proiectare de detaliu și implementare.......................................................................355.1 Modulul de DAC................................................................................................365.2 Modulul de Input Capture .................................................................................375.3 Modulul de PWM...............................................................................................395.4 Modulul de ADC ...............................................................................................395.5 Modulul de RTCC..............................................................................................405.6 Programul principal............................................................................................40

5.6.1 Structura comenziilor..................................................................................415.6.2 Trimiterea datelor către tabletă...................................................................425.6.3 Funcția de trimitere a datelor către Android...............................................435.6.4 Inițializarea comunicației pe USB și ADK.................................................435.6.5 USBTask()= keep the stack running...........................................................445.6.7 Inițializarea plăcii de dezvoltare.................................................................44

5.7 Logica generală a aplicației................................................................................446. Testare și validare......................................................................................................467. Manual de instalare și utilizare................................................................................49

7.1. Instalare.............................................................................................................497.1.1 Instalare hardware.......................................................................................497.1.2 Instalare software........................................................................................51

7.2 Manualul utilizatorului.......................................................................................528. Concluzii...................................................................................................................53

8.1 Rezumat..............................................................................................................538.2 Rezultate obținute...............................................................................................538.3 Posibile dezvoltări și îmbunătățiri ulterioare......................................................54

9. Bibliografie...............................................................................................................56 10. Anexe........................................................................................................................57

5

Page 6: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

1. Introducere – Contextul proiectului

1.1 Contextul proiectuluiLucrarea de față este o componentă a mașinii solare dezoltată în cadrul

Universității Tehnice din Cluj-Napoca și intitulată Solis.EV. Vehiculul se dorește a fi unul de tip autonom, a cărui propulsie este de tip electric, alimentarea făcându-se folosind acumulatori încărcați de la panouri fotovoltaice.

Pentru preluarea informațiilor de la senzori se folosește un microcontroller, util și pentru acționarea motoarelor. Afișarea informațiilor și intepretarea lor se face folosind o tabletă care are un sistem de operare de tip Android, în locul panoului central de bord.

1.2 Domeniul temei de licențăProblema pe care lucrarea de față o abordează se referă la conducerea unei mașini

în mod eficient, având ca și constrângeri o destinație aflată la un anumit număr de kilometri sau/și o constrângere legată de timpul maxim până la care se dorește ajungerea la destinație. Ca și model de mașină se va considera una de tip solar, cu alimentare electrică de la acumulatori.

Comparativ cu circuitele analogice, un sistem de comanda si monitorizare bazat pe microcontroller permite o mai mare flexibilitate, și o adaptare mai bună la modificarea parametrilor. Pentru senzori și elemente de acționare se va folosi o adresare individuală în locul unei magistrale comune.

În cadrul mașinii solare un aspect important îl reprezintă monitorizarea bateriilor, deoarece folosirea lor peste limita permisă poate produce distrugerea lor. Astfel se va monitoriza consumul de curent din circuit precum și gradul lor de descărcare. Cunoașterea acestor parametri permite o estimare a timpului rămas până la descarcarea bateriilor, în ritmul de consum actual. Folosind curbele de descărcare se pot indica diverse moduri de prelungire a duratei de descărcare, în funcție de consumul de curent.

Un alt aspect important îl constituie acționarea motoarelor. În urma testelor s-a constat că circuitele de acționare răspund în mod diferit la stimuli. Din această cauză este necesar ca atunci când se conectează un set nou de motoare să se facă o calibrare inițială a lor. În timpul funcționării se folosește și o buclă de comandă închisă, implementată în software, pentru a reduce diferențele între turații.

Comunicarea cu senzorii, sau cu tableta se face folosind protocoale cum ar fi I2C respectiv USB. Datele circulă în general într-o singură direcție de la senzori spre microcontroller, sau de la acesta spre elementele de acționare și în ambele sensuri pe USB.

6

Page 7: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

2. Obiectivele proiectului

2.1 Măsurarea tensiunii pe șunt și pe divizorul de tensiunePrincipalul obiectiv al acestei lucrări îl constituie monitorizarea descărcării unor

acumulatori când sunt folosiți cu un consum variabil. În acest sens s-a folosit un șunt de 0.8Ω astfel încât măsurând căderea de tensiune să se poată afla consumul momentan de curent. Pentru măsurarea lui s-a folosit puntea Wheatstone, datorită necesității existenței unei precizii ridicate pentru măsurarea unei rezistențe de valoare mică.

Principiul prin care se află intensitatea știind căderea de tensiune pe șunt este de a folosi legea lui Ohm: U= I* R. Voi folosi un scurt exemplu: la o valoare de tensiune măsurată pe șunt de 0.4V și rezistența de 0.8Ω, folosind formula enunțată anterior se ajunge la valoarea intensității de 0.5A.

Astfel obiectivul principal presupune măsurarea în fapt a două tensiuni: una pe acumulatori, folosind un divizor și alta pe șunt. S-a ales un șunt de o valoare mică pentru a avea un consum minim de curent. Acest fapt face ca tensiunea măsurată să nu depășească 0.5V. Valoarea măsurată pe divizor este de 3 ori mai mare, maximul fiind de 1.5V.

2.1.1 Asigurarea bazei de timp pentru achiziție dateUn alt aspect important în cadrul proiectului este de integrare în timp a celor două

valori măsurate. Pentru aceasta este necesar ca achiziția datelor să se facă la intervale de timp foarte bine stabilite. Nu este atât de important să se și trimită datele cu exact aceiași constanță. Pentru aceasta s-a ales o bază de timp de 1Hz, care este asigurată de circuitul de RTCC. O variație în generarea acestei baze de timp va duce în timp la rezultate eronate.

2.1.2 Asigurarea voltajului de referințăO altă parte esențială a măsurării tensiunilor o constituie menținerea referinței

pentru ADC la o valoare constantă. Pentru aceasta se vor folosi regulatorul de tensiune de pe placă în combinație cu circuitul de DAC. Convertorul din analogic în digital va folosi o referință de 1.5V în locul celei e 3.25V folosindu-se mai eficient cei 10 biți ai rezultatului conversiei din analog și tot odată duce la o precizie ridicată la măsurarea mV.

2.1.3 Ameliorarea variaților consumului de curentDatorită modului de construcție al motoarelor și a faptului că sunt comandate în

PWM apar variații ale consumului de curent, de frecvența comenzii primite. Acest lucru se datorează răspunsului bobinelor la semnalul dreptunghiular. Pentru atenuarea efectului s-a folosit un condensator și o mediere a valoriilor măsurate folosind software-ul. Asigurarea unei referințe stabile pentru ADC nu este suficientă. Baza de timp a convertorului trebui să fie de asemenea stabilă. În acest sens oscilatorul intern al modului nu poate fi folosit, fiind nerecomandat la măsurători de precizie. Folosirea semnalului de ceas al perifericelor(care este divizat din oscilatorul principal) este o alternativă mult mai potrivită.

7

Page 8: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

2.2 Comunicarea cu tabletaDatorită capacității limitate de procesare și de afișare a microcontroller-ului se

impune folosirea unei tablete pentru prelucrea informațiilor, salvarea și afișarea lor în timp real, utilizatorului uman. Acest lucru ridică cel puțin două probleme: trimitirea informațiilor la o frecvență ridicată și posibilitatea alimentarii tabletei în același timp.

2.2.1 Protocolul Android Open AccessoryEste un protocol dezvoltat de Google care folosește USB-ul împreună cu un

mecanism de hand-shake permițând comunicarea între un master și un slave. Trebuie avut în vedere că (momentan) tableta joacă rolul de slave. Astfel codul necesar funcționării comunicației cade în sarcina microcontroller-ului. Un alt dezavantaj ce trebuie avut în vedere este că doar ultimele versiuni de Android suportă acest protocol.

2.2.2 Alimentarea tableteiObținerea alimentării continue a tabletei este necesară deoarece dacă se folosește

ca și panou de bord, nu se poate îndepărta în timpul funcționării pentru a se reîncărca. Folosirea unei surse alternative de alimentare nu este o soluție generală, deoarece de cele mai multe ori, nu există o mufă separată în acest scop.

Avantajul USB este acela că permite transferul datelor la viteze de ordinul MB/s permițând și alimentarea slave-ului în același timp. Tensiunea de alimentare este de 5V la un curent maxim de 250mA, ceea ce în cazul de față este suficient.

2.2.3 Posibilitatea înlocuiri tableteiSe dorește folosirea unui protocol care să permită o înlocuire cât mai facilă a unei

tablete cu alta de același tip sau alt model. Soluțiile de tip „hacking” pe cât sunt de interesante și de captivante presupun de cele mai multe ori desfacerea carcasei și cositorirea unor fire.

Folosirea soluției prezentate în această lucrare, presupune doar îndepărtarea cablului de USB, schimbarea tabletei, încărcarea pe aceasta a programului Android, apoi se reconectează cablul și se poate relua activitatea.

2.3 Asigurarea independenței în comunicareSe dorește ca o schimbare fie a dispozitivului slave, fie a celui master să nu

presupună și modificarea protocolului de comunicare. În acest sens s-a ales un protocol simplu, bazat pe trimiterea de octeți. Astfel fiecare mesaj este precedat de un cod de identificare, urmat apoi de un număr fix de octeți care reprezintă argumentele.

Octet 1 Octet 2 .... Octet n+1

Cod mesaj Argument 1 .... Argument n

Tabelul 2.1: Formatul general al unui mesaj

În cazul în care o valoare ocupă mai mult de un octet(ca de exemplu valoarea de

8

Page 9: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

la ADC care este pe 10 biți) se va trimite pe numărul necesar de octeți, cu aliniere la dreapta în cadrul grupui de bytes.

2.3.1 Trimiterea parametrilor de configurație ai microcontroller-uluiFiecare microcontroller este influențat de hardware în ceea ce privește modul de

reprezentare al rezultatelor și numărul de biți pe câți se reprezintă acestea. Astfel este de preferat ca înainte de a se începe trimiterea de mesaje să se trimită configurațiile plăcii de dezvoltare. Trebuie avut în vedere că și frecvența plăcii poate să fie diferită, precum și frecvența de lucru pentru periferice.

9

Page 10: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

3. Studiu bibliograficMaterialele folosite pentru realizarea acestei lucrări cuprind: data sheet, reference

manual, aplication note, cărți, lucrări de laborator, precum și numeroase pagini de pe internet. Acestea sunt în marea majoritate în limba engleză cu câteva excepții în limba română. Datorită noutății tehnologiei ADK, care a fost lansată în primăvara anului 2011, nu se poate vorbi despre o bibliografie de mari dimensiuni.

3.1 Variante alternative de conectare la microcontroller

3.1.1 HackingReprezintă varianta cea mai riscantă și în același timp și cea mai interesantă de

comunicare. Așa cum se arată în articolul [1] sunt două abordări posibile: prima presupune folosirea unui bridge între USB și portul serial, iar a doua și cea mai dificilă presupune găsirea și conectarea la portul serial direct de pe magistrala telefonului.

Principalul avantaj al ultimei metode îl constituie costul. Dezavantajul major, îl constituie faptul că fiecare dispozitiv cu Andoid, are pinii de la portul serial situați în altă locație. Accesul la schemele hardware este dificil, și de cele mai multe ori acestea nu sunt făcute publice deoarece clientul nu are nevoie în mod normal de aceste informații.

3.1.2 Bridge între USB și serialFolosirea unui bridge între serial și USB este prezentat în resursa [2], în acest

articol fiind prezentat modul concret de construire al acestui bridge. Avantajul abordării curente și a celei precedente este reprezentat de faptul că pe partea de microcontroller se folosește comunicarea prin protocolul UART. Acesta este suportat nativ de către toate dispozitivele și de asemenea este un protocol ușor de folosit.

Un bridge pentru microcontroller este explicat și în resursa [3], care spre deosebire de variantele anterioare bazate pe serial necesită și folosirea unei librării mai complexe. De asemenea suportul pentru kit-ul de dezvoltare este oferit doar pentru Arduino, ceea ce limitează complexitatea programului ce poate fi încărcat pe placă.

3.1.3 Bridge între BlueTooth și serialAsupra variantelor wireless m-am oprit cu documentarea doar pe varianta de

Bluetooth, datorită prețului mai redus al shield-ului, și a protocolului care este mai simplu. Pentru aceasta se poate folosi [4], care nu este altceva decât o librărie tot pentru Arduino. Aceasta acceptă un număr mare de bridge-uri între UART şi BlueTooth, atât timp cât se setează baud rate-ul pentru comunicația serială la o valoare prestabilită.

În tutorialul [5] se explică pe larg modul general de conectare între device-uri folosind un bridge de la BlueTooth la serial. Se oferă de asemenea atât schemele de montaj construite în jurul unui Arduino și a unui bridge de la SparkFun, precum și codul pentru Android și pașii necesari dezvoltării aplicației pe microcontroller.

10

Page 11: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

3.2 Android Open Accessory Protocol( ADK)Fiecare telefon sau tabletă poate folosi USB-ul împreună cu protocolul ADB(care

în mod normal este folosit pentru depanare) pentru trimiterea datelor, așa cum este prezentat în blog-ul [6]. O privire critică asupra ADK se găsește pe blog-ul lui Romfron [7], unde se combate vehement ADK-ul, fiind considerat ca lipsit de inovație față de ADB, deoarece limitează folosirea telefonului/tabletei precum și modele acceptate. ADK are totuși avantajul că permite folosirea( momentan în dezvoltare) în paralel a funcție de depanare fie printr-un USB secundar sau prin wireless.

Singurele documentații oficiale referitoare la ADK sunt cele oferite de Google, unde există o scurtă secțiune dedicată [8], în cadrul ghidului pentru Android. Acestei documentații i se alătură documentația oferită de către Microchip [9]. Ambele documentații însă nu sunt destul de detaliate, oferind informații foarte puține.

ADK folosește momentan telefonul pe post de slave și placa de dezvolatare pe post de master, USB-ul fiind un protocol asimetric. Decizia aceasta a fost luată, așa cum se arată în blog-ul oficial [10], deoarece momentan majoritatea telefoanelor nu au modul master și nici OTG, ci numai slave. De asemenea deoarece majoritatea suportă ADB, au cel puțin modul de slave, pentru a se conecta la PC și a realiza depanarea print-un cablu USB. Din această cauză, așa cum se remarcă și în blog, este o situație inversată, „cu susul în jos”: telefonul deși are putere de calcul mai mare acționează ca și slave, având de asemenea nevoie și de alimentare.

Pe viitor, așa cum se arată în blog-ul amintit mai sus, [10], se va încerca să nu se mai ofere alimentare telefonului și să se suporte distribuirea de conținut audio peste USB( acest lucru nu este fezabil în varianta de față, deoarece nu se suportă transferul izocron). În cadrul Google I/O din 2011 [11] s-a lansat ideea chiar ca telefonul să fie host, ceea ce ar ușura foarte mult munca dezvoltatorilor de embedded.

3.2.1 Android@HomeConceptul a fost prezentat în cadrul Google I/O 2011 [12], ca fiind o extindere

pentru Android Open Accessory Protocol pentru automatizarea unei întregi locuințe. Dispozitivul Android va trebui să folosească Android@Home Framework pentru a putea comunica cu senzorii folosind Wi-Fi.

Un protocol wireless, care folosește unde radio de 900MHz a fost dezvoltat pentru conectarea elementelor ce nu pot îngloba capacitățiile de Wi-Fi. În acest sens a fost prezentat un bec bazat pe tehnologia LED și produs împreună cu Light Science, care folosește acest protocol proprietar.

Oferta de produse compatibile cu Android@Home este momentan redusă. Totuși posibilitatea conectării la internet oferă accesul la Google Cloud și toate serviciile asociate lui. Un alt exemplu prezentat a fost înglobarea serviciului Music Beta, care permite sincronizarea diverselor dispozitive care au Android, prin folosirea unui cont Google. Toată muzica se va afla salvată în cloud, astfel încât nu va ocupa spațiu pe disc.

11

Page 12: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

3.3 Sistem audio-video al mașinii conectat la AndroidÎn resursa [13] se exemplifică o implementare a protocolului ADK oferită de

Harman, prin sistemul lor de audio-video instalat pe mașină. Telefonul sau tableta pot fi comandate de la comenziile de pe ecranul tactil, prin comandă vocală, butoanele de pe volan sau direct din panoul central sistemului audio- video.

Se poate astfel să se trimită un sms sau e-mail folosind comanda vocală, sau să se redea conținutul unui mesaj primit în boxele mașinii. Posibilitatea de a răspunde la telefon, sau de a apela un număr se poate face tot vocal, sau din butoanele de pe volan. Rețele sociale, cum ar fi Facebook sau Twitter au fost și ele tratate de Harman. Conținutul text al oricărui post primit poate fi redat de către sistemul audio al mașinii.

Aplicațiile de navigație care se găsesc pe telefoane și tablete pot fi folosite pentru găsirea celei mai apropiate stații de alimentare cu carburanți, sau pentru a descoperi restaurantele din zonă. De asemenea pot fi redate și filme, pe panoul sistemului audio-video sau pe ecrane care pot fi montate în tetiere.

Totuși sitemul audio-video oferit de firma Harman nu interfațează cu partea de control al parametrilor mașinii(cu excepția volumului în difuzoare, și a conținutului unor ecrane), fiind mai mult o extindere a ecranului tactil al tabletei. Aici dispozitivul Android are rolul de gestionar pentru muzică, filme, apleuri și mesaje primite, sau postăriile de pe rețelele sociale.

3.4 Conducerea eficientă a vehiculelor electrice În lucrarea [14] se tratează modul în care pot fi satisfăcute cerințele clientului

ținând cont de resursele mașinii. Abordarea adoptată în acest articol este ierarhică, și cuprinde 4 module.

Fiecare modul constituie o intrare pentru cel de nivel superior, astfel încât se transmit o colecție de soluții stagiului următor, acesta combinând fiecare soluție primită cu cea proprie, pentru a obține tot o colecție de soluții. Un optim local unui nivel poate să nu facă parte și din soluția globală, de aceea se trimit un set de soluții.

Soluția unui singur drum optimal, din punct de vedere al clientului, implică satisfacerea constrângerilor de timp și de consum energetic. La acestea se pot adăuga costuri de reîncărcare, timpi morți în care se face alimentarea, numărul de astfel de opriri și alte criterii.

Primul nivel tratat este cel al componentelor mașinii, cu rol asupra confortului clientului sau asupra posibilității efective de locomoție. La acest nivel strategiile sunt foarte simple, și sunt constituite în mare din compararea unor threshold-uri.

La nivelul următor, cel al călătoriei se iau în considerare punctele de alimentare și destinațiile, și modul în care se poate ajunge cât mai eficient la ele. Aici pentru elaborarea strategiilor se folosesc grafuri.

Nivelul călătoriei este format dintr-o serie de rute, și puncte de staționare/parcare reprezentate de destinații intermediare sau finale. Pentru conectarea rutelor se folosește programarea dinamică, sau găsirea unui optim local.

Ultimul nivel este cel de asigurare a mobilității, în care un client nu este legat în mod direct de un anumit mijloc de transport; poate folosi și mijloace de transport în comun, sau pe anumite porțiuni poate să călătorească alături de un cunoscut. În acest scop

12

Page 13: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

se folosesc algoritmi din teoria jocului.Concluzia acestei lucrări este că nu doar costul unei călătorii poate fi îmbunătățit,

dar chiar și timpul total poate fi mult îmbunătățit în paralel. Pentru susținerea acestei afirmații s-a dezvoltat un cadru matematic prin care se studiază complexitatea algoritmilor, și spațiu computațional al soluțiilor. Este necesar să se renunțe la anumite variante în stagii cât mai incipiente, deoarece dacă nu spațiul soluțiilor poate ajunge la ordinul miilor, iar analiza lor va consuma foarte mult timp. De asemenea alegerea unei medii, în locul unui optim global poate să satisfacă de cele mai multe ori cerințele clientului.

3.5 Roboți autonomiÎn cartea [15] se prezintă tipurile de roboți autonomi, mobilitatea lor, senzori și

percepția mediului, localizarea și planificarea călătoriei.

Un robot care are 3 roți are avantajul stabilității și de asemenea nu are nevoie de suspensie, deoarece un plan este determinat de 3 puncte și astfel fiecare roată are contact permanent cu solul. O altă condiție necesară este ca centrul de greutate să se găsească în interiorul triunghiului format de cele 3 roți.

Pentru control direcției, puntea din față se acționează independent, iar în spate se poate folosi o roată sferică sau una pivotantă. Schimbarea direcției se face prin rotirea în jurul centrului de greutate, blocând o roată și cealaltă fiind acționată în sensul dorit. În locul blocării se poate folosi acționarea în sens invers, ceea ce duce ca robotul să rotească la punct fix. Dificultatea controlului constă în faptul că turațiile celor două roți motoare trebuie să fie identice pentru o deplasare în linie dreaptă. Folosirea unei roți sferice sau a uneia pivotante în spate nu influențează în mod semnificativ manevrabilitatea robotului.

Pentru atingerea destinației se poate folosi o planificare fie în buclă deschisă, fie în buclă închisă. Prima abordare presupune divizarea traseului în mai multe segmente de tipul liniilor sau arcelor de cerc. Această tehnică nu ia în calcul modificăriile neprevăzute în configurația mediului, și de asemenea viteza de deplasare are fluctuații mari datorită neregularitățiilor ce apar în compunerea drumului ales.

Folosirea unei bucle închise, prin analiza feed back-ului primit de la diverși senzori, constituie o abordare mai realistă și ușor adaptabilă la schimbăriile de mediu. Tehnica de bază constă în alegerea unor puncte intermediare, care urmează să fie vizitate.

13

Page 14: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

4. Analiză și fundamentare teoretică

4.1 MPLAB XMediul de dezvoltare MPLAB X v.1.10, asigură dezvoltarea facilă a aplicațiilor

pentru microcontroller-ele Microchip. Are funcții de programare a acestora folosind un cablu USB sau un programator, de citire a conținutului memoriei și de execuție a unui program pas-cu-pas.

Testarea aplicațiilor, în lipsa unei plăci de dezvoltare, se poate face folosind simulatorul, care poate emula orice microcontroller suportat de mediul de dezvoltare. Are dezavantajul de a afișa registrele în mod listă, ordonate după adresă sau după nume, în locul unei grupări după perifericul de care aparțin.

Dezvoltarea programelor se poate face, folosind fie limbajul de asamblare fie C. Prin folosirea directive pentru compilare, se permite introducerea de cod scris în alt limbaj decât cel ales de utilizator la crearea proiectului. Se oferă suport pentru limbajul de asamblare prin ASM iar prin C18/C30/C32 respectiv HI-TECH PICC/PICC-18 se oferă suport pentru C. Varietatea mare de compilatoare se explică prin multitudinea de arhitecturi suportate: de 8, 24 și 32 de biți precum și procesoare digitale de semnal.

Pe lângă compilatoarele necesare, pentru rularea IDE-ului este nevoie și de instalarea unui JRE. În cazul în care este instalată și versiunea 8 de MPLAB este nevoie de un driver switch pentru conectarea la placa de dezvoltare. Switch-ul are rolul de a încărca driver-ul corespunzător folosiri USB ca și programator pentru microcontroller; atât versiunea 8 cât și versiunea X au driver propriu.

Mediul de programare fiind dezvoltat plecând de la NetBeans oferă un grad ridicat de modularitate printr-un set de plug-in-uri. Unul foarte util este DMCI care permite vizualizarea diverselor tipuri de variabile, afișarea unui vector pe grafic sau modificarea unor valori folosind sliders sau butoane de tip on/off pentru booleans.

4.2 Microchip Application LibraryCuprinde o serie de librării scrise în C pentru folosirea perifericelor de pe placă, a

căror programare este mai dificilă. Se oferă acces la stivele de TCP/IP, USB, Wireless, ecrane tactile, SD card și sisteme de fișiere. Aceste librări pot fi folosite individual sau pot fi combinate în cazul în care aplicația este mai complicată.

Librăria Android Accessory Framework, folosește și librăria de USB pentru a oferi un API facil dezvoltării aplicațiilor de tip ADK. Generarea fișierelor de configurație pentru driver-ul de USB se poate face folosind programul USB Config, prin configurarea pas-cu-pas a fiecărei opțiuni asociate comunicației seriale.

Librăriile necesare pot fi incluse în proiectul curent în două moduri: prin adăugarea locației la include path ca și cale absolută, sau prin copierea lor în proiectul curent și referirea folosind calea relativă. Metoda a doua asigură nu doar portabilitate, dar împiedică modificarea voluntară sau nu a fișierelor originale din librărie. Compilatorul folosește include path pentru a căuta dependențele proiectului, cum ar fi fișierele din librăriile standard.

14

Page 15: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

4.3 Componente hardware

4.3.1 Circuitul de achizițieCircuitul de achiziție este prezentat în figura 4.1, în continuare fiind prezentate

componentele constructive. Schema a fost realizată folosind: falstad.com/circuit/, un applet în Java, de tip drag-and-drop.

Acumulatorii sunt de tip reîncărcabil, cu o tensiune la borne de 1.2V și o capacitate de 2450mAh. În locul acumulatorilor se pot folosi baterii obișnuite de 1.5V. Cei 4 acumulatori sunt legați în serie, oferind astfel 4.8V, capacitatea rămânând la valoarea de 2450mAh.

Circuitul de măsură al voltajului la borne este format din 4 rezistențe de 1KΩ în serie, cu scopul de a forma un divizor de tensiune. Rezistențele pot fi de orice valoare, cât timp sunt de valori egale. Dacă sunt de valori diferite tensiunea pe o rezistență va trebui calculată folosind proporțiile aritmetice. În cazul folosiri a 4 rezistențe, căderea de tensiune pe o rezistență este de 4 ori mai mică decât în tot circuitul serie. În cazul de față s-a ales valoarea de 1KΩ pentru a se reduce consumul de curent în circuit.

Condensatorul este de tip electrolitic și are o capacitate de 4.7mF, iar cele două motoare sunt reprezentate pe schemă ca și două rezistențe de 100Ω, aflate în partea dreaptă. Asupra rolului condensatorului voi reveni într-un capitol viitor, iar motoarele vor fi prezentate în continuare.

4.3.2 H-BridgeCircuitul are rolul de a schimba direcția motorului, fără a fi necesară modificarea

montajului. Pentru aceasta se folosesc patru tranzistori grupați în două perechi: Q1/Q3 și

15

Figura 4.1: Circuitul de achiziție

Page 16: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Q2/Q4, comandați prin semnalele A, respectiv B.

Dacă A are valoarea '1', iar B are valoarea '0', motorul se va roti în sensul acelor de ceasornic, iar dacă A este '0' și B este '1', se va roti în sensul opus acelor de ceasornic. Pentru a se opri motorul, ambele semnale de control trebuie să fie la valoarea '0'. Dacă ambele semnale sunt '1', comportamentul va fi nedefinit.

În figura 4.2 este prezentat un Pmod ce îndeplinește funcția descrisă mai sus, și schema generală a circuitului de H bridge, folosită pentru exemplificarea funcționării. Așa cum se poate observa circuitul de alimentare este separat de comandă, astfel încât motoarele pot fi acționate la tensiuni și curenți mari.

4.3.3 Motoarele de curent continuuMotoarele sunt de tip Igarashi IG22, cu o cutie de viteze încorporată, ce are un

raport de 1:19, funcționând ca un reductor cu raport fix. Modelul de față se poate alimenta la tensiuni de maxim 6V, curent continuu, iar consumul de curent are valoarea maximă de 125mA. În figura 4.3 este prezentată o privire de ansamblu asupra motorului, o vedere din spate a encoder-ului și ieșirea în defazaj a celor doi senzori Hall.

În partea din spate a fiecărui motor se află un encoder, bazat pe efect Hall, care măsoară gradul de rotație. Scopul acestui circuit este să determine turația motorului, folosind doi senzori magnetici dispuși la o anumită distanță unul față de celălalt. Magnetul folosit este unul obișnuit, de tip Nord-Sud. Cei doi senzori oferă la ieșire semnalele A și B, defazate cu 900, și cu un factor de umplere de 50%, așa cum se vede în

16

Figura 4.2: PMod HB5(în partea stângă) și schema generală a H bridge(în dreapta)

Page 17: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

partea dreaptă jos.

Trebuie avut în vedere că senzorii măsoară direct turația rotorului, astfel valoarea obținută este de 19 ori mai mare decât ieșirea din reductor, care acționează roțile. Senzorul Hall poate fi folosit chiar dacă motorul nu este alimentat. Valoarea gradului de rotație este una relativă la momentul începerii măsurării. Folosirea unei codificări Gray asociate acestui encoder ar fi permis cunoașterea în orice moment al gradului de rotație.

Figura 4.3: Motorul de curent continuu și encoder-ul

4.4 Perifericele microcontroller-uluiÎn sectiuniile următoare sunt prezentate perifericele folosite în cadrul proiectului.

Termenul de PB se referă la semnalul de ceas al perifericelor, iar SOSC la oscilatorul secundar. Ceasul general al sistemului, SYSCLK , este divizat pentru a se obține PB. Notația 'x' din denumirea registrelor sau pinilor se referă la registrul/pinul asociat unei anumite instanțe a perifericului, ca de exemplu dacă x este 1 în TxCK este pinul semnalului de ceas extern pentru Timer 1.

4.4.1 TimerAm folosit ca și principală sursă de informare Reference Manual [16]. Acest

model de chip are un numar de 5 timere de 16 biți(T1- T5). Pentru a se obține un timer de 32 de biți se pot asocia T2 cu T3 sau T4 cu T5.

17

Page 18: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Se foloseşte termenul de Type A pentru cele care pot fi folosite doar ca și 16 biți, respectiv Type B pentru cele care pot fi folosite și ca 32 biți. În cazul B se folosesc notațiile de TimerX și TimerY, primul fiind considerat master(exemplu Timer 2) iar al doilea fiind considerat slave(exemplu T3). Masterul stabilește perioada și setăriile de bază, registrele lui Y sunt folosite doar pentru setarea întreruperilor.

Pot fi identificate mai multe moduri de operare: Modul sincron care este asemănător pentru tipul A și B presupune folosirea

Peripheral Bus Clock (PB) și eventual a unui prescaler. Modul sincron cu ceas extern presupune folosirea unui pin(TxCK) unde este

furnizat un ceas extern. Acesta este sincronizat cu ceasul sistemului. Modul gated presupune folosirea unui semnal extern care validează numărarea. Modul asincron. Acesta este singurul mod care apare doar la tipul A, spre

deosebire de modurile de mai sus care apar la ambele tipuri. Se poate folosi ca și sursa T1CK sau oscilatorul secundar (SOSC). Se oferă mecanisme de sincronizare între PB clock și ceasul extern.Fiecare timer are propria întrerupere, a cărei prioritate/subprioritate poate fi setată

individual. Poate avea surse multiple cum ar fi atingerea valorii din PR sau, dacă se folosește în modul gated, de un falling edge pe gate.

4.4.2 Output ComparePrincipala sursă de informare privind PWM a constituit-o Reference Manual[17].

Poate fi folosit doar cu Timer 2 sau cu Timer 3. Se pot folosi un număr de maxim 5 canale. În privința registrelor necesare, numărul acestora este mic:

OCxCON, folosit pentru configurarea modulului OCxR și OCxRS folosite pentru compararea cu valori de 16 biți sau de 32 de biți

18

Figura 4.4: Timer 1

Page 19: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

dacă se folosește și registrul secundar(OCxRS).Din punctul de vedere al modurilor de funcționare se pot distinge:

modul Single compare, a cărui ieșire poate fi folosită pentru a avea high, low sau toggle, la potrivirea valorii din timer cu cea din output compare(OcxR).

Modul Dual compare, folosește ambele registre pentru comparare. De exmplu la atingerea valorii din primul registru va trece în starea low, apoi la atingerea valorii din registrul al doilea va trece în high.

Modul PWM. Perioada se stabilește prin setarea timer-ului, iar factorul de umplere prin setarea OcxR. OcxRS are aici rol de buffer, și se transferă în OcxR la overflow-ul timer-ului.

PWM poate fi folosit cu scopul de convertor digital-analogic. Modificând factorul de umplere se modifică și ieșirea. La frecvențe mari, de ordinul kHz, un factor de umplere de x%, va face ca ieșirea să fie percepută ca fiind x% din valoarea maximă. În exemplul din figura 4.6 la un factor de umplere de 50%, ieșirea este măsurată ca fiind 5V, jumătate din cei 10V, cât reprezintă valoarea high a semnalului dreptunghiular.

Fiecare canal are asociat o întrerupere, astfel se pot seta individual prioritățiile și subprioritățiile.

19

Figura 4.6: PWM ca și regulator de tensiune

Figura 4.5: Funcționarea OC

Page 20: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

4.4.3 Input captureEste folosit pentru a se efectua măsurători ale frecvenței sau ale duratei unui

impuls, așa cum se arată în Reference Manual [18].

Modulul are două registre: unul pentru configurare ICxCON și unul de tip buffer ICxBuf. Prin intermediul acestui registru buffer poate fi citită stiva(FIFO). Dacă stiva conține 4 valori atunci sunt necesare 4 citiri din ICxBUF. Stiva are un număr maxim de 4 cuvinte. Se poate folosi ca și bază de timp Timer 2, Timer 3 sau ambele pentru o bază de timp de 32 de biți.

Se poate folosi în următoarele moduri: simple capture, mod în care se alege modul de rising/falling, iar întreruperea va fi

generată după numărul de evenimente specificat în ICxCON. prescaled capture, mod în care se va genera un eveniment tot la al 4-lea sau 16-

lea eveniment. Modul edge detect va detecta atât tranzițiile high-low cât și low-high. Modul

interrupt-only se folosește pentru modul sleep și idle.Modulul are două întreruperi: ICxIF, care apare după numărul dorit de

evenimente și ICxIE care apare în urma unei erori cum ar fi faptul ca nu se citește din FIFO și apare over run.

20

Figura 4.7: Modulul de input capture

Page 21: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Figura 4.8: Modul general de folosire al IC și TimerÎn figura 4.8, este prezentat conceptual funcționarea modului. Modul de folosire

este de single capture, și evenimentele de interes sunt cele de tipul rising edge, marcate cu verde pe figură. Registrul se va incrementa cu frecvența ceasului folosit ca și bază pentru măsurătoare. Dacă apare un eveniment se generează o întrerupere, se salvează valoarea, apoi registrul se va reinițializa.

4.4.4 I2CCele mai importante caracteristici ale modulului sunt următoarele:

logică separată pentru partea de slave/master posibilitatea de a lucra atât cu adrese 7 bit cât și de 10 bit posibilitatea arbitrări în sisteme de tip multimaster poate lucra la frecvențe de 100KHz, 400KHz sau 1MHz.

Registrele care controlează modulul de I2C sunt prezentate în [19] și sunt următoarele:

I2CxCON, este registrul care va controla funcționarea I2C I2CxSTAT, conţine o serie de flags I2CxADD, este registrul ce conține adresa în cazul în care funcționează ca și slave I2CxMSK, este un registru de mască pentru adresă, astfel încât să poată să

răspundă la mai multe adrese I2CxBRG, folosit pentru baud rate I2CxTRN, aici se vor pune datele care se doresc trimise I2CxRCV, aici se vor depunde datele primite

Întreruperile asociate cu acest modul sunt diferențiate pentru modul de folosire master, slave sau sunt comune(bus collision), sursele în fiecare caz fiind multiple. Pentru recepționarea datelor se folosește principiul de double buffer. Prima dată datele sunt deplasate folosind I2CxRSR iar apoi odată terminată operația(după primirea a 8 biți) se mută datele în I2CxRCV. Dacă vechea valoare nu a fost citită din acest registru se va semnaliza prin flagul I2xCOV, iar valoarea nouă se va pierde.

Funcția de reload automat pentru Baud Rate Generator are sens în contextul arbitrării, pentru a determina o nouă încercare de obținere a magistralei. BRG se va decrementa cât timp SCL este low, iar apoi va încerca să aducă SCL în starea high. Pierderea arbitrării poate să apară la Start, Repeated Start, trimitere de date, adresă, sau la Stop; și se va semnaliza prin setarea flag-ului de BCL.

In continuare voi prezenta unele particularități pentru modulul de I2C în modul master. La inițializarea unui Start trebuie să se aștepte terminarea lui, altfel se va

21

Page 22: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

semnaliza o coliziune pe bus. Pentru a se verifica dacă bus-ul este idle(SCL este high) se mai poate verifica flagul de Stop. Pentru o abordare bazată pe întreruperi este necesară construirea unui state machine deoarece, întreruperea pentru modul master poate fi activată de mai multe surse.

4.4.5 ADC

Registrele folosite pentru programarea modului sunt următoarele: AD1CON1, AD1CON2, AD1CON3, folosite pentru configurare AD1CHS, folosit la selectarea pinilor ce vor fi conectați la SHA, prin cele două

multiplexoare AD1PCFG, este folosit pentru configurarea pinilor ca și digital sau analogic AD1CSSL, este folosit pentru alegerea piniilor ce vor fi folosiți la scanare ADC1BUF0- ADC1BUFF, constituie stiva unde vor fi depuse rezultatele

Pentru a se folosi un pin ca și intrare analogică mai întâi se va marca ca și pin de intrare folosind registrul TRIS, apoi se va seta ca și analogic folosind AD1PCFG. Rezultatul conversie este de 10 biți, dar poate fi citit ca și un număr pe 16 sau pe 32 de biți atât în format întreg cât și în format fracțional, cu semn sau fără. Numerele negative nu se obțin în urma citiri unei valori negative, ci datorită faptului că sunt în prima jumătate a intervalului, în mijlocul intervalului fiind valoarea 0.

Setarea modului de conversie poate fi realizată în 4 feluri și anume: manual prin setarea bitului de sample; prin folosirea Timer2 și/sau Timer3; printr-o întrerupere

22

Figura 4.9: Modulu ADC

Page 23: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

externă; sau în mod auto. Modul auto va seta la finalul conversie bitul de sample, ceea ce va duce la începerea unei noi eșantionări.

Se poate specifica numărul de conversii după care se va genera o întrerupere, acest număr fiind de maxim 16 sau 8 în funcție de Buffer Fill Mode. Rezultatele vor fi salvate în stivă începând cu BUF0 și continuând până la maxim BUFF. Prin folosirea dual buffer stiva este împărțită în două zone: primele 8 BUF0- BUF7 și ultimele BUF8- BUFF. Astfel mai întâi se scrie în prima zona, se generează întrerupere, apoi se trece la a doua zonă, și se generează întrerupere, apoi rezultatele conversiei vor fi depuse din nou în prima zonă. Generarea întreruperii se face după scrierea numărului indicat de valori, valoarea maximă în acest mod fiind de 8. Mai întâi se va scrie în buffer-ul 0, apoi în 1,2 în prima zonă; respectiv 8, 9, 10 pentru zona a doua. Astfel se permite o operație de citire dintr-o zonă, în timp ce se scriu rezultatele în altă zonă, fără riscul de suprascriere a valorilor.

Perioada convertorului se numește TAD și este dată fie de un oscilator intern, fie de semnalul de ceas al perifericelor. Convertorul este unul de tipul sample and hold, fiind prezentat în figura 4.9 ca o zonă punctată cu denumirea S/H. Funcționarea este prezentată în figura 4.10, valoarea analogică având culoarea gri, punctele de eșantionare fiind prezentate cu linii punctate, și valoarea digitizată având culoarea roșie pe grafic. Prima dată se face o încărcare a condenstatorului, urmată de decuplarea întrerupătorului. După perioada de eșantionare, urmează perioada de hold în care se face conversia valorii din condensator. Perioada de sample poate fi modificată de la 1 la 127 TAD , dar perioada de conversie este fixată la 12 TAD.

În sectiunia 17.5 din [20] se prezintă modul de calcul al TAD și pentru a se obține o frecventa de eșantionare de 1000ksps.

4.4.6 RTCCRTCC este un circuit ce asigură păstrarea datei în format BCD, facilitând astfel

interpretarea cât mai rapidă a datei fără a mai fi nevoie de prelucrări ulterioare. Se oferă posibilitatea de întrerupere și toggle de output la intervale de o secundă, un minut, o oră și alte intervale mai mari. În mod intern perioada de lucru este de o jumătate de secundă, dar pentru citire rezoluția este la o secundă.

În ceea ce privește alarma ea poate fi setată într-un interval de la o jumătate de secundă până la un an și poate fi repetată de un număr de maxim 255 de ori. Dacă se folosește opțiunea de Chime se va repeta la nesfârșit, detectând atingerea numărului de 0 repetări contorul se va reinițializa.

Accesul la registrele pentru timp și pentru alarmă se face doar dacă bitul

23

Figura 4.10: Funcționarea S/H

Page 24: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

RTCSYNC, respectiv ALRMSYNC este zero. Acest interval de timp este de 32 de perioade de ceas, o citire sau o scriere în afara acestui interval producând efecte nedefinite.

În figura 4.11 se prezintă modul în care se incrementează registrul secundelor. După 32768 de perioade de ceas are loc incrementarea registrului.

În cazul în care se observă că referința nu are exact 32 768Hz se poate ajusta cu formula: (32 768- Frecvență măsurată)*60= Eroare. Acestă valoare poate avea atât valori pozitive cât și negative. Modulul va face corecțiile necesare o dată la 1 minut, prin modificarea secundelor.

Pentru alarmă se va seta data și timpul primei declanșări, apoi se alege când(după o secundă, o zi, un an) se va declanșa și de câte ori se va repeta alarma la intervalul specificat. Data primei alarme este comparată cu o mască. De exemplu, dacă se alege un interval de un minut nu se vor lua în considerare secundele pentru a se stabili perioada de declanșare. La incrementarea registrului minutelor vom avea o alarmă. În cazul extrem, de repetare la un interval de o secundă, setarea datei primei alarme este inutilă. Configurația măști în acest caz face ca prima alarmă să apară după o secundă de la setarea bitului de enable. Pentru înțelegerea acestui modul recomand urmărirea [21]și [22].

4.4.7 Controller-ul de întreruperiAcest microcontroller are un număr de 46 vectori de întrerupere și un număr de 58

de IRQ( surse de întrerupere, inclusiv cele 5 externe). Atât în modul single cât și în modul multi- vector se pot folosi registre de tip shadow(secondary register set).

Modul single vector : este modul default, în care va intra după reset. Se va folosi aceiași adresă indiferent de vectorul care a generat-o.

Modul multi vector : fiecare vector are asociat o adresă unică calculată folosind o adresă de bază și un deplasament.

Întreruperile pot avea prioritate între 1(minim) și 7(maxim). Prioritatea 0 se folosește pentru a inhiba întreruperea. Controller-ul de întreruperi va servi o întrerupere de ordin superior, chiar dacă există una de ordin inferior în execuție. Aceiași ordonare și regulă de servire apare și în cazul folosirii subprioritățiilor ce au valori între 0(minim) și 3(maxim). Pe lângă aceste reguli pentru ordonare se folosește și ordinea naturală, unde 0 este maxim și vectorul 45 este minim. La intrarea în ISR(Interrupt service routine) este obligatoriu să se marcheze sursa care a generat întreruperea pentru a evita întreruperi de tip recursiv.

Registrele shadow(al doilea set de registre GPR) aduc o creștere a performanței deoarece nu mai este nevoie să se facă salvări de context pe stivă. Acestea

24

Figura 4.11: Incrementarea secundelor

Page 25: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

sunt valabile pentru single vector, iar în multi vector sunt valabile doar pentru întreruperile de nivel mai ridicat.

Tehnica TEMPORAL PROXIMITY INTERRUPT COALESCING, presupune folosirea unei cozi unde se pun întreruperile, de grad egal sau mai mic cu un prag dat, și care vor fi apoi servite înlănțuit. Se folosește un timer, care este declanșat de apariția primei întreruperi ce respectă condiția de grad. Odată ajuns la zero, se vor procesa înlănțuit toate acele întreruperi care au respectat condiția de a intra în coada de așteptare. Pentru aceasta este nevoie să se încarce pragul dorit în TPC și valoarea de unde se va decrementa în IPTMR( valoare pe 32 biți). Acest timer folosește direct SYSCLK, fără prescaler.

Se pot folosi de asemenea și până la 5 intreruperi externe, care pot fi pe front crescător sau descrecător, și două întreruperi de tip soft, a căror declanșare poate fi făcută exclusiv prin cod. Pentru înțelegerea întreruperilor recomand [23].

4.5 Protocoale folosite

4.5.1 I2CEste un protocol de tipul master slave. Se folosesc două linii pentru comunicare:

una pentru date(SDA), și alta pentru semnalul de ceas(SCL). Ambele linii sunt de tipul open-drain, pentru a se putea modifica valoarea liniei din orice punct. Pe linia de SDA se pot încărca datele fie de către master, fie de către slave; dar linia de SCL este permanent controlată de master, slave-ul putând doar să prelungească timpul în care se găsește în starea '0'.

Figura 4.12: Magistrala I2C

Liniile au valoarea default '1', datorită rezistențelor de pull-up Rp, care sunt conectate la Vdd, așa cum se poate vedea în figura 4.12. Pentru modificarea valorii la '0' se va conecta linia dorită la GND, fie din master, fie din slave.

Pentru a se modifica valoarea linie SDA, linia de SCL trebuie să fie în poziția low. Singurele exceptii de la această regulă sunt condițiile de start și stop, în care datele trec din high în low și invers, deși linia semnalului de ceas are valoarea '1', așa cum se arată și în figura 4.13.

25

Page 26: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Datele transmise pe magistrală au 8 biți în dimensiune, urmate apoi de bit de confirmare. În figura 4.14 se prezintă schema generală de transfer pe magistrala I2C. Repetarea startului apare pentru a nu se pierde arbitrarea atunci când se dorește să se transfere mai mult de 1 byte spre un dispozitiv.

Magistralele cu mai mult de un master au nevoie de arbitrare. În figura 4.15 s-a presupus că sunt conectate 2 astfel de dispozitive. Ambele verifică linia de SCL și încearcă pornirea unui transfer, și implicit obținerea magistralei. Deoarece ambele au putut da startul, vor continua să pună datele în paralel, până când Data1 este '1', însă SDA este '0', ceea ce înseamnă că primul a pierdut magistrala, și astfel renunță să mai pună date pe I2C.

26

Figura 4.14: Formatul general de transfer al datelor

Figura 4.13: Start, schimbare date, stop

Page 27: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Un mecanism similar celui de arbitrare apare și la semnalul de ceas și se numește 'clock streching'. Dacă slave-ul mai are nevoie de timp pentru procesare va menține linia de clock la valoarea '0', exemplificat în figura 4.14, pentru a putea face procesăriile necesare.

Protocolul I2C presupune trimiterea mai întâi a adresei slave-ului de la care se dorește recepționarea/trimiterea datelor, însoțit de un bit de read/write, iar la final de ACK. În octeții următori se găsesc datele de la slave spre master, sau în sens invers. Cel care este destinatarul datelor trebuie să confirme transferul prin ACK. Asupra tipurilor de transfer voi reveni în capitolele următoare unde vor fi și exemplificate pentru DAC.

4.5.2 USBPentru această prezentare generală a protocolului am folosit [24] și [25], precum

și unele constatări experimentale.

4.5.2.1 O scurtă introducereDiferențele între funcționalitățiile portului USB de pe placa de dezvoltare și cel de

pe un PC sunt minime. Diferențele majore sunt următoarele: oferă suport doar pentru anumite clase sau dispozitive, poate suporta doar anumite tipuri de transfer, nu suportă hub-uri, cantitatea de curent oferită este limitată.

Permite conectarea diverselor periferice la calculator prin folosirea unui cablu unic. Într-un sistem conţinând o magistrală USB, perifericele se pot conecta în serie sau într-o topologie sub formă de stea pe mai multe nivele. Un avantaj important îl reprezintă conectarea de tip plug-and-play care nu necesită desfacerea carcasei sau repornirea sistemului.

Portul USB detectează adăugarea unui nou periferic şi determină în mod automat resursele necesare acestuia, inclusiv driver-ul software, rata de transfer și consumul de curent. Perifericele se pot afla la o distanţă de până la 5 m unele faţă de altele sau faţă de un distribuitor(hub).

În configurația de față oferită de Microchip nu se poate folosi distribuitor. Din această cauză topologiile de tip stea nu pot fi implementate. De asemenea deși din punct

27

Figura 4.15: Arbitrarea a două masters

Page 28: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

de vedere al USB Host Stack se permite conectarea mai multor dispozitive in serie, placa de dezvoltare asigură un singur port de USB și astfel se poate conecta practic un singur periferic la un moment dat.

Fiecare funcţie(periferic) conţine informaţii de configuraţie care descriu posibilităţile sale şi resursele necesare. Aceste informaţii sunt transmise calculatorului gazdă ca răspuns la o tranzacţie de control. Înaintea utilizării unei funcţii, aceasta trebuie configurată de calculatorul gazdă. Această configurare presupune alocarea unei lăţimi de bandă în cadrul magistralei USB şi selectarea opţiunilor specifice de configuraţie.

4.5.2.2 Tipuri de transferArhitectura USB permite patru tipuri de transferuri de date: de control, de

întrerupere, de date voluminoase şi izocrone. Transferurile de control se utilizează de driver-ele calculatorului gazdă pentru

configurarea dispozitivelor care sunt ataşate la sistem. Transferurile de întrerupere se utilizează pentru date care trebuie transmise cu

o întârziere limitată. Transferul acestor date poate fi solicitat de un dispozitiv în orice moment, iar rata de transfer pe magistrală nu poate fi mai redusă decât cea specificată de dispozitiv. Tastatura sau mouse-ul pot folosi acest tip de transfer pentru notificarea apăsării unei taste, respectiv pentru trimiterea noilor coordonate ale cursorului.

Transferurile de date voluminoase (“bulk”) se utilizează cu periferice cum sunt memorii de masă, imprimante sau scanere. Aceste date sunt secvenţiale, și de dimensiuni mari. Fiabilitatea transferurilor este asigurată la nivel hardware prin utilizarea unui cod detector de erori şi reluarea unui transfer cu erori de un anumit număr de ori. Rata de transfer poate varia în funcţie de alte activităţi de pe magistrală.

Transferurile izocrone se utilizează pentru datele care trebuie furnizate cu o anumită rată de transfer constantă şi a căror sincronizare trebuie garantată. Un exemplu ar fi streaming-ul audio sau video, unde o eroare la transmiterea unui pachet duce la anularea retransmisiei și continuarea cu următorul din secvența de transfer.

În cazul aplicației dezvoltate se folosesc cu precădere transferuri de control și de întrerupere, existând suport și pentru bulk; transferurile izocrone nu sunt suportate.

4.5.2.3 Modelul de comunicație USBProtocolul USB este de tip asimetric, și folosește adresarea pentru identificarea

dispozitivelor conectate. Spre deosebire de I2C magistrala nu este de tipul multimaster. Magistrala USB are 4 fire: VBUS și GND sunt folosite pentru alimentarea dispozitivelor iar D+ și D- se folosesc pentru transferul într-o singură direcție la un moment dat al datelor.

Comunicarea între host și periferic se face folosind fluxuri de comunicație numite pipes, pentru realizarea legăturii la nivel de end point-uri. End point-ul este folosit alături de adresa device-ului pentru identificare. El este necesar deoarece la o adresa(la un dispozitiv) pot exista mai multe tipuri de transferuri fiecare fiind asociat cu un end point. Punctele terminale pot fi de intare sau de ieșire, iar cel cu număr 0 este default fiind folosit pentru configurare.

Există două moduri de comunicaţie printr-o conductă(pipe): şir sau mesaj. În modul şir, datele nu au o structură definită de specificaţiile USB. Datele sunt transferate secvenţial şi au o direcţie predefinită, de intrare sau de ieşire. Conductele de tip şir permit

28

Page 29: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

transferuri de întrerupere, bulk sau izocrone. În modul mesaj, datele au o anumită structură definită de specificaţiile USB. Conţinutul datelor transferate printr-o conductă de tip mesaj este interpretat de controller-ul USB. Aceste conducte sunt controlate de calculatorul gazdă şi permit doar transferuri de control, în ambele direcţii, fiind folosite pentru configurarea dispozitivelor.

Punctele terminale conţin buffere de intrare sau de ieşire prin intermediul cărora se realizează comunicaţia între calculatorul gazdă şi dispozitivul USB. De exemplu, dacă programul rulat pe calculatorul gazdă transmite un pachet adresat unui anumit dispozitiv USB, acest pachet va fi depus în bufferul unui punct terminal de ieşire al dispozitivului. Ulterior, controller-ul dispozitivului va citi din buffer pachetul recepţionat. Dacă dispozitivul trebuie să transmită date la calculatorul gazdă, nu poate depune datele direct pe magistrală, deoarece toate tranzacţiile sunt iniţiate de master. Dispozitivul va depune datele în buffer-ul unui punct terminal de intrare, iar aceste date vor fi transferate la cererea calculatorului printr-un pachet de intrare. Noțiunile de intrare/ieșire sunt relative la host. Master-ul a fost denumit alternativ calculator sau host. Pentru slave s-a folosit denumirea de dispozitiv.

4.5.2.4 Descriptorii de USBIerarhia de descriptori are ca rădăcină la nivelul superior descriptorul de

dispozitiv. La nivelul următor se află descriptorii de configuraţie; există câte un asemenea descriptor pentru fiecare configuraţie a dispozitivului. Pentru fiecare configuraţie pot exista unul sau mai mulţi descriptori de interfaţă, în funcţie de numărul de interfeţe ale configuraţiei respective. În sfârşit, pentru fiecare punct terminal al fiecărei interfeţe există câte un descriptor al punctului terminal.

Descriptorul de dispozitiv este folosit pentru a oferi informații generale despre dispozitiv: clasa/subclasa producator ID/produs ID, revizia de USB. Descriptorul de configurație este folosit pentru a primi informații legate de tipul alimentării: proprii sau prin bus-ul de USB. În cazul în care un dispozitiv are asociate mai multe astfel de dispozitive, la un moment dat poate fi activat doar unul. Un număr oarecare de puncte terminale pot fi grupate logic într-un descriptor de interfață; care este folosit in cadrul dispozitivelor multifuncționale. La un moment dat pot fi activate mai mulți asemenea descriptori. Conține informații legate de numărul de puncte terminale și tipul de clasă/subclasă. Descriptori de end-point sunt folosiți pentru a se stabili direcția, timpul de acces, lațimea de bandă, adresa dispozitivului. Un alt descriptor opțional dar care este implementat in USB Host Stack este cel de șir de caractere( string) folosit pentru a se obține informații in plain text legate de capabilitățiile dispozitivului.

4.5.2.5 Procesul de enumerareAtunci când un dispozitiv este conectat/deconectat la magistrala USB,

calculatorul gazdă execută un proces numit enumerare pentru a determina modificările apărute în configuraţia sistemului USB. La conectarea unui dispozitiv USB la magistrală, se execută următoarele operaţii:

1. Calculatorul gazdă folosind o rezistență determină conectarea unui nou dispozitiv.

2. Calculatorul gazdă aşteaptă un timp de cel puţin 100ms pentru ca tensiunea de

29

Page 30: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

alimentare a dispozitivului să devină stabilă, după care transmite o comandă de validare şi de resetare a portului. Folosind măsurarea tensiunii pe liniile de date, se determină prezența rezistențelor de pull-up/pull-down, și astfel se determină viteza dispozitivului: viteză ridicată(480 Mbiţi/s) sau viteza normală (12 Mbiţi/s).

3. După terminarea procedurii de resetare, portul este validat. Dispozitivul se află acum în starea implicită şi poate absorbi un curent de maxim 100 mA de pe linia VBUS a magistralei. Dispozitivul va răspunde la tranzacţii cu adresa implicită zero.

4. Calculatorul gazdă solicită descriptorul de dispozitiv, iar dispozitivul transmite acest descriptor prin intermediul conductei implicite.

5. Calculatorul gazdă asignează o adresă unică dispozitivului. 6. Calculatorul gazdă solicită descriptorii de configuraţie, iar dispozitivul

transmite calculatorului gazdă aceşti descriptori. 7. Pe baza informaţiilor de configuraţie, calculatorul gazdă asignează o anumită

configuraţie dispozitivului. Dispozitivul se află acum în starea configurată şi toate punctele terminale ale acestei configuraţii sunt configurate conform caracteristicilor specificate în descriptorii acestora.

Dispozitivul este pregătit pentru utilizare şi poate absorbi de pe linia VBUS a magistralei curentul specificat pentru configuraţia selectată.

Atunci când dispozitivul USB este deconectat de la un port USB, calculatorul gazdă dezactivează portul respectiv şi actualizează informaţiile sale despre topologia magistralei.

4.5.2.6 USB Embedded Host StackÎn Application note [26] se face o scurtă introducere a modului de funcționare a

USB host adaptat pentru embedded. Articolul [27] vine ca și o completare a articolului precedent, insistându-se mai mult pe partea de programare, cu multe exemple de cod.

4.5.2.6.1 Target Peripheral List( TPL)

Conține o descriere a dispozitivelor ce pot fi suportate de host fie pe bază de clasă și de protocol (ca de exemplu tabelul 4.1 ) sau de VID-PID (ca de exemplu tabelul 4.2). În cazul microcontroller-ului, spre deosebire de PC, TPL rămâne fix, putându-se suporta doar dispozitivele declarate inițial.

Descriere Numele clasei Codul clasei Codul subclasei Protocol

Flash Drive Mass Storage 0x08 0x06 0x50

Tabelul 4.1: Exemplu de TPL pentru Clasă, Subclasă și Protocol

Descriere Producător Model VID(vector ID) PID(product ID)

Device cu suport ADK

Google Telefon/ tabletă 0x18D1 0x2D00

Tabelul 4.2: Exemplu de TPL pentru VID, PID

30

Page 31: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

4.5.2.6.2 Arhitectura stivei

Este formată din două părți: mașina de stări(pentru enumerarea dispozitivelor) și handler-ul de întreruperi(pentru procese critice).

În figura 4.16 se prezintă schema generală pentru state machine. Inițializarea are rolul de a pregăti controller-ul USB, și se realizează o singură dată după reset, trecându-se apoi în starea detached, în care se așteaptă conectarea dispozitivelor. Un dispozitiv atașat trece din starea atached în starea de primire a unei adrese dacă respectă condițiile electrice specifice. Starea configured presupune pregătirea end point-urilor pentru a se realiza transferul bidirecțional, printr-un apel al handler-ului de inițializare specific dispozitivului, folosind intrările din TPL și Client Driver Table. La deconectare se trece din starea running în starea detached.

Stiva de firmware este o structură de tip ierarhic. Aplicația( codul utilizatorului) reprezintă ultimul nivel, USB Client Driver este folosit pentru inițializarea dispozitivului

31

Figura 4.16: Mașina de stări

Page 32: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

descoperit, iar USB Host Layer este librăria care facilitează accesul la resursele hardware și oferă funcționalitatea de bază pentru modul: identificare, enumerare, managementul de drivere. Pot exista mai multe USB Client Driver dacă se dorește oferirea suportului pentru un număr mai mare de dispozitive.

O organizare pe layers se folosește și pentru handler-ul de întrerupere, având trei nivele: electric, mesaje USB și mesaje Android(ultimul nivel). Fiecare nivel tratează evenimentele specifice, iar la întâlnirea unuia necunoscut se face o trimitere spre nivelele superioare pentru analiză.

4.5.2.6.3 Driver-ul client bazat pe evenimente

Aplicația principală are rolul de a apela constant layer-ul de la nivelul cel mai scăzut: USB host(săgeată #2). La terminarea unei activități pe USB se va apela(#3) în client driver, iar dacă este suportat, se va apela mai apoi aplicația(#4). Apelurile, folosind structuri, trimit și informații legate de sursă și parametrii. Astfel tranzițiile de la nivelele superioare, apar ca urmare a evenimentelor de pe USB, fiecare nivel având un state machine.

Layer-ul Host este influențat și de evenimetele ce apar pe magistrală cum ar fi conectarea sau deconectarea unui dispozitiv. Apelul #2 are rolul de a permite tranzițiile între sub-stăriile de la adresare sau configurare.

Se poate implementa driver-ul client și folosind polling. Diferența între cele două metode apare la modul în care se face tranziția între stări, marcată prin folosirea de while loops ( polling) sau de întreruperi și call backs( event based). Varianta cu întreruperi este mai eficientă. Exemple de call back sunt apelurile #3 și #4.

4.5.3 Android Open Accessory ProtocolUn USB host(accesoriul) va trebui să implementeze următorii pași:

așteaptă și detectează conectarea device-ului cu Android

verifică dacă acest device suportă modul accesoriu

dacă nu este deja în acest mod va încerca pornirea acestuia în modul amintit

stabilește comunicarea cu device-ul folosind protocolul amintit în subtitlu32

Figura 4.17: Driver-ul bazat pe evenimente

Page 33: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Accesoriul verifică la fiecare conectare a unui slave ca vendor ID device-ului să fie 0x18D1, și ID de produs să fie 0x2D00(ADK) sau 0x2D01(ADK și ADB). Dacă nu se primesc aceste răspunsuri, microcontroller-ul va încerca pornirea dispozitivului în mod accesoriu: trimite o comandă de tip 51, de obținere a protocolului, iar device-ul va răspunde cu un număr nenul dacă are implementat ADK.

Folosind comanda 52 se vor trimite pe rând descrierile către accesoriu. Apoi se va trimite device-ului comanda 53 pentru a porni în modul accesoriu. După trimiterea comenzii 53, USB-ul de pe device se va reporni ceea ce duce la un nou proces de enumerare. De această dată vendor ID și product ID trebuie să fie cele corecte, în caz contrar, sau la orice eroare apărută pe parcurs, înseamnă că device-ul nu cunoaște protocolul cerut. Pentru mai multe detalii legate de structura acestor mesaje standard poate fi consultată secțiunea 5.9. Comenzi USB din [25].

Command Request Type Request Value Index Length Data(optional)

Get protocol

(5110)

USB_Dir_out| USB_type_Vendor| USB_Device

51 0 0 2 Get protocol

Send strings

(5210)

USB_Dir_out| USB_type_Vendor| USB_Device

52 0 0... 5 String dimension

Send a string

Strart(5310)

USB_Dir_out| USB_type_Vendor| USB_Device

53 0 0 0 Send Null

Tabelul 4.3: Comenzi de inițializare ADK

Dacă ID-ul de producător este 0x2D00, atunci este o singură interfață cu două endpoint-uri bulk, unul pentru intrare și altul pentru ieșire. Dacă primim ID 0x2D01, atunci sunt două interfețe(ADK și ADB) fiecare cu câte două bulk endpoints. În tabelul 4.3 sunt prezentate schematic etapele protocolului, numerele fiind în baza zece. Valorile lui index pentru comanda 52 în ordine crescătoare sunt: producător, model, descriere, versiune, URI, și număr serial. URI se folosește pentru a se descărca aplicația din Google Play în cazul în care nu este instalată pe telefon/tabletă. Comenziile 52 și 53 nu se folosesc dacă device-ul se află deja în modul accesoriu.

4.6 Algoritmii propușiÎntregul sistem poate fi privit ca și un sistem distribuit, deoarece fiecare modul își

execută funcționalitatea independent de restul.

33

Page 34: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Figura 4.18: Structura logică a aplicațieiÎn figura 4.18 este prezentată schema generală a aplicației. Codul de culori oferă o

mai bună grupare vizuală a componentelor. Perifericele producătoare/consumatoare de date sunt colorate cu albastru, iar zonele partajate sunt de culoarea orange. Memoriile partajate pot fi privite ca și buffere, cu mai multe periferice care scriu și care citesc din aceste zone. Circuitele de USB și RTCC sunt colorate cu verde respectiv roșu deoarece îndeplinesc funcționalități speciale. RTCC se folosește pentru a controla procesul de actualizare a zonei comune văzută de USB, copierea datelor făcându-se de la dreapta la stânga(săgeata de pe desen). Modulul USB este cel care comunică mai departe cu tableta. Direcția săgeților arată modul de deplasare al datelor, fără a se insista pe tipul sau numele datelor care circulă.

Datele care intră în ADC sunt de tip analogic, iar cele care intră, respectiv ies din IC și din PWM sunt de tip digital, de tip semnal dreptunghiular. RTCC este alimentat de o sinusoidă de 32768Hz.

34

Page 35: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

4.6.1 Conversia din analogic în digital

În figura 4.19 se prezintă schema generală de conversie din analogic în digital. Primul pas presupune eșantionarea și conversia efectivă a celor două tensiuni(canal 1 si canal 2). În funcție de ce zonă folosim pentru salvare se va salva în zona 0 sau în 1. Valoriile pentru i sunt de la 0 la 7, iar pentru j sunt de la 8 la 15. Atât i, cât și j se vor incrementa, iar după ce au ajuns la 7 respectiv 15 se generează o întrerupere și se reinițializează. În întrerupere are loc citirea celor 8 valori din buffere, în funcție de zona de lucru și medierea lor. Eșantionarea celor două tensiuni se face în mod alternativ.

De exemplu, considerăm că zona de lucru este 0. Se face conversia primei tensiuni și salvarea în buffer-ul 0, iar a doua tensiune se salvează în bufferul 1. Se va continua cu salvarea canalului 1 în buffer-ul 2, și a canalului 2 în buffer-ul 3. După ce s-a scris și în bufferul 7 se generează întreruperea. În întrerupere se ține seama de zona curentă de lucru și de alternanța cu care se salvează cele două canale.

4.6.2 Măsurarea turației

35

Figura 4.19: Schema generală de conversie

Page 36: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

În figura 4.20 se prezintă modul general în care se măsoară frecvența unui semnal dreptunghiular. Cât timp nu apare un front crescător se incrementează un timer. La apariția unui eveniment se generează o întrerupere. În întrerupere se verifică dacă a fost primul astfel de eveniment. În caz afirmativ se reinițializează timer-ul. La al doilea eveniment mai întâi se va salva valoarea ceasului, apoi acesta se va reinițializa. Al treilea eveniment este considerat din nou ca fiind primul, acțiunea algoritmului fiind similară.

Figura 4.21: Modul de folosire al două module de IC și un Timer

În figura 4.21 se prezintă cazul în care se măsoară două frecvențe folosind un singur timer. Culoarea albastră reprezintă primul canal, iar culoarea verde reprezintă al doilea canal. În acest caz mai întâi se analizează primul canal în așteptarea a două fronturi

36

Figura 4.20: Măsurare frecvență puls

Page 37: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

de interes(F1 și F2). În acest timp orice eveniment pe al doilea canal este ignorat. După măsurarea perioadei primului canal(T canal 1) acesta se ignoră și se urmărește apariția a două fronturi pe canalul 2. Ciclul apoi se reia cu primul canal. Pentru măsurarea perioadei pe oricare canal se consideră algoritmul prezentat în prima parte a secțiunii.În mod similar, cazul de față poate fi extins la orice număr de canale, creșterea numărului ducând la scăderea ratei cu care se actualizează informațiile legate de frecvența lor.

4.6.3 Actualizarea datelorActualizarea datelor apare în figura 4.18 ca și un transfer între două zone partajate.

Actualizarea repezintă o copiere a datelor din zona din partea dreaptă în zona din partea stângă.

Figura 4.22: Cele două moduri de actualizare a datelorÎn figura 4.22 sunt prezentate cele două regimuri de funcționare a mecanismului

de actualizare: normal și calibrarea motoarelor. În modul de funcționare normală se face o copiere a datelor la o frecvență de 1Hz. Această frecvență poate fi obținută folosind un circuit extern, un timer intern sau circuitul de RTCC. Circuitul de RTCC are avantajul că nu este folosit de altă componentă sau de către program.

În cazul în care se dorește o calibrare a motoarelor valoriile măsurate vor fi transferate imediat ce au fost calculate. Pentru aceasta la fiecare modificare a factorului de umplere al PWM are loc un răspuns care cuprinde tensiuniile și frecvențele măsurate.

37

Page 38: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

4.6.4 Calibrare motoareProcedura de calibrare presupune

folosirea factorului de umplere al PWM care comandă viteza motoarelor. Factorul de umplere va lua valoarea initială 100%, și va continua să scadă atât timp cât turația motorului este diferită de zero. În cazul în care s-a ajuns la 0, motorul se consideră oprit, și factorul de umplere se setează la zero. Procedura este evidențiată în figura 4.23 și trebuie repetată pentru fiecare motor în parte.

Calibrarea are rolul de a stabili intervalul de valori pentru PWM care produce rotirea motorului. Ca și rezultat se elimină zonele cu factor de umplere mic, în care motorul are turație 0.

În locul decrementării factorului de umplere se poate porni de la valoarea zero, și apoi să se incrementeze cât timp turația este zero. Această variantă a algoritmului produce un prag al factorului de umplere mai mare decât varianta care presupune decrementarea. Explicația constă în faptul că pentru a se pune inițial în mișcare bobina rotorului este nevoie de un impuls de tensiune mai mare. Odată obținută mișcarea de rotație, se poate reduce factorul de umplere cu câteva procente, fără a se constata oprirea motorului.

4.6.5 Înlănțuirea comenzilor pe USB În figura 4.24 se prezintă modul în care poate fi crescută performanța

transferurilor pe USB prin înlănțuirea comezilor. Fiecare comandă este identificată printr-un cod unic urmată de un număr cunoscut de argumente. În exemplul următor s-a considerat transmisia unui număr de 3 comenzi pe magistrala serială, fiecare comandă fiind de dimensiune variabilă. Fiecare dreptunghi are dimeunea de 1 octet. Se folosește un vector unde vor fi copiate comenziile, lungimea fiind egală cu suma dimensiunilor comenzilor în cazul maxim de înlănțuire.În cazul extrem număr maxim de înlănțuiri este egal cu numărul de comenzi de ieșire pe magistrala serială. Numărul poate fi redus dacă existența unor comenzi de ieșire este exclusivă. Pointer-ul se folosește pentru a indica locația următoare unde se poate copia informația.

La primul pas se copiază prima comandă și se incrementează poziția pointerului cu 3, reprezentând numărul de octeți mutați. Acțiuni similare se execută și pentru următoarele două comenzi, pointer-ul indicând la final locația de după argumentul comenzii 3. Operația poate fi extinsă până la copierea unui număr de 1023 de octeți, dacă se folsește modul bulk. Principalul avantaj al înlănțuirii îl constituie faptul că printr-un singur transfer de USB se vor transmite mai multe date. Un dezavantaj minor este reprezentat de logica de decodificare a mesajului, care presupune împărțirea acestuia în

38

Figura 4.23: Calibrare motor

Page 39: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

tokens(comenzi) în funcție de codul aflat pe primul octet și manipularea individuală a fiecărei comenzi.

Pentru a se trimite și date care nu constituie comenzi, sau a căror lungime este variabilă, trebuie ca informațiile să fie împachetate. În acest sens, se va folosi un cod de mesaj special, pentru a codifica informațiile care nu constituie comenzi. Pe următorul octet se va specifica numărul de bytes al mesajului, iar în următorii octeți se vor copia datele efective. În acest caz pentru a se putea descifra mesajul este nevoie să se citească primi doi octeți, primul este folosit pentru a marca un mesaj special, iar următorul pentru a specifica numărul de argumente componente.

O altă abordare pentru mesajele speciale presupune încadrarea datelor între un cod special și un marcator de final(asemănător \n în C). Pentru a se include marcatorul de sfârșit în corpul mesajului se va adopta o tehnică similară caracterelor escape din C. Lipsa marcatorului de final va permite citirea întregului buffer de intrare al USB, ceea ce poate duce la pierderea comenziilor care nu vor mai fi interpretate.

Pentru introducerea mesajelor de dimensiune variabilă, prima abordare este mai sigură și mai ușor de implementat.

39

Figura 4.24: Înlănțuirea comenziilor pe USB

Page 40: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

5. Proiectare de detaliu și implementare

În figura 5.1 se prezintă schema generală a aplicației. Microcontroller-ul(uC) este prezentat ca o componentă separată, cu rol în controlul traficului informației. Săgețiile indică direcțiile de circulație ale datelor. Senzorii și elementele de acționare sunt prezentate ca și componente separate, dar o parte sunt unități din interiorul uC, divizarea fiind făcută astfel doar pentru a evidenția rolul lor diferit în sistem.

În figura 5.2 se prezintă structura aplicației din punct de vedere al depenențelor de componte hardware și software. Aplicația de față are ca și bază un exemplu oferit de Microchip, în care se folosește tableta pentru a controla 4 LED-uri, a citi 2 butoane și un potențiometru de pe placă. Codul de culori s-a folosit pentru a evidenția zonele care au presupus dezvoltare, sau care au avut nevoie doar de documentare și testare.

În partea superioară a imaginii sunt prezenate cu orange fișierele create pentru realizarea funcționalităților propuse. Divizarea pe fișiere are rolul de a permite o grupare a algoritmilor folosiți pentru îndeplinirea unui task. Fișierul mainDef.h conține o serie de variabile externe, vizibile din mai multe fișiere, precum și încapsularea accesului pentru datele folosite de mai multe module prin folosirea de macro-uri. Pentru îndeplinirea unei funcționalități se foloște perechea de fișiere .h și.c. În fișierul header sunt redefiniți regiștrii folosiți(pentru o denumire uniformă) și parametrii de configurare. În fișierul sursă se găsește codul efectiv. Main.c este fișierul principal, și folosește funcționalități din restul modulelor. Conține inițializăriile modulelor și bucla principală.

Android Accessory Framework și USB Stack sunt cele două librării care realizează comunicarea pe protocolul Andoid Open Accessory. Aplicația folosește cele

40

Figura 5.1: Schema generală a aplicației

Page 41: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

două librării amintite, împreună cu Microchip Peripheral Library(MPL), care este folosit pentru accesul la modulele de bază ale microcontroller-ului. MPL folosește cod scris în ASM sau în C. Toate librăriile au fost folosite ca atare, fiind nevoie doar integrarea lor în proiect și testarea funcționalităților.

Folosirea modulelor a presupus analiza modului de operare și a interdependențelor existente, pentru a se folosi cât mai eficient un număr minim de astfel de componente. Partea de hardware a presupus design-ul folosind unelte cum ar fi falstad.com/circuit, prototipizarea pe breadboard și împrimarea efectivă a montajului pe o placă.

Figura 5.2:Dependențele aplicației

5.1 Modulul de DACAcest modul are o adresă fixă 0x60, pinii de A0- A2 find lipiți la GND. Acest

modul este un convertor pe 12 biți asigurând astfel un interval de 4096 de valori. Ieșirea este proporțională cu intrarea, din această cauză este sensibil la valoarea intrării.

S-au implementat funcțiile de scriere în registru și în EEROM precum și de citire a registrului și a memoriei. Memoria nevolatilă poate fi folosită pentru a se programa o singură dată modulul, pentru ca apoi acesta să păstreze valoriile și după o repornire a sistemului.

Semnăturile celor două funcții de scriere void writeDACRegister(unsigned int DACValue, unsigned short PowerDownOption) și respectiv a void

41

Page 42: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

writeDACRegisterAndEEPROM(unsigned int DACValue, unsigned int PowerDownOption) sunt identice, prima valoare fiind un număr între 0- 4095, iar cea dea doua valoare reprezintă opțiunea de power down, pentru a se obține high impedance dacă se dorește. Implementarea acestor metode urmărește Reference Manual-ul de la producător.

Funcția de citire din DAC nu este folosită, semnătura ei fiind BOOL readDACRegisterANDEEPROM (BYTE i2cbyte[]), și returnează un boolean pentru a semnaliza dacă operația s-a executat sau nu cu succes, iar rezultatul este depus în i2cbyte[].

În figura 5.3 se prezintă modul în care se poate scrie în registrele circuitului de DAC, fără salvarea în EEPROM. În primul octet se precizează adresa dispozitivului, împreună cu tipul operației, în acest caz este una de scriere. În octetul al doilea și al treilea se prezintă valoriile care trebuie încărcate în registre, de interes fiind DAC Register, care va reprezenta valoarea ieșirii; tipul operației se specifică prin Fast Mode Command. Fiecare byte se va confirma(Ack) de către DAC. Pentru a se salva în EEPROM, în locul bitului de stop se repetă conținutul octețiilor 2 și 3 de pe figură.

5.2 Modulul de Input Capture S-a ales folosirea Timer 2 ca și bază de timp pe 16 biți, cu un prescaler de 16, și a

întreruperilor de la canalul 2, respectiv 3 de la Input Capture. Am ales folosirea unei abordări de tip state machine state pentru a se permite măsurarea cît mai exactă a două frecvențe folosind un singur timer.

Se definesc macro-urile pentru prima sursă sampleIC2Start și sampleIC2Stop , respectiv sampleIC3Start și sampleIC3Stop, pentru a doua sursă de frecvență și se folosește o variabilă care va trece prin cele 4 stări. Ca și exemplificare se folosește tabelul 5.1, abordarea fiind similară cu cea propusă în secțiunea 4.6.2.

Pentru măsurarea lui IC2, variabila va lua mai întâi valoarea sampleIC2Start, odată cu primul rising edge; la următorul eveniment pe IC2 va trece în sampleIC2Stop. În timpul în care variabila a avut una din cele două valori enumerate mai sus, orice eveniment de pe IC3 va fi pur și simplu ignorat. În sampleIC2Stop, doar un eveniment pe IC3 va determina tranziția în sampleIC3Start, evoluția fiind similară pentru IC3.

Detecția opririi unuia dintre motoare se face folosind detectarea condiției de overflow de la baza de timp, caz în care se verifică dacă variabila este sampleIC2Start sau sampleIC3Start , pentru a se determina sursa. Se va trece apoi la canalul următor în starea de start, pentru a se evita blocarea algoritmului.

42

Figura 5.3: Scrierea în registre, fără salvare în EEPROM

Page 43: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

stare actuală rising edge stare următoare Observații

sampleIC2StartIC2 sampleIC2Stop resetează Timerul

IC3 păstrază starea actuală

sampleIC2StopIC3 sampleIC3Start preia valoarea din

Timer și îl resetează

IC2 păstrază starea actuală

sampleIC3StartIC2 păstrază starea

actuală

IC3 sampleIC3Stop resetează Timerul

sampleIC3StopIC3 păstrază starea

actuală

IC2 sampleIC2Start preia valoarea din Timer și îl resetează

Tabelul 5.1: Evoluția stărilor pentru implementarea input capture

În continuare voi prezenta codul pentru ISR de input capture pentru primul canal:1 | #if CaptureMotor1INTLevel == IC_INT_PRIOR_42 | void __ISR(CaptureMotor1INTVector, ipl4)

InputCapture2Routine(void){3 | INTClearFlag(INT_IC2);4 | bufferTemp= CaptureMotor1ReadCapture()& 0xFFFF;5 | if(sampleICx== sampleIC2Start){6 | TimerValueReg= 0; // reset the timer7 | sampleICx= sampleIC2Stop; // go to next state8 | }else9 | if(sampleICx== sampleIC2Stop){10| val1IC2= bufferTemp; TimerValueReg= 0; sampleICx= 11| sampleIC3Start;}12| if(CaptureMotor1ControlReg.ICOV)13| val1IC2= InCapOVFL;14| }15| #endif, și codul pentru ISR a timer-ului:1 | void __ISR(_TIMER_2_VECTOR, ipl1) Timer2Routine(void){2 | INTClearFlag(INT_T2);3 | if((sampleICx== sampleIC2Start) ||(sampleICx== sampleIC2Stop)){4 | sampleICx= sampleIC3Start; val1IC2= TimerOVFLInCap;5 | }else6 | if((sampleICx== sampleIC3Start) ||(sampleICx== sampleIC3Stop)){7 | sampleICx= sampleIC2Start; val1IC3= TimerOVFLInCap;8 | }9 | }

43

Page 44: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

5.3 Modulul de PWMÎn cadrul acestui modul, spre deosebire de celelalte, nu sunt alte funcții decât cea

de set up, nefiind necesare întreruperi, totul fiind controlat de hardware.Codul pentru funcția de set-up este următorul:

1 | MotorsDirectionConfigPins(); 2 | MotorSpeedPWMConfigPins(); 3 | setMotorsDirection(1);4 | PWM_PRReg_FREQ= getPR_For_PWM(PWM_desired_freq, 1);5 | OpenTimerForMotors(MotorConfigs, PWM_PRReg_FREQ);6 | OpenOCMotor1(Motor1Configs, 0,0);//PWM motor 17 | OpenOCMotor2(Motor2Configs, 0,0);//PWM motor 2

Pinii de output ai modului de PWM trebuie marcați ca fiind de ieșire.În funcția de mai sus se setează doar frecvența bazei de timp, factorul de umplere pentru motoare fiind fixat la zero.

5.4 Modulul de ADC

Active buffer Index Valoare

0

0 channel4mas1

1 channel8mas1

2 channel4mas2

3 channel8mas2

4 channel4mas3

5 channel8mas3

6 channel4mas4

7 channel8mas4

1

8 channel4mas1

9 channel8mas1

10 channel4mas2

11 channel8mas2

12 channel4mas3

13 channel8mas3

14 channel4mas4

15 channel8mas4

Tabelul 5.2: Folosirea buffer-elor de la ADC

În figura 5.2 se prezintă modul în care sunt folosite cele 15 buffere pentru eșantionarea alternativă a două canale. Ordinea se salvare a celor două canale eșantionate

44

Page 45: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

este alternativă. La un moment dat se poate lucra cu o singură zonă, fiind disponibile fie registrele 0- 7, fie 8- 15. În întrerupere se citesc cele 4 valori pentru fiecare canal din zona activă, valoarea canalului fiind media lor. Modulul nu se poate folosi în cazul de față la valoarea maximă, deoarece produce blocarea restului perifericelor, chiar dacă are o prioritate mai mică decât restul.

5.5 Modulul de RTCCÎn continuare se prezintă o parte a void setUpRTCC_1secINT(), care realizează

configurarea modulului și codul handler-ului de întrerupere void __ISR(_RTCC_VECTOR, ipl7SRS) RtccIsr(void). 1| RtccInit(); 2| while(RtccGetClkStat()!= RTCC_CLK_ON);3| RtccChimeEnable();4| RtccSetAlarmRptCount(255);5| RtccSetAlarmRpt(RTCC_RPT_SEC);6| RtccAlarmEnable();

În acest cod are loc o inițializare a modului de RTCC, urmată prin while-ul care testează dacă este conectat oscilatorul extern. Următoarele 4 instrucțiuni sunt folosite pentru a seta alarm și repetarea ei nedefinită( funcția de chime).1 | #if RTCCLevel== INT_PRIORITY_LEVEL_72 | void __ISR(_RTCC_VECTOR, ipl7SRS) RtccIsr(void)3 | {4 | INTClearFlag(INT_RTCC);

5 | SetInputCapture1(GetFreqMotor1());6 | SetInputCapture2(GetFreqMotor2());7 | SetVoltageBatt(GetChannel4Batt());8 | SetVoltageSunt(GetChannel8Sunt());

9 | mLedRTCCToggle();10| rtcc_1secINTR= TRUE;11| }12| #endif

Handler-ul de întrerupere al RTCC este cel care controlează schimbul de date de la și spre USB. Acest lucru se realizează prin cele 4 apeluri de macro și marcarea flag-ului rtcc_1secINTR cu TRUE. Variabila booleană se folosește în bucla principală din main pentru încărcarea efectivă a datelor pe magistrală. Pentru a se obține o frecvență mai mare va trebui modificat repetarea alarmei la RTCC_RPT_HALF_SEC, ceea ce va dubla frecvența de trimitere a datelor. Toggle-ul LED-ului are scop de verificare vizuală.

5.6 Programul principalÎn continuare voi prezenta programul principal prin evidențierea zonelor

importante pentru înțelegerea algoritmului. Bucățiile de cod pot să fie diferite față de cele din codul aplicației, deoarece unele linii de cod au fost înlăturate pentru a se putea urmării mai ușor logica aplicației.

45

Page 46: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

5.6.1 Structura comenziilorComenziile sunt definite folosind o enumerare, în locul unor typedef/macro pentru

o grupare vizuală mai eficientă.1 |typedef enum _ACCESSORY_DEMO_COMMANDS2 |{3 | COMMAND_getConfig_ADC = 0x01,4 | COMMAND_getConfig_Fuses_PWM = 0x02,5 | COMMAND_getConfig_InputCapture = 0x03,6 | COMMAND_getValue_InputCapture = 0x04,7 | COMMAND_getValue_Voltage = 0x05,8 | COMMAND_setValue_PWM = 0x06,9 | COMMAND_shutDown = 0x07,10| COMMAND_initialPWMConfig = 0x08, 11| COMMAND_finishedPWMConfig = 0x09,12| COMMAND_getConfig_MotorsID = 0x0A,13| COMMAND_setDirectionMotor = 0x0B,14| COMMAND_APP_CONNECT = 0xFE,15| COMMAND_APP_DISCONNECT = 0xFF16|} ACCESSORY_DEMO_COMMANDS;

, iar lungimiile sunt fixe:1 | #define Command_getValue_Voltage_Size 4

Comandă

Arg 1 Arg 2 Arg 3 Arg 4 Arg 5 Arg 6 Arg 7 Arg 8

1 ADC Size [Vref] {Vref}

2 Freq proc FPLLMUL

FPLLDIV

FPLLODIV

FPBDIV OC size Freq OC OC presc

3 IC presc IC size Event size

4 HFreq IC 1 LFreq IC 1 HFreq IC 2 LFreq IC 2

5 HU șunt LU șunt HU battery LU battery

6 HDuty motor 1

LDuty motor 1

HDuty motor 2

LDuty motor

2

7

8

9

10 ID motor 1 ID motor 2

11 Dir motors

254

255

Tabelul 5.3: Comenziile trimise între tabletă și uC

În tabelul 5.3 se prezintă structura comenziilor. O parte a acestor comenzi sunt de tipul flag, și nu au argumente, contând doar ID lor, cum ar fi 7,8,9. Pentru parametrii care ocupă mai mult de un octet s-a folosit HArg respectiv LArg pentru partea superioară

46

Page 47: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

respectiv inferioară a argumentului. Comenziile au structură și lungime fixă.Pachetele de intrare și de ieșire nu sunt altceva decât un șir de bytes, lucru

evidențiat prin codul care urmează:1| typedef struct __attribute__((packed))2| {3| BYTE command;4| BYTE data[MAX_COMMAND_DATA_Size];5| }ACCESSORY_APP_PACKET outgoing_packet;;

Structura precedentă poate fi folosită ca atare sau se poate considera că este formată dintr-un vector de bytes, așa cum se folosește în codul următor:1 | errorCode = AndroidAppRead(device_handle, (BYTE*)&command_packet, (DWORD)sizeof(command_packet));

2 |switch(command_packet->command)3 | {4 | case COMMAND_setValue_PWM:5 | commandSize= Command_setValue_PWM_Size+ 1;6 | if(initialPWMconfig== TRUE){7 | rtcc_1secINTR= TRUE;8 | SetInputCapture1(GetFreqMotor1());9 | SetInputCapture2(GetFreqMotor2());10| SetVoltageBatt(GetChannel4Batt());11| SetVoltageSunt(GetChannel8Sunt());12| }13| break;14| case COMMAND_initialPWMConfig:15| break;16| case COMMAND_finishedPWMConfig:17| break;18| case COMMAND_setDirectionMotor:19| break;20| case COMMAND_shutDown:21| break;22| case COMMAND_APP_DISCONNECT: 23| break;24| default:

//Error, unknown command25| DEBUG_ERROR("Error: unknown command received");26| break;27| }

În timpul citiri cu AndroidAppRead, pe magistrala USB pot exista mai multe comenzi înlănțuite. Prin verificarea primului octet, care indică lungimea primei comenzi, se determină numărul de bytes rămași pentru procesare și adresa din cadrul vectorului de unde se va continua procesarea.

1| size-= commandSize;2| relativeAddressInCommandPacket+= commandSize;3| if(size!= 0)4| memcpy(command_packet,&read_buffer[relativeAddress],size);

5.6.2 Trimiterea datelor către tabletăÎn cazul în care se trimit mesaje la viteză maximă, fără a folosi întârzierea de o

secundă se produce încălzirea tabletei. Pentru a se limita numărul de mesaje trimise în

47

Page 48: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

bucla principală din main se verifică dacă a trecut o secundă de la ultima transmisie:1| if(rtcc_1secINTR== FALSE)2| continue;

Se verifică dacă sunt și alte operații de scriere în așteptare, iar în caz negativ se va putea trimite mesajul dorit. Pentru a crește eficiența în coada de mesaje pot fi puse mai multe mesaje, fiecare de dimensiune definită.1| if(writeInProgress == FALSE){2| outgoing_packet.command = COMMAND_getValue_InputCapture;3| outgoing_packet.data[0]= ....

4| memcpy(&write_buffer[adresaWrite], (BYTE*)&outgoing_packet, Command_getValue_InputCapture_Size+ 1);5| adresaWrite+= Command_getValue_InputCapture_Size+ 1;6| }

În final are loc și scrierea propriuzisă, precum și marcarea faptului că a avut loc o scriere(writeInProgress ):1| if(writeInProgress== FALSE){2| rtcc_1secINTR= FALSE; 3| writeInProgress= TRUE;

4| errorCode = AndroidAppWrite(device_handle, write_buffer, adresaWrite);5| }

5.6.3 Funcția de trimitere a datelor către AndroidÎn continuare se va prezenta modul în care se trimit datele către tableta Android,

fiind evidențiate și fișierele în care sunt definite funcțiile respective, pentru a se putea urmării nivelurile multiple de redirectări care apar ca urmare a existenței layer-urilor.

usb_host_android.c:: AndroidAppRead(void* handle, BYTE* data, DWORD size) . Se face o parcurgere a numărului de dispozitive Android și fiecare va fi notificat. Parametrul handle reprezintă informația primită la conectara dispozitivului, iar data este un buffer unde va fi depozitată informația. Dacă la acest nivel se face verificarea de device la nivel de Android, la următorul nivel de redirectare se va face verificarea de adresa, RX/TX busy, stare:

usb_host_android_protocol_v1.c::AndroidAppRead_Pv1(void* handle, BYTE* data, DWORD size). Se folosește o redirectare la:

usb_host.c::BYTE USBHostRead( BYTE deviceAddress, BYTE endpoint, BYTE *pData, DWORD size ), unde se va verifica la nivel de tip de endpoint și starea ultimului transfer. Se va face o nouă redirectare la o metodă din același fișier

void _USB_InitRead( USB_ENDPOINT_INFO *pEndpoint, BYTE *pData, WORD size ) care va face încărcarea efectivă a registrelor cu valorile necesare.

5.6.4 Inițializarea comunicației pe USB și ADKSe folosesc funcțiile: USBHostInit(unsigned long flag) și AndroidAppStart

(&myDeviceInfo), pentru realizarea inițializăriilor necesare.În cadrul primei funcții se folosește structura usbDeviceInfo pentru a se vedea dacă există sau trebuie alocat

48

Page 49: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Endpoint-ul 0, singurul care se folosește momentan în aplicație. Are loc și o inițializare a variabilelor folosite pentru menținerea adreselor și starea endpoint-ului curent, precum și inițializarea stivei de evenimente.

În cadrul celei de-a doua funcții se inițializează structuriile: ANDROID_ACCESSORY_INFORMATION, care conține informații legate de producător, model, descriere; ANDROID_DEVICE_DATA care conține informații legate de driver, protocol, stare, adrese; ANDROID_PROTOCOL_V1_DEVICE_DATA se inițializează cu informații legate de adresa device-ului, starea acestuia, numărul endpoint-ului de intrare și de ieșire, precum și starea liniilor RX și TX.

5.6.5 USBTask()= keep the stack running

Cuprinde două apeluri de funcții: USBHostTask() și AndroidTask(). Prima funcție are rolul de a asigura procesarea ultimului eveniment din stivă, și de a notifica aplicația.

Funcția void AndroidTasks( void) verifică dacă dispozitivul conectat suportă modul accesoriu. Se folosește AndroidTasks_Pv1() pentru a itera peste numărul de dispozitive conectate, verificând la fiecare descrierea și dacă poate întra în modul accesoriu. În caz afirmativ se apelează funcția de call back din fișierul principal USB_ApplicașionEventHandler , folosit pentru a seta flag-uri care marchează descoperirea unui nou dispozitiv.

5.6.7 Inițializarea plăcii de dezvoltareFuncția initPIC() are rolul de a inițializa platforma de dezvoltare să funcționeze la

o frecvență de 60MHz. În fișierul HARDWARE_PROFILE_PIC32MX460F512L.h se definesc parametrii de funcționare cum ar fi frecvența de bază a sistemului, frecvența pentru periferice, și o serie de flag-uri pentru a semnala perifericele folosite de aplicație.

5.7 Logica generală a aplicațieiFolosind ca și suport explicațiile din capitolele anterioare în continuare se va

prezenta logica de ansamblu a aplicaţiei. Se va folosi pseudocod pentru exemplificare:1 | inițializare_module();2 | activare_intreruperi();3 | while(1){4 | USBTasks();5 | if(device_attached == FALSE) continue;6 | if(readyToRead == TRUE)AndroidAppRead();7 | AndroidAppIsReadComplete();8 | while(size > 0)procesează_comenzi();9 | readyToRead= True;10| if(connected_to_app == FALSE)continue;11| if(configsSendOK== FALSE)send_configs();12| if(writeInProgress== TRUE )13| AndroidAppIsWriteComplete() ;14| if(rtcc_1secINTR== FALSE)continue;15| if(writeInProgress== FALSE)AndroidAppWrite();16| }

Aplicația este formată din două părți: inițializarea modulelor folosite și bucla 49

Page 50: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

principală care rulează la infinit.

În partea de inițializare se configurează fiecare modul și se activează global întreruperile.

Fiecare iterație a buclei va apela USBTask pentru a menține funcționarea stivei USB. În cazul în care nu este atașat niciun dispozitiv pe magistrală se continuă cu iterația următoare. Spre deosebire de linia 5, în linia 10 se verifică dacă s-a primit mesajul de conectare de la aplicația Android. Și în acest caz se continuă cu iterația următoare în caz negativ.

Mecanismul de citire este prezentat în liniile 6 și 7, iar cel de scriere în liniile 13 și 15. Mecanismul de citire verifică la fiecare pas dacă ultima operație de citire s-a executat cu succes, însă pentru write se foloște un flag, verificarea fiind făcută doar dacă a avut loc o scriere precedentă. În cazul în care s-a citit cel puțin o comandă în linia 8 se va procesa șirul de octeți primit, iar în rândul următor se marchează terminarea procesării, ceea ce permite citirea unei noi valori.

Fiecare dispozitiv conectat pe magistrală va primi informațiile legate de configurația microcontroller-ului: dimensiunea registrelor, frecvențele folosite, procedeu evidențiat în linia 11.

Pentru a nu se produce o încărcare a magistralei cu informații despre turații și tensiuni, se folosește o întârziere de minim o secundă față de ultimul transfer. La frecvențe mari ale transferului dinspre microcontroller spre Android s-a constat o creștere a temperaturii tabletei, și performanțe mai scăzute.

Un mecanism care nu a fost prezentat în pseudocod este cel de schimbare a direcției motoarelor. Se folosește mecanismul din linia 14 pentru a verifica că a trecut cel puțin o secundă între oprirea motoarelor și schimbarea direcției, cu scopul de a proteja puntea H de scurt-circuit. Orice instrucțiune aflată după linia 14 va fi executată o dată la o secundă.

6. Testare și validare50

Page 51: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Verificarea RTCC s-a făcut folosind DMCI, un plug-in pentru NetBeans, folosind ca și bază de timp un timer pe 32 de biți, alimentat direct de la ceasul sistemului la 80MHz. În întreruperea de la RTCC o dată la o secundă se citește timerul apoi acesta se reinițializează. Curbele obțiute sunt relativ line, iar abaterea astfel calculată este de 2.25e-6, ceea ce reprezintă o perioadă de 1.0000655 secunde pentru RTCC.

În figurile 6.1 și 6.2 se prezintă graficele pentru funcționarea extremă: alături de o sursă de căldură sau folosind un ventilator îndreptat spre oscilator.

În figura 6.3 s-a analizat oscilatorul circuitului de timp real, model LF XTAL002995, al firmei IQD, după ce a fost adăugat un condensator de 220pF, in paralel celui exstent, C15 de pe placă. S-a obținut o frecvență apropiată de 32 768Hz.

51

Figura 6.2: Funcționarea cu o sursă de căldură

Figura 6.1: Functionarea cu o sursă răcire

Page 52: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Alături de analiza circuitului de RTCC s-au studiat și diferențele între valoarea afișată pe tabletă și măsurată folosind osciloscopul, pentru divizorul de tensiune(figura 6.4) și pentru șunt(figura 6.5), diferențele fiind nesemnificative.

În figura 6.5 cu galben se prezintă tensiunea pe șunt după filtrarea folosind condensatorul iar cu roșu se prezintă semnalul dacă nu se folosește filtrare. Frecvența vârfurilor de consum este identică cu cea de la acționarea motoarelor cu semnalul dreptunghiular al PWM.

52

Figura 6.3: Analiza folosind osciloscopul

Figura 6.4: Valoarea măsurată pe osciloscop(stânga) și 4* tensiunea măsurată de placă(dreapta); pentru divizorul de tensiune

Page 53: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Ieșirea circuitului DAC a fost analizată folosind osciloscopul, fără a se obține diferențe notabile între valoarea dorită și cea măsurată. De asemenea forma este una liniară, fără fluctuații, potrivită astfel pentru a fi folosită ca și referință.

53

Figura 6.5: Valoarea măsurată pe șunt folosind osciloscopul(stânga) și tableta(dreapta)

Figura 6.6: Ieșirea circuitului de DAC

Page 54: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

7. Manual de instalare și utilizare

7.1. InstalareÎn continuare se vor explica modul în care se realizează montajul cablat asociat

microcontroller-ului și pașii necesari instalării aplicației.

7.1.1 Instalare hardwarePentru a se putea realiza montajul sunt necesare: o placă de tip Cerebot32MX4, 4

rezistențe, 1 condensator, două motoare, suporturile necesare și cabluri pentru conectică.

Placa de tip Cerebot32MX4, poate fi schimbată ușor cu alt tip de placă, de la Digilent care are microcontroller de tip PIC 32MX, fiind necesare doar mici modificări, care pot fi ușor descoperite prin compararea celor două Reference Manual. În continuare se va prezenta montajul.

Schema circuitului de măsurare a fost prezentată în figura 4.1. Ea cuprinde 4 rezistențe de 1 KΩ, legate în serie, și având rol de divizor de tensiune. Condensatorul are rol de netezire a fluctuațiilor de tensiune, și are valoarea de 4700 μF, fiind produs de SAMXON. Șuntul este unul improvizat, cu 4 borne, cîte două pentru plus respectiv minus și are o rezistență de 0.8Ω măsurată cu puntea Wheatstone.

Deoarece acumulatorii actuali sunt de capacitate mică se recomandă alimentarea plăcii prin alt circuit. Poate fi folosit în acest sens cablul USB folosit la programare sau o sursă de la Digilent( care se conectează la 220V) sau 4 baterii de 1.5V. Pentru alimentarea plăcii se vor folosi tensiuni cuprinse între 3.6V- 5V DC, iar consumul de curent este între 250mA și 300mA.

În figura 7.1 se prezintă schema generală de montaj. Nu se insistă exact pe pinii unde se conectează perifericele, fiind evidențiat doar portul. Pentru a afla poziția pinilor se va folosi tabelul 7.2. Firele de alimentare folosesc convenția: roșu la Vcc și negru la GND. În cazul conectării circuitului de măsură la placă se folosesc 3 fire: negru, alb și roșu. Pe această schemă se folosesc alte culori pentru a se deosebi de circuitul de alimentare. Culoarea albastră folosită la conectarea motoarelor și pentru USB are rolul de a arăta că este vorba despre o grupare de fire, respectiv despre o magistrală.

Tensiunea generată de DAC se conectează la ADC ca și referință externă prin două fire: roșu și negru. Oscilatorul cu quartz, modelul LF XTAL002995 al firmei IQD, din poziția X2 este reprezentat în zona centrală folosind o imagine default. Pentru funcționarea corectă are nevoie de lipirea în paralel cu C15 a unui condensator de 220 pF.

În tabelul 7.1 se prezintă poziția jumper-ilor care influențează în mod direct aplicația. Restul jumper-ilor pot fi în orice poziție, și nu vor influența funcționarea normală. Se pot folosi în paralel cablul de programare/depanare conectat la PC și la J11 și o alimentare de la o sursă externă pentru placă.

54

Page 55: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Figura 7.1: Schema generală de montaj

Jumper Poziție Explicații

J10 Ieșirea de la DAC

J12 External power Alimentare de la o sursă externă prin J13, J14 sau J18

J16 VBUSON Alimentare USB

JP5 Conectat Detectare supra-curenți pe USB

JP6 HostSelecție între alimentarea J17 și J15(micro USB, pe verso-ul plăcii)

JPA- JPK 3.3V Alimentare periferice la 3.25V

Restul Poziție default Nu influențează aplicația

Tabelul 7.1: Poziție jumpers

55

Page 56: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

În tabelul 7.2 se prezintă modul de conectare al perifericelor la placă.

Pin PMod(periferic) Pin Cerebot Explicații

DAC GND( Negru) JK 07Referința pentru ADC

DAC Referință( Roșu) JK 08

GND circuit măsură(Negru) JJ 02

Circuitul extern de măsurăVoltaj șunt(Roșu) JJ 09

Voltaj divizor baterii(Alb) JJ 07

Motor 1 HB5 JD 01- JD06 Motoarele au nevoie de sursă externă de alimentareMotor 2 HB5 JD 07- JD12

Tabletă Android J17 Conectare tabletă folosind cablu USB

Tabelul 7.2: Legarea pinilor de la Cerebot la pinii perifericelor.

7.1.2 Instalare softwarePentru a se putea rula aplicația de față este nevoie să fie instalat MPLAB X v1.10

sau o variantă mai nouă; instalarea Microchip Application Library nefiind necesară. Ca și sitem de operare am folosit Windows 7, pe 64 de biți. Librăria de PIC C folosită are versiunea 2.02.

Folosind opțiunea de Package care poate fi găsită printr-un click dreapta pe proiect se va obține o copie portabilă a proiectului. Structura de directoare după dezarhivare diferă de o structură clasică de proiect, deoarece toate dependențele sunt copiate local. Pentru a se programa mucrocontroller-ul se vor executa pașii:

1. Se va dezarhiva codul sursă. Fie C:\Folder Test\Android App calea unde s-a realizat dezarhivarea. În folderul Andoid App se va găsi directorul scr care conține aplicația și toate dependențele.

2. Se va importa codul sursă aflat în C:\Folder Test\Android App\src\Android Accessories\Basic Communication Demo [RMK] – v2\Firmware

3. Folosind click dreapta pe proiect și Properties se va verifica că în partea dreaptă în zona Configuration tipul Device -ului este PIC32MX460F512L(figura 7.2, marcajul #1). Se va verifica ca la Compiler Toolchains să fie selectat un C32(#2). În partea stângă la Categories se verifică că PIC32MX460F512L_PIM este activ(înconjurat cu [ și ])(#3). În caz contrar în partea de jos la Manage configurations(#4) se va putea activa(#5).

4. Se vor salva modificările prin Ok (#6).

5. Se va programa microcontroller-ul folosind opțiunea Make and program device main project.

Un prim indiciu asupra succesului programării îl constituie aprinderea lui LED2 la un interval de 1 secundă.

56

Page 57: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Figura 7.2: Proprietățiile proiectului

În figura 7.3 se prezintă buid path; căile analizate pentru include sunt fie locale, obținute în urma dezarhivării codului și aflate în C:\Folder Test\Android App ; sau sunt fișiere aflate în sursele compilatorului C:\Program Files (x86)\Microchip\mplabc32.

7.2 Manualul utilizatoruluiUtilizatorul va trebui să acționeze întrerupătorul SW1( pentru a permite alimentarea

microcontroller-ului) și să conecteze tableta folosind USB-ul.

57

Figura 7.3: Structura de directoare analizată pentru include

Page 58: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

8. ConcluziiAceastă rubrică cuprinde 3 categorii, și anume: un rezumat, rezultatele

experimentale obținute și posibile dezvoltări/ îmbunătățiri.

8.1 RezumatSistemul de față are principalele atribuții de a monitoriza consumul de curent din

circuit și de acționa motoarele. Interacțiunea cu utilizatorul se face printr-o tabletă, folosind USB și protocolul Android Open Accessory.

Se folosesc două canale analogice pentru măsurarea tensiunii de pe șunt și de pe divizorul de tensiune. Șuntul fiind de valoare cunoscută se va transforma căderea de tensiune în curent. Ca și voltaj de referință se folosește ieșirea circuitului de DAC, care este fixată la 1.5V.

Frecvențele minime ale motoarelor ce pot fi măsurate au valoarea de 30Hz. Se măsoară turațiile efective, înainte de reductorul de 1:19. La turații mai mici decât limita inferioară se constată oprirea motorului deoarece corespunde unui factor de umplere al PWM sub pragul minim de funcționare.

Pentru calcularea consumului total în circuit se folosește un circuit de RTCC pentru a salva o dată la o secundă valoriile măsurate care apoi vor fi trimise pe USB și însumate pe tabletă. Principalele date care sosesc de la tabletă sunt cele referitoare la factorul de umplere pentru PWM.

Pentru a se asigura independența și portabilitatea, înaintea conectării unui dispozitiv pe USB se trimit parametrii microcontroller-ului: dimensiunea registrelor care conțin rezultatele și frecvețele de lucru pentru ceasul sistem și cel al perifericelor precum și factorii de divizare pentru semnalele de ceas folosite de periferice.

8.2 Rezultate obținute

58

Page 59: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

În figura 8.1 se prezintă comportarea circuitului de RTCC în condiții normale, măsurat folosind oscilatorul principal de 80MHz. Tehnica de măsurare folosită a fost descrisă în capitolul 6, și se bazează pe acuratețea cristalui principal de pe placă. Abaterea frecvenței măsurată în acest nod este de 2.25ppm, valoare care se încadrează în limita recomandată de producător de ±20ppm. Cu toate acestea valoriile obtinute pentru intervalul de o secundă sunt în jurul valorii de 1.0000655sec. Frecvența diferită a oscilatorului secundar este confirmată de figura 6.3 unde valoarea măsurată este de 32.89KHz. Funcționarea în prezența unei surse de căldură(figura 6.1) sau de răcire(6. 2) produce efecte vizibile în ceea ce privește frecvența de funcționare, așa cum specifică și producătorul. Aspectul uniform al graficelor, precum și eroarea mai mică de 10e-6, recomandă folosirea RTCC ca și bază de timp pentru măsură.

Diferențele între valoriile de tensiune măsurate pe microcontroller-ul și osciloscop sunt mai mici de ordinul 0,001, lucru vizibil în figurile 6.4, și 6.5. Pot să apară unele diferențe momentane mai mari, în special la valoarea de pe șunt, care așa cum se observă în imaginea 6.5 prezintă mici fluctuații. Pentru calibrare s-a folosit măsurarea unei tensiuni stabile(ieșirea de la DAC) folosind ADC de pe placă; în acest caz erorile au fost sub pragul de 0.001. Nu se recomandă folosirea depanării pentru a citi valoarea măsurată, deoarece fiecare pas de depanare produce o fluctuație semnificativă în consumul de curent. Pentru verificare se poate folosi trimierea valorii pe UART.

Funcția de calibrare a motoarelor obține diferențe între cele două turații ale motoarelor de 6Hz, ceea ce reprezintă o abatere de 3% între motoare. O cauză posibilă o reprezintă diferențele între cele două punți H, care nu reușesc să producă ieșiri identice chiar dacă comenziile sunt identice( au fost conectate același PWM). Pentru compensare, se folosește o buclă închisă de reglaj implementată în software-ul de pe tabletă. Motorul care are turație mai mare va fi încetinit pentru a ajunge la turația celui lent.

Pentru testare s-a folosit un singur microcontroller și o singură tabletă, precum și un singur circuit de măsură. Posibilitatea portării codului pentru placa de dezvoltare a fost testată folosind un alt PC și urmărind pașii din secțiunea 7.1.2.

59

Figura 8.1: Valoare RTCC măsurată în condiții normale

Page 60: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

8.3 Posibile dezvoltări și îmbunătățiri ulterioareO primă dezvoltare ar putea fi introducerea unui RTOS. Acest lucru aduce cu sine

o serie de probleme cum ar fi faptul că stiva de Android/USB trebuie adaptată pentru mediul multi-tasking. Această problemă este tratată în Integrating Microchip Libraries with a Real-Time Operating System, un application note oferit de Microchip. Avantajele evidente sunt: o mai mare modularitate a codului și evidențierea mult mai clară a dependențelor între module prin folosirea cozilor, sau a semafoarelor. În acest sens s-a instalat pe placă FreeRTOS, și s-au rulat unele aplicații de test, fără a instala și librăria de USB.

O altă dezvoltare legată tot de sistemele de operare o constituie instalarea unei versiuni de Linux. Acest lucru face posibilă folosirea unui număr mare de programe scrise în C pentru Linux și destinate inițial pentru PC, să fie folosite și aici. Instalarea unui kernel clasic de Linux pe configurația actuală este aproape imposibilă, în principal datorită memoriei limitate, așa cum se arată pe forumul [28], dar o versiune minimală de Linux, adaptată pentru embedded, ar putea fi instalată.

Folosirea codului scris în asamblare constituie întotdeauna o îmbunătățire, însă pentru aceasta este necesară o analiză amănunțită a codului, pentru a identifica zonele care merită îmbunătățite. Se poate folosi în acest sens Legea lui Amdahl.

Ca și o altă îmbunătățire, o analiză mai amănunțită a codului ar putea duce la o reducere a dimensiunii unor variabile, sau la eliminarea altora. De asemenea câmpurile structurilor pot fi specificate de ce dimensiune să fie, împiedicând astfel să se mai facă alinierea.

O altă îmbunătățire o constituie folosirea zonelor critice. În aplicație, în configurația de față, nu se folosesc zone critice pentru a se accesa variabilele importante pentru aplicație. Singurul mecanism de protecție fiind folosirea nivelelor multiple de priorități pentru întreruperi, cu nivelul cel mai ridicat pentru RTCC. Cel mai simplu mod de implementare a zonelor critice îl constituie dezactivarea generală a întreruperilor la intrarea în ISR și reactivarea lor la ieșirea din handler.

Pentru a se reduce consumul de curent se poate folosi microcontroller-ul în modul de sleep, atunci cînd nu sunt date de procesat. Pentru aceasta, ar trebui diminuată de asemena și frecvența cu care se intră în întreruperile fiecărui modul, să fie cît mai apropiată de 10 Hz, pentru a se realiza 10 măsurători între două transferuri pe magistrala de USB.

Funcțiile a căror durată de execuție este mare, pot fi împărțite între mai multe stări și la fiecare apel să se facă doar un pas din algoritm. Astfel se reduce durata apelului funcției dar crește complexitatea în ceea ce privește înțelegerea codului și mentenanța lui. Pentru a se îmbunății și mai mult timpul general de execuție și main loop-ul poate fi divizat în stări și vor fi apelate anumite funcții doar dacă a fost un eveniment.

Ca și o îmbunătățire a codului, se poate schimba vizibilitatea variabilelor și se pot semnala cele accesibile din mai multe surse cu volatile. De asemnea se pot folosi mult mai intens pointeri. Respectarea unui standard industrial cum ar fi MISRA sau chiar ANSI C ar fi binevenită.

60

Page 61: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Pentru creșterea modularității în anamblu se poate folosi un ecran tactil, care să ne permită realizarea configurațiilor plăcii. Astfel se poate selecta numărul de motoare din sistem, dacă se dorește conectarea la același Output Compare, ce resurse hardware se vor folosi(în cazul în care se poate alege între două module similare), diverse frecvențe de lucru. Acest lucru ar duce la o adaptare mult mai bună la cerințe, și o configurare rapidă pentru un număr mare de aplicații.

61

Page 62: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Bibliografie[1] "Android Serial Port", http://www.progsrp.moonfruit.com/#/android-serial/4548697508.[2] "Android G1 Serial to USB Cable", http://www.instructables.com/id/Android-G1-Serial-Cable/.[3] "Microbridge", http://code.google.com/p/microbridge/.[4] "Amarino", 2009, http://www.amarino-toolkit.net/index.php/docs.html. [5] "Tutorial: Android to Microcontroller via Bluetooth", 2011, http://www.ryandebenham.com/?cat=14. [6] "The Android Debug Bridge (ADB)", 2011, http://www.androidauthority.com/about-android-debug-bridge-adb-21510/. [7] "A closer look at Google’s open accessory development kit", 2011, www.romfont.com/2011/05/11/a-closer-look-at-googles-open-accessory-development-kit/. [8] "Android Open Accessory Development Kit", 2011, http://developer.android.com/guide/topics/usb/adk.html. [9] "Microchip's Accessory Framework for Android(tm)", Microchip, 2011. [10] "A Bright Idea: Android Open Accessories", 2011, http://android-developers.blogspot.com/2011/05/bright-idea-android-open-accessories.html. [11] "Google I/O 2011: Android Open Accessory API and Development Kit (ADK)", 2011, http://www.youtube.com/watch?v=s7szcpXf2rE. [12] "Google I/O 2011: Keynote Day One ", 2011, http://www.youtube.com/watch?feature=player_embedded&v=OxzucwjFEEs#!. [13] "Harman to bring Android integration to cars... finally", 2011, www.autoblog.com/2011/07/15/harman-to-bring-android-integration-to-cars-finally/. [14] Nicklas Hochy, Kevin Zemmery, Bernd Wertherand Roland Y. Siegwart ,"Electric Vehicle Travel Optimization—Customer Satisfaction Despite ResourceConstraints", IEEE 2012 Intelligent Vehicles Symposium, Alcalá de Henares, 2012. [15] Roland Siegwart, Illah R. Nourbakhsh ,"Introduction to Autonomous Mobile Robots", MIT Press, Cambridge, 1st edition, 2004.[16] "Timers", Microchip, 2011. [17] "Output Compare", Microchip, 2011. [18] "Input Capture", Microchip, 2011. [19] "Inter-Integrated Circuit™ (I2C™)", Microchip, 2011. [20] "10-bit Analog-to-Digital Converter (ADC)", Microchip, 2011. [21] "Oscillators Reference Manual", Microchip, 2011. [22] "Real-Time Clock and Calendar (RTCC)", Microchip, 2011. [23] "Interrupts Reference Manual", Microchip, 2011. [24] Zoltan Francisc Baruch ,"Sisteme de I/E", Editura Albastră, Cluj-Napoca, ediția 1, 2000.[25] Baruch Zoltan Francisc ,"INTERFAŢA USB", UTCN, Cluj-Napoca, Lucrare de laborator.[26] "USB OTG and Embedded Host", Microchip, 2008. [27] "USB Embedded Host Stack Programmer's Guide", Microchip, 2008. [28] "PIC32 Linux / eCos Challenge", 2011, http://www.microchip.com/forums/m293237.aspx.

62

Page 63: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Anexa 1./* * File: HardwareProfile - PIC32MX460F512L PIM.h * Description: Used to specify board settings */#ifndef HARDWARE_PROFILE_PIC32MX460F512L_PIM_H#define HARDWARE_PROFILE_PIC32MX460F512L_PIM_H

/** Board definition ***********************************************/ // These defintions will tell the main() function which board is // currently selected. This will allow the application to add // the correct configuration bits as wells use the correct // initialization functions for the board. These defitions are only // required in the stack provided demos. They are not required in // final application design. #define DEMO_BOARD PIC32MX460F512L_PIM #define EXPLORER_16

//#define RUN_AT_48MHZ //#define RUN_AT_24MHZ #define RUN_AT_60MHZ // Various clock values #if defined(RUN_AT_48MHZ) #define GetSystemClock() 48000000UL #define GetPeripheralClock() 48000000UL #define GetInstructionClock() (GetSystemClock() / 2) ??? #elif defined(RUN_AT_24MHZ) #define GetSystemClock() 24000000UL #define GetPeripheralClock() 24000000UL #define GetInstructionClock() (GetSystemClock() / 2) ??? #elif defined(RUN_AT_60MHZ) #define GetSystemClock() 60000000UL #define GetPeripheralClock() 60000000UL // Will be divided down #define GetInstructionClock() (GetSystemClock() / 2) ??? #else #error Choose a speed #endif

#define DEMO_BOARD_NAME_STRING "PIC32MX460F512L PIM" /** Hardware use, the values aren't used in practice ****************/ #define InputCaptureChannel2 #define InputCaptureChannel3 3 #define ADC1 1 #define OutputCompare2 2 #define OutputCompare3 3 #define Timer2ForInputCapture 2 #define Timer3ForOutputCompare 3 #define RTCC1sec 1 #define I2CChannel1ForDAC 1 /** Interrupts level ***********************************************/

63

Page 64: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

#define CaptureMotor1INTLevel IC_INT_PRIOR_4 #define CaptureMotor2INTLevel IC_INT_PRIOR_4 #define TimerForICINTLevel T1_INT_PRIOR_1 #define INTLevelADC ADC_INT_PRI_3 #define RTCCLevel INT_PRIORITY_LEVEL_7 /** I/O pin definitions ********************************************/ #define INPUT_PIN 1 #define OUTPUT_PIN 0

#endif //HARDWARE_PROFILE_PIC32MX460F512L_PIM_H

Anexa 2./* * File: InputCap.h * Description: Define public function; redefine used registers * * Created on March 6, 2012, 9:54 PM */#include "HardwareProfile.h"

#ifndef InputCap_H#define InputCap_H #define sampleIC2Start 1 #define sampleIC2Stop 2 #define sampleIC3Start 3 #define sampleIC3Stop 4 #define TimerOVFLInCap 1 #define InCapOVFL 2 // - Capture Every rise edge // - Enable capture interrupts // - Use Timer 2 source // - Interrupt on every edge of interest #define ICsettings IC_EVERY_RISE_EDGE | IC_INT_1CAPTURE | IC_TIMER2_SRC | IC_FEDGE_RISE | IC_ON /** * Will prepare the Input Capture for channel 2 and 3, using as the time base Timer 2 * We use a prescaler for Timer 2, in order to get small frequencies, around 30HZ * We will use interrupts asociated with the input capture and the timer */ void setUpInputCap(); #ifdef InputCaptureChannel2 #define CaptureMotor1PortEnable mPORTDSetPinsDigitalIn(1<< 9); // IC2 for the first motor #define OpenCaptureMotor1 OpenCapture2 #define SetPriorityICMotor1 SetPriorityIntIC2 #define EnableINTICMotor1 EnableIntIC2 #define CaptureMotor1INTVector _INPUT_CAPTURE_2_VECTOR #define CaptureMotor1INTBit INT_IC2 #define CaptureMotor1ReadCapture mIC2ReadCapture #define CaptureMotor1ControlReg IC2CONbits #endif #if defined(InputCaptureChannel3)

64

Page 65: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

#define CaptureMotor2PortEnable mPORTCSetPinsDigitalIn(1<< 1); // and IC3 for the second motor #define OpenCaptureMotor2 OpenCapture3 #define SetPriorityICMotor2 SetPriorityIntIC3 #define EnableINTICMotor2 EnableIntIC3 #define CaptureMotor2INTVector _INPUT_CAPTURE_3_VECTOR #define CaptureMotor2INTBit INT_IC3 #define CaptureMotor2ReadCapture mIC3ReadCapture #define CaptureMotor2ControlReg IC3CONbits

#endif #if defined(Timer2ForInputCapture) #define OpenTimerForIC OpenTimer2 #define TimerForICConfigs T2_ON | T2_SOURCE_INT| T2_PS_1_32 #define TimerForICSetPriority mT2SetIntPriority #define TimerForICSetSubPriority mT2SetIntSubPriority #define TimerForICINTEnable mT2IntEnable #define TimerValueReg TMR2 #endif#endif

Anexa 3./* * File: InputCap.c * Description: Contains the code to sample two channels */#include <plib.h>#include "InputCap.h"#include "../HardwareProfile.h"

unsigned int bufferTemp;/*@see main.c*/extern unsigned int val1IC2;extern unsigned int val1IC3;extern BYTE nrImpulsuriIC2;extern BYTE nrImpulsuriIC3;extern BYTE nrEvents1, nrEvents2;

BYTE sampleICx= sampleIC2Start;void setUpInputCap(){ CaptureMotor1PortEnable; CaptureMotor2PortEnable;

// Enable Input Capture Module 2 OpenCaptureMotor1(ICsettings); SetPriorityICMotor1(CaptureMotor1INTLevel | IC_INT_SUB_PRIOR_3); // Priority 4 EnableINTICMotor1;

// Enable Input Capture Module 3 OpenCaptureMotor2(ICsettings); SetPriorityICMotor2(CaptureMotor1INTLevel | IC_INT_SUB_PRIOR_2); // Priority 4 EnableINTICMotor2;

65

Page 66: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

// We use timer 2 for measuring the input capture OpenTimerForIC(TimerForICConfigs, 0xFFFF); // we use a prescaler of 32 to get freq over 30Hz TimerForICSetPriority(TimerForICINTLevel); // will have a freq of 3.75Mhz for a Periph clock of 60Mhz and T= 266.7 ns TimerForICSetSubPriority(2); TimerForICINTEnable(TRUE);}/** * We use a state machine to figure out if it is time to read the value or not */#if CaptureMotor1INTLevel == IC_INT_PRIOR_4 void __ISR(CaptureMotor1INTVector, ipl4) InputCapture2Routine(void){ INTClearFlag(INT_IC2); bufferTemp= CaptureMotor1ReadCapture()& 0xFFFF; nrImpulsuriIC2++; // will count no mather in what state we are if(sampleICx== sampleIC2Start){ TimerValueReg= 0; // reset the timer sampleICx= sampleIC2Stop; // go to next state }else if(sampleICx== sampleIC2Stop){ val1IC2= bufferTemp; TimerValueReg= 0; // reset the timer sampleICx= sampleIC3Start; // go to next state } if(CaptureMotor1ControlReg.ICOV) val1IC2= InCapOVFL; }#endif/** * We use a state machine to figure out if it is time to read the value or not */#if CaptureMotor2INTLevel == IC_INT_PRIOR_4 void __ISR(CaptureMotor2INTVector, ipl4) InputCapture3Routine(void){ INTClearFlag(CaptureMotor2INTBit); bufferTemp= CaptureMotor2ReadCapture()& 0xFFFF; nrImpulsuriIC3++; // will count no mather in what state we are if(sampleICx== sampleIC3Start){ TimerValueReg= 0; // reset the timer sampleICx= sampleIC3Stop; // go to next state }else if(sampleICx== sampleIC3Stop){ val1IC3= bufferTemp; TimerValueReg= 0; // reset the timer sampleICx= sampleIC2Start; // go to next state } if(CaptureMotor2ControlReg.ICOV) val1IC3= InCapOVFL; }#endif/**

66

Page 67: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

* if I have overflow this means we don't have input on IC2 or IC3 */#if TimerForICINTLevel == T1_INT_PRIOR_1 void __ISR(_TIMER_2_VECTOR, ipl1) Timer2Routine(void){ INTClearFlag(INT_T2); if((sampleICx== sampleIC2Start) ||(sampleICx== sampleIC2Stop)){ sampleICx= sampleIC3Start; val1IC2= TimerOVFLInCap; }else if((sampleICx== sampleIC3Start) ||(sampleICx== sampleIC3Stop)){ sampleICx= sampleIC2Start; val1IC3= TimerOVFLInCap; } }#endif

Anexa 4./* * File: DAC.h * Author: elcano * Description: Defines the settings used by the DAC; enumerate the

public functions * Created on March 6, 2012, 10:03 PM */

#ifndef DAC_H#define DAC_H

// Clock Constants #define I2C_CLOCK_FREQ 400000 //The I2C on the board support a medium speed (100K or 400K bps),

// DAC Constants #define DAC_I2C_BUS I2C1 #define DAC_ADDRESS 0x60 // 0b1100000 MPC4725 DAC #define dutyCicleMaxDAC 0x0FFF

/** * Writes the DAC register, but don't write the EEPROM * It doesn't need the reead command to verify the RDY bit, because we don't use EEPROM * * @param DACValue A 12 bit value [0- 4095] or [0x0000- 0x0FFF] * @param PowerDownOption In general we use 0x0 for normal use */ void writeDACRegister(unsigned int DACValue, unsigned short PowerDownOption); /** * I recomand to use a read command and verify the RDY bit * See the previous description for the param * @param DACValue * @param PowerDownOption */ void writeDACRegisterAndEEPROM(unsigned int DACValue, unsigned int PowerDownOption);

67

Page 68: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

/** * NEED REWORK, IT DOWSN'T WORK PROPERLY * Read the setting[1 byte], content of the DAC Register[2 byte], and then the content of the EEPROM [2 byte] * @param i2cbyte * @return */ BOOL readDACRegisterANDEEPROM(BYTE i2cbyte[5]); /** * Will set the DAC to the desired value * @param valReg should be a value betwen 0 and 4095. At 4095 is 3.25V the output(the value of the board) */ void setUpDAC(unsigned short valReg);#endif

Anexa 5./* * File: DAC.c * Author: elcano * Descriptor: The code for the DAC * Created on March 6, 2012, 10:03 PM */#include <plib.h>#include "DAC.h"#include "HardwareProfile.h"// ****************************************************************************// ****************************************************************************// Local Support Routines// ****************************************************************************// ****************************************************************************

/******************************************************************************* Function: BOOL StartTransfer( BOOL restart )

Summary: Starts (or restarts) a transfer to/from the EEPROM.

Description: This routine starts (or restarts) a transfer to/from the EEPROM, waiting (in a blocking loop) until the start (or re-start) condition has completed.

68

Page 69: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Precondition: The I2C module must have been initialized.

Parameters: restart - If FALSE, send a "Start" condition - If TRUE, send a "Restart" condition

Returns: TRUE - If successful FALSE - If a collision occured during Start signaling

Example: <code> StartTransfer(FALSE); </code>

Remarks: This is a blocking routine that waits for the bus to be idle and the Start (or Restart) signal to complete. *****************************************************************************/

BOOL StartTransfer( BOOL restart ){ I2C_STATUS status;

// Send the Start (or Restart) signal if(restart) { I2CRepeatStart(DAC_I2C_BUS); } else { // Wait for the bus to be idle, then start the transfer while( !I2CBusIsIdle(DAC_I2C_BUS) );

if(I2CStart(DAC_I2C_BUS) != I2C_SUCCESS) { DBPRINTF("Error: Bus collision during transfer Start\n"); return FALSE; } }

// Wait for the signal to complete do { status = I2CGetStatus(DAC_I2C_BUS);

} while ( !(status & I2C_START) );

return TRUE;}

/************************************************************************

69

Page 70: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

******* Function: BOOL TransmitOneByte( BYTE data )

Summary: This transmits one byte to the EEPROM.

Description: This transmits one byte to the EEPROM, and reports errors for any bus collisions.

Precondition: The transfer must have been previously started.

Parameters: data - Data byte to transmit

Returns: TRUE - Data was sent successfully FALSE - A bus collision occured

Example: <code> TransmitOneByte(0xAA); </code>

Remarks: This is a blocking routine that waits for the transmission to complete. *****************************************************************************/

BOOL TransmitOneByte( BYTE data ){ // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(DAC_I2C_BUS));

// Transmit the byte if(I2CSendByte(DAC_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION) { DBPRINTF("Error: I2C Master Bus Collision\n"); return FALSE; }

// Wait for the transmission to finish while(!I2CTransmissionHasCompleted(DAC_I2C_BUS));

return TRUE;}

/******************************************************************************* Function: void StopTransfer( void )

70

Page 71: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Summary: Stops a transfer to/from the EEPROM.

Description: This routine Stops a transfer to/from the EEPROM, waiting (in a blocking loop) until the Stop condition has completed.

Precondition: The I2C module must have been initialized & a transfer started.

Parameters: None.

Returns: None.

Example: <code> StopTransfer(); </code>

Remarks: This is a blocking routine that waits for the Stop signal to complete. *****************************************************************************/

void StopTransfer( void ){ I2C_STATUS status;

// Send the Stop signal I2CStop(DAC_I2C_BUS);

// Wait for the signal to complete do { status = I2CGetStatus(DAC_I2C_BUS);

} while ( !(status & I2C_STOP) );}

/** * Writes the DAC register, but don't write the EEPROM * It doesn't need the reead command to verify the RDY bit, because we don't use EEPROM * * @param DACValue A 12 bit value [0- 4095] or [0x0000- 0x0FFF] * @param PowerDownOption In general we use 0x0 for normal use */void writeDACRegister(unsigned int DACValue, unsigned short PowerDownOption){ BYTE i2cData[10]; I2C_7_BIT_ADDRESS SlaveAddress; int Index; int DataSz;

71

Page 72: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

BOOL Success = TRUE;

// Initialize the data buffer I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, DAC_ADDRESS, I2C_WRITE); i2cData[0] = SlaveAddress.byte; i2cData[1] = 0x40| (PowerDownOption& ((1<< 1)| (1<< 2))); // C2, C1, C0= 010 WriteDAC Register, and PD1, PD0= 00 for normal mode of power down i2cData[2] = (DACValue& 0x0FF0)>> 4; // DAC output high byte i2cData[3] = (DACValue& 0x000F)<< 4; // DAC output low byte (12 bits in total) DataSz = 4;

// Start the transfer to write data to the EEPROM if( !StartTransfer(FALSE) ) { while(1); }

// Transmit all data Index = 0; while( Success && (Index < DataSz) ) { // Transmit a byte if (TransmitOneByte(i2cData[Index])) { // Advance to the next byte Index++;

// Verify that the byte was acknowledged if(!I2CByteWasAcknowledged(DAC_I2C_BUS)) { DBPRINTF("Error: Sent byte was not acknowledged\n"); Success = FALSE; } } else { Success = FALSE; } }

// End the transfer (hang here if an error occured) StopTransfer(); if(!Success) { while(1); }}/** * I recomand to use a read command and verify the RDY bit * See the previous description for the param * @param DACValue * @param PowerDownOption */void writeDACRegisterAndEEPROM(unsigned int DACValue, unsigned int PowerDownOption){

72

Page 73: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

BYTE i2cData[10]; I2C_7_BIT_ADDRESS SlaveAddress; int Index; int DataSz; BOOL Success = TRUE;

// Initialize the data buffer I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, DAC_ADDRESS, I2C_WRITE); i2cData[0] = SlaveAddress.byte; i2cData[1] = 0x60| (PowerDownOption& ((1<< 1)| (1<< 2))); // C2, C1, C0= 011 WriteDAC Register and EEPROM; and PD1, PD0= 00 for normal mode of power down i2cData[2] = (DACValue& 0x0FF0)>> 4; // DAC output high byte i2cData[3] = (DACValue& 0x000F)<< 4; // DAC output low byte (12 bits in total) i2cData[4] = 0x60| (PowerDownOption& ((1<< 1)| (1<< 2))); // C2, C1, C0= 011 WriteDAC Register and EEPROM; and PD1, PD0= 00 for normal mode of power down i2cData[5] = (DACValue& 0x0FF0)>> 4; // DAC output high byte i2cData[6] = (DACValue& 0x000F)<< 4; // DAC output low byte (12 bits in total) DataSz = 7;

// Start the transfer to write data to the EEPROM if( !StartTransfer(FALSE) ) { while(1); }

// Transmit all data Index = 0; while( Success && (Index < DataSz) ) { // Transmit a byte if (TransmitOneByte(i2cData[Index])) { // Advance to the next byte Index++;

// Verify that the byte was acknowledged if(!I2CByteWasAcknowledged(DAC_I2C_BUS)) { DBPRINTF("Error: Sent byte was not acknowledged\n"); Success = FALSE; } } else { Success = FALSE; } }

// End the transfer (hang here if an error occured) StopTransfer(); if(!Success) { while(1);

73

Page 74: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

}}

BOOL readDACRegisterANDEEPROM(BYTE i2cbyte[5]){ BYTE i2cData[10]; I2C_7_BIT_ADDRESS SlaveAddress; int Index; int DataSz; BOOL Success = TRUE;

// Initialize the data buffer I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, DAC_ADDRESS, I2C_READ); i2cData[0] = SlaveAddress.byte; DataSz = 1;

// Start the transfer to read the EEPROM. if( !StartTransfer(FALSE) ) { while(1); }

// Address the EEPROM. Index = 0; while( Success & (Index < DataSz) ) { // Transmit a byte if (TransmitOneByte(i2cData[Index])) { // Advance to the next byte Index++; } else { Success = FALSE; }

// Verify that the byte was acknowledged if(!I2CByteWasAcknowledged(DAC_I2C_BUS)) { DBPRINTF("Error: Sent byte was not acknowledged\n"); Success = FALSE; } }

// Read the DAC register Index = 0; while( Success & (Index < 5) ) { if(I2CReceiverEnable(DAC_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW) { DBPRINTF("Error: I2C Receive Overflow\n"); Success = FALSE; } else { while(!I2CReceivedDataIsAvailable(DAC_I2C_BUS));

74

Page 75: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

i2cbyte[Index] = I2CGetByte(DAC_I2C_BUS); I2CAcknowledgeByte(DAC_I2C_BUS, TRUE); Index++; }

}

// End the transfer (stop here if an error occured) StopTransfer(); if(!Success) { while(1); }

if((i2cbyte[0]& (0x80)== 1)) return TRUE; else return FALSE;}

void setUpDAC(unsigned short valReg){ UINT32 actualClock;

// Initialize debug messages (when supported) DBINIT(); #if defined(I2CChannel1ForDAC) // Set the I2C baudrate actualClock = I2CSetFrequency(DAC_I2C_BUS, GetPeripheralClock(), I2C_CLOCK_FREQ); if ( abs(actualClock-I2C_CLOCK_FREQ) > I2C_CLOCK_FREQ/10 ) { DBPRINTF("Error: I2C1 clock frequency (%u) error exceeds 10%%.\n", (unsigned)actualClock); }

// Enable the I2C bus I2CEnable(DAC_I2C_BUS, TRUE); ///////////////////////////////////////////////////////////////////// //////////////// Testarea functiilor /////////////////////////////// ///////////////////////////////////////////////////////////////////// writeDACRegisterAndEEPROM(valReg, 0); //1.5V I2CEnable(DAC_I2C_BUS, FALSE); // and now we will disable it #endif }

Anexa 6./* * File: ADCsetUp.h * Author: elcano * Description: Defines the parameters used by the ADC; redefines the

used registers; enumerate the public functions

75

Page 76: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

* Created on March 6, 2012, 8:46 PM */#include "HardwareProfile.h"

#ifndef ADCsetUp_H#define ADCsetUp_H // define setup parameters for OpenADC10 // Turn module on | in idle mode | ouput in integer | trigger mode auto | enable autosample #define PARAM1 ADC_MODULE_ON | ADC_IDLE_CONTINUE| ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON // ADC ref external | disable offset test | enable scan mode | perform 8 samples whith average | use dual buffers | do not use alternate mode #define PARAM2 ADC_VREF_EXT_EXT | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_8 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_OFF // use ADC PB clock | set sample time | maxim= 127 (ADCS+ 1)*2 #define PARAM3 ADC_CONV_CLK_PB| ADC_SAMPLE_TIME_12| ADC_CONV_CLK_32Tcy // Scan #1 | Scan #2 #define PARAM4 ENABLE_AN4_ANA| ENABLE_AN8_ANA // Skip all but Analog 4| Analog 8 #define PARAM5 SKIP_SCAN_AN0| SKIP_SCAN_AN1| SKIP_SCAN_AN2| SKIP_SCAN_AN3| \ SKIP_SCAN_AN5| SKIP_SCAN_AN6| SKIP_SCAN_AN7| \ SKIP_SCAN_AN9| SKIP_SCAN_AN10| SKIP_SCAN_AN11| SKIP_SCAN_AN12| SKIP_SCAN_AN13| SKIP_SCAN_AN14| SKIP_SCAN_AN15

/************************************ Methods signature ******************************************************/ /** * Will prepare the ADC to work with interrupts * Will use double buffers and will make 4 samples for each channel, and will save the average * Will use the internal counter for sampling * Auto convert and auto sampling: in this mode will sample and convert for the desired time and then will restart the process */ void setUpADC();

#if defined(ADC1) #define CloseADC CloseADC10 #define SetChannelADC SetChanADC10 #define OpenConfigADC OpenADC10 #define ConfigureINTADC ConfigIntADC10 #define INTConfigADC ADC_INT_ON| INTLevelADC| ADC_INT_SUB_PRI_2 #define EnableADC EnableADC10 #define ADCVecor _ADC_VECTOR #define ADCClearINTFlag mAD1ClearIntFlag #define ReadADCActiveBuffer ReadActiveBufferADC10 #define ReadADCStack ReadADC10 #endif#endif

76

Page 77: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Anexa 7./* * File: ADCsetUp.c * Description: The code for the ADC*/#include "ADCsetUp.h"#include "HardwareProfile - PIC32MX460F512L PIM.h"#include <plib.h>/** * The method used to configure the ADC *//*@see main.c for declaration*/extern volatile unsigned int channel4, channel8;unsigned int channel4mas1, channel4mas2, channel4mas3, channel4mas4;unsigned int channel8mas1, channel8mas2, channel8mas3, channel8mas4;void setUpADC(){ CloseADC();{ // ensure the ADC is off before setting the configuration // we use only MUX A, and AN1 as external ground SetChannelADC( ADC_CH0_NEG_SAMPLEA_AN1 ); OpenConfigADC( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using parameter define above ConfigureINTADC(INTConfigADC); }EnableADC(); // Enable the ADC}/** * The interrupt handler for ADC, we use a level 3 for interrupt */#if INTLevelADC == ADC_INT_PRI_3 void __ISR(ADCVecor, ipl3) ADCHandler(void){ ADCClearINTFlag(); unsigned int offset = 8 * ((~ReadADCActiveBuffer() & 0x01)); // determine which buffer is idle and create an offset // GND Prima sonda Scan #1 Scan #2 Scan #3 Scan #4 //#define PARAM4 ENABLE_AN1_ANA | ENABLE_AN3_ANA| ENABLE_AN8_ANA| ENABLE_AN9_ANA| ENABLE_AN14_ANA| ENABLE_AN15_ANA channel4mas1= ReadADCStack(offset); channel8mas1= ReadADCStack(offset+ 1); channel4mas2= ReadADCStack(offset+ 2); channel8mas2= ReadADCStack(offset+ 3); channel4mas3= ReadADCStack(offset+ 4); channel8mas3= ReadADCStack(offset+ 5); channel4mas4= ReadADCStack(offset+ 6); channel8mas4= ReadADCStack(offset+ 7);

channel4= (channel4mas1+ channel4mas2+ channel4mas3+ channel4mas4)>> 2; channel8= (channel8mas1+ channel8mas2+ channel8mas3+ channel8mas4)>> 2; }#endif

Anexa 8./* * File: PWMMotors.h

77

Page 78: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

* Author: elcano * Description: Enumerate the public function; redefines the used

registers * Created on March 6, 2012, 9:13 PM */#include "HardwareProfile.h"

#ifndef PWMMotors_H#define PWMMotors_H #define PWM_desired_freq 5000 // 5KHzs /** * It uses Timer 3 as time base and Output compare 2& 3 as PWM. * Here we don't use interrupts, everything is done in hardware */ void setUpPWM(); /** * A small function used to calculate the value witch will be save in a register, based on the values of desired frequency, the prescaler, and the peripheral clock * @param desiredFreq * @param prescaler * @return */ unsigned int getPR_For_PWM(unsigned int desiredFreq, unsigned int prescaler); /** * Used to set the direction of the motors * Will set the direction in opossite, because the motors are monted back to back * @param direction 0 or 1 * @pre before the enable signal should be stopped(the PWM output) */ void setMotorsDirection(BYTE direction); #define SetDutyMotor1 SetDCOC2PWM #define SetDutyMotor2 SetDCOC3PWM #if defined(OutputCompare3) #if defined(OutputCompare3) #define Motor1DirectionPin 6 #define Motor2DirectionPin 7 #define Motor1SpeedPWMPin 1 #define Motor2SpeedPWMPin 2 #define MotorsDirectionPort LATD #define mPortMotorsDirectionSetDigitalOut(x) mPORTDSetPinsDigitalOut(x) // here is the same port for direction and for speed(PWM) #define mPortMotorsSpeedPWMSetDirectionOut(x) mPORTDSetPinsDigitalOut(x)

#define MotorsDirectionConfigPins() mPortMotorsDirectionSetDigitalOut((1<< Motor1DirectionPin)|(1<< Motor2DirectionPin)) // direction for motors #define MotorSpeedPWMConfigPins() mPortMotorsSpeedPWMSetDirectionOut((1<< Motor1SpeedPWMPin)| (1<< Motor2SpeedPWMPin)) // speed of the motors //_RD1| _RD2 (PWM output)

#define OpenOCMotor1 OpenOC2 #define Motor1Configs OC_ON | OC_TIMER_MODE16 |

78

Page 79: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE #define OpenOCMotor2 OpenOC3 #define Motor2Configs OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE #endif #endif #if defined(Timer3ForOutputCompare) #define OpenTimerForMotors OpenTimer3 #define MotorConfigs T3_ON | T3_SOURCE_INT| T3_PS_1_1 #endif#endif

Anexa 9./* * File: PWMMotors.c * Description: The code for the PWM, in this case only the setUp function*/#include <plib.h>#include "PWMMotors.h"#include "HardwareProfile.h"unsigned int PWM_PRReg_FREQ, duty;/* * First we will set up the pins then the timer and the output compare */void setUpPWM(){ MotorsDirectionConfigPins(); // direction for motors MotorSpeedPWMConfigPins(); // speed of the motors //_RD1| _RD2 (PWM output) setMotorsDirection(1);

PWM_PRReg_FREQ= getPR_For_PWM(PWM_desired_freq, 1); OpenTimerForMotors(MotorConfigs, PWM_PRReg_FREQ); // 16bit Sysnc mode, pentru o frecventa de OpenOCMotor1(Motor1Configs, 0,0);//PWM motor 1 OpenOCMotor2(Motor2Configs, 0,0);//PWM motor 2}unsigned int getPR_For_PWM(unsigned int desiredFreq, unsigned int prescaler){ return GetPeripheralClock()/(prescaler* desiredFreq);};inline __attribute__((always_inline)) void setMotorsDirection(BYTE direction){ MotorsDirectionPort&= 0xFFFF^ ((1<< Motor1DirectionPin)|(1<< Motor2DirectionPin)); MotorsDirectionPort|= ((direction& 1)<< Motor1DirectionPin)| ((1<< Motor2DirectionPin)^((direction& 1)<< Motor2DirectionPin));}

Anexa 10./* * File: rtcc_1secINTR.h * Author: elcano * Description: Enumerate the public function; because it is only a

79

Page 80: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

RTCC, we don't redefine the registers, only some macros. * Created on March 26, 2012, 7:42 PM */#include "HardwareProfile.h"

#ifndef rtcc_1secINTR_H#define rtcc_1secINTR_H

/** * Will set the internal RTCC to a frequency of 1Hz interrupt generation * We don't use date and time because here it is useless * We use internal interrupt */ void setUpRTCC_1secINT();

#ifdef RTCC1sec #define LEDRTCCTest BIT_11 #define mSetLedRTCCOutDir() {mPORTBSetPinsDigitalOut(LEDRTCCTest);} #define mLedRTCCOn() {mPORTBSetBits(LEDRTCCTest);} #define mLedRTCCOff() {mPORTBClearBits(LEDRTCCTest);} #define mLedRTCCToggle() {mPORTBToggleBits(LEDRTCCTest);}

#define RTCC_IntrruptDisable() {RtccAlarmDisable();} // {INTEnable(INT_RTCC, INT_DISABLED);} #define RTCC_InterruptEnable() {RtccAlarmEnable();} // {INTEnable(INT_RTCC, INT_ENABLED);} // it is call by default in SetUpRtcc_1secINTR #endif#endif

Anexa 11./* * File: rtcc_1secINTR.h * Description: The code for the RTCC, for test it is used an onboard LED*/

#include <plib.h>#include "rtcc_1secINTR.h"#include "GenericTypeDefs.h"#include "HardwareProfile.h"#include "mainDef.h"#include "InputCap.h"

extern BOOL rtcc_1secINTR;void setUpRTCC_1secINT(){ mSetLedRTCCOutDir(); // only to see on a PIN the frequency mLedRTCCOff();

//RtccSetCalibration(-12); // if we need calibration, could be set when the RTCC is turned off RtccInit(); // init the RTCC while(RtccGetClkStat()!= RTCC_CLK_ON); // wait for the SOSC to

80

Page 81: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

be actually running and RTCC to have its clock source // could wait here at most 32ms

// set time and date (not necesary if we use only to generate 1 second interrupt) // RtccOpen(0x17040000, 0x08100604, 0);// time is MSb: hour, min, sec, rsvd. date is MSb: year, mon, mday, wday. // please note that the rsvd field has to be 0 in the time field!

RtccChimeEnable(); // rollover of the alarm when it is decremented to 0, it jumps to 0xFF RtccSetAlarmRptCount(255); // if we use "chime" we could use here any number and stilwe wil get uninterrupted repeats RtccSetAlarmRpt(RTCC_RPT_SEC); // one alarm every second // set the alarm (not necesary if we use only to generate 1 second interrupt) // RtccSetAlarmTimeDate(0x17045000, 0x08100604); RtccAlarmEnable(); // enable the alarm

INTSetVectorPriority(INT_RTCC_VECTOR, RTCCLevel);// set the RTCC priority in the INT controller

INTSetVectorSubPriority(INT_RTCC_VECTOR, INT_SUB_PRIORITY_LEVEL_1); // set the RTCC sub-priority in the INT controller INTEnable(INT_RTCC, INT_ENABLED); // enable the RTCC event interrupts in the INT controller.

mLedRTCCOn();}/** * Interrupt handler with Second register set */#if RTCCLevel== INT_PRIORITY_LEVEL_7 void __ISR(_RTCC_VECTOR, ipl7SRS) RtccIsr(void) { // once we get in the RTCC ISR we have to clear the RTCC int flag INTClearFlag(INT_RTCC); // will copy the values from interrupt(like IC, ADC) to the variables whitch will be send over USB // we don't verify if the values changes, we only asure that we have a 1 second freq SetInputCapture1(GetFreqMotor1()); SetInputCapture2(GetFreqMotor2()); SetVoltageBatt(GetChannel4Batt()); SetVoltageSunt(GetChannel8Sunt()); SetNrEventsMotor1(GetNrImpulsuri1()); SetNrEventsMotor2(GetNrImpulsuri2());

mLedRTCCToggle(); rtcc_1secINTR= TRUE; }#endif

81

Page 82: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Anexa 12./* * File: mainDef.h * Author: elcano * Description: Enumerate the variables used by several modules; defines some macros used by several source files; defines the command size * Created on March 11, 2012, 10:23 PM */

#ifndef mainDef_H#define mainDef_H

#include "ADCsetUp.h"#include "InputCap.h"#include "PWMMotors.h"#include "DAC.h"#include "rtcc_1secINTR.h"#include "InputCap.h"

// will be declared in the main fileextern volatile unsigned int val1IC2;extern volatile unsigned int val1IC3;extern volatile BYTE nrImpulsuriIC2;extern volatile BYTE nrImpulsuriIC3;extern volatile BYTE nrEvents1, nrEvents2;extern volatile unsigned int inputCapture1;extern volatile unsigned int inputCapture2;extern volatile unsigned int voltageSunt;extern volatile unsigned int voltageBatt;extern volatile unsigned int channel4;extern volatile unsigned int channel8; //#define DEBUG_MODE 1

#define Command_getConfig_ADC_Size 3 // whitout the command ID(name), only the data #define Command_getConfig_Fuses_PWM_Size 8 #define Command_getConfig_InputCapture_Size 3 #define Command_getValue_Voltage_Size 4 #define Command_getValue_InputCapture_Size 6 #define Command_setValue_PWM_Size 4 #define Command_shutDown_Size 0 #define COMMAND_initialPWMConfig_Size 0 #define COMMAND_finishedPWMConfig_Size 0 #define Command_App_Disconnect_Size 0 #define Command_App_Connect_Size 0 #define COMMAND_getConfig_MotorsID_Size 2 #define COMMAND_setDirectionMotor_Size 1 #define MAX_COMMAND_DATA_Size 8 // whitout the command ID only the data

#define DAC_1dot5V 1890 // the value witch should be put in DAC register to have Vout= 1.5V at Vin= 3.25V typedef enum _MotorChangeDirectionStates{ IDLE= 1, //IDLE= Changed NeedToChange= 2, ChangeNow= 3,

82

Page 83: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

}MotorChangeDirectionStates;

// some getters for values calculated in interrupts #define GetFreqMotor1() val1IC2 #define GetFreqMotor2() val1IC3 #define GetChannel8Sunt() channel8 #define GetChannel4Batt() channel4 #define GetNrImpulsuri1() nrImpulsuriIC2 #define GetNrImpulsuri2() nrImpulsuriIC3

// some setters, for variables whitch will be send over USB #define SetInputCapture1(value) {inputCapture1= value;} #define SetInputCapture2(value) {inputCapture2= value;} #define SetVoltageSunt(value) {voltageSunt= value;} #define SetVoltageBatt(value) {voltageBatt= value;} #define SetNrEventsMotor1(value){nrEvents1= value; value= 0;} // read and after we make a reset #define SetNrEventsMotor2(value){nrEvents2= value; value= 0;} // read and after we make a reset

// some getters, used to send values on the USB #define GetInputCapture1() inputCapture1 #define GetInputCapture2() inputCapture2 #define GetVoltageSunt() voltageSunt #define GetVoltageBatt() voltageBatt #define GetNrEventsMotor1() nrEvents1 #define GetNrEventsMotor2() nrEvents2

/** * Will send the configuration to Android, using the commands of the type: COMMAND_getConfig_xxxx * Precondition: The USB must be set up before * Postcondition: None, it have no side efects */ void sendConfigToAndroid();#endif

Anexa 13./*******************************************************************************

USB Android Accessory basic demo with accessory in host mode

The code for the application;

*******************************************************************************/

// Include files#include <stdio.h>#include "USB/usb.h"#include "USB/usb_host_android.h"#include "Compiler.h"#include "HardwareProfile.h"

83

Page 84: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

#include "mainDef.h"

// If a maximum current rating hasn't been defined, then define 500mA by default#ifndef MAX_ALLOWED_CURRENT #define MAX_ALLOWED_CURRENT (500) // Maximum power we can supply in mA#endif

// Define a debug error printing#define DEBUG_ERROR(a) Nop(); Nop(); Nop();

// Configuration bits for the device. Please refer to the device datasheet for each device// to determine the correct configuration bit settings#ifdef __C30__ #if defined(__PIC24FJ256GB110__) _CONFIG2(FNOSC_PRIPLL & POSCMOD_HS & PLL_96MHZ_ON & PLLDIV_DIV2) // Primary HS OSC with PLL, USBPLL /2 _CONFIG1(JTAGEN_OFF & FWDTEN_OFF & ICS_PGx2) // JTAG off, watchdog timer off #elif defined(__PIC24FJ64GB004__) _CONFIG1(WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & ICS_PGx1 & GWRP_OFF & GCP_OFF & JTAGEN_OFF) _CONFIG2(POSCMOD_HS & I2C1SEL_PRI & IOL1WAY_OFF & OSCIOFNC_ON & FCKSM_CSDCMD & FNOSC_PRIPLL & PLL96MHZ_ON & PLLDIV_DIV2 & IESO_ON) _CONFIG3(WPFP_WPFP0 & SOSCSEL_SOSC & WUTSEL_LEG & WPDIS_WPDIS & WPCFG_WPCFGDIS & WPEND_WPENDMEM) _CONFIG4(DSWDTPS_DSWDTPS3 & DSWDTOSC_LPRC & RTCOSC_SOSC & DSBOREN_OFF & DSWDTEN_OFF) #elif defined(__PIC24FJ256GB106__) _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2) _CONFIG2( 0xF7FF & IESO_OFF & FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_HS & FNOSC_PRIPLL & PLLDIV_DIV3 & IOL1WAY_ON) #elif defined(__PIC24FJ256DA210__) || defined(__PIC24FJ256GB210__) _CONFIG1(FWDTEN_OFF & ICS_PGx2 & GWRP_OFF & GCP_OFF & JTAGEN_OFF) _CONFIG2(POSCMOD_HS & IOL1WAY_ON & OSCIOFNC_ON & FCKSM_CSDCMD & FNOSC_PRIPLL & PLL96MHZ_ON & PLLDIV_DIV2 & IESO_OFF) #elif defined(IOIO) _CONFIG1(FWDTEN_OFF & ICS_PGx2 & GWRP_OFF & GCP_OFF & JTAGEN_OFF) _CONFIG2(POSCMOD_NONE & IOL1WAY_ON & OSCIOFNC_ON & FCKSM_CSDCMD & FNOSC_FRCPLL & PLL96MHZ_ON & PLLDIV_NODIV & IESO_OFF) #elif defined(__dsPIC33EP512MU810__) || defined(PIC24EP512GU810_PIM) _FOSCSEL(FNOSC_FRC); _FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); _FWDT(FWDTEN_OFF); #endif#elif defined( __PIC32MX__ ) #pragma config UPLLEN = ON // USB PLL Enabled #pragma config FPLLMUL = MUL_15 // PLL Multiplier #pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider #pragma config FPLLIDIV = DIV_2 // PLL Input Divider #pragma config FPLLODIV = DIV_1 // PLL Output Divider #pragma config FPBDIV = DIV_1 // Peripheral Clock divisor

84

Page 85: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

#pragma config FWDTEN = OFF // Watchdog Timer #pragma config WDTPS = PS1 // Watchdog Timer Postscale //#pragma config FCKSM = CSDCMD // Clock Switching & Fail Safe Clock Monitor #pragma config OSCIOFNC = OFF // CLKO Enable #pragma config POSCMOD = EC /** ANDROID: WE use Discera "clock"*/ #pragma config IESO = OFF // Internal/External Switch-over #pragma config FSOSCEN = ON /** ANDROID: Secondary Oscillator Enable for RTCC */ #pragma config FNOSC = PRIPLL // Oscillator Selection #pragma config CP = OFF // Code Protect #pragma config BWP = OFF // Boot Flash Write Protect #pragma config PWP = OFF // Program Flash Write Protect #pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select #pragma config DEBUG = ON // Background Debugger Enable

#else #error Cannot define configuration bits.#endif

// C30 and C32 Exception Handlers// If your code gets here, you either tried to read or write// a NULL pointer, or your application overflowed the stack// by having too many local variables or parameters declared.#if defined(__C30__)

void _ISR __attribute__((__no_auto_psv__)) _AddressError(void){

DEBUG_ERROR("Address error"); while(1){}

}void _ISR __attribute__((__no_auto_psv__)) _StackError(void){ DEBUG_ERROR("Stack error");

while(1){}}

#elif defined(__C32__)void _general_exception_handler(unsigned cause, unsigned status){

unsigned long address = _CP0_GET_EPC();

DEBUG_ERROR("exception"); while(1){}

}#endif

//Definitions of the various application commnands that can be senttypedef enum _ACCESSORY_DEMO_COMMANDS{ COMMAND_getConfig_ADC = 0x01, COMMAND_getConfig_Fuses_PWM = 0x02, COMMAND_getConfig_InputCapture = 0x03,

85

Page 86: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

COMMAND_getValue_InputCapture = 0x04, COMMAND_getValue_Voltage = 0x05, COMMAND_setValue_PWM = 0x06, COMMAND_shutDown = 0x07, COMMAND_initialPWMConfig = 0x08, // used to calculate the lower limit for PWM at the desired freq COMMAND_finishedPWMConfig = 0x09, COMMAND_getConfig_MotorsID = 0x0A, COMMAND_setDirectionMotor = 0x0B, COMMAND_APP_CONNECT = 0xFE, COMMAND_APP_DISCONNECT = 0xFF} ACCESSORY_DEMO_COMMANDS;//Creation of the data packet that is going to be sent. In this example// there is just a command code and a one byte data.typedef struct __attribute__((packed)){ BYTE command; BYTE data[MAX_COMMAND_DATA_Size];}ACCESSORY_APP_PACKET;

//Local prototypes#if defined(__C32__)static void InitPIC32(void);#endif

//local variablesstatic BYTE read_buffer[64];static BYTE write_buffer[64];static BYTE adresaWrite= 0; // pointer to the next location where will be put the commandstatic ACCESSORY_APP_PACKET outgoing_packet;static void* device_handle = NULL;static BOOL device_attached = FALSE;

static char manufacturer[] = "Microchip Technology Inc.";static char model[] = "Basic Accessory Demo";static char description[] = DEMO_BOARD_NAME_STRING;static char version[] = "2.0";static char uri[] = "http://www.microchip.com/android";static char serial[] = "N/A";volatile unsigned int channel4, channel8;volatile unsigned int val1IC2, val1IC3;volatile unsigned int inputCapture1= 0xFFFF, inputCapture2= 0xFFFF;volatile unsigned int voltageSunt= 0xFF, voltageBatt= 0xFF;volatile BYTE nrImpulsuriIC2= 0;volatile BYTE nrImpulsuriIC3= 0;volatile BYTE nrEvents1=0, nrEvents2= 0;BOOL rtcc_1secINTR= FALSE;BOOL configsSendOK= FALSE; // if we could send the configs setting, will be reset when the device is disconnectedBOOL initialPWMconfig= FALSE; // if it is true will ignore the 1 second rate transmit, and will transmit when it have the dataMotorChangeDirectionStates needToChangeMotorDirection= IDLE;BYTE desiredDirectionForMotors;ANDROID_ACCESSORY_INFORMATION myDeviceInfo ={ manufacturer,

86

Page 87: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

sizeof(manufacturer), model, sizeof(model), description, sizeof(description), version, sizeof(version), uri, sizeof(uri), serial, sizeof(serial)};

/**************************************************************************** Function: int main(void)

Summary: main function

Description: main function

Precondition: None

Parameters: None

Return Values: int - exit code for main function

Remarks: None ***************************************************************************/int main(void){ DWORD size = 0; BYTE commandSize = 0x00; // because our commands have different sizes BOOL readyToRead = TRUE; BOOL writeInProgress = FALSE; BYTE errorCode; BYTE relativeAddressInCommandPacket= 0; ACCESSORY_APP_PACKET* command_packet = NULL;

BOOL connected_to_app = FALSE; BOOL need_to_disconnect_from_app = FALSE;

#if defined(__PIC32MX__) InitPIC32(); #endif

87

Page 88: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

#if defined(__dsPIC33EP512MU810__) || defined (__PIC24EP512GU810__)

// Configure the device PLL to obtain 60 MIPS operation. The crystal // frequency is 8MHz. Divide 8MHz by 2, multiply by 60 and divide by // 2. This results in Fosc of 120MHz. The CPU clock frequency is // Fcy = Fosc/2 = 60MHz. Wait for the Primary PLL to lock and then // configure the auxilliary PLL to provide 48MHz needed for USB // Operation.

PLLFBD = 38; /* M = 60 */CLKDIVbits.PLLPOST = 0; /* N1 = 2 */CLKDIVbits.PLLPRE = 0; /* N2 = 2 */OSCTUN = 0;

/* Initiate Clock Switch to Primary * Oscillator with PLL (NOSC= 0x3)*/

__builtin_write_OSCCONH(0x03);__builtin_write_OSCCONL(0x01);while (OSCCONbits.COSC != 0x3);

// Configuring the auxiliary PLL, since the primary // oscillator provides the source clock to the auxiliary // PLL, the auxiliary oscillator is disabled. Note that // the AUX PLL is enabled. The input 8MHz clock is divided // by 2, multiplied by 24 and then divided by 2. Wait till // the AUX PLL locks.

ACLKCON3 = 0x24C1; ACLKDIV3 = 0x7; ACLKCON3bits.ENAPLL = 1; while(ACLKCON3bits.APLLCK != 1);

TRISBbits.TRISB5 = 0; LATBbits.LATB5 = 1;

#endif // initialization setUpInputCap(); //setUpDAC(DAC_1dot5V); // should be call only once because it writes the value in EEPROM whitch isn't affected by a reset setUpPWM(); setUpADC(); setUpRTCC_1secINT();

INTEnableSystemMultiVectoredInt(); INTEnableInterrupts();

USBInitialize(0); AndroidAppStart(&myDeviceInfo);

while(1) { //Keep the USB stack running USBTasks();

//If the device isn't attached yet,

88

Page 89: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

if(device_attached == FALSE) { need_to_disconnect_from_app = FALSE; connected_to_app = FALSE; size = 0;

//Continue to the top of the while loop to start the check over again. continue; }

//If the accessory is ready, then this is where we run all of the demo code if(readyToRead == TRUE) { errorCode = AndroidAppRead(device_handle, (BYTE*)&read_buffer, (DWORD)sizeof(read_buffer)); //If the device is attached, then lets wait for a command from the application if( errorCode != USB_SUCCESS) { //Error DEBUG_ERROR("Error trying to start read"); } else { readyToRead = FALSE; } }

size = 0; relativeAddressInCommandPacket= 0; if(AndroidAppIsReadComplete(device_handle, &errorCode, &size) == TRUE) { //We've received a command over the USB from the Android device. if(errorCode == USB_SUCCESS) { //Maybe process the data here. Maybe process it somewhere else. command_packet = (ACCESSORY_APP_PACKET*)&read_buffer[0]; //readyToRead= TRUE; will be set after the message it is bean digest, the size is zero } else { //Error DEBUG_ERROR("Error trying to complete read request"); }

}

while(size > 0) { if(connected_to_app == FALSE) {

89

Page 90: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

if(command_packet->command == COMMAND_APP_CONNECT) { connected_to_app = TRUE; need_to_disconnect_from_app = FALSE; commandSize= Command_App_Connect_Size+ 1;

//size-= Command_App_Connect_Size+ 1;// recalculate the size, using the relative size of the command //relativeAddressInCommandPacket+= Command_App_Connect_Size+ 1; } } else { if(configsSendOK== TRUE) switch(command_packet->command) { case COMMAND_setValue_PWM: if(sizeof(command_packet-> data)>= Command_setValue_PWM_Size){ // could be more than one command SetDutyMotor1((command_packet-> data[0]<< 8)| command_packet-> data[1]); // we make a 16 bit from two 8 bit SetDutyMotor2((command_packet-> data[2]<< 8)| command_packet-> data[3]); commandSize= Command_setValue_PWM_Size+ 1; if(initialPWMconfig== TRUE){ rtcc_1secINTR= TRUE; // will force to transmit the data faster SetInputCapture1(GetFreqMotor1()); SetInputCapture2(GetFreqMotor2()); SetVoltageBatt(GetChannel4Batt()); SetVoltageSunt(GetChannel8Sunt()); } //size-= Command_setValue_PWM_Size+ 1; //relativeAddressInCommandPacket+= Command_setValue_PWM_Size+ 1; } break; case COMMAND_initialPWMConfig: if(sizeof(command_packet-> data)>= COMMAND_initialPWMConfig_Size){ // could be more than one command commandSize= COMMAND_initialPWMConfig_Size+ 1; initialPWMconfig= TRUE; RTCC_IntrruptDisable(); // we will generate manual the sampling rate setUpDAC(DAC_1dot5V); // here it is a good place to initialize also the DAC to be sure it is ok the voltage reference } break; case COMMAND_finishedPWMConfig: if(sizeof(command_packet-> data)>=

90

Page 91: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

COMMAND_finishedPWMConfig_Size){ // could be more than one command commandSize= COMMAND_finishedPWMConfig_Size+ 1; initialPWMconfig= FALSE; // we are finished with the "burst" mode RTCC_InterruptEnable(); // the sampling rate will be generate in auto mode at 1Hz } break; case COMMAND_setDirectionMotor: if(sizeof(command_packet-> data)>= COMMAND_setDirectionMotor_Size){ // could be more than one command commandSize= COMMAND_setDirectionMotor_Size+ 1; SetDutyMotor1(0); // before we stop the PWMs, and then, after a second we change the sign SetDutyMotor2(0); desiredDirectionForMotors= command_packet->data[0]; needToChangeMotorDirection= NeedToChange; } break; case COMMAND_shutDown: if(sizeof(command_packet-> data)>= Command_shutDown_Size){ /** * ANDROID: * The code to shut down the system * For now we will shut down both motors */ SetDutyMotor1(0); SetDutyMotor2(0); commandSize= Command_shutDown_Size+ 1; //size-= Command_shutDown_Size+ 1; //relativeAddressInCommandPacket+= Command_shutDown_Size+ 1; } break;

case COMMAND_APP_DISCONNECT: if(sizeof(command_packet-> data)>= Command_App_Disconnect_Size){ need_to_disconnect_from_app = TRUE; commandSize= Command_App_Disconnect_Size+ 1; //size-= Command_App_Disconnect_Size+ 1; //relativeAddressInCommandPacket+= Command_App_Disconnect_Size+ 1; } break;

default: //Error, unknown command DEBUG_ERROR("Error: unknown command

91

Page 92: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

received"); break; } } // And move the pointer to the next packet (this works because // all command packets are 2 bytes. If variable packet size // then need to handle moving the pointer by the size of the // command type that arrived. size-= commandSize; relativeAddressInCommandPacket+= commandSize; if(size!= 0) memcpy(command_packet, &read_buffer[relativeAddressInCommandPacket], size);

if(need_to_disconnect_from_app == TRUE) { break; } }

if(size == 0) { readyToRead = TRUE; }

if(connected_to_app == FALSE) { //If the app hasn't told us to start sending data, let's not do anything else. continue; } // WE TRY TO SEND THE CONFIGS // At first run we move in the buffer the configs(a local one); here will be put the local buffer contain in the output buffer // At second run we will verify if have been send with succes the infos, and if so we will set a flag // Because the flag eill be set only at the second pass, the program counter won't go further, because of the continue statement adresaWrite= 0; if(configsSendOK== FALSE){ // If there is a write already in progress, we need to check its status if( writeInProgress == TRUE ) { if(AndroidAppIsWriteComplete(device_handle, &errorCode, &size) == TRUE) { writeInProgress = FALSE; if(errorCode != USB_SUCCESS) { //Error DEBUG_ERROR("Error trying to complete write"); }else configsSendOK= TRUE;

92

Page 93: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

} }else{ sendConfigToAndroid(); // we will prepare the output buffer whir all the configs writeInProgress= TRUE; errorCode = AndroidAppWrite(device_handle, write_buffer, adresaWrite); if( errorCode != USB_SUCCESS ) { DEBUG_ERROR("Error trying to send button update"); } } } if(configsSendOK== FALSE) continue; // if we are here after all the continue statemant maybe we have smth to send, we will use a local buffer

// If there is a write already in progress, we need to check its status if( writeInProgress == TRUE ) { if(AndroidAppIsWriteComplete(device_handle, &errorCode, &size) == TRUE) { writeInProgress = FALSE; if(need_to_disconnect_from_app == TRUE) { connected_to_app = FALSE; need_to_disconnect_from_app = FALSE; }

if(errorCode != USB_SUCCESS) { //Error DEBUG_ERROR("Error trying to complete write"); } } }

if((need_to_disconnect_from_app == TRUE) && (writeInProgress == FALSE)) { outgoing_packet.command = COMMAND_APP_DISCONNECT; //outgoing_packet.data = 0; writeInProgress = TRUE;

errorCode = AndroidAppWrite(device_handle,(BYTE*)&outgoing_packet, Command_App_Disconnect_Size+ 1); if( errorCode != USB_SUCCESS ) { DEBUG_ERROR("Error trying to send button update"); } }else // it isn't the time to send smth, we will wait a little more

93

Page 94: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

if(rtcc_1secINTR== FALSE) continue; if(needToChangeMotorDirection== ChangeNow){ setMotorsDirection(desiredDirectionForMotors); needToChangeMotorDirection= IDLE; // do not change the order of the two ifs } if(needToChangeMotorDirection== NeedToChange){ needToChangeMotorDirection= ChangeNow; // we will wait minimum 1 sec } // If we need up update the inputCapture on the Android device and we aren't // already busy in a write, then we can send the new button data. // if((inputCapNeedUpdate == TRUE)&& (writeInProgress== FALSE)) if(writeInProgress == FALSE) { outgoing_packet.command = COMMAND_getValue_InputCapture; outgoing_packet.data[0]= GetInputCapture1() >> 8; // we send the first value, followed by the second one outgoing_packet.data[1]= GetInputCapture1() & 0x00FF; outgoing_packet.data[2]= GetInputCapture2() >> 8; outgoing_packet.data[3]= GetInputCapture2() & 0x00FF; outgoing_packet.data[4]= GetNrEventsMotor1()& 0x00FF; outgoing_packet.data[5]= GetNrEventsMotor2()& 0x00FF;

memcpy(&write_buffer[adresaWrite], (BYTE*)&outgoing_packet, Command_getValue_InputCapture_Size+ 1); adresaWrite+= Command_getValue_InputCapture_Size+ 1;

// writeInProgress = TRUE; }

//If we need up update the pot status on the Android device and we aren't // already busy in a write, then we can send the new pot data. if(writeInProgress == FALSE) { outgoing_packet.command = COMMAND_getValue_Voltage; outgoing_packet.data[0]= GetVoltageSunt() >> 8; outgoing_packet.data[1]= GetVoltageSunt() & 0x00FF; outgoing_packet.data[2]= GetVoltageBatt() >> 8; outgoing_packet.data[3]= GetVoltageBatt() & 0x00FF;

memcpy(&write_buffer[adresaWrite], (BYTE*)&outgoing_packet, Command_getValue_Voltage_Size+ 1); adresaWrite+= Command_getValue_Voltage_Size+ 1;

// writeInProgress = TRUE; }

// at the end we try to write smth, could be locked by the need of deconect from the app if(writeInProgress== FALSE){ rtcc_1secINTR= FALSE; // will be set by the RTCC writeInProgress= TRUE;

94

Page 95: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

errorCode = AndroidAppWrite(device_handle, write_buffer, adresaWrite); if( errorCode != USB_SUCCESS ) { DEBUG_ERROR("Error trying to send pot update"); } } } //while(1) main loop}/**************************************************************************** Function: BOOL USB_ApplicationDataEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size )

Summary: Handles USB data application events

Description: Handles USB data application events

Precondition: None

Parameters: BYTE address - address of the device causing the event USB_EVENT event - the event that has occurred void* data - data associated with the event DWORD size - the size of the data in the data field

Return Values: BOOL - Return TRUE of the event was processed. Return FALSE if the event wasn't handled.

Remarks: None ***************************************************************************/BOOL USB_ApplicationDataEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size ){ return FALSE;}

/**************************************************************************** Function: BOOL USB_ApplicationEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size )

Summary: Handles USB application events

95

Page 96: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

Description: Handles USB application events

Precondition: None

Parameters: BYTE address - address of the device causing the event USB_EVENT event - the event that has occurred void* data - data associated with the event DWORD size - the size of the data in the data field

Return Values: BOOL - Return TRUE of the event was processed. Return FALSE if the event wasn't handled.

Remarks: None ***************************************************************************/BOOL USB_ApplicationEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size ){ switch( event ) { case EVENT_VBUS_REQUEST_POWER: // The data pointer points to a byte that represents the amount of power // requested in mA, divided by two. If the device wants too much power, // we reject it. if (((USB_VBUS_POWER_EVENT_DATA*)data)->current <= (MAX_ALLOWED_CURRENT / 2)) { return TRUE; } else { DEBUG_ERROR( "\r\n***** USB Error - device requires too much current *****\r\n" ); } break;

case EVENT_VBUS_RELEASE_POWER: case EVENT_HUB_ATTACH: case EVENT_UNSUPPORTED_DEVICE: case EVENT_CANNOT_ENUMERATE: case EVENT_CLIENT_INIT_ERROR: case EVENT_OUT_OF_MEMORY: case EVENT_UNSPECIFIED_ERROR: // This should never be generated. case EVENT_DETACH: // USB cable has been detached (data: BYTE, address of device) case EVENT_ANDROID_DETACH: device_attached = FALSE;

96

Page 97: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

configsSendOK= FALSE; // if another device will be connected return TRUE; break;

// Android Specific events case EVENT_ANDROID_ATTACH: device_attached = TRUE; device_handle = data; return TRUE;

default : break; } return FALSE;}

/**************************************************************************** Function: void InitPIC32(void)

Summary: Initialize the PIC32 core to the correct modes and clock speeds Also enables multi vector interrupt

Description: Initialize the PIC32 core to the correct modes and clock speeds

Precondition: Only runs on PIC32

Parameters: None

Return Values: None

Remarks: None ***************************************************************************/#if defined(__PIC32MX__)static void InitPIC32(void){ int value;

#if defined(RUN_AT_60MHZ) // Use OSCCON default #else OSCCONCLR = 0x38000000; //PLLODIV #if defined(RUN_AT_48MHZ) OSCCONSET = 0x08000000; //PLLODIV /2 #elif defined(RUN_AT_24MHZ) OSCCONSET = 0x10000000; //PLLODIV /4

97

Page 98: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

#else #error Cannot set OSCCON #endif #endif

value = SYSTEMConfigWaitStatesAndPB( GetSystemClock() );

// Enable the cache for the best performance CheKseg0CacheOn();

// INTEnableSystemMultiVectoredInt(); // will be set later

/*ANDROID: We let JTAG enable for debugging * */ //DDPCONbits.JTAGEN = 0; value = OSCCON; while (!(value & 0x00000020)) { value = OSCCON; // Wait for PLL lock to stabilize }

// INTEnableInterrupts(); // will be set later}#endif

/** * Will send the configuration to Android, using the commands of the type: COMMAND_getConfig_xxxx * Precondition: The USB must be set up before * Postcondition: None, it have no side efects * Return: Will return true if all the configs were send with succes, and false if not */void sendConfigToAndroid(){ BYTE sizeWhitoutIDCmd; BYTE index= 0; // folosit pentru parcurgerea tabloului de configs BYTE nrOfTry= 1; // se va incerca de 1 ori sa se trimita configurarile BOOL allFlags= FALSE; // will be an AND of the flagsOkTransmit[] BYTE configs[4][MAX_COMMAND_DATA_Size+ 2]={ //Size+ 1 for the ID and another one for the size {COMMAND_getConfig_ADC, Command_getConfig_ADC_Size,

10, (1<< 5)| ((5>> 8)& 0x1F), 5, 0, 0, 0, 0, 0}, // ID, dim data, ADCsize, Vref intreg & Vref fractional parte dominanta, Vref fractional {COMMAND_getConfig_Fuses_PWM, Command_getConfig_Fuses_PWM_Size,

80, 15, 2, 1, 1, 16, PWM_desired_freq/100, 1}, // ID, dim data, Freq a cristalului de pe placa* 100KHz, FPLLMUL, FPLLDIV, FPLLODIV, FPBDIV, OutComp reg size, OutComp freq *100Hz, T3_PS_1_1 {COMMAND_getConfig_InputCapture, Command_getConfig_InputCapture_Size,

32, 16, 8, 0, 0, 0, 0, 0}, // ID, dim data, Prescaler

98

Page 99: web.clicknet.roweb.clicknet.ro/crisan.gligor/Licenta/Licenta_final.doc  · Web view4.1 MPLAB X 9. 4.2 Microchip Application Library 9. 4.3 Componente hardware 10. ... WORD size )

T2_PS_1_16, dim in biti a rezultatului, dim in bits of the number of events {COMMAND_getConfig_MotorsID, COMMAND_getConfig_MotorsID_Size,

1, 2, 0, 0, 0, 0, 0, 0} // ID, id motor 1(with IC2 and OC2), id motor 2(with IC3 and OC3) };

while((nrOfTry)> 0&& (allFlags== FALSE)){ nrOfTry-- ; allFlags= TRUE; // if remain true it means that all configs have been send with success // we have to send 3 configs arrays, whitch means 3 commands with data // at every step we send the command+ data then we try to see if there was completed the last write on Android for(index= 0; index< 4; index++){ sizeWhitoutIDCmd= configs[index][1]; outgoing_packet.command = configs[index][0]; memcpy(outgoing_packet.data, &configs[index][2], sizeWhitoutIDCmd); memcpy(&write_buffer[adresaWrite], (BYTE*)&outgoing_packet, sizeWhitoutIDCmd+ 1); adresaWrite+= sizeWhitoutIDCmd+ 1; } }}

99


Recommended