Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
Obě strany předchozí revize Předchozí verze Následující verze | Předchozí verze | ||
2015:sstv-gen [2016/01/26 05:31] Tomáš Kret [Firmware] |
2015:sstv-gen [2016/01/26 18:04] (aktuální) Tomáš Kret [Záver] |
||
---|---|---|---|
Řádek 1: | Řádek 1: | ||
====== Generátor SSTV signálu ====== | ====== Generátor SSTV signálu ====== | ||
+ | * Tomáš Kret | ||
+ | * xkrett00@stud.feec.vutbr.cz | ||
===== Zadanie ===== | ===== Zadanie ===== | ||
Implementujte audio generátor pre signál SSTV (slow-scan television), napr. mód Martin M1 alebo Robot B&W. Obrazové data prečítajte z SD karty alebo USB flash disku, signál vygenerujte a odošlite pomocou DAC alebo zvukového kodeku. Overte príjem softwarom MMSSTV. | Implementujte audio generátor pre signál SSTV (slow-scan television), napr. mód Martin M1 alebo Robot B&W. Obrazové data prečítajte z SD karty alebo USB flash disku, signál vygenerujte a odošlite pomocou DAC alebo zvukového kodeku. Overte príjem softwarom MMSSTV. | ||
Řádek 165: | Řádek 167: | ||
</code> | </code> | ||
+ | Funkcia generujúca harmonický signál vzorkovaný 48k: | ||
+ | <code> | ||
+ | void frgen(int32_t frq, int32_t tm) { | ||
+ | /*freq[Hz] tm[us]*/ | ||
+ | static int64_t ph = 0; | ||
+ | static int32_t ind1=0; | ||
+ | int32_t ind2=0; | ||
+ | int32_t tmd = 0; | ||
+ | float32_t tmdel = tmd*(20.833333333); | ||
+ | while((tmdel<=tm)) { | ||
+ | float32_t x=2.0*3.141592*(frq*ind2+ph)*0.000020833333333; | ||
+ | float32_t y=32767.0; | ||
+ | buffer[ind1] = (int16_t)(arm_sin_f32(x)*y); | ||
+ | ind1++; | ||
+ | ind2++; | ||
+ | tmd++; | ||
+ | if (ind1 >= BUFFER_SIZE*4) { | ||
+ | //ind1&=(BUFFER_SIZE*4-1); | ||
+ | ind1 = 0; | ||
+ | BSP_LED_On(LED5); | ||
+ | while(!pol2); | ||
+ | pol2=0; | ||
+ | BSP_LED_Off(LED5); | ||
+ | } | ||
+ | else if (ind1 == (BUFFER_SIZE*2)) { | ||
+ | BSP_LED_On(LED3); | ||
+ | while(!pol1); | ||
+ | BSP_LED_Off(LED3); | ||
+ | pol1=0; | ||
+ | } | ||
+ | tmdel = tmd*(20.833333333); | ||
+ | } | ||
+ | ph += frq*ind2; | ||
+ | } | ||
+ | </code> | ||
+ | Funkcia //frgen(int32_t frq, int32_t tm)// je základná funkcia využívaná generátorom. Generuje harmonický signál s nastaviteľnou frekvenciou a časom dĺžky trvania. Pre SSTV prenos je potrebné zabezpečiť plynulú zmenu kmitočtu - o to sa stará pričítavanie zvyškovej fázy do 64-bitovej premennej ph, ktorá je daná súčinom diskrétneho času s frekvenciou. Premenné typu float32_t alokujú miesto pre float unit a tým úrychľujú výpočet. Buffer pre výpočet vzoriek je rozdelený do dvoch častí pomocou premenných pol 1 a pol2. Kým prebieha výpočet v 1. častu, DMA prenos prebieha v druhej časti a naopak. Buffere sú kruhové. Premenná tmdel sleduje dĺžku generovaného signálu. | ||
+ | |||
+ | Obsluha prerušenia na koniec DMA prenosu: | ||
+ | <code> | ||
+ | void BSP_AUDIO_OUT_TransferComplete_CallBack(void) | ||
+ | { | ||
+ | static int32_t index = 0; | ||
+ | if(0) | ||
+ | { | ||
+ | BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW); | ||
+ | index = 0; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | static uint8_t ind = 0; | ||
+ | BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)&wind[0], 2*BUFFER_SIZE); | ||
+ | |||
+ | index = index + BUFFER_SIZE; | ||
+ | index &= (BUFFER_SIZE*4-1); | ||
+ | if (index>=BUFFER_SIZE*2) { | ||
+ | pol2 = 1; | ||
+ | pol1=0; | ||
+ | BSP_LED_Off(LED5); | ||
+ | } | ||
+ | else { | ||
+ | pol1=1; | ||
+ | pol2=0; | ||
+ | BSP_LED_Off(LED3); | ||
+ | } | ||
+ | |||
+ | |||
+ | pref(index); | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | Wind je kruhový bufer, do ktorého sa nové hodnoty vkladajú až zavolaním funkcie //pref(int32_t indx)//: | ||
+ | <code> | ||
+ | void pref(int32_t indx) { | ||
+ | int ind = 0; | ||
+ | do { | ||
+ | wind[(ind*2)&(BUFFER_SIZE*2-1)] = buffer[(ind+indx)&(4*BUFFER_SIZE-1)]; | ||
+ | wind[(ind*2+1)&(BUFFER_SIZE*2-1)] = buffer[(ind+indx)&(4*BUFFER_SIZE-1)]; | ||
+ | if ((ind+indx)>(4*BUFFER_SIZE-1)) BSP_LED_Off(LED4); | ||
+ | else if ((ind+indx)<(2*BUFFER_SIZE-1)) BSP_LED_On(LED4); | ||
+ | ind++; | ||
+ | |||
+ | } while ((ind*2+1)<=(2*BUFFER_SIZE+buf)); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | Funkcia //pref(int32_t indx)// slúži na duplikovanie vzoriek do oboch kanálov. Hodnoty bufferov sa načítavajú a zapisuju cyklicky, čím sa predpočítajú prvky do ďalšieho kroku. | ||
+ | |||
+ | Celý firmware pre EmBitz {{:2015:sstv-gen:sstv.zip|tu}}. | ||
+ | |||
+ | Súbory uložené na USB flash disku {{:2015:sstv-gen:matlab_generated_files.zip|tu}}. | ||
+ | |||
+ | ===== Overenie funkčnosti ===== | ||
+ | {{ :2015:sstv-gen:img_20160126_062859_1.jpg?300 |}} | ||
+ | Testovacie podmienky | ||
+ | {{ :2015:sstv-gen:test.png |}} | ||
+ | {{ :2015:sstv-gen:test_lines.jpg |}} | ||
+ | {{ :2015:sstv-gen:landscape.jpg |}} | ||
+ | {{ :2015:sstv-gen:sstv.jpg |}} | ||
+ | Výsledky prenosov (vpravo synchronizačné signály) a porovnanie s originálmi | ||
+ | **Videozáznam prenosu SSTV** | ||
+ | {{youtube>sZ8ZAE_yu98?medium}} | ||
+ | ===== Záver ===== | ||
+ | Na obrázkoch je vidieť, že dochádza k miernemu rozladeniu farieb ako aj synchronizácie, rozladenie môže byť spôsobené vlastnosťami mikrofónu. Synchronizácia by sa mohla zlepšiť pridaním multitaskingu, odstránením blokujúcich čakaní, lepšou synchronizáciou jednotlivých buferov, zvýšením vzorkovacieho kmitočtu a lepším zaokrúhľovaním času. Pre správne načítanie dát z usb po zapnutí treba približne 5 až 10 sekúnd čakať pred stlačením user tlačidla kvôli dokončeniu enumerácie, avšak nie je to nikde signálizované, čo je tiež potrebné vyriešiť. |