Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

ATMEGA[BASCOM] Najprostsze odtwarzanie Wav .

adambehnke 14 Jan 2011 23:40 95049 328
Computer Controls
  • #271
    LordBlick
    VIP Meritorious for electroda.pl
    Duch__ wrote:
    A to koledzy widzieli? Wave file player

    Możliwość odtwarzania 8 bitowych plików (22ksps - stereo oraz 44ksps - mono)

    Właśnie testuje go na atmedze 644 i działa rewelacyjnie. Próbuje go przy okazji zoptymalizować do atmegi32, gdyż szkoda używać takiego olbrzyma jak 644.
    Phiiii... Szkoda takiego olbrzyma jak ATmega32 - look here :
    http://elm-chan.org/works/sd8p/report.html
    ;)
  • Computer Controls
  • #272
    heyka
    Level 17  
    Witam

    przy komilacji kodu z 9 strony tego watku otrzymuje komunikat o braku wolnej pamięci SRAM, jak sobie z tym poradzić?
  • #273
    PiotrEtenM500
    Level 19  
    Zmień układ na Atmega 32 lub większy, fat zabiera ponad 2kb!!!
  • #275
    heyka
    Level 17  
    Code:
    '-------------------------------------------------------------------------------
    
    '-------------------------------------------------------------------------------
    '--------WAV PLAYER-----16kHz 8bit mono-----------------------------------------
    '-------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------

    '$PROG &HFF,&HDF,&HDF,&H00' generated. Take care that the chip supports all fuse bytes.

    '---PROCESOR--------------------------------------------------------------------
    $regfile = "M32Def.dat"
    $crystal = 16000000
    $hwstack = 128
    $swstack = 64
    $framesize = 64
    $baud = 38400                                               ' use baud rate
    '-------------------------------------------------------------------------------


    '---DEKLARACJE ZMIENNYCH--------------------------------------------------------
    Dim Timer1_licznik As Byte
    Dim Buffer(256) As Byte At 1024
    Dim Write_position As Byte
    Dim Read_position As Byte
    Dim Write_position_word As Word
    Dim S As String * 36
    Dim A As Byte
    Dim B As Word
    Dim Volume As Byte
    Dim Mix(2) As Integer
    Dim Mixx As String * 3
    Dim Vol_val As String * 10
    '-------------------------------------------------------------------------------


    '---MOJE ZMIENNE TESTOWE--------------------------------------------------------


    Dim Play As Integer                                         'START/STOP ODTWARZANIA
    Dim Plik As String * 30                                     'NAZWA PLIKU DO OTWARCIA

    'UART
    Dim Uart_flaga As Integer
    Dim Uart_dane As String * 30

    '-------------------------------------------------------------------------------


    '---TIMER 1---------------------------------------------------------------------
    On Timer1 Timer1_handler Nosave
    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 1
    '-------------------------------------------------------------------------------
    Pwm1a = 129

    '---PORTY-----------------------------------------------------------------------
    Config Porta = &B00000000                                   'nc
    Config Portc = &B00000000                                   'nc
    Config Portb = &B00000110
    Config Portd = &B00100110                                   'OCR1A = Output

    Porta = &B00000000                                          'nc
    Portc = &B00000000                                          'nc
    'Portb = &B00000000
    Portd = &B00000000




    '-------------------------------------------------------------------------------


    '---PLIKI ZEWNĘTRZNE I BIBLIOTEKI-----------------------------------------------
    $include "CONFIG_AVR-DOS.Bas"
    '-------------------------------------------------------------------------------


    '---ZEGAR-----------------------------------------------------------------------
    Config Clock = Soft
    '-------------------------------------------------------------------------------


    '---UART------------------------------------------------------------------------
    Config Serialin = Buffered , Size = 20 , Bytematch = 13     'KONFIGURACJA PRZERWANIA OD UART-A
    '-------------------------------------------------------------------------------


    '---WATCHDOG---------------------------------------------------------------------------
    Config Watchdog = 1024                                      'reset wystąpi po 1024ms = 1s
    '-------------------------------------------------------------------------------


    '---SPI-HW----------------------------------------------------------------------
    Const Cmmc_soft = 0                                         'SPI HARDWARE

       ' define Chip-Select Pin
       Config Pinb.4 = Output                                   ' define here Pin for CS of MMC/SD Card
       Mmc_cs Alias Portb.4
       Set Mmc_cs

       ' Define here SS Pin of HW-SPI of the CPU (f.e. Pinb.0 on M128)
       Config Pinb.7 = Output                                   ' define here Pin of SPI SS
       Spi_ss Alias Portb.7
       Set Spi_ss                                               ' Set SPI-SS to Output and High por Proper work of
                                                      ' SPI as Master

       ' HW-SPI is configured to highest Speed
      Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1       'Config Spi = Soft , Din = Pinb.3 , Dout = Portb.2 , Ss = Portb.0 , Clock = Portb.1
       Spsr.0 = 1                                               ' Double speed on ATMega128
       Spiinit                                                  ' Init SPI

    'Spiinit
    ' Error
    Const Cperrdrivereset = 225                                 ' Error response Byte at Reset command
    Const Cperrdriveinit = 226                                  ' Error response Byte at Init Command
    Const Cperrdrivereadcommand = 227                           ' Error response Byte at Read Command
    Const Cperrdrivewritecommand = 228                          ' Error response Byte at Write Command
    Const Cperrdrivereadresponse = 229                          ' No Data response Byte from MMC at Read
    Const Cperrdrivewriteresponse = 230                         ' No Data response Byte from MMC at Write
    Const Cperrdrive = 231
    Const Cperrdrivenotsupported = 232                          ' return code for DriveGetIdentity, not supported yet
    Waitms 700
    Dim Gbdriveerror As Byte                                    ' General Driver Error register
    Dim Gbdriveerrorreg As Byte                                 ' Driver load Error-Register of HD in case of error
    Dim Gbdrivestatusreg As Byte                                ' Driver load Status-Register of HD on case of error
    Dim Gbdrivedebug As Byte
    $lib "MMC.LIB"                                              ' link driver library
    $external _mmc
    '-------------------------------------------------------------------------------


    '---WŁĄCZENIE PRZERWAŃ-------------------------------------------------
    Enable Interrupts
    '-------------------------------------------------------------------------------


    '---SD-INICJACJA KARTY I SYSTEMU PLIKÓW-----------------------------------------
    'B = Drivecheck()
    Gbdriveerror = Driveinit()
    B = Initfilesystem(1)
    '-------------------------------------------------------------------------------


    '---USTAWIENIA WSTĘPNE----------------------------------------------------------

    Set Portb.0                                                 'podciągnięcie do vcc klawisza TEST

    Plik = "helo.wav"
    Play = 0
    '-------------------------------------------------------------------------------


    '***********************ODCZYT USTAWIENIA POZIOMU GŁOŚNOŚCI*********************
    Readeeprom Volume , 5
    If Volume > 250 Then Volume = 15
    If Volume < 0 Then Volume = 0
    '*******************************************************************************

    Print "ONLINE:" ; Volume ; Chr(13);

    '---URUCHOMIENIE WATCHDOG-A----------------------------------------------------------------------------
    Start Watchdog                                              'uruchamiamy układ watchdog
    '-------------------------------------------------------------------------------
    Clear Serialin



    '---PĘTLA GŁÓWNA PROGRAMU-------------------------------------------------------
    Do

    'klawisz TEST"
    If Pinb.0 = 0 Then
       Waitms 20
       Bitwait Pinb.0 , Set                                     ' jak puscisz przycisk to dalej wykonuje program
       Plik = "test.wav"
       Play = 1
    End If


    If Uart_flaga = 1 Then Gosub Zatrzymanie
    If Uart_flaga = 1 Then Gosub Dekoder                        'SPRAWDZANIE CZY ODEBRANE DANE SĄ POPRAWNE

    If Play = 0 Then Portb.1 = 0                                'Używam sobie tego podczas testów
    If Play = 1 Then Portb.1 = 1                                'Używam sobie tego podczas testów
    If Play = 0 Then Portb.2 = 1                                'Używam sobie tego podczas testów
    If Play = 1 Then Portb.2 = 0                                'Używam sobie tego podczas testów
    If Play = 1 Then Gosub Odtwarzacz                           'ZEZWOLENIE I SKOK DO ODTWARZANIA



    Reset Watchdog                                              'resetujemy watchdoga
    Loop
    '-------------------------------------------------------------------------------
    End                                                         'KONIEC PROGRAMU PRZY OPUSZCZENIU PĘTLI GŁÓWNEJ


    Zatrzymanie:

    'Zatrzymanie odtwarzania do czasu rozpoznania danych
       For Write_position_word = 1 To 256                       'czyszczenie bufora
       Buffer(write_position_word) = 128
       Next Write_position_word
       Disable Timer1                                           'zatrzymanie timera1
       Close #2
       Start Watchdog
    Return


    '---DEKODOWANIE ODEBRANYCH DANYCH Z UART-A--------------------------------------
    Dekoder:


    If Right(uart_dane , 4) <> ".wav" Then Goto Clp

       Plik = Uart_dane                                         'NAZWA PLIKU DO ODTWORZENIA
       Play = 1                                                 'ZEZWOLENIE NA SKOK DO ODTWARZANIA

       Clp:
       Uart_dane = ""
       Uart_flaga = 0
       Clear Serialin

    Return
    '-------------------------------------------------------------------------------



    '---ODTWARZACZ------------------------------------------------------------------
    Odtwarzacz:
    Stop Watchdog

    Open Plik For Binary As #2

    Pwm1a = 129

    For Write_position_word = 1 To 256
    Get #2 , Buffer(write_position_word)
    Next Write_position_word

    For Write_position_word = 1 To 256
    Get #2 , Buffer(write_position_word)
    Next Write_position_word


    Write_position = 0
    Enable Timer1



    Do
        If Write_position <> Read_position Then
            Get #2 , A

            lds R16, {A}
            subi R16, 128
            lds R17, {Volume}                                   'Od 0 do 255
            mulsu R16, R17
            mov R16, R1
            subi R16, 128

            ldi R27, 4                                          '<------------------- Starsza połówka adresu bufora. Np. 4 = High(1024)
            lds R26, {Write_position}
            st X+, R16
            sts {Write_position}, R26

        End If

        If Play = 0 Then Goto Stp                               'Nagły stop odtwarzania

    Loop Until Eof(#2) <> 0

    Stp:
    For Write_position_word = 1 To 256                          'czyszczenie bufora
    Buffer(write_position_word) = 129
    Next Write_position_word

    Play = 0                                                    'wstrzymanie odtwarzania
    Disable Timer1                                              'zatrzymanie timera1
    Close #2                                                    'ZAMKNIĘCIE PLIKU

    Start Watchdog
    Return
    '-------------------------------------------------------------------------------



    '---PRZERWANIE OD TIMERA 1------------------------------------------------------
    Timer1_handler:
      push R16
      In R16, SREG
      push R26
      push R27

      lds R26, {Timer1_licznik}
      inc R26
      sts {Timer1_licznik}, R26
      cpi R26, 2
      brlo R26_mniejsze_2
          ldi R26, 0
          sts {Timer1_licznik}, R26

          ldi R27, 4                                            '<------------------- Starsza połówka adresu bufora. Np. 4 = High(1024)
          lds R26, {Read_position}
          ld R27, X+
          !Out OCR1AH, R27
          !Out OCR1AL, R27

          sts {Read_position}, R26
      R26_mniejsze_2:

      pop R27
      pop R26
      !Out SREG, R16
      pop R16
    Return
    '-------------------------------------------------------------------------------



    '---PRZERWANIE OD UART-A--------------------------------------------------------
    Serial0charmatch:

    Play = 0

    Input Uart_dane Noecho                                      'ODBIÓR DANYCH Z UART-A


    'VOLUME
    If Left(uart_dane , 4) = "vol:" Then
       Mix(1) = Len(uart_dane)                                  'całkowita długość odebranych danych z początkiem vol:
       Mix(2) = Mix(1) - 4                                      'całkowita długość wartości do wstawienia do volume
       Mixx = Mid(uart_dane , 5 , Mix(2))
       Volume = Val(mixx)
       If Volume < 0 Then Volume = 0
       If Volume > 250 Then Volume = 250
       Writeeeprom Volume , 5                                   'zapis poziomu głośności do pamięci eeprom
    End If

    'STOP
    If Uart_dane = "stop" Then                                  'JEŚLI ODEBANO STOP TO WSTRZYMAJ ODTWARZANIE
       Play = 0 : Uart_dane = ""
       Clear Serialin
    End If

    'RESET
    If Uart_dane = "reset" Then
       Uart_dane = ""

       For Write_position_word = 1 To 256                       'czyszczenie bufora
       Buffer(write_position_word) = 129
       Next Write_position_word

       Play = 0                                                 'wstrzymanie odtwarzania
       Disable Timer1                                           'zatrzymanie timera1
       Close #2                                                 'ZAMKNIĘCIE PLIKU

       Gosub Reset_systemu
    End If

    'ZAPYTANIE O POZIOM GŁOŚNOŚCI
    If Uart_dane = "vol_val" Then                               'SPRAWDZANIE AKTUALNEGO POZIOMU GŁOŚNOŚCI

       Vol_val = "vol_val:" + Str(volume)
       Print #4 , Vol_val ; Chr(13);
       Clear Serialin

    End If

    Uart_flaga = 1                                              'FLAGA INFORMUJĄCA ŻE ODEBRANO DANE

    Clear Serialin
    Return
    '-------------------------------------------------------------------------------



    '---PĘTLA POWODUJĄCA ZAPLANOWANY I CELOWY RESET SYSTEMU-------------------------
    Reset_systemu:
    Start Watchdog
       For Write_position_word = 1 To 256                       'czyszczenie bufora
       Buffer(write_position_word) = 129
       Next Write_position_word

       Play = 0                                                 'wstrzymanie odtwarzania
       Disable Timer1                                           'zatrzymanie timera1
       Close #2
    Do
    'Pusta pętla spowoduje reset wywołany przepełnieniem watchdoga
    Loop
    Return

    To jest cały kod, procesor atmega 32, jak zmienie na 64 wszystko jest ok.
  • #277
    heyka
    Level 17  
    Nie wiem ile RAMU brakuje, w jaki sposob to sprawdzić?

    Dodano po 11 [minuty]:

    Tak się zastanawiam, a nie dalo by się zrobić takiego odtwarzacza np na atemega8, cos to nie tak że Atmega 32 sobie z tym nie radzi :(
  • Computer Controls
  • #279
    heyka
    Level 17  
    Error:22 Line 121 Out of SRAM space, in File : D:\... ścierzka dostępu....\config_AVR-DOS.bas

    tak wyglada cały komunikat błedu

    Dodano po 12 [minuty]:

    wstawilem do projektu zmodyfikowany plik avr-dos (podany w tym watku) i sie skompilowalo, czas na budowe urzadzenia

    Dodano po 5 [godziny] 54 [minuty]:

    Zależy mi aby program był pisany w Bascomie a z tego co przeglądałem odtwarzacz na atemega 8 nie jest pisany w Bascomie.
  • #280
    atom1477
    Level 43  
    heyka wrote:
    Error:22 Line 121 Out of SRAM space, in File : D:\... ścierzka dostępu....\config_AVR-DOS.bas

    tak wyglada cały komunikat błedu

    Chm, kiedyś chyba wypisywało o ile przekroczyło rozmiar RAMu. A w pliku informacyjnym nic nie pisze?

    heyka wrote:
    Zależy mi aby program był pisany w Bascomie a z tego co przeglądałem odtwarzacz na atemega 8 nie jest pisany w Bascomie.

    No to się zdecyduj, chcesz żeby to się zmieściło w ATMega8, czy chcesz żeby to było w BASCOMie. Bo tych dwóch rzeczy nie pogodzisz (Wykorzystując oryginalną bibliotekę AVRDOS z BASCOMa. Z własną biblioteką to oczywiście dało by się i w BASCOMie.).
  • #281
    heyka
    Level 17  
    Chciałbym żeby działało na Atemega8, niestety nie jestem w tym aż tak biegły żeby napisac własną bibliotekę, dlatego będę musiał pozostać przy avr-dos, zastosowałem zmienioną bibliotekę avr-dos która była dostępna w tym wątku i program się skomilował.
    Mam nadzieję że zadziała, jak uruchomie to się pochwalę.
    Serdeczne dzieki za zainteresowanie i pomoc w temacie. Pozdrawiam
  • #282
    misiekdg
    Level 13  
    Mam problem z tym układem... w głosniku słychać pisk i jakies "lekkie" przebicia dziwnych dzwięków pasujących do pliku jaki wrzucę na kartę. Transmisja z kartą jest poprawna, na oscyloskopie widać jak przesyłane są informacje. ustawiałem stałą wartość głośności, testowałem rózne pliki równiez ten umieszczony wczesniej w tym temacie na 100% sprawny, próbowałem wszyskich kodów i na wszystkich mam to samo, tak jakby PWM nie działał tak jak powinien, zmieniałem tez na fastPwm ale bez rezultatu, zmienił sie tylko ton pisku. Testowałem na dwóch AtMega32 i jednej AtMega32a... Nie wiem gdzie szukać problemu?
  • #283
    LordBlick
    VIP Meritorious for electroda.pl
    misiekdg wrote:
    Mam problem z tym układem... w głosniku słychać pisk i jakies "lekkie" przebicia dziwnych dzwięków pasujących do pliku jaki wrzucę na kartę. Nie wiem gdzie szukać problemu?
    Zbyt niska częstotliwość nośna (podstawowa) PWM...
  • #284
    WOBI
    Level 19  
    misiekdg wrote:
    Mam problem z tym układem... w głosniku słychać pisk i jakies "lekkie" przebicia dziwnych dzwięków pasujących do pliku jaki wrzucę na kartę. Transmisja z kartą jest poprawna, na oscyloskopie widać jak przesyłane są informacje. ustawiałem stałą wartość głośności, testowałem rózne pliki równiez ten umieszczony wczesniej w tym temacie na 100% sprawny, próbowałem wszyskich kodów i na wszystkich mam to samo, tak jakby PWM nie działał tak jak powinien, zmieniałem tez na fastPwm ale bez rezultatu, zmienił sie tylko ton pisku. Testowałem na dwóch AtMega32 i jednej AtMega32a... Nie wiem gdzie szukać prblemu?


    Masz nieustawione fuse bity i nie taktujesz procesora właściwą częstotliwością, sam piszesz że wgrywasz pliki z tego wątku, a pliki i programy są dobre i działaja więc błąd leży tylko po Twojej stronie, niewłaściwie zaprogramowanego procesora. Dużo postów na tym forum jest właśnie związanych ze złym taktowaniem procesora, źle ustawione FUse bit a w prodedurach krytycznych czasowo od których zależy prawidłowe działanie programu tak sie dzieje że źle działa prawidłowo napisany program.
  • #285
    arktik1
    Level 27  
    Witam.
    Złożyłem to na Atmega 32 i działa super.
    Zastanawiam się, czy można użyć do tego Atmega 328p dip28 :?:
    W końcu jest mniejsza gabarytowo. :D
  • #287
    arktik1
    Level 27  
    Jaki można najlepszy dźwięk tym odtworzyć?
    32.000 kHz, 8 bit, trochę szumi.
  • #288
    idla
    Level 2  
    Kochani, kompilator (1.11.8.6) wyrzuca błąd:
    22 Line : 120 Out of SRAM space , in File : C:\PROGRAM FILES\MCS ELECTRONICS\BASCOM-AVR\CONFIG_AVR-DOS.Bas.
    Pozdrawiam i proszę o pomoc.
    idla
  • #289
    elektryk101
    Conditionally unlocked
    idla wrote:
    Kochani, kompilator (1.11.8.6) wyrzuca błąd:
    22 Line : 120 Out of SRAM space , in File : C:\PROGRAM FILES\MCS ELECTRONICS\BASCOM-AVR\CONFIG_AVR-DOS.Bas.
    Pozdrawiam i proszę o pomoc.
    idla

    Jakiego procesora używasz w $regfile ?
    Błąd dotyczy małej ilości Ram-u.
  • #291
    idla
    Level 2  
    Atmega32. Ustawiłem Atmega64 i poszło.
    Dzięki
  • #292
    FastProject
    Level 28  
    Witam,
    zamierzam wykonać sobie ten player i próbuje zrozumieć oraz zmienić kod dla swoich potrzeb. Mam pytania mianowicie:
    1. Dlaczego w podprogramie Odtwarzacz dwukrotnie wykonuje się odczyt:
    Code: basic4gl
    Log in, to see the code


    2. Czy zamiast Get #2 może być Get #1? Czym wybór kanału został tu uzależniony?

    3. Czy sprawdzał ktoś kod kolegi WOBI z tego postu https://www.elektroda.pl/rtvforum/viewtopic.php?p=7817283#7817283

    4. C.d.n.
  • #294
    FastProject
    Level 28  
    Dziękuje za szybką odpowiedź.

    Ad. 1. No tak po to gdzieś było napisane aby na początku pliku dodać krótką ciszę aby uzupełnić do tych początkowych 256B.
  • #295
    WOBI
    Level 19  
    Przecież Get dotyczy otwieranego pliku, konkretnie funkcji w bibliotece, poczytaj o bascomdos.
    Code:
    Open Plik For Binary As #1 


    Get i tu numer dotyczy numeru otwartego pliku nie wiem dlaczego wątpisz, poprostu wszystkie odniesienia do obsługi pliku muszą mieć ten sam numer, jeśli używasz 5 to wszędzie będzie #5 a jeśli będzie 1 to wszędzie #1.

    W moim przykładzie używam #1 jakbyś nie zauważył...

    A mój kod działa, wystarczy wgrać do procka i sprawdzić czy to aż tak trudne :) to nie boli. A omijanie nagłówka jest prosto zrobione wystarczy zobaczyć w moim przykładzie. Czy tak trudno sobie poeksperymentować i coś przy okazji się nauczyć? ;)
  • #296
    FastProject
    Level 28  
    WOBI wrote:
    Przecież Get dotyczy otwieranego pliku, konkretnie funkcji w bibliotece, poczytaj o bascomdos.
    Code:
    Open Plik For Binary As #1 


    Get i tu numer dotyczy numeru otwartego pliku nie wiem dlaczego wątpisz, poprostu wszystkie odniesienia do obsługi pliku muszą mieć ten sam numer, jeśli używasz 5 to wszędzie będzie #5 a jeśli będzie 1 to wszędzie #1.

    W moim przykładzie używam #1 jakbyś nie zauważył...

    Tak myślałem i zauważyłem to dlatego pytam. Wolałem spytać i zrozumieć niektóre sprawy, żeby później nie popełniać i nie pytać o głupoty.

    WOBI wrote:
    A mój kod działa, wystarczy wgrać do procka i sprawdzić czy to aż tak trudne :) to nie boli. A omijanie nagłówka jest prosto zrobione wystarczy zobaczyć w moim przykładzie. Czy tak trudno sobie poeksperymentować i coś przy okazji się nauczyć? ;)

    Nie jest to trudne i właśnie to robię. Jednak nie kopiuje słowo w słowo niczyjego kodu. Jedynie posługuje się kodami w celu zrozumienia tematu. Na ich bazie buduje i piszę własne programy.

    P.S. Jak długo trwa wywołanie inicjalizacji karty (Gbdriveerror = Driveinit() ) może to być kilka sekund w przypadku gdy nie ma podłączonej karty? Pytam, bo jeszcze nie mam katy a trwa to dosyć długo.

    Niedługo dam znać o wynikach eksperymentów. Dziękuje za odpowiedzi i podpowiedzi.
  • #298
    FastProject
    Level 28  
    Dzięki za potwierdzenie. U mnie też jest to coś koło tego, nie mierzyłem dokładnie bo dorwałem kartę.

    Podsumowując układ z programem kolego WOBI działa bardzo fajnie na ATmega32, nie słychać żadnych trzasków, nie ma zawieszeń. Jako wzmacniacz wykorzystałem układ LM4871 z funkcją Shutdown pozwalającą zrealizować funkcję MUTE w player-ku.
  • Helpful post
    #300
    FastProject
    Level 28  
    No więc właśnie przydałby ci się ten LM4871 (3W dla 4 Ohm) lub podobny w którym pin Shutdown pozwala i na oszczędność baterii i na wyciszenie głośnika w przerwach w odtwarzaniu.