Operácie

Akordy s procesorom AVR

Zo stránky SensorWiki

Záverečný projekt predmetu MIPS / LS2024 - Kristián Pauliny


Zadanie

Naprogramujte nejakú pesničku aj s akordmi (využite skutočnosť, že procesor má až tri nezávislé časovače).

Vývojová doska ACROB.

Literatúra:


Analýza a opis riešenia

Opíšte sem čo a ako ste spravili, ak treba, doplňte obrázkami...

Zapojenie, vypracovanie je inšpirované cvičením 5 – Generovanie tónov, kde sme dostali funkčný program, v ktorom stačilo len “naprogramovať melódiu“.

Hranie tónov cez AVR je založené na vstavaných perifériách – počítadlá v stave CTC (Clear Timer on Compare Match). Budem používať všetky 3 nezávislé počítadlá (T0, T1, T2) – konkrétne ich výstupy OC0A, OC1A, OC2A (Output Compare Register) na riadenie výšky tónov. Nastavenie počítadiel vysvetlím konkrétne ako pre počítadle T0 – po pochopení jedného sa proces dá zopakovať aj pri ostatných.

Počítadlo T0 je 8-bitové. Cez registre TCCR0A a TCCR0B (Timer/Counter control register) možno nastaviť jeho preddeličku, PWM mód a hlavne režim generovania priebehu. Do TCCR0A a TCCR0B ide číslo ktorým nastavujeme počítadlo (8-miestny kód v binárnej sústave alebo to isté číslo prepočítané do inej sústavy). Viem, že potrebujem pre počítadlo nastaviť:

- Toggle OC0A on compare match – oživiť register OC0A

- Normal port operation, OC0B disconnected – register OC0B nechať vypnutý

- CTC – režim počítadla Clear Timer on Compare Match

- Preddelička 256 – ako “rýchlo“ má počítať


V tabuľkách DataSheetu dohľadám ako treba nastaviť podregistre COM0A1, COM0A0, COM0B1, COM0B0, WGM02, WGM01, WGM00, CS02, CS01, CS00 a zadám ich dokopy do registrov TCCR0A a TCCR0B podľa rozloženia: (obrázok)

Forma rozpoloženia podregistrov v registroch TCCR0A a TCCR0B.

Pre počítadlo T0 majú byť TCCR registre nastavené nasledovne: TCCR0A = 0b01000010; TCCR0A = 0b00000100; Register OCR0A je priamo napojený na katódu (pozitívnu nožičku) pasívneho meniča. Anóda meniča je pripojená na zem. Do registra OCR0A však nemôžem v AVR kóde napísať skutočnú frekvenciu zvuku ako mechanického vlnenia v prírode, ale treba ju prepočítať. Tento prepočet je daný jednoduchým vzťahom:

Kde platí: - fOCnx je skutočná frekvencia zvuku (napr. komorné “a“ = 440Hz) - fclkIO je frekvencia oscilátora procesora – v prípade Arduina UNO (procesor ATmega328P) je to 16MHZ - N je preddelička – 256 - OCRnx je hľadaná hodnota reprezentujúca skutočnú frekvenciu, pri konkrétnej preddeličke skompilovateľná cez AVR Tento prevod za mňa dokáže urobiť jednoduchý, šikovný program AVRcalc (https://sourceforge.net/projects/avrcalc/). Stačí vybrať hore v záložkách 8-bit Timer, Mode nechať na Clear Timer on Compare Match, Prescaler zmeniť na 256, Clock zadať ako 16 000 000 a hýbať so sliderom v riadku Compare kým v riadku Frequency nebude moja želaná frekvencia. Hodnota v riadku Compare ide do registra OCR0A.

Aby boli tieto tóny čitateľné pre ľudí na začiatku programu som im pridelil formou makier korešpondujúce mená tónov v štandardnom notopise

#define C4 118

Dĺžku tónov viem ovládať v main() programe funkciou delay(), ktorá zamrzne procesor na danú dobu v milisekundách a teda bude tú dobu hrať jeden tón, a potom prepísať OCR0A na iný tón.

Na ukážku funkčnosti tohto projektu som si vybral pieseň Happy Birthday. Je to jednoduchá kozonantná skladba ktorej som pre limitácie zvukovej kvality buzzerov musel pomeniť harmóniu. Finálne noty vyzarajú takto:

Schéma zapojenia:

Repráčiky na pinoch D9 a D11 majú sériovo pred sebou zapojený rezistor (R = 220 Ω) aby ich zvuk bol o trošku tichší. Na pine D6 je pripojený repráčik, ktorý hrá hlavnú melódiu a na D9, D11 repráčiky, ktoré hrajú sprievodnú harmóniu (akordy), čiže potrebujem aby boli trošku komplimentárne, tichšie voči D6 a prepojím ich signál cez rezistor. Projekt funguje aj bez rezistorov napojením repráčikov priamo na signál, ale potom to znie akoby sa repráčiky prekrikovali.


Algoritmus a program

Algoritmus programu je....


#include <avr/io.h>

int main(void)
{
  unsigned int measuredValue;

  while (1)
  {
    /*  relax  */  
  }

  return(0);
}
#include <avr/io.h>

void adc_init(void);                                   // A/D converter initialization

unsigned int adc_read(char a_pin);

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: zdrojaky.zip


Overenie

Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.

Aplikácia.

Video:

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