Forum: Mikrocontroller und Digitale Elektronik Timer 90S8535


von mirli (Gast)


Angehängte Dateien:

Lesenswert?

Folgendes Problem:
Ich habe mit TCCR1A den Timer (16 Bit)des 90S8535 realisiert. TCNT1
wird mit OCR1A/B (PD5/PD4) verglichen und wie kann ich diesen Wert
ausgeben?

mfg
mirli

von crazy horse (Gast)


Lesenswert?

schreib mal genauer, was du eigentlich genau machen willst. Ich verstehe
es nicht ganz.

von mirli (Gast)


Lesenswert?

Ich möchte mit dem Timer einen Impuls
(Ultraschall-Ansteuerung)erzeugen.
0,2ms auf HIGH und die restliche Zeit (14,8ms) auf LOW.

thx mirli

von crazy horse (Gast)


Lesenswert?

dann solltest du den CTC-Mode (top=OCR1A) wählen. Vorteiler passend zu
deiner Quarzfrequenz wählen, so dass der OCR1A-Wert möglichst hoch wird
(allerdings max 65535).
Bei z.B. 4MHz Taktfrequenz (0,25µs) ohne Vorteiler, 15ms
Zyklus=15.000/0,25=60.000).
OCR1A=60.000 //15ms
OCR1B=59.200 //14,8ms

Dazu die entsprechenden Interruptprogramme:
OCR1A: output_port=0;
OCR1B: output_port=1;

Das wars dann schon.

PS: 15ms sind nicht gerade Ultraschall:-)

von mrili (Gast)


Lesenswert?

Wenn ich CTC verwende, kann dann nur TCCR1B verwendet werden, da dieser
ja für diesen aktiviert wird?

und wie funktioniert die ausgabe genauer?

von Hannes L. (hannes)


Lesenswert?

TCCR1B???

OCR1B...

Wenn du mit OCR1B(H/L) die Gesamtperiode (im CTC-Mode) einstellst, dann
kannst du mit OCR1A die Impulspause oder die Impulsbreite einstellen.

Da der CTC-Mode von OCR1B den Zählumfang des Timers begrenzt, bestimmt
OCR1B die Periodendauer. Dabei wird der OCR1B-Interrupt ausgelöst.
Wenn du nun mit OCR1A einen Wert einstellst, der kleiner ist als der
Wert in OCR1B, dann wird bei Erreichen dieses Wertes der
OCR1A-Interrupt ausgelöst.

Nun kommt es darauf an, ob du mit OCR1A die Impulspause oder die
Impulsdauer angibst. Gibst du die Impulsdauer an, dann must du im
OCR1A-Interrupt den Port ausschalten und im OCR1B-Interrupt
einschalten.

Die Namen der Interrupts stimmen jetzt nicht mit den von ATMEL
vergebenen Namen überein, ich hatte keine Lust, deswegen das Datenblatt
zu wälzen.

...

von mirli (Gast)


Angehängte Dateien:

Lesenswert?

@ Hannes

kannst du mir das mit den Interrupts ein bisschen genauer beschreiben
und die Ausgabe des Impulses erfolgt über die Interruptroutine?

Habe das PROG einmal abgeändert.

von pebisoft (Gast)


Lesenswert?

wenn du in winavr-c proggen tust, kannst du kein bytewert eingeben
:0b00011000, sondern nur hex:x018 oder dec:24 .
mfg pebisoft

von mirli (Gast)


Lesenswert?

danke

gut zu wissen, dass das bei winavr-c nicht möglich ist. wieso bringt
dann winavr keinen fehler?

von pebisoft (Gast)


Lesenswert?

das wird glaube ich als deci eingelesen und wird nicht als fehler
ausgeworfen.
schreibe eine zahl: wert=0b00000011 und printe die mal aus, dann wirst
du sehen, das keine 3 rauskommt.
mfg pebisoft

von mirli (Gast)


Lesenswert?

habe die werte nun auf hex umgeschriebn.

aber wie funktioniert jetzt die ausgabe?
gibt es irgendein ähnliches bsp, oder so etwas?

von Hannes L. (hannes)


Lesenswert?

