Tranzystor pisze:Ja tam tylko zauważyłem, że on nie do końca składa wszystkie literki poprawnie. Mam nadzieję, że to jeszcze uda Ci się dopracować.
Żaden problem. Muszę tylko popoprawiać dane, gdyż wszystko da się podocinać jak trzeba. Niestety jak mówisz to wypowiadane sentencje akcentujesz, a tego wystkiego się nie da zaimplementować by mowa była doskonała - po prostu braknie pamięci.
Tranzystor pisze:No to pomyśl o jakimś sterowniku domu. Może zamontujesz go w ścianie i będziesz w nocy z nim gadał
Wolałbym spać w nocy niż słuchać opowieści w stylu "01:59", "02:00", "02:01" itd. Zatem program w godzinach nocnych mówić nie będzie, chyba, że jakiś nocny Marek sobie to tak skonfiguruje.
Tranzystor pisze:W takim razie jakie jest próbkowanie tego PWMa? Szczerze mówiąc dzięki Twojemu projektowi wpadłem na ciekawy pomysł Zobaczymy czy uda mi się go zrealizować.
Częstość podsyłania kolejnych wartości dobrałem eksperymentalnie.

Nie chciało mi się liczyć ile zajmie czasu transmisja przez TWI + przygotowywanie danych. Próbki były w 1995r. zresamplowane na 6kHz. Stąd nieco marna jakość dżwięku. Jakbym użył licznika do odliczania okresu t=1/6000Hz przy pzesyłaniu kolejnych bajtów to dzwięk byłby oryginalny.
Samo odtwarzanie jest krótkie i zwięzłe:
Kod: Zaznacz cały
;--------------------------------------------------------------
pwm_setup: ; teraz czas na generator PWM (jako przetwornik DAC)
ldi r16, (1<<CS00)|(1<<WGM00)|(1<<WGM01)|(1<<COM00)|(1<<COM01)
; preskaler 8, tryb PWM Fast, inverted mode
out TCCR0, r16
clr r16 ; OCR jest na poziomie 0
out OCR0, r16 ; zeruj rejestr
sbi DDRB, PORTB3 ; OCR0 jako wyjście
; koniec pwm
Kod: Zaznacz cały
;--i2c+odtwarzanie---------------------------------------------
_i2c_start:
ldi r24, (1 << TWINT)|(1 << TWSTA)|(1 << TWEN)
out TWCR, r24 ; włącz TWI, magistrala:START
rcall __wait_4_twiready ; czekaj aż wykona
ldi r24, 0b10100000 ; adres+zapis (SLA+W) + ACK
out TWDR, r24 ; z adresem 24C512 (A0.A1=0.0)
ldi r24, (1 << TWINT)|(1 << TWEN)
out TWCR, r24 ; wyślij teraz
rcall __wait_4_twiready ; czekaj aż wykona
out TWDR, YH ; poślij adres w pamięci H
ldi r24, (1 << TWINT)|(1 << TWEN)
out TWCR, r24 ; wyślij teraz
rcall __wait_4_twiready ; czekaj aż wyśle
out TWDR, YL
ldi r24, (1 << TWINT)|(1 << TWEN)
out TWCR, r24 ; wyślij teraz
; a my tymczasem...
lpm ; pobierz długość
mov YL, r0 ; najpierw młodszy
adiw ZL:ZH, 1 ;
lpm
mov YH, r0 ; teraz starszy i wpisz do licznika Y
rcall __wait_4_twiready ; czy TWI gotowe?
ldi r24, (1 << TWINT)|(1 << TWSTA)|(1 << TWEN)
out TWCR, r24 ; magistrala: RSTART
rcall __wait_4_twiready
ldi r24, 0b10100001 ; adres+odczyt (SLA+R) + ACK
out TWDR, r24 ;
ldi r24, (1 << TWINT)|(1 << TWEN)
out TWCR, r24 ; wyślij teraz
__play_loop:
ldi r24, (1 << TWINT)|(1 << TWEN)|(1 << TWEA)
out TWCR, r24 ; czytaj bajt z potwierdzeniem ACK
rcall __wait_4_twiready
in r24, TWDR ; przepisz odebraną wartość do R24
ldi r16, 127
add r24, r16 ; dodaj 127 bo dane są signed
out OCR0, r24 ; poślij do przetwornika
ldi r24, 65 ; odczekaj chwilę
__play_pause:
dec r24 ; licznik - 1
nop ; standard :)
nop
brne __play_pause
sbiw YL:YH, 1 ; zmniejsz licznik Y
brne __play_loop ; jak dalsze dane to skocz
ldi r24, (1 << TWINT)|(1 << TWEN)|(0 << TWEA)
out TWCR, r24 ; inaczej odczytaj bajt z NACK
rcall __wait_4_twiready
in r24, TWDR ; dana niepotrzebna - NACK się liczył
ldi r24, (1 << TWINT)|(1 << TWSTO)|(1 << TWEN)
out TWCR, r24 ; magistrala: STOP