Forum: Mikrocontroller und Digitale Elektronik ton erzeugen, frequenz aendern, mega8


von kitesurfer1404 (Gast)


Lesenswert?

moin moin,
nachdem ich hier zu meinen letzten projekten so gute hilfe bekommen 
habe, versuch ich es gleich nocheinmal.
leider konnte ich bisher nichts passendes im forum finden.

mein aufbau:
mega8 an 5V, kleiner lautsprecher an D0 und masse.

idee:
ton ausgeben (rechteck-signal mit timer)
frequenz während der ton ausgegeben wird erhöhen. anfangsfrequenz: 
500Hz, endfrequenz: 1650Hz
zeit, in der der ton erhöht werden soll: 1s

mein ansatz:
timer1 schaltet den pin high/low
timer0 erhöht das timer-register, damit die frequenz höher wird.

einzelne töne kann ich ausgeben, kein ding. also nichts mit 
"wackelkontakt und co"
die timer funktionieren auch beide. hab mit beiden töne produziert. nur 
das zusammenspiel... s.u.

problem (vermutung):
leider kommt kein ton, wenn ich die interrupt-zeit von timer1 
verkleiner.
ich glaube, es liegt daran, dass timer0 das timer1 register um 700 
schritte erhöhen muss, um von ton 500Hz zu ton 1650Hz zu kommen. naja, 
700 pro sekunde ist ja im bereich des interrupts von timer1. daher 
scheinen sich beide zu überschneiden. am lautsprecher kommt ein ganz 
leises, tiefes summen.

meine fragestellung:
wie kann ich den ton von 500Hz innerhalb von 1s auf 1650Hz erhöhen?
(anwendungsbereich soll eine sirene sein)
ich denke mal, dass ich das umgekehrt (1650 -> 500Hz) hinbekomme, wenn 
mir hiermit weitergeholfen wird.

prescale:
timer1: 1
timer0: 8

hier etwas code:

main:
[...] config kram

ldi freq_l, LOW(64535)  ;500Hz-ton
ldi freq_h, HIGH(64535)

loop:
rjmp loop


TIM1_OVF:      ; timer1 overflow interrupt
  swap port_reg    ;signal-bits: ein/ausschalten
  out PORTB, port_reg  ;ausgabe am PORTB

  ; Timer1 wieder aufladen
  out TCNT1h,tmrH
  out TCNT1l,tmrL
reti

TIM0_OVF:
  dec temp  ;erst nach 15 mal interrupts weiter, dann ton ändern (damit 
700 änderungen pro sekunde)
  tst temp
  breq weiter1
  reti    ;gleich raus

  weiter1:
  mov temp, tmr  ;tmr ist 15 (multiplikator für die interrupt-runden^^
  rjmp wail_load  ;timer1 aktualisieren


wail_load:
  adiw freq_l, 1    ;frequenz_timer (low) um 1 erhoehen
  mov tmrH, freq_h
  mov tmrL, freq_l
reti



wäre schön, wenn ihr mir auf die sprünge helfen könntet.
schönes martin-horn kann "sie" schon - jetzt soll sie amerikanisch 
lernen ;)

von Otto (Gast)


Lesenswert?

Du initialisierst und lädst "temp" nie....

Otto

von kitesurfer1404 (Gast)


Lesenswert?

oh, sry. das passiert ganz am anfang. [...] ;-)
ist also schon mit 15 "geladen"

so würde/sollte es auch nur einmal durchlaufen und den ton endlos 
erhöhen, weil kein ende abgefragt wird.
das ist später natürlich nicht so.
aber es fängt ja nichtmal an, töne zu machen

von Otto (Gast)


Lesenswert?

ja nee - nach "dec" ist es irgendwann 0 und DANN 255
Otto

von kitesurfer1404 (Gast)


Lesenswert?

aber dann:

tst temp
  breq weiter1

und bei weiter1:
 mov temp, tmr

und tmr ist konstant bei 15. wird nur hier verwendet.
da wird temp wieder "aufgeladen"

von Otto (Gast)


Lesenswert?

OK - hast recht - aber was ist mit

Reset und Inrerrupt - Vektor:

.org 0

rjmp main

usw. ...

Otto

von kitesurfer1404 (Gast)


Lesenswert?

.org 0x000       ; kommt ganz an den Anfang des Speichers
    rjmp RESET   ; Interruptvektoren berspringen
        ; und zum Hauptprogramm
reti    ;rjmp EXT_INT0   ; IRQ0 Handler
reti    ;rjmp EXT_INT1   ; IRQ1 Handler
reti    ;rjmp TIM2_COMP  ; Timer2 Compare Handler
reti    ;rjmp TIM2_OVF  ; Timer2 Overflow Handler
reti    ;rjmp TIM1_CAPT   ; Timer1 Capture Handler
reti    ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
reti    ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
    rjmp TIM1_OVF   ; Timer1 Overflow Handler
    rjmp TIM0_OVF   ; Timer0 Overflow Handler
reti    ;rjmp SPI_STC   ; SPI Transfer Complete Handler
reti    ;rjmp USART_RXC   ; USART RX Complete Handler
reti    ;rjmp USART_DRE   ; UDR Empty Handler
reti    ;rjmp USART_TXC   ; USART TX Complete Handler
reti    ;rjmp ADC   ; ADC Conversion Complete Interrupt Handler
reti    ;rjmp EE_RDY   ; EEPROM Ready Handler
reti    ;rjmp ANA_COMP   ; Analog Comparator Handler
reti    ;rjmp TWSI   ; Two-wire Serial Interface Handler
reti    ;rjmp SPM_RDY   ; Store Program Memory Ready Handler


RESET:         ; hier beginnt das Hauptprogramm

         ldi temp, LOW(RAMEND)
         out SPL, temp
         ldi temp, HIGH(RAMEND)
         out SPH, temp

; timer0 prescaling:
  ldi temp,0b00000010    ;clk prescaling: clk/8
  out TCCR0,temp

;timer1 prescaling:
  ldi temp,0b00000001    ;clk prescaling: clk/1
  out TCCR1B,temp

;timer enable:
  ; enable by setting bits:
  ; ldi temp,0bABCDEFGH  ;  A: timer2 ovf int
        ;  B: timer2 cmp int
        ;  C:
        ;  D:
        ;  E:
        ;  F: timer1 ovf int
        ;  G:
        ;  H: timer0 ovf int

  ldi temp, 0b00000101  ; enable ovf(timer0,1)
  out TIMSK,temp

; timer0 config
  ldi tmr, 15      ; multiplikator für timer0
          ; 15: 0,5s

  ldi temp,0
  out TCNT0,temp

; timer1 config
  ldi tmrH,0xD9      ; Timer1 Interrupt
  out TCNT1h,tmrH
  ldi tmrL,0xDA
  out TCNT1l,tmrL

von Otto (Gast)


Lesenswert?

da stimmen die Adressen nicht, weil ein "reti"
kürzer ist als ein "rjmp xxxx".....

Otto

von kitesurfer1404 (Gast)


Lesenswert?

wenn ich aber mit timer1 die töne vom martin-horn mache und mit timer0 
die töne wechsel (overflow von timer1 ändern), klappt es.

von johnny.m (Gast)


Lesenswert?

> da stimmen die Adressen nicht, weil ein "reti"
> kürzer ist als ein "rjmp xxxx".....
Nö, sind beides 1-Wort-Befehle. Das stimmt schon, vorausgesetzt, die 
Vektortabelle an sich ist i.O.. Was Du meinst ist ein "jmp xxxx", den es 
aber nur bei AVRs mit mehr als 8 KB Flash gibt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.