Da ich jetzt keine Lust hatte, mich durch den Wust von
Timer1-Spezialfunktionen (PWM) im Datenblatt durchzuwuseln, habe ich
für das folgende Beispiel eine Version gewählt, bei der auf den
CTC-Mode verzichtet wird und die Impulsdauer und Impulspause durch
Aufaddieren von Intervallen auf die OCR1xx-Register erzeugt wird. Der
Timer1 läuft dabei frei durch. Es werden nur die OCRxx-Register
verändert.
Dies (das Setzen der nächsten Interrupt-Zeit-Referenzen) geschieht in
der ISR für die Periodendauer.

Das Beispiel ist in AVR-Assembler und mit AVR-Studio simuliert worden:


;Beispiel für Impulserzeugung nach einem Hilferuf von "mirli"
;http://www.mikrocontroller.net/forum/read-1-255079.html#255090


.include"m8535def.inc"

.equ clock=1000000  ;1MHz Taktfrequenz

.equ iport=portb    ;Impulsausgabe-Port
.equ ipin=pb0       ;Impulsausgabe-Pin
.equ periode=15000  ;Periodendauer in Timer-Takten
.equ impuls=200     ;Impulsdauer in Timer-Takten

.equ ipause=periode-impuls  ;Dauer Impulspause

.def srsk=r2        ;Siko SREG

.def wl=r24         ;working low
.def wh=r25         ;working high


.cseg
.org 0          ;Reset- und Interrupt-Vektoren AT-Mega 8535
 rjmp RESET         ; Reset Handler
 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
 rjmp TIM1_COMPA    ; Timer1 Compare A Handler
 rjmp TIM1_COMPB    ; Timer1 Compare B Handler
 reti; rjmp TIM1_OVF    ; Timer1 Overflow Handler
 reti; 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_UDRE  ; UDR Empty Handler
 reti; rjmp USART_TXC   ; USART TX Complete Handler
 reti; rjmp ADC         ; ADC Conversion Complete 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 EXT_INT2    ; IRQ2 Handler
 reti; rjmp TIM0_COMP   ; Timer0 Compare Handler
 reti; rjmp SPM_RDY     ; Store Program Memory Ready Handler
;
reset:              ;Initialisierungen
 ldi wl,low(ramend)     ;Stackpointer
 out spl,wl
 ldi wl,high(ramend)
 out sph,wl             ;einrichten

 sbi iport-1,ipin       ;Datenrichtung Ausgabe
 sbi iport,ipin         ;ersten Impuls aktivieren

 ldi wl,0               ;alle Bits auf 0
 out tccr1a,wl          ;in tccr1a (DB S. 108)
 ldi wl,1               ;Vorteiler 1  alle Features aus
 out tccr1b,wl          ;für Timer1

 ldi wl,low(impuls)     ;Impulsdauer
 ldi wh,high(impuls)    ;
 out ocr1ah,wh          ;
 out ocr1al,wl          ;setzen

 ldi wl,low(periode)    ;Periodendauer
 ldi wh,high(periode)   ;
 out ocr1bh,wh          ;
 out ocr1bl,wl          ;setzen

 ldi wl,1<<se           ;Sleep im Mode IDLE
 out mcucr,wl           ;anmelden

 ldi wl,(1<<ocie1a)|(1<<ocie1b) ;beide Compare-Interrupts
 out timsk,wl           ;für Timer1 aktivieren und evtl.
 out tifr,wl            ;bereits gesetzte Int-Flags löschen

 sei                    ;Interrupts freigeben


mainloop:           ;Hauptschleife
 sleep                  ;schlafen
 rjmp mainloop          ;weiter schlafen

TIM1_COMPA:         ;ISR für Impulsdauer
 cbi iport,ipin         ;Impuls beenden
 reti                   ;fertig

TIM1_COMPB:         ;ISR für Periodendauer
 sbi iport,ipin         ;Impuls einschalten
 in srsk,sreg           ;SREG sichern
 in wl,ocr1bl           ;Zeitstempel dieses Interrupts
 in wh,ocr1bh           ;einlesen
 subi wl,(low(-impuls)) ;Impulsdauer
 sbci wh,(high(-impuls));addieren
 out ocr1ah,wh          ;und als Referenz für
 out ocr1al,wl          ;Impulsdauer-Int ausgeben
 subi wl,(low(-ipause)) ;Impulspausendauer
 sbci wh,(high(-ipause));addieren
 out ocr1bh,wh          ;und als Referenz für nächsten
 out ocr1bl,wl          ;Periodendauer-Int ausgeben
 out sreg,srsk          ;SREG wiederherstellen
 reti                   ;fertig

Ich hoffe, es veranschaulicht die Funktionsweise der Impulserzeugung.

...

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.