Dźwięk z ATMEGA8

Tutaj mozesz poruszać tematy ogólne powiązane z elektroniką, np. dyskusje na temat podzespołów, układów, zasad ich działania. Czyli można pisać o wszystkim czego nie da się przyporządkować do innych działów.
Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Dźwięk z ATMEGA8

Post autor: Aro » 06 gru 2006, 19:02

Mam problem z utworzeniem dźwięku w bascomie. "Piski" przetwarza płytka piezo. To jest program jaki próbowałem uruchomic.

Kod: Zaznacz cały

Dim B As byte
Config Pind.3 = Output
Config Timer1 = Timer , Prescale = 8 , Clear Timer = 1 , Compare A = Toggle
Enable Timer1 
Enable Interrupts   
Do
     For A = 0 To 21 Step 1      
      B = Lookup(a , Mel)     'wczytaj wartośc z tablicy stałych
      Compare1a = B           ' załaduj do compare1a
      Waitms 100
    Next
  Loop

Mel:
Data 50 , 10 , 60 , 10 , 50 , 10 , 60 , 10 , 50 , 10 , 60 , 10 , 50 , 10 , 60 , 50 , 50 , 10 , 60 , 10 , 50 , 10
Zamiast takiej melodii słychac jej pourywane fragmenty. Może jest jakaś gotowa funkcja w bascomie?

Awatar użytkownika
Brzozza93
Użytkownik
Posty: 474
Rejestracja: 26 cze 2006, 17:35
Lokalizacja: Gdynia
Kontakt:

Post autor: Brzozza93 » 06 gru 2006, 21:18

Co prawda nie programuję procesorów ale oto co znalazłem w dokumentacji bascoma:

Funkcja SOUND

Przeznaczenie:

Wysyła ciąg impulsów na wybraną końcówkę portu.

Składnia:

SOUND pin , il_impulsów , czas_impulsu

gdzie:

pin nazwa końcówki portu będącą linią wyjściową,
il_impulsów ilość generowanych pełnych impulsów,
czas_impulsu czas trwania pojedynczego impulsu.
Opis:

Gdy do podanej linii portu dołączony będzie głośniczek lub buzzer, można użyć instrukcji SOUND w celu generacji pojedynczych tonów.

Końcówka portu jest ustawiana w stan 0 i 1 w czasie trwania pełnego impulsu. Czas trwania tej sekwencji jest określony parametrem czas_impulsu. Liczba tych impulsów jest określona jako drugi parametr.

Uwaga! Instrukcja SOUND nie jest przeznaczona do generowania przebiegów o określonej częstotliwości. W tym celu najlepiej użyć przerwań jednego z sprzętowych liczników.


Przykład:

Kod: Zaznacz cały

Sound Portb.1 , 10000, 10       'generuj jakiś dźwięk

End

K_o_n_r_a_d
Użytkownik
Posty: 123
Rejestracja: 29 lip 2005, 10:21
Lokalizacja: Lublin

Post autor: K_o_n_r_a_d » 07 gru 2006, 1:06

Bascomowe SOUND z kilku powodów nie jest najlepszym rozwiązaniem do generowania melodyjek.

A co do przedstawionego kodu to przede wszystkim podaj jaką masz częstotliwość zegara. Twój kod wygląda poprawnie.

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 07 gru 2006, 13:29

Według mnie ten kod też jest poprawny, ale w praktyce jest troche inaczej. Jak masz możliwośc to wypróbuj jak to chodzi, a jak nie to prześle w załączniku nagranie mp3 tego "czegoś". Wypróbrubuje jeszcze sound, może będzie lepsza. K_o_n_r_a_d czemu sądzisz że to kiepski pomysł?

[ Dodano: 2006-12-07, 13:36 ]
zegar 1MHz RC wewnętrzny

K_o_n_r_a_d
Użytkownik
Posty: 123
Rejestracja: 29 lip 2005, 10:21
Lokalizacja: Lublin

