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

[Mega16][ASM] DDS z tablicą różną od 256 bajtów

gnatho 28 Lip 2010 15:53 1143 4
REKLAMA
  • #1 8339796
    gnatho
    Poziom 10  
    Witam,

    Od jakiegoś czasu zmagam się z pewnym problemem. Udało mi się stworzyć generator dds (głównie w oparciu o MiniDDS) na atmedze16 i przy standardowych próbkach (sin, trojkąt, piąa, kwadrat), chodzi bezbłędnie. Problem w tym, że każda z tablic ma dokładnie 256 wartości, a ja chciałbym użyć tablicy np. 20- lub 3000-bajtowej. Przy zastosowaniu 20, oscylogram poprawnie pokazuje pierwsze 20, a potem daje same zera, przy wiekszych od 256, pomija pozostałe bajty.

    Głównym elementem kodu jest przerwanie timera, gdzie odbywa się "generowanie" próbek

    
    .org 0x0026
    
    cli	;wylacz przerwania
    
    add	r28,r24	;dodaj akumulator
    adc  	r29,r25			
    adc	r30,r26       ; ZL
    
    lpm ;zaladuj XL:XH do r0
    	
    out	OCR2,r0 ; pwm
    
    clr temp ;czyszczenie licznika
    out TCNT0, temp
    
    sei	;przywroc przerwania
    reti   ;wroc z przerwania
    


    Pytanie, jak ograniczyć ZL, żeby nie przekraczało np. wartości 0x30, a mimo to działało ciągle jak DDS oraz jak zmienić kod, żeby analogicznie ZH (r31), pobierało wartości powyżej 256 bajtów
  • REKLAMA
  • #2 8339844
    asembler
    Poziom 32  
    X=R26,R27 Y=R28,R29 Z R30,R31 chyba tak sie utarło.
  • REKLAMA
  • #3 8339870
    gnatho
    Poziom 10  
    Faktycznie, myślałem o Z, a napisałem X. Już poprawiam
  • REKLAMA
  • #4 8342658
    Andrzej__S
    Poziom 28  
    Jeżeli to procedura obsługi przerwania to:
    # instrukcje cli i sei są zbędne,
    # jeśli cały program masz w asm, to może nie być konieczne odkładanie na stos użytych w przerwaniu rejestrów, ale wypadałoby chociaż odłożyć na stos SREG.

    Proponowałbym też użyć trybu CTC timera - nie będzie konieczności zerowania TCNT0 podczas przerwania.

    gnatho napisał:

    ...żeby analogicznie ZH (r31), pobierało wartości powyżej 256 bajtów

    Trzeba rozszerzyć akumulator o jeden byte i dodawać go do ZH:
    
    add   r28,r24   ;dodaj akumulator 
    adc     r29,r25          
    adc   r30,r26       ; ZL
    adc   r31, r27      ; ZH
    


    gnatho napisał:

    ...jak ograniczyć ZL, żeby nie przekraczało np. wartości 0x30

    Jeśli już masz zamiar używać tablic większych niż 256 to nie możesz ograniczyć ZL. Jeżeli chcesz używać tablic o zmiennych rozmiarach, należałoby całą zawartość wskaźnika ZH:ZL porównywać z wartością maksymalną, jaką może osiągnąć i po jej przekroczeniu załadować ponownie wartość początkową, od której startował, czyli wskaźnik na pierwszy element tablicy. To znacznie skomplikje Ci obsługę przerwania wydłużając czas na jej wykonanie i w efekcie ograniczając zakres możliwych do uzyskania częstotliowści. Poza tym znacznie skomplikuje wyznaczanie prawidłowej wartości akumulatora dla uzyskania żądanej częstotliwości.
    Poza tym, po co Ci tablice dłuższe niż 256 bajtów przy rozdzielczości PWM 8 bitów. To w żaden sposób nie wpłynie na jakość generowanych sygnałów, przynajmniej tych podstawowych (sinus, trójkąt, piła). No chyba, że masz zamiar generować jakieś inne, skomplikowane przebiegi o małej powtarzalności cyklu.
    Z kolei mniejsze rozmiary tablicy też nie mają zbytnio zastosowania. Przy większych wartościach akumulatora i tak generowane są tylko niektóre próbki. Zaoszczędzisz może trochę flasha a skoplikujesz sobie znacznie program.
  • #5 8347367
    gnatho
    Poziom 10  
    Dzięki za konkretną odpowiedź. Potrzebuję tablic o większej wielkości, bo staram się zbudować quasi "syntezator" i muszę jakos odtwarzać sample. Z początku próbowałem rozwiązać to na przerwaniach i po prostu odczekiwać jakiś czas pomiędzy kolejnymi próbkami, ale niestety to nie dawało wymaganej dokładności nut. Zainteresowałem się DDSem i próbuje zmusić program to sczytywania większych tablic. Dzięki za wskazówki, postaram się coś wykombinować.
REKLAMA