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

Jak zaprogramować generowanie tonów na uC 8051 w asemblerze?

extreme-dh 12 Sty 2008 16:46 3167 6
REKLAMA
  • #1 4686166
    extreme-dh
    Poziom 2  
    Posty: 3
    Witam.

    Czy ktoś może podsunąć pomysł jak w asemblerze zaprogramować generowanie tonów o różnych częstotliwościach?

    Oczywiście chodzi mi o użycie buzzer'a. Jak uzyskać określony ton trwający zadaną liczbę milisekund.

    Byłbym wdzięczny za jakieś wskazówki i odrobinkę przykładowego kodu. :)
  • REKLAMA
  • Pomocny post
    #2 4686456
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    dwa timery - jeden sluzy jako generator (jego okres musi wiec wynosic polowe okresu tonu). drugi sluzy do wylaczania pierwszego po osiagnieciu zadanej wartosci (czyli do tego, zeby ton trwal ilestam czasu)

    w ASM max 30 linijek, wiec do dziela [;

    0x41 0x56 0x45!!
  • REKLAMA
  • Pomocny post
    #3 4686667
    Bigfoot
    Poziom 25  
    Posty: 982
    Pomógł: 74
    Ocena: 13
    Wystarczy jeden timer. Okres decyduje o czestotliwosci a dlugosc trwania dzwieku zrealizujesz zliczajac w jakiejs zmiennej liczbe tych okresow. W 8051 sa tylko 2 timery wiec szkoda ich marnowac na cos co nie jest konieczne.

    Lub najprosciej:
    
    while(1){
    PIN  = !PIN;
    delay_us(1000);
    }
    

    Wyjdzie 1kHz.

    BF
  • REKLAMA
  • #4 4709245
    extreme-dh
    Poziom 2  
    Posty: 3
    OK, Stworzyłem mniej więcej taki program, oczywiście prezentuję tylko przykładową część, ale czy to zadziała w taki sposób?

    
    	BUZZER	EQU P1.5
    	COUNT	EQU R0
    	
    	LJMP	START
    	ORG	100H
    	
    START:	
    	LCALL A1	;pierwszy ton
    	MOV A, #01	;przerwa
    	LCALL DELAY_100MS
    	
    	LCALL C2	;drugi ton
    	MOV A, #01	
    	LCALL DELAY_100MS
    	
    	LCALL E2	;trzeci ton
    	MOV A, #02	
    	LCALL DELAY_100MS
    	
    	LJMP START	;powtorka
    
    A1:	
    	MOV 	COUNT,#154 ;ILOSC ITERACJI
    	
    	CPL 	BUZZER
    	MOV	TH0, #251 ;STARSZY BAJT (251 * 256 = 64,256)
    	MOV	TL0, #233 ;MŁODSZY BAJT (64,256 + 233 = 64,489)
    	LCALL 	WAIT
    	
    	CPL 	BUZZER
    	MOV	TH0, #251 
    	MOV	TL0, #233
    	LCALL 	WAIT	
    
    	DJNZ	COUNT, A1 ;KOLEJNA ITERACJA
    	
    	RET
    
    	
    C2:	
    	MOV 	COUNT,#183
    	
    	CPL 	BUZZER
    	MOV	TH0, #252
    	MOV	TL0, #143 
    	LCALL 	WAIT
    	
    	CPL 	BUZZER
    	MOV	TH0, #252 
    	MOV	TL0, #143
    	LCALL 	WAIT	
    
    	DJNZ	COUNT, C2
    	
    	RET
    	
    E2:	
    	MOV 	COUNT,#231
    	
    	CPL 	BUZZER
    	MOV	TH0, #253
    	MOV	TL0, #69 
    	LCALL 	WAIT
    	
    	CPL 	BUZZER
    	MOV	TH0, #253 
    	MOV	TL0, #69
    	LCALL 	WAIT	
    
    	DJNZ	COUNT, E2
    	
    	RET			
    
    WAIT:	
    	MOV	TMOD,#01 ;USTAWIA TIMER 0 NA TRYB 16 BITOWY
    	SETB	TR0	 ;URUCHAMIA TIMER 0
    	JNB	TF0, $	 ;JESLI TIMER 0 NIE PRZEPELNIL SIE, CZEKA
    	CLR	TR0	 ;ZATRZYMUJE TIMER 0
    	RET
    
  • REKLAMA
  • #5 4709405
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    po co ci 3 takie same fragmenty kodu, skoro mozna to zrobic jednym i przekazywac mu poprzez 2 rejestry wartosc dla TIMERa?

    optymalizacja sie klania...

    0x41 0x56 0x45!!
  • #6 4709435
    extreme-dh
    Poziom 2  
    Posty: 3
    Jeśli chodzi Ci o te podprogramy A1, C2 i E2 to są wywoływane więcej razy niż widać na tym kodzie powyżej. Wydaje mi się że jest to lepsze rozwiązanie niż za każdym razem przypisywać rejestrom wartości za każdym wywołanie podprogramu. Co prawda mogę się mylić, jeśli tak proszę mnie poprawić
  • #7 4709518
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    mylisz sie. [;

    jesli twoim celem jest optymalizacja rozmiaru kodu, to nalezy tak zrobic jak pisalem. jesli mozna to zrobic jednym podprogramem i nic nie sugeruje zrobiebnia tego inaczej - tak wlasnie nalezy zrobic. a ze kod jest wywolywany wiecej razy? no i co z tego?

    jesli zas twoim celem jest optymalizacja szybkosci albo zuzycia energii, to twoj sposob jest mniej wiecej poprawny.

    zauwaz tez, ze w kazdym z podprogramow masz dwie czesci kodu, ktore sa identyczne, wiec moze wystarczyloby przesunac licznik petli o jeden w lewo (pomnozyc przez 2) i zrezygnowac z polowy kodu.

    0x41 0x56 0x45!!



    0x41 0x56 0x45!!

Podsumowanie tematu

✨ Dyskusja dotyczy programowania generowania tonów o różnych częstotliwościach na mikrokontrolerze 8051 w asemblerze, z wykorzystaniem buzzera. Proponowane rozwiązania obejmują użycie jednego lub dwóch timerów: jeden do generowania sygnału o okresie odpowiadającym połowie okresu tonu, drugi do określenia czasu trwania dźwięku. Przykładowy kod asemblerowy pokazuje implementację generowania trzech różnych tonów z wykorzystaniem rejestrów TH0 i TL0 do ustawiania wartości timera oraz pętli sterującej długością trwania tonu. Wskazano możliwość optymalizacji kodu poprzez stworzenie jednego podprogramu przyjmującego parametry częstotliwości i czasu trwania zamiast powielania podobnych fragmentów kodu. Dyskusja porusza także kwestie efektywności kodu pod kątem rozmiaru, szybkości działania i zużycia energii.
Wygenerowane przez model językowy.
REKLAMA