Post autor: K_o_n_r_a_d » 07 gru 2006, 16:42

Uwaga! Instrukcja SOUND nie jest przeznaczona do generowania przebiegów o określonej częstotliwości. W tym celu najlepiej użyć przerwań jednego z sprzętowych liczników.

(c) Zbigniew Gibek, 2002-2005 (c) MCS Electronics, 1999-2005
SOUND nie korzysta z przerwań, więc jest mało precyzyjny, gdy w trakcie dzwięku pojawi się przerwanie bedzie przerywało (zależnie od czasu wykonywania przerwania). Zatrzymuje cały program, gdy generuje dzwięk (akurat w Twoim przypadku to nie ma znaczenia bo i tak robisz opóźnienia poprzez WAIT).

Możesz zamieścić nagranie swoich pisków. :) Jestem ciekawy co z tego wychodzi. Jak znajdę chwilę czasu to sprawdzę to u siebie i zamieszcze wyniki doświadczeń.

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 07 gru 2006, 18:37

przy takich wartościach wygląda to tak - załącznik

Kod: Zaznacz cały

Mel:
Data 1 , 100 , 1 , 100 , 50 , 1 , 50 , 1 , 50 , 1 , 50 , 1 , 50 , 1 , 50 , 1 , 50 , 1 , 50 , 1 , 50 , 1
[/code]
Załączniki
pipipi.rar
(253.99 KiB) Pobrany 515 razy

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 07 gru 2006, 23:49

Masz funkcje obsługi przerwania z Timera1 ? Jeśli nie - wyłącz jego przerwanie. To nie jest potrzebne aby działało PWM.

Awatar użytkownika
marcing
Użytkownik
Posty: 868
Rejestracja: 14 lut 2006, 14:13
Lokalizacja: z pociągu...
Kontakt:

Post autor: marcing » 08 gru 2006, 8:25

Problem jest jeszcze w tym, że program (i wpisywanie danych do rejestru porównania) nie jest w jakimkolwiek stopniu zsynchronizowany z licznikiem...
Może się zdażyć sytuacja, gdzie dane zostaną nadpisane jeszcze przed wpisaniem ich do rejestru porównania (z bufora).
Wszystko zależy od czasu wykonania pętli jak wyżej... A w tejże jest dodatkowo polecenie "WAITMS" - rozbija to całkiem synchronizację...

W programie brak deklaracji zmiennej "A"

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 08 gru 2006, 17:03

:arrow: marcing Prohram nie jest kompletny, bo przenosiłem fragmenty kodu(cały sie nie zmieścił- nie chciało wysłac) . Z tą synchronizacją to by pasowało bo dźwięk jest niestabilny przy instrukcji waitms, a dobrze odtwarzaprzy instrukcji wait(tylko za wolno!). Jest sposób żeby temu zaradzic?
:arrow: Koppel Przerwanie zablokowac poleceniem disable timer1?

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 08 gru 2006, 18:15

Aro pisze:Przerwanie zablokowac poleceniem disable timer1?
Po prostu usuń linię

Kod: Zaznacz cały

Enable Timer1
Brakuje mi poza tym tutaj

Kod: Zaznacz cały

Start Timer1
Może już sama konfiguracja albo włączanie przewania uruchamia licznik? Dawno nie korzystałem z Bascoma...

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 08 gru 2006, 19:36

próbowałem, próbowałem i nic ! Ciągle to samo. Chyba będe zmuszony użyc

Kod: Zaznacz cały

for
toggle potrd.3
waitus 100
next
...
...

W załączniku przesyłam cały program, którym się posługiwałem do wytworzenia tej melodii. Instrukcja sound wogóle nie działała.
Załączniki
Mellody.rar
(465 Bajtów) Pobrany 232 razy

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 08 gru 2006, 20:25

Jedna rzecz jest dla mnie niejasna. Tworzysz tak na prawdę generator PWM. Wartość wpisywana do rejestru odpowiada za wypełnienie impulsów. Jak to ma grać melodyjkę? Będzie cały czas ta sama częstotliwość, tylko głośność inna (no dobrze, brzmieć będzie to trochę inaczej, bo zmienia się zawartość wyższych harmonicznych, ale częstotliwość podstawowa pozostaje bez zmian).

Powinieneć w chwili porównania zerować zawartość timera. Spróbuj w konfiguracji timera 1 dodać opcje CLEAR TIMER = 1. Nie wiem tylko, czy będzie to dobrze działało z automatycznym zmienianiem stanu portu. Jeśli nie - dodaj i aktywuj przerwanie na porównanie i w jego obsłudze zmieniaj stan portu. Chociaż nie wydaje mi się aby to było konieczne.

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 08 gru 2006, 20:48

Przecież jest polecelnie czyszczenia i kiedy compare1a=timer1 to zeruje timer1

K_o_n_r_a_d
Użytkownik
Posty: 123
Rejestracja: 29 lip 2005, 10:21
Lokalizacja: Lublin

Post autor: K_o_n_r_a_d » 08 gru 2006, 21:57

Koppel pisze:Jedna rzecz jest dla mnie niejasna. Tworzysz tak na prawdę generator PWM. Wartość wpisywana do rejestru odpowiada za wypełnienie impulsów. Jak to ma grać melodyjkę? Będzie cały czas ta sama częstotliwość, tylko głośność inna (no dobrze, brzmieć będzie to trochę inaczej, bo zmienia się zawartość wyższych harmonicznych, ale częstotliwość podstawowa pozostaje bez zmian).

Powinieneć w chwili porównania zerować zawartość timera. Spróbuj w konfiguracji timera 1 dodać opcje CLEAR TIMER = 1. Nie wiem tylko, czy będzie to dobrze działało z automatycznym zmienianiem stanu portu. Jeśli nie - dodaj i aktywuj przerwanie na porównanie i w jego obsłudze zmieniaj stan portu. Chociaż nie wydaje mi się aby to było konieczne.
Chyba jednak nie przeczytałeś dokładnie programu. W tym przypadku wypełnienie będzie zawsze 50% a będzie się zmieniała częstotliwość.

Taki kod u mnie działa bardzo ładnie (nawet sie pokusiłem o policzenie odpowiednich częstotliwości dla odpowiednich tonów) :):

Kod: Zaznacz cały

$regfile = "m8def.dat"
$crystal = 4000000
Pwm1a = 0
Config Timer1 = Timer , Prescale = 8 , Compare A = Toggle , Clear Timer = 1

Do
   Pwm1a = 956
   Start Timer1
   Waitms 500
   Stop Timer1
   Pwm1a = 851
   Start Timer1
   Waitms 500
   Stop Timer1
   Pwm1a = 758
   Start Timer1
   Waitms 500
   Stop Timer1
   Pwm1a = 716
   Start Timer1
   Waitms 500
   Stop Timer1
   Pwm1a = 638
   Start Timer1
   Waitms 500
   Stop Timer1
   Pwm1a = 568
   Start Timer1
   Waitms 500
   Stop Timer1
   Pwm1a = 506
   Start Timer1
   Waitms 500
   Stop Timer1
   Wait 4
Loop
End
A nawet tego: START TIMER1 i STOP TIMER1 nie trzeba dawać.

Awatar użytkownika
Aro
Użytkownik
Posty: 677
Rejestracja: 30 paź 2006, 18:49
Lokalizacja: Świerczyniec | Wrocław
Kontakt:

Post autor: Aro » 09 gru 2006, 11:47

Działa poprawnie, ale... tylko wolno. Jak dam wszędzie waitms 100 to już wariuje. Nie da się tego jakoś przyspieszyc?

ODPOWIEDZ