Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2017:fn-generator

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
2017:fn-generator [2018/01/14 22:19]
Martin Lelek [Firmware]
2017:fn-generator [2018/01/14 23:56] (aktuální)
Martin Lelek [Závěr]
Řádek 1: Řádek 1:
-======== ​Zadání ​========+======== ​Funkční generátor ​========
  
-Na vhodné architektuře (STM32F407) implementujte algoritmus schopný přes DA převodník generovat základní funkční signály v pásmu minimálně do 50kHz (AUDIO). Generátor umožní regulovat kmitočet, amplitudu a stejnosměrný offset výstupního signálu. Dále implementujte vhodné ovládání (LCD, tlačítka, rotační kodér apod.) pro pohodlné řízení generátoru. Pro FW procesoru realizujte vhodnou HW nadstavbu s potřebnými analogovými obvody včetně napájení. 
  
 **Vypracoval:​ Martin Lelek** **Vypracoval:​ Martin Lelek**
 +
 +----
 +
 +======= Zadání =======
 +
 +Na vhodné architektuře (STM32F407) implementujte algoritmus schopný přes DA převodník generovat základní funkční signály v pásmu minimálně do 50kHz (AUDIO). Generátor umožní regulovat kmitočet, amplitudu a stejnosměrný offset výstupního signálu. Dále implementujte vhodné ovládání (LCD, tlačítka, rotační kodér apod.) pro pohodlné řízení generátoru. Pro FW procesoru realizujte vhodnou HW nadstavbu s potřebnými analogovými obvody včetně napájení.
  
 ---- ----
Řádek 63: Řádek 68:
 uint8_t ​ func = 1;​ //​proměnná definující zvolenou funkci uint8_t ​ func = 1;​ //​proměnná definující zvolenou funkci
 uint8_t ​ cursor = 0;​ //​proměnná definující pozici kurzoru uint8_t ​ cursor = 0;​ //​proměnná definující pozici kurzoru
