- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: ATMega16 und Timer Verständnisproblem

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    09.07.2006
    Ort
    Schönstedt
    Alter
    38
    Beiträge
    20

    ATMega16 und Timer Verständnisproblem

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,
    ich versuche seite 2, 3 Tagen einen Timer mit einem ATMega16 auf die Beine zu stellen, der jede Sekunde eine Zahl verändert. Wie ich es mit Zyklen machen kann hab ich schon so einigermaßen hin bekommen, aber für meine Zwecke wäre eine Interruptlösung besser, da ich die aktuelle Zahl besser ausgeben kann. Einige Ansätze dazu hab ich auch schon gefunden, aber nichts was mir so weitergeholfen hat, das ich es auch verstanden hab was der Code bewirkt, und wo ich die Zeitabstände einstellen kann.
    Im Basiswissen unter Timer/Counter (Avr) hab ich schon was gelesen wie es Theoretisch abläuft, aber wie gesagt, die Umsätzung fehlt mir. Das Einzigste was ich jetzt so am groben Ansatz hab ist, das ich den Interrupt definieren muß. Irgenwie mit TCCR0 TCNT0 und so weiter. Kann mir das jemand mal so Schritt für Schritt erklären?

    Danke schon mal für euer Bemühen....

    mfG Tim

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    19.02.2005
    Alter
    36
    Beiträge
    470
    Also das mit dem Interrupt verhätl sich so, dass die ersten paar Wörter im Flash Interruptvektoren sind, das heist, das wenn ein Interrupt aktiviert ist und dieser aufgerufen wird dann springt dein Programmzeiger auf genau diese addresse ( zb $0010 ), da du da jab aber nur ein befehl ausführen könntest schreibt man dort ein rjmp rein, welches zu deiner Interruptroutine führt. Deine interruptroutine beendest du nicht mit ret sondern mit RETI !!!!

    So das waren die Basics nun aber zum Code:

    1.
    Als erstes werden die Interruptvektoren eingerichtet:
    Die addresse findest du entweder im Datenbaltt oder im INC File
    Code:
    ;----[ Interrupt-Vektoren ]---------------------------------------------------------
    
    .org 0000                                 ; Zum Programmbeginn springen
     rjmp reset
    
    .org OVF1addr                          ; Timer1 überlauf 
     rjmp Overflow
    3.
    Den Timer einrichten, aber das kannste ja schon

    4.
    Den Timerinterrupt aktivieren:
    Dazu musst du im TIMSK Register den TOIE1 aktiverien ( TimerOverflowInterruptEnable1 für timer1 )
    Code:
    ldi tmp, (1<<TOIE1)                   ; Timer1 Interrupt 
    out timsk, tmp                        ; aktivieren
    5.
    GANZ WICHTIG!!! GLOBALE INTERRUPTFREIGABE!!!
    sonst geht überhaupt kein Interrupt

    Dazu einfach den befehl SEI benuzen.

    Code:
    sei                                   ; Interuptts freigeben
    6.
    Zum schluß deine Iinterruptroutinen ans ENDE deines Quellcodes
    beginen mit deinem LABELD ( hier Overflow ) und Ende mit RETI

    Code:
    Overflow:
     ; HIER DEIN CODE
    reti
    So das wars auch schon, das kannste so für alle Interrupts übernehmen.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    09.07.2006
    Ort
    Schönstedt
    Alter
    38
    Beiträge
    20
    Hallo danke, das hat mich schon mal ein ganzes Stück weiter gebrach denn die Testled blinkt schon mal

    Das mit dem Punkt "3. Den Timer einrichten, aber das kannste ja schon " .. Theoretisch hab ich das glaube verstanden, aber wie ich das im ASM umsetze bin ich leider überfragt könntest du mir das auch noch mal erklären?

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    09.07.2006
    Ort
    Schönstedt
    Alter
    38
    Beiträge
    20
    Also ich hab jetzt was gefunden und das auf meinen µC umgearbeitet. Die berechnung stimmt nicht genau. Der Timer schaltet nicht bei jeder sekunde aber so in etwa bei 1,5, das ist aber auch etwas nebensache/einstellungssache
    Kann mir mal jemand den Code erklären?

    Code:
    ;************************************************************************/
    ;*                                                                      */
    ;*			Precise 1 Second Timebase			*/
    ;*                                                                      */
    ;*              Author: Peter Dannegger                                 */
    ;*                      danni@specs.de                                  */
    ;*                                                                      */
    ;************************************************************************/
    .nolist
    .include"m16def.inc"
    
    .equ	xtal	= 8000000
    .equ	debounce = 100
    .equ	remainder = xtal - xtal / debounce * debounce
    
    .def	isreg	= r15
    .def	wr0	= r16
    .def	iwr0	= r17
    .def	prescaler = r18
    .def	second = r19
    
    .list
    	rjmp	init
    	.org	OC1Aaddr
    	rjmp	OC1Aint
    ;-------------------------------------------------------------------------
    OC1Aint:
    	in	isreg, sreg
    ;************************************************************************/
    ;*			Insert Key Debouncing Here			*/
    ;************************************************************************/
    
    	ldi	iwr0, high( xtal / debounce - 1 )
    	out	ocr1ah, iwr0
    	ldi	iwr0, low( xtal / debounce - 1 )
    	out	ocr1al, iwr0
    
    	dec	prescaler
    	brne	_oci1
    
    	ldi	prescaler, debounce
    	inc	second
    
    	ldi	iwr0, high( xtal / debounce + remainder - 1 )
    	out	ocr1ah, iwr0
    	ldi	iwr0, low( xtal / debounce + remainder - 1 )
    	out	ocr1al, iwr0
    _oci1:
    	out	sreg, isreg
    	reti
    ;-------------------------------------------------------------------------
    init:
    	ldi	wr0, 0xFF
    	out	ddrb, wr0
    
    	ldi	wr0, high( ramend )
    	out	sph, wr0
    	ldi	wr0, low( ramend )
    	out	spl, wr0
    
    	ldi	wr0, 1<<WGM12^1<<CS10
    	out	TCCR1B, wr0
    
    	ldi	wr0, high( 8000000 / 100 - 1 )
    	out	ocr1ah, wr0
    	ldi	wr0, low( 8000000 / 100 - 1 )
    	out	ocr1al, wr0
    	out	tcnt1l, wr0
    	ldi	prescaler, debounce
    
    	ldi	wr0, 1<<OCIE1A
    	out	TIMSK, wr0
    	sei
    main:
    	ldi	second, 0
    _mai1:
    	cpi	second, 60
    	breq	main
    	out	ddrb, second
    	rjmp	_mai1
    ;------------------------------------
    Die Erklärung würde mir für den init Teil reichen. Danke

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    19.02.2005
    Alter
    36
    Beiträge
    470
    Schau dir einfach mal im Datenblat die Timerrigeister TIMSK TCCRxA TCCRxB an, da stehts wunderbar beschrieben, die daten schreibste mit dem befehl OUT

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    09.07.2006
    Ort
    Schönstedt
    Alter
    38
    Beiträge
    20
    Hallo dann werd ich mich mal durch das Englisch durchquälen. (mein Englisch ist nicht das beste )

    Also danke erst mal.

    mfg Timmee

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    09.07.2006
    Ort
    Schönstedt
    Alter
    38
    Beiträge
    20
    Eine kleine Verständnisfrage hab ich da noch, wenn der Interrupt ausgelöst wurde, wartet dann der Timer mit weiterzählen bis die Ausgelöste Rotiene fertig ist oder zählt er gleich na dem Auslösen weiter?

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    19.02.2005
    Alter
    36
    Beiträge
    470
    Der Zählt weiter

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    09.07.2006
    Ort
    Schönstedt
    Alter
    38
    Beiträge
    20
    Ich ich den Code jetzt soweit das ich den Timer in der geschwindigkeit einstellen kann. Dann hab ich mir mit dem Programm rnVAR berechen lassen, welchen Prescaler (Teiler) und welchen Timervorgabewert ich nehmen soll. Das Programm hat mir als Teiler 256 und als Timervorgabewert 34286 Vorgeschalgen. Mit diesen Infos hab ich dann den Code gefüttert, aber mein timer reagiert nicht bei einer Sekunde sondern bei ca 7-8 Sekunden. Kann mir jemand sagen wo mein Fehler liegt?

    Verwendete Hardware:
    • ATMega16
      8MHz Quarz


    Code:
    .include"m16def.inc"
    
    
    .def	isreg	= r15
    .def	wr0	= r16
    .def	iwr0	= r17
    .def	prescaler = r18
    .def	second = r19
    
    
    .list
    	rjmp	init
    	.org	OC1Aaddr
    	rjmp	Timerinterrupt
    
    
    Timerinterrupt:
    
    	inc	second
    	reti
    
    init:
    	ldi	wr0, 0xFF
    	out	ddrb, wr0
    
    	ldi	wr0, high( ramend )
    	out	sph, wr0
    	ldi	wr0, low( ramend )
    	out	spl, wr0
    
    	ldi	wr0, 1<<WGM12^1<<CS12 ; Festlegen des Teilers 265
    	out	TCCR1B, wr0
    
    	ldi	wr0, high( 34286 ) ;Festlegen des Timervorgabewertes
    	out	ocr1ah, wr0
    	ldi	wr0, low( 34286 ) ;Festlegen des Timervorgabewertes
    	out	ocr1al, wr0
    	out	tcnt1l, wr0
    
    	ldi	wr0, 1<<OCIE1A
    	out	TIMSK, wr0
    	sei
    
    main:
    	ldi	second, 0
    
    _mai1:
    	cpi	second, 60
    	breq	main
    	out	PORTB, second
    	rjmp	_mai1
    Kann mir jemand sagen wo mein Rechen- oder Codefehler liegt?

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    55
    Beiträge
    1.258
    Hallo -tim-,
    reagiert nicht bei einer Sekunde sondern bei ca 7-8 Sekunden. Kann mir jemand sagen wo mein Fehler liegt?
    hast du die Fuses auf externen Quarz gestellt oder läuft der AVR noch auf den internen 1MHz?

    Gruß, Michael

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen