1 Sound
Pro generování tónů na pozadí potřebuju nějaký nepoužitý Timer a jeho pin, se kterým můžu kmitat.
Piny jsou použity všechny. Ale asi nejmíň to bude vadit na portu L, kde jsou adresy pro Shared RAM, kterou zrovna nepoužívám (až MHF bude grafickou kartou, tak to moc nepůjde).
Je to "zneužití", takže budeme předpokládat, že může být kdykoli odstřeleno, tudíž provedu inicializaci při každém spuštění a kdokoli kdykoli může spustit stop.
Princip
Frekvence na OC5A:
f_OUT = f_CPU / (2*N*(1+OCR5A))
a obráceně
OCR5A= f_CPU / (2*N*f_OUT) - 1
kde:
- f_CPU = 16 MHz
- N = prescaler
- OCR5A = compare registr
Použijeme prescaler 8, protože dobře vychází pro audio tóny.
;
; sound.S
; ATmega2560
; OC5A = PL3
;
#include <avr/io.h>
.global sound_init
.global sound_play
.global sound_stop
; ============================================================
; sound_init
; ============================================================
sound_init:
; PL3 / OC5A jako output
sbi DDRL, 3
; Timer stopped
ldi r16, 0
sts TCCR5A, r16
sts TCCR5B, r16
ret
; ============================================================
; sound_play
;
; vstup:
; r25:r24 = OCR5A hodnota
;
; ============================================================
sound_play:
// sound_init:
; PL3 / OC5A jako output
sbi DDRL, 3
// ; Timer stopped - rovnou ho rozebehnu o kousek niz
// ldi r16, 0
// sts TCCR5A, r16
// sts TCCR5B, r16
; nastavit compare value
sts OCR5AL, r24
sts OCR5AH, r25
;
; Toggle OC5A on compare match
;
; COM5A0 = 1
;
ldi r24, (1<<COM5A0)
sts TCCR5A, r24
;
; CTC mode
; WGM52 = 1
;
; prescaler = 8
; CS51 = 1
;
ldi r24, (1<<WGM52) | (1<<CS51)
sts TCCR5B, r24
ret
; ============================================================
; sound_stop
; ============================================================
sound_stop:
; stop timer
ldi r24, 0
sts TCCR5B, r24
; disconnect OC5A
sts TCCR5A, r24
; output low
cbi PORTL, 3
ret
2 Tabulka tónů
Pro F_CPU = 16 MHz, prescaler 8.
Tyto hodnoty dáváš do OCR5A.
; ; Tone table ; .equ NOTE_C4 = 3821 .equ NOTE_CS4 = 3607 .equ NOTE_D4 = 3405 .equ NOTE_DS4 = 3214 .equ NOTE_E4 = 3033 .equ NOTE_F4 = 2863 .equ NOTE_FS4 = 2702 .equ NOTE_G4 = 2551 .equ NOTE_GS4 = 2407 .equ NOTE_A4 = 2272 .equ NOTE_AS4 = 2145 .equ NOTE_B4 = 2024 .equ NOTE_C5 = 1911 .equ NOTE_D5 = 1702 .equ NOTE_E5 = 1516 .equ NOTE_F5 = 1431 .equ NOTE_G5 = 1275 .equ NOTE_A5 = 1136 .equ NOTE_B5 = 1012
Jak přehrát tón
Například A4 (440 Hz):
ldi r24, low(NOTE_A4) ldi r25, high(NOTE_A4) rcall sound_play
Jak tón vypnout
rcall sound_stop
3 HW
- Test na beeper 4312 zapojeny na Timer 1A pin D9 na Arduino Nano
- Zapojeni pin -- beeper -- +5V funguje
- Zapojeni pin -- emitor NPN , colector -- beeper -- +5V je hlasitejsi
- pridavani odporu to ztisuje, diodu to taky nepotrebuje.
Sound