-</​code ​c>+</​code>​
  
 +== Inicializace ==
 Po spuštění hlavní funkce MAIN dojde k inicializaci veškerých potřebných periferií pomocí funkcí HAL_Init(), SystemClock_Config(), ​ MX_GPIO_Init(), ​ MX_SPI2_Init() a MX_TIM3_Init(). Dále se provede inicializace alfanumerického LCD pomocí uzemnění pinu R/W. Po vypsání uvítací obrazovky „STM32F4“ spolu s „Initialize“ se aktivuje blikající kurzor LCD. Následuje zavolání funkce sine_calc(),​ která do pole sine_buff() uloží N vzorků jedné periody sinusové funkce: Po spuštění hlavní funkce MAIN dojde k inicializaci veškerých potřebných periferií pomocí funkcí HAL_Init(), SystemClock_Config(), ​ MX_GPIO_Init(), ​ MX_SPI2_Init() a MX_TIM3_Init(). Dále se provede inicializace alfanumerického LCD pomocí uzemnění pinu R/W. Po vypsání uvítací obrazovky „STM32F4“ spolu s „Initialize“ se aktivuje blikající kurzor LCD. Následuje zavolání funkce sine_calc(),​ která do pole sine_buff() uloží N vzorků jedné periody sinusové funkce:
  
 +<code c>
 +void sine_calc(void)
 +{
 +    uint16_t i = 0;
 +    float FI = 0;
 +
 +    for(i = 0; i < N; i++)
 +    {
 +        FI = (( M_PI* 2)/ N)* i;
 +
 +        sine_buff[i] = ( 16383 *sin( FI)) + 16383;
 +    }
 +}
 +</​code>​
 +
 +Procesor STM32F407 má dostatek paměti RAM pro pojmutí tohoto pole. 
 +
 +Po vypočtení pole hodnot sinusové funkce se po návratu spustí čítač TIM3 pomocí funkcí HAL_TIM_Base_Start_IT(&​htim3) a HAL_TIM_PWM_Start(&​htim3,​ TIM_CHANNEL_4). Vzorkovací kmitočet činí 100 kHz, je generován jako invertovaný signál PWM se střídou přibližně 3%, po která je tento signál v log. 1. Tímto krátkým pulzem dojde k zapsání dat do vnitřního 24b registru, do kterého byla po SPI tato data předtím vyslána. Sestupnou hranou pulzu je generováno přerušení – volání CallBack funkce pro jeho obsluhu.
 +
 +== Ovládání ==
 +Po spuštění čítače je zinicializována obrazovka LCD a vypsány primární hodnoty. Program dále skočí do hlavní smyčky programu, ve které testuje čtyři tlačítka. ​
 +
 +Tlačítka doprava a doleva (GPIO_PIN_0 a GPIO_PIN_1) slouží pro posuv kurzoru po LCD, v jejich podmínkách se pouze inkrementuje a dekrementuje hodnota proměnné cursor. Podmínky též obsahují jednoduché odrušení řešené pomocí zpoždění.
 +
 +Další dvě tlačítka (GPIO_PIN_2 a GPIO_PIN_3) slouží pro nastavení aktuálně zvolené pozice kurzoru. Nastavování na dané pozici je řešeno pomocí funkce switch, jež má jako parametr proměnnou cursor. V první části funkce switch je nastavován kmitočet s ohledem na možné meze, v druhé části je měněna hodnota proměnné func, jež určuje svojí hodnotou typ funkce průběhu (SINE, SAW, SQUARE, ZERO). ​
 +
 +Ve třetí a čtvrté části funkce switch je podobným způsobem nastavována hodnota amplitudy a stejnosměrného offsetu. Při změně těchto hodnot dojde k nastavení flagu necessary, jež je zahrnut při odesílání dat v CallBack funkci přerušení čítače TIM3.
 +
 +== CallBack timeru a odesílání dat ==
 +Ve funkci CallBack je na základě hodnoty proměnné func rozhodnuto, který daný vzorek bude po sběrnici vyslán ven. Odpovídá-li hodnota proměnné funkci SINE, odesílají se periodicky vzorky z tabulky sine_buff do DA převodníku. ​
 +
 +Ten který vzorek má být odeslán, je určeno pomocí jednoduchého výpočtu z vzorkovacího kmitočtu, nastaveného kmitočtu a celkového počtu vzorků na periodu:
 +
 +<code c>
 +case 1:     //​SINE
 +    if( sam_num < ( ( N* 10) - frequency - 10))
 +    {
 +        sam_num = sam_num + frequency;
 +    }
 +    else
 +    {
 +        sam_num = frequency - (( N* 10) - sam_num - 10);
 +    }
 +
 +    buff[2] = sine_buff[ sam_num/ 10] >> 0;    //​LOWER ​ bits
 +    buff[1] = sine_buff[ sam_num/ 10] >> 8;    //HIGHER bits
 +    //buff[0] = 0;
 +break;
 +</​code>​
 +
 +Pro generování funkcí SAW a SQUARE je pro jednoduchost využit výpočet v reálném čase. Na závěr CallBack funkce jsou odesílána data po SPI – buď vzorek do DA převodníku,​ nebo v případě nastavení flagu necessary pouze data do digitálních potenciometrů.
 +
 +Funkce out_freq, out_amp a out_dc jsou využity pouze pro vypisování proměnných odpovídajících těmto třem parametrům,​ podobně funkce set_cursor a put_func.
 +
 +-----
 +
 +===== Závěr =====
 +
 +Vynaloženým úsilím se podařilo vytvořit funkční prototyp generátoru sinusového,​ pilovitého a obdélníkového signálu. Ve firmwaru kontroléru nebyla využita sběrnice DMA pro odesílání SPI dat, byl využit přímo dostupný HAL driver. Toto řešení se ne příliš později projevilo jako fatální v omezení schopností celého zařízení při použitém vzorkovacím kmitočtu a požadovaného kmitočtu signálu na výstupu. Měřením na datových a CS vodičích bylo zjištěno, že tento přístup k SPI periferii zanáší mezi zavoláním funkce pro odeslání dat a samotným odesláním dat z periferie zpoždění přibližně třetinu periody vzorkovacího kmitočtu. Důsledkem tohoto, jelikož jsou odesílány tři bajty dat za sebou, nelze vzorkovací kmitočet již dále zvyšovat. Řešením by bylo použití sběrnice DMA, popřípadě emulované sběrnice SPI.
 +
 +Dalším opomenutým nešvarem budiž absence rekonstrukčního filtru. Podvědomí autora si nejspíše naivně myslelo, že se sinusovka o kmitočtu 50kHz bude při vzorkovacím kmitočtu 100kHz jevit plynule jako vycházející a zapadající slunce.. Leč byl to omyl a to více než krutý. Tímto opomenutím je relativně dobrá použitelnost prototypu omezena na pásmo do 20kHz, což však pro použití v audio pásmu v podstatě stačí.
 +
 +**Fotografie nasazeného modulu je zde:**
 +
 +{{ :​2017:​fn_gen:​gen_proto.jpg?​direct&​400 |}}
 +
 +**ZIP archiv se schematem a PCB v SW Eagle a zdrojovými kódy:**
 +
 +{{ :​2017:​fn_gen:​xlelek02_2017_project_mpoa.zip |}}
 +
 +**Krátké video demonstrující funkci:**
 +
 +https://​youtu.be/​UYy0PPRKk28
 +
 +{{ youtube>​UYy0PPRKk28?​medium |}}
2017/fn-generator.1515964750.txt.gz · Poslední úprava: 2018/01/14 22:19 autor: Martin Lelek