Operácie

Zbernica SPI: D/A prevodník MCP4812: Rozdiel medzi revíziami

Zo stránky SensorWiki

Balogh (diskusia | príspevky)
Vytvorená stránka „Záverečný projekt predmetu MIPS / LS2026 - '''Meno Priezvisko''' == Zadanie == Mojou úlohou bolo pracovať so vstupmi vo forme tlačidiel a na základe ich postupného stláčania vytvoriť sekvenciu, ktorú systém vyhodnocuje. Program sleduje poradie stlačených tlačidiel a po zadaní celej sekvencie ho porovná s vopred definovaným správnym kódom. V prípade správneho zadania sa rozsvieti žltá LED dióda, pri nesprávnom zadaní sa rozsvieti červ…“
 
StudentMIPS (diskusia | príspevky)
Bez shrnutí editace
Riadok 1: Riadok 1:
Záverečný projekt predmetu MIPS / LS2026 - '''Meno Priezvisko'''
Záverečný projekt predmetu MIPS / LS2026 - '''Jakub Milošev'''




== Zadanie ==
== Zadanie ==


Mojou úlohou bolo pracovať so vstupmi vo forme tlačidiel a na základe ich postupného stláčania vytvoriť sekvenciu, ktorú systém vyhodnocuje. Program sleduje poradie stlačených tlačidiel a po zadaní celej sekvencie ho porovná s vopred definovaným správnym kódom. V prípade správneho zadania sa rozsvieti žltá LED dióda, pri nesprávnom zadaní sa rozsvieti červená LED dióda.
Navrhnúť a realizovať program pre Arduino ATmega328P, ktorý komunikuje s D/A prevodníkom MCP4812. Program má umožniť zadávanie celých čísel v rozsahu 0 až 4 prostredníctvom sériovej komunikácie (PuTTY). Po zadaní hodnoty sa na výstupe D/A prevodníka vytvorí analógové napätie zodpovedajúce zadanému číslu v rozsahu 0 V až 4 V.


[[Obrázok:ard.jpg|500px|thumb|center|Vývojová doska ACROB.]]
[[Obrázok:ard.jpg|500px|thumb|center|Vývojová doska ACROB.]]


'''Literatúra:'''  
'''Literatúra:'''  
* [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k doske Acrob]
* [https://ww1.microchip.com/downloads/en/devicedoc/20002249b.pdf Datasheet k MCP4812]
* [http://www.humanbenchmark.com/tests/reactiontime/index.php Vyskúšajte si zmerať reakciu on-line]




Riadok 17: Riadok 16:
== Analýza  a opis riešenia ==
== Analýza  a opis riešenia ==


Opíšte sem čo a ako ste spravili, ak treba, doplňte obrázkami...
Najprv sme museli ísť do datasheetu prevodníka na dozvedenie informácii ako koľko bitový je, čo jednotlivé bity robia.  
Podrobne opíšte použité komponenty (okrem základnej dosky s ATmega328P procesorom), pridajte linky na datasheety alebo opis obvodu.  


[[Súbor:GeminiAI-image3.jpg|400px|thumb|center|Celkový pohľad na zariadenie.]]
[[Súbor:Jednotlive_bity_MCP4812.jpg|400px|thumb|center|Pohľad na jednotlivé bity]]


Nezabudnite doplniť schému zapojenia! V texte by ste mali opísať základné veci zo zapojenia, samotná schéma nie je dostačujúci opis.
GA sme nastavili ako 0 aby sme mali 2 násobok napätia Vref (2*Vref=4,096) a mohli sme sa pohybovať v rozpätí 0 až 4 V.
 
Piny prevodníka.
 
[[Súbor:GeminiAI-image3.jpg|400px|thumb|center|Jednotlivé piny prevodníka]]
 
[[Súbor:GeminiAI-image3.jpg|400px|thumb|center|Popis pinov prevodníka]]
 
== Schéma zapojenia ==
 
Podľa datasheetu samotnej dosky a obrázka vyššie sme prepojili pin CS s pinom SS (PB2), pin SCK s pinom SCK (PB5) a pin SDI s pinom MOSI (PB3). Piny VSS a LDAC boli pripojené na zem (GND). Pin LDAC bol pripojený na GND, aby sa výstup prevodníka automaticky aktualizoval po prijatí novej hodnoty bez potreby dodatočného impulzu.


[[Súbor:GeminiAI-image2.jpg|400px|thumb|center|Schéma zapojenia.]]
[[Súbor:GeminiAI-image2.jpg|400px|thumb|center|Schéma zapojenia.]]
Riadok 29: Riadok 37:
=== Algoritmus a program ===
=== Algoritmus a program ===


Algoritmus programu využíva toto a toto, základné funkcie sú takéto a voláma ich tuto...  
Ako prvé sa spustí UART (oba sú totožné z UARTami z cvík) čo umožní komunikáciu s PuTTY. Potom sa spustí SPI kde sa nastavia piny PB3, PB5 a PB2 ako výstupy a CS pin nastaví na HIGH čo znamená že prevodník zatiaľ nekomunikuje.
Výpis kódu je nižšie...
 
Ďalej program prejde do while slučky kde čaká na znak z PuTTY. Funkcia uart_getc() čaká dokým sa nenapíše znak nepotvrdí sa enterom, a následne sa prijatý znak uloží do premennej prijate (if skontroluje či je daný znak číslo od 0 do 4).
 
Program skontroluje či je teda to číslo od 0 do 4 a následne ho prevedie z ASCII na číslo odčítaním ‘0‘ napríklad ‘3‘  - ‘0‘  = 3  a uloží ho do premennej hodnota.
 
Hodnota sa následne vynásobí 1024 a vydelí referenčnou hodnotou napätia 4,096, a uloží sa do premennej vysledok (napríklad pre 3 je výsledok 750 túto hodnotu si už prevodník prevedie na napätie).
 
Výsledok sa pošle do funkcie DAC_write kde sa poskladá 16 bitový príkaz. Výsledok sa posunie o 2 bity doľava a pomocou OR sa vloží do command. Výsledný príkaz obsahuje v horných 4 bitoch konfiguráciu a v zvyšných bitoch dáta.
 
CS pin sa nastaví na LOW čím prevodník začne očakávať hodnoty. Príkaz sa rozdelý na 2 byty horný byte sa pošle ako prvý do SPI_send kde sa zapíše do registra SPDR. Program čaká kým sa odosielanie dokončí pomocou while slučky ktorá kontroluje bit SPIF v registri SPSR aby sa náhodou neprepísala správna hodnota. Potom sa rovnako pošle dolný byte (toto celé je spôsobené kvôli tomu že Arduino 328P je len 8 bitové a posielame viac ako 8 bitov). Po odoslaní oboch bytov sa CS nastaví na HIGH čím sa komunikácia ukončí.
 
Prevodník následne poskladá oba prijaté byty späť do 16 bitového príkazu, skontroluje konfiguračné bity a dátové bity, a nastaví napätie na VoutA.
 
Ako potvrdenie program vypíše do PuTTY Nastavena hodnota: 3V a vráti sa na začiatok while slučky.
 




<tabs>
<tabs>
<tab name="AVR C-code"><syntaxhighlight  lang="c++" style="background: LightYellow;">
<tab name="AVR C-code"><syntaxhighlight  lang="c++" style="background: LightYellow;">
#include <avr/io.h>
 
#define F_CPU 16000000UL     
 
#include <avr/io.h>          
#include "uart.h"           
 
 
void SPI_init(void)
{
    DDRB |= (1 << PB3) | (1 << PB5) | (1 << PB2); //nastavenie vystupov jednotlivych pinov
 
    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
 
    PORTB |= (1 << PB2);
}
 
 
 
// Funkcia na odoslanie 1 bytu cez SPI
void SPI_send(uint8_t data)
{
    // Zapise data do SPI registra
    SPDR = data;
 
    while (!(SPSR & (1 << SPIF))); // caka na skoncenie odosielania
}
 
 
void DAC_write(uint16_t vysledok)
{
    uint16_t command;
    command =  0b0001000000000000; //príkaz z datasheetu
 
    // Posunutie 10-bit dat na spravne miesto
    command |= (vysledok << 2);
 
   
    PORTB &= ~(1 << PB2);
 
    SPI_send(command >> 8);
    SPI_send(command & 0xFF);
 
    PORTB |= (1 << PB2);
}
 


int main(void)
int main(void)
{
{
  unsigned int measuredValue;
    uart_init();
    SPI_init();
 
 
    char prijate;
    uint8_t hodnota;
    uint16_t vysledok;
 
    while (1)
    { 
        prijate = uart_getc();


  while (1)
        if(prijate >= '0' && prijate <= '4')
  {
        {
    /*  relax  */ 
           
  }
            hodnota = prijate - '0';


  return(0);
            // Prevod napatia na DAC hodnotu
           
vysledok = (hodnota) * 250; //250=1024/4.096
            // Zapis hodnoty do DAC
            DAC_write(vysledok);
 
            // Vypis textu do Putty
            uart_puts("Nastavena hodnota: ");
            uart_putc(prijate);
            uart_puts("V\n");
        }
    }
}
}


</syntaxhighlight ></tab>
<tab name="filename.h"><syntaxhighlight  lang="c++" style="background: LightYellow;">
#include <avr/io.h>


void adc_init(void);                                  // A/D converter initialization
unsigned int adc_read(char a_pin);
</syntaxhighlight ></tab>
</syntaxhighlight ></tab>
</tabs>
</tabs>


Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x ''zdrojaky.zip'':


Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
Riadok 65: Riadok 149:
=== Overenie ===
=== Overenie ===


Ako ste overili funkciu, napríklad... Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia.  
Program sme otestovali zapojením vyššie uvedenej schémy. Zapisovali sme do PuTTY rôzne čísla od 0 do 4 a sledovali sme výstup prevodníka pomocou multimetru kde ukazovalo správne hodnoty.
Na konci uvádzame fotku hotového zariadenia.  
Na konci uvádzame fotku hotového zariadenia.  


Riadok 75: Riadok 159:


== Čo by som urobil inak ==
== Čo by som urobil inak ==
Zamyslite sa spätne nad problémom, ktorý ste riešili a napíšte, čo sa vám nepodarilo a nabudúce by ste spravili inak.




Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.


[[Category:AVR]] [[Category:MIPS]]
[[Category:AVR]] [[Category:MIPS]]

Verzia z 12:21, 6. jún 2026

Záverečný projekt predmetu MIPS / LS2026 - Jakub Milošev


Zadanie

Navrhnúť a realizovať program pre Arduino ATmega328P, ktorý komunikuje s D/A prevodníkom MCP4812. Program má umožniť zadávanie celých čísel v rozsahu 0 až 4 prostredníctvom sériovej komunikácie (PuTTY). Po zadaní hodnoty sa na výstupe D/A prevodníka vytvorí analógové napätie zodpovedajúce zadanému číslu v rozsahu 0 V až 4 V.

Vývojová doska ACROB.

Literatúra:


Analýza a opis riešenia

Najprv sme museli ísť do datasheetu prevodníka na dozvedenie informácii ako koľko bitový je, čo jednotlivé bity robia.

Pohľad na jednotlivé bity

GA sme nastavili ako 0 aby sme mali 2 násobok napätia Vref (2*Vref=4,096) a mohli sme sa pohybovať v rozpätí 0 až 4 V.

Piny prevodníka.

Jednotlivé piny prevodníka
Popis pinov prevodníka

Schéma zapojenia

Podľa datasheetu samotnej dosky a obrázka vyššie sme prepojili pin CS s pinom SS (PB2), pin SCK s pinom SCK (PB5) a pin SDI s pinom MOSI (PB3). Piny VSS a LDAC boli pripojené na zem (GND). Pin LDAC bol pripojený na GND, aby sa výstup prevodníka automaticky aktualizoval po prijatí novej hodnoty bez potreby dodatočného impulzu.

Schéma zapojenia.


Algoritmus a program

Ako prvé sa spustí UART (oba sú totožné z UARTami z cvík) čo umožní komunikáciu s PuTTY. Potom sa spustí SPI kde sa nastavia piny PB3, PB5 a PB2 ako výstupy a CS pin nastaví na HIGH čo znamená že prevodník zatiaľ nekomunikuje.

Ďalej program prejde do while slučky kde čaká na znak z PuTTY. Funkcia uart_getc() čaká dokým sa nenapíše znak nepotvrdí sa enterom, a následne sa prijatý znak uloží do premennej prijate (if skontroluje či je daný znak číslo od 0 do 4).

Program skontroluje či je teda to číslo od 0 do 4 a následne ho prevedie z ASCII na číslo odčítaním ‘0‘ napríklad ‘3‘ - ‘0‘ = 3 a uloží ho do premennej hodnota.

Hodnota sa následne vynásobí 1024 a vydelí referenčnou hodnotou napätia 4,096, a uloží sa do premennej vysledok (napríklad pre 3 je výsledok 750 túto hodnotu si už prevodník prevedie na napätie).

Výsledok sa pošle do funkcie DAC_write kde sa poskladá 16 bitový príkaz. Výsledok sa posunie o 2 bity doľava a pomocou OR sa vloží do command. Výsledný príkaz obsahuje v horných 4 bitoch konfiguráciu a v zvyšných bitoch dáta.

CS pin sa nastaví na LOW čím prevodník začne očakávať hodnoty. Príkaz sa rozdelý na 2 byty horný byte sa pošle ako prvý do SPI_send kde sa zapíše do registra SPDR. Program čaká kým sa odosielanie dokončí pomocou while slučky ktorá kontroluje bit SPIF v registri SPSR aby sa náhodou neprepísala správna hodnota. Potom sa rovnako pošle dolný byte (toto celé je spôsobené kvôli tomu že Arduino 328P je len 8 bitové a posielame viac ako 8 bitov). Po odoslaní oboch bytov sa CS nastaví na HIGH čím sa komunikácia ukončí.

Prevodník následne poskladá oba prijaté byty späť do 16 bitového príkazu, skontroluje konfiguračné bity a dátové bity, a nastaví napätie na VoutA.

Ako potvrdenie program vypíše do PuTTY Nastavena hodnota: 3V a vráti sa na začiatok while slučky.


#define F_CPU 16000000UL      

#include <avr/io.h>           
#include "uart.h"            


void SPI_init(void)
{ 
    DDRB |= (1 << PB3) | (1 << PB5) | (1 << PB2); //nastavenie vystupov jednotlivych pinov

    SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);

    PORTB |= (1 << PB2);
}



// Funkcia na odoslanie 1 bytu cez SPI
void SPI_send(uint8_t data)
{
    // Zapise data do SPI registra
    SPDR = data;

    while (!(SPSR & (1 << SPIF))); // caka na skoncenie odosielania
}


void DAC_write(uint16_t vysledok)
{
    uint16_t command;
	
    command =  0b0001000000000000; //príkaz z datasheetu

    // Posunutie 10-bit dat na spravne miesto
    command |= (vysledok << 2);

    
    PORTB &= ~(1 << PB2);

    SPI_send(command >> 8);
    SPI_send(command & 0xFF);

    PORTB |= (1 << PB2);
}


int main(void)
{
    uart_init();
    SPI_init();

   
    char prijate;
	
    uint8_t hodnota;
    uint16_t vysledok;

    while (1)
    {  
        prijate = uart_getc();

        if(prijate >= '0' && prijate <= '4')
        {
            
            hodnota = prijate - '0';

            // Prevod napatia na DAC hodnotu
            
			vysledok = (hodnota) * 250; //250=1024/4.096
			
            // Zapis hodnoty do DAC
            DAC_write(vysledok);

            // Vypis textu do Putty
            uart_puts("Nastavena hodnota: ");
            uart_putc(prijate);
            uart_puts("V\n");
        }
    }
}


Zdrojový kód: zdrojaky.zip

Overenie

Program sme otestovali zapojením vyššie uvedenej schémy. Zapisovali sme do PuTTY rôzne čísla od 0 do 4 a sledovali sme výstup prevodníka pomocou multimetru kde ukazovalo správne hodnoty. Na konci uvádzame fotku hotového zariadenia.

Aplikácia.

Video:


Čo by som urobil inak