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

Sinusoida PWM, asambler, ATmega8

blood dwarf 08 Lut 2009 12:53 3566 12
  • #1 6120255
    blood dwarf
    Poziom 10  
    Witam
    Mam problem ze zrozumieniem kodu, oraz ze znalezieniem błędu w nim. Program (jak w temacie) napisany na ATmega8, ma służyć do generowania przebiegu sinusoidalnego za pomocą PWM z filtrem uśredniającym na wyjściu.
    Oto kod programu:
    
    .INCLUDE "m8def.inc"
    
    .CSEG
    .ORG $0400	
          SINUS: .db 128, 136, 144, 152, 160, 168, 175, 182, 190, 197, 203, 210, 216, 221, 227, 232, 236, 240, 244, 247, 250, 252, 254, 255, 256, 256, 256, 255, 254, 252, 250, 247, 244, 240, 236, 232, 227, 221, 216, 210, 203, 197, 190, 182, 175, 168, 160, 152, 144, 136, 128, 120, 112, 104, 96, 88, 81, 74, 66, 59, 53, 46, 40, 35, 29, 24, 20, 16, 12, 9, 6, 4, 2,1,0,0,0,1,2,4,6,9,12,16,20,24,29,35,40,46,53,59,66,74,81,88,96,104,112,120
    
    .ORG $0000	;reset
    
    			RJMP RESETaddr	;skok do programu po resecie
    
    .ORG $0009 
    			RJMP T0OVF	;skok do podprogramu z obsługą przerwania po przepełnieniu timera0
    
    .ORG $0013 
    RESETaddr:	LDI R16,High(RAMEND)	
    			OUT SPH,R16				
    			LDI R16,Low(RAMEND)
    			OUT SPL,R16			
    			LDI R16,1
    			OUT SFIOR,R16
    			SBI DDRB,1
    			
    			LDI R17,0x00		
    			OUT OCR1AH,R17		
    			LDI R17,0x00
    			OUT OCR1AL,R17
    			LDI R17,0x81
    			OUT TCCR1A,R17
    			LDI R17,0x09
    			OUT TCCR1B,R17
    			LDI R16,1 			
    
    			OUT TCCR0,R16		
    			LDI R16,1 			
    			OUT TIMSK,R16		
    			SEI				
    
    			LDI R18,100
    			LDI ZH,high(SINUS<<1)
    			LDI ZL,low(SINUS<<1)
    
    KONIEC:		RJMP KONIEC
    
    T0OVF:		LPM R16,Z+
    		LDI R17,0x00		
    		OUT OCR1AH,R17		
    		OUT OCR1AL,R16
    		CPSE R18,ZL
    		RETI
    		LDI ZH,high(SINUS<<1)
    		LDI ZL,low(SINUS<<1)
    		RETI				
    
    Nie rozumiem tych instrukcji:
    			LDI ZH,high(SINUS<<1)
    			LDI ZL,low(SINUS<<1)
    

    Wiem że to jakaś operacja na tablicy, ale prosiłbym o dokładne wytłumaczenie.
    Ponadto podczas generowania sinusa wyskakuje w pewnym momencie przerwa w generacji sygnału (tak jakby cofnięcie się do wcześniejszego elementu w tablicy). Byłbym wdzięczny za podanie powodu takiego zachowania. Z góry dziękuję za odpowiedź.

    Proszę używać znaczników [code] - uzupełniłem.
    [zumek]
  • #2 6120320
    ZbeeGin
    Poziom 39  
    Ładowanie do rejestru Z (indeks dla operacji LPM) adresu tablicy sinusa (bajtowej, dlatego to przesuwanie bitów). Poczytaj o organizacji pamięci w procesorach AVR to wszystko stanie się jasne.

    Zastanów się także co kompilator zrobi z tym:

    SINUS: .db (...) 254, 255, 256, 256, 256, 255, (...)

    Symulacja w AVR Studio Twoim przyjacielem.
  • #3 6120893
    blood dwarf
    Poziom 10  
    Jeśli chodzi o rejestr Z to już rozumiem. Chodzi tam o bajtową organizację pamięci i to że tablica przechowywana w 2 bajtach (nie wiem czy dobrze to teraz napisałem, ale wiem o co chodzi).

    Jeśli chodzi o ten przebieg, to przy wartości 256 rejestr R16 ulega przepełnieniu i przechowuje wartość 0. Z tego co widzę należało by przeskalować jeszcze raz wartości w tablicy tak, by maksymalnie wynosiła 255, albo zmienić tryb PWM na np. poprawnej fazy i częstotliwości, by wykorzystać starsze bity rejestru OCR1A.

    Proszę o potwierdzenie moich przypuszczeń, bo do końca nie jestem pewien słuszności mojego osądu :)

    P.S. Dziękuję za zainteresowanie i wskazanie właściwej drogi rozwiązania problemu.
  • #4 6120914
    Nawigator
    Poziom 33  
    Nie rozumiem tych instrukcji:
    LDI ZH,high(SINUS<<1)
    LDI ZL,low(SINUS<<1)
    Wiem że to jakaś operacja na tablicy, ale prosiłbym o dokładne wytłumaczenie
    Pod tym adresem jest pierwsza wartość PWM sinusa czyli tu 128, po przejściu cyklu musisz wrócić na początek tablicy.
    Brak w kodzie w przerwaniu push/pop SREG i instrukcja cpse r18, ZL głupieje.

    N.
  • #5 6121185
    ZbeeGin
    Poziom 39  
    blood dwarf. Lepiej jednak przeskalować dane sinusa, gdyż po przełączeniu w tryb Dual-Slope PWM musiałbyś też zmniejszyć częstość generacji przerwań z przepełnienia Timer0. Inaczej pewne wartości z tablicy by wypadły i PWM by nie miał szans ich wygenerować (mechanizm Glitch Free by zadziałał). I aby uzyskać taką samą częstotliwość sinusa na wyjściu taktowanie procesora trzeba by zwiększyć x2.

    Nawigator napisał:
    Brak w kodzie w przerwaniu push/pop SREG i instrukcja cpse r18, ZL głupieje.

    CPSE jak sama nazwa wskazuje (Compare and Skip if Equal) sama sobie porównuje operandy bez użycia znaczników. Zauważ też, że ona ich wogóle nie zmienia.
  • #6 6121361
    blood dwarf
    Poziom 10  
    Jeśli chodzi o SREG to utrzymuje on stałą wartość 0x3F, więc push/pop nic tutaj nie pomoże moim zdaniem (co prawda dopiero się uczę, więc mogę się mylić :) ).

    Dostęp do płytki i oscyloskopu będę miał dopiero po weekendzie, więc niestety mogę opierać się jedynie wynikami z symulatora. Ale po niedzieli sprawdzę co wyjdzie po przeskalowaniu tablicy. Gdyby jeszcze coś nie działało poprawnie to dam znać.

    Tymczasem bardzo dziękuję za pomoc i poświęcony czas. Pozdrawiam.
  • #7 6122000
    Nawigator
    Poziom 33  
    Rzeczywiście CPSE nie zmienia SREG, przeoczyłem, ale na etapie pisania kodu lepiej wstawić save SREG.
    Przyglądnąłbym się LPM r16, Z+ bo pamiętam miałem podobny problem z Z+ który działał tylko w zakresie jednego bajtu a tabela zaczyna się tutaj od 0x0400, musiałem użyć ADIW ZL, 1

    N.
  • #8 6122091
    ZbeeGin
    Poziom 39  
    Tu możemy użyć takiego uproszczenia, bo adres jest parzysty i w LSB ma pełne zero, a danych jest mniej niż 255. Zatem sprawdzenie czy Zl==100 (r18) jaki robi CPSE już po postinkrementacji w LPM dokładnie odliczy 100 przerwań.
  • #9 6163906
    jacek6666
    Poziom 11  
    Witam.
    A moze ma ktoś napisany program do ATmega8 lub attiny2313 do uzyskania sinusojdy (chodzi mi o taka do przetwórnicy).
    Pozdrawiam i prosze o odpowiedź.
  • #11 6163972
    jacek6666
    Poziom 11  
    Ten program nie nada sie raczej na przetwórnice
  • #13 6165287
    jacek6666
    Poziom 11  
    Ale przepraszam nic takiego nie pisalem. Ja sie tylko pytalem czy ma ktos a nie zeby mi napisal. A to jest różnica
REKLAMA