logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Marsz Imperialny na Atmega32

Jellyeater 23 Gru 2006 16:27 6442 10
REKLAMA
  • Używając Atmega32 oraz mostka H: BA6418N, zrobiłem prosty generator dźwięków. Urządzenie generuje przebieg prostokątny jednopołówkowy (dla dwupołówkowego głośnik gorzej działał [więc ten mostek h nie był mi właściwie potrzebny]) o określonej czestotliwości i czasie trwania. Potem podajemy w programie czestotliwości nut i gramy.

    = = = = = = = = = = = = = = = = = = = = = =
    = = = = = = = = = = = = = = = = = = = = = =




    Fajne? Ranking DIY
    O autorze
    Jellyeater
    Poziom 17  
    Offline 
    Jellyeater napisał 246 postów o ocenie 3, pomógł 6 razy. Mieszka w mieście Warszawa. Jest z nami od 2005 roku.
  • REKLAMA
  • #2 3362877
    yogib
    Poziom 13  
    Posty: 68
    Ocena: 2
    Podziel się kodem programu.
  • REKLAMA
  • #3 3363267
    CMS
    VIP Zasłużony dla elektroda
    Posty: 8468
    Pomógł: 258
    Ocena: 2601
    No calkiem "zabawna" kostrukcja rozumiem ze to potrafi zagrac dowolny "utwor"

    ps.
    czy to ten sam Jelly co na WGK ??
  • REKLAMA
  • #4 3364153
    lechoo
    Poziom 39  
    Posty: 5161
    Pomógł: 377
    Ocena: 546
    Trochę kiepska jest ta pozytywka, na mnie nie robi to żadnego wrażenia.
    ATmega32 posiada na tyle dużą moc obliczeniową, że możnaby pokusić się o napisanie programu odtwarzającego muzyczkę z plików MOD znanych chociażby z Amigi...
  • #5 3364885
    Jellyeater
    Poziom 17  
    Posty: 246
    Pomógł: 6
    Ocena: 3
    Tia z WGK.

    Fałsz wynika z tego, że podaje sie prostokąt. Nie ma to jak 3 i 5 harmoniczna... Przynajmniej tak mi się wydaje... No i może troche niedokładnie są częstotliwości.

    #include <avr/io.h>
    #include <compat/deprecated.h>
    
    #define SPP cbi(PORTA,PA3);sbi(PORTA,PA2)
    #define SPM cbi(PORTA,PA2);sbi(PORTA,PA3)
    #define SPOFF cbi(PORTA,PA2);cbi(PORTA,PA3)
    
    #define LED1_ON sbi(PORTA,PA0)
    #define LED1_OFF cbi(PORTA,PA0)
    #define LED2_ON sbi(PORTA,PA1)
    #define LED2_OFF cbi(PORTA,PA1)
    
    void Nuta(uint8_t czas, int freq){
    	unsigned int i,j,delay,ilpow,przerwa;
    
    	if(freq<450) LED1_ON;
    	if((freq>449)&&(freq<600)) LED2_ON;
    	if(freq>599){
    		LED1_ON;
    		LED2_ON;
    	}
    
    	delay=(int)(333386/freq);
    	ilpow=(int)(658119/(czas*delay));
    	przerwa=(int)(73133/(czas*delay));
    	for(j=0;j<ilpow; j++){
    		SPP;
    		for(i=0; i<delay; i++) 
        	{ 
            	 asm volatile ("WDR"::); 
        	} 
        	SPM;
    		for(i=0; i<delay; i++) 
        	{ 
            	 asm volatile ("WDR"::); 
        	}
    	}
    	LED1_OFF;
    	LED2_OFF;
    	for(j=0;j<przerwa; j++){
    		SPOFF;
    		for(i=0; i<delay; i++) 
        	{ 
            	 asm volatile ("WDR"::); 
        	} 
        	SPOFF;
    		for(i=0; i<delay; i++) 
        	{ 
            	 asm volatile ("WDR"::); 
        	}
    	}	
    }
    
    void Delayms(unsigned int _ms) 
    { 
       unsigned int delay, delay_ms; 
       for(delay=0; delay<_ms; delay++) 
       { 
          for(delay_ms=0; delay_ms<76; delay_ms++) 
          { 
             asm volatile ("WDR"::); 
          } 
       }    
    }
    
    int main (void){
    
    sbi(DDRA,PA2);
    sbi(DDRA,PA3);
    
    
    	for (;;){			
    		Nuta(4,350);
    		Nuta(4,350);
    		Nuta(4,350);
    		Nuta(5,294);
    		Nuta(16,440);
    
    		Nuta(4,350);
    		Nuta(5,294);
    		Nuta(16,440);
    		Nuta(2,350);
    
    		Nuta(4,523);
    		Nuta(4,523);
    		Nuta(4,523);
    		Nuta(5,587);		
    		Nuta(16,440);
    
    		Nuta(4,350);
    		Nuta(5,294);
    		Nuta(16,440);		
    		Nuta(2,370);		
    
    		Nuta(4,699);
    		Nuta(5,350);
    		Nuta(16,350);
    		Nuta(4,699);
    		Nuta(5,699);
    		Nuta(16,659);
    
    		Nuta(16,622);
    		Nuta(16,587);
    		Nuta(8,659);
    		Nuta(8,20000);//pauza		
    
    		Nuta(8,370);
    		Nuta(4,554);
    		Nuta(5,523);
    		Nuta(16,494);
    
    		Nuta(16,466);
    		Nuta(16,440);
    		Nuta(8,494);
    		Nuta(8,20000);//pauza
    	
    		Nuta(8,311);
    		Nuta(4,370);
    		Nuta(5,330);
    		Nuta(16,350);
    				
    		Nuta(4,466);
    		Nuta(5,392);
    		Nuta(16,494);
    		Nuta(2,587);
    
    		Nuta(4,783);
    		Nuta(5,350);
    		Nuta(16,350);
    		Nuta(4,783);
    
    		Nuta(5,740);
    		Nuta(16,699);
    
    		Nuta(16,659);
    		Nuta(16,622);
    		Nuta(8,659);
    		
    		Nuta(8,20000);//pauza
    
    		Nuta(8,415);
    		Nuta(4,554);
    		Nuta(5,523);//c gorne
    		Nuta(16,493);
    
    		Nuta(16,466);
    		Nuta(16,440);
    		Nuta(8,466);		
    
    		Nuta(8,20000);//pauza
    
    		Nuta(8,311);
    		Nuta(4,370);
    		Nuta(5,311);
    		Nuta(16,494);
    
    		Nuta(4,392);
    		Nuta(5,311);
    		Nuta(16,466);
    		Nuta(2,392);
    
    		Delayms(5000);		
    	}
    
        return (0);     
    }
  • #6 3365036
    yogib
    Poziom 13  
    Posty: 68
    Ocena: 2
    Dzięki za udostępnienie kodu. Osobiście interesowały mnie częstotliwości kolejnych nut. Czy są gdzieś gotowe utwory dopasowane do tego zapisu? Czy ma to coś wspólnego z Nokia Composer?
  • #7 3365452
    CMS
    VIP Zasłużony dla elektroda
    Posty: 8468
    Pomógł: 258
    Ocena: 2601
    W takim Razie witam serdecznie, nie wiedzialem ze bawisz sie w takie rzeczy (tzn myslalem ze twoje glowne zajecie to narzekanie :) )
    Pozdrawiam
  • #8 3365521
    Jellyeater
    Poziom 17  
    Posty: 246
    Pomógł: 6
    Ocena: 3
    Mogę ponarzekać. Zrobiłem nową wersją, w której podzieliłem kazdy okres na 10 i wysterowywałem z wypełnieniem takim, by średnia wartosć byłą sinusoidalna. Myślałem, że troch wyeliminuję harmoniczne. Ogólnie brzmi to jeszcze gorzej i na dodatek Atmega32 nie jest jednak taka szybka i przestała się wyrabiać dla tych 20 KHz i słychać pisk tak w okolicy 10 KHz. Program dobrałem tak by miał dobre częstotliwości dla 350 Hz i opóźnienia dla 1/4 nuty. Dla 1/8 i 20 KHz coś się musi dłużej wykonywać...

    Tak czy siak nie wiem jak to poprawić. Można by budować filtr który by odciął wszystko powyżej 1 KHz.

    Na Amidze raczej nie generowano dźwięków za pomocą PWM. Pewnie był tam przetwornik DAC... Właściwie to Atmega ma DAC tyle, że 8 bit. A to troche za mało by generować muzykę.
  • #9 3365706
    lechoo
    Poziom 39  
    Posty: 5161
    Pomógł: 377
    Ocena: 546
    Do przetwarzania C/A w ATmega można wykorzystać tryb Fast PWM. Dla częstotliwości zegara 16MHz i ograniczenia przetwarzania do 8 bitów uzyskać można częstotliwość nośną 62,5kHz, a więc całkiem przyzwoicie. Zamiast tego można zbudować prosty 8-bitowy równoległy przetwornik C/A w postaci drabinki R-2R. Jednak w obu przypadkach należy odfiltrować częstotliwości leżące powyżej połowy częstotliwości próbkowania (nie mylić z częstotliwością nośną PWM) aby uniknąć zniekształceń wywołanych aliasingiem.

    Amiga miała przetworniki C/A właśnie 8-bitowe. Jak mi czas pozwoli to w styczniu spróbuję zaimplementować prosty odtwarzacz MOD-ów na ATmega.
    ____________________

    EDIT:

    Znalazłem gotowca opartego na ATmega32 na czeskiej stronie:
    -> http://elektronika.kvalitne.cz/ATMEL/MODplayer/MODplayer.html
    Odtwarza 4-kanałowe pliki MOD zapisane w pamięci EPROM lub RAM z jakością 22kHz/16bit/stereo - został użyty tani scalony przetwornik I2S audio.
    Mniejsze pliki MOD możnaby umieścić bezpośrednio w pamięci Flash mikrokontrolera. Program napisany jest w asemblerze i zajmuje zaledwie 6kB - łącznie z obsługą wyświetlacza LCD i klawiszy sterujących. Dostępny jest kod źródłowy z obszernymi komentarzami, więc jego modyfikacja nie powinna sprawić problemów.

    Inna wersja tego MOD-playera:
    -> http://elektronika.kvalitne.cz/ATMEL/MODplayer/MODplayer2.html
    Odtwarza pliki MOD o wielkości do 512kB każdy, zapisane w karcie pamięci CF max. 128MB.
  • REKLAMA
  • #10 3379763
    Mje3sław
    Poziom 14  
    Posty: 140
    Pomógł: 2
    Ocena: 11
    Ja tu słyszę nie tyle fałsz, co chrypienie ze stałą częstotliwością - przerwania, albo po prostu nie przemyślany do końca program.

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy realizacji prostego generatora dźwięków na mikrokontrolerze Atmega32 z wykorzystaniem mostka H BA6418N. Urządzenie generuje jednopołówkowy przebieg prostokątny o określonej częstotliwości i czasie trwania nut, co powoduje obecność harmonicznych (3. i 5.) i niedokładności w częstotliwościach. Autor udostępnił fragment kodu źródłowego, który steruje wyjściem i diodami LED w zależności od częstotliwości. Próby poprawy jakości dźwięku obejmowały modulację wypełnienia impulsu, aby uzyskać średnią sinusoidalną, jednak Atmega32 okazała się niewystarczająco szybka do generowania wysokich częstotliwości (do 20 kHz). Wskazano, że Atmega32 posiada 8-bitowy DAC i możliwość wykorzystania trybu Fast PWM do generowania sygnału audio z częstotliwością nośną do 62,5 kHz, co wymaga filtracji antyaliasingowej. W dyskusji pojawiły się sugestie dotyczące odtwarzania plików MOD na Atmedze32, w tym link do projektu odtwarzacza MOD z czeskiej strony, wykorzystującego zewnętrzny przetwornik I2S audio (22 kHz, 16 bit, stereo). Wspomniano także o implementacji odtwarzania MOD na Atmedze32 z przetwornikiem TDA1543. Krytyka dotyczyła jakości generowanego dźwięku i możliwych problemów z przerwaniami lub niedopracowaniem programu. Poruszono tematykę ograniczeń sprzętowych i konieczności stosowania filtrów dolnoprzepustowych dla poprawy jakości dźwięku.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA