-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 19

Thema: timer in C verwenden, 2. Versuch

  1. #1

    timer in C verwenden, 2. Versuch

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    So, nachdem ich im Dezember schonmal versucht habe, den Timer in C zu verwendne, habe ich micht heute mal wieder drann gesetzt und es erneut versucht.

    Zunächst habe ich ein Einfaches programm in Bascom Basic geschrieben, welchens mithilfe des Timers eine LED blinken lässt.
    Funktionierte.

    Dann habe ich die binärdatei Disassembliert, und aus dem Code eine einfachses Assemblyprogramm geschrieben, welches ebenfalls LEDs blinken lässt.
    Funktioniert.

    Da ich nun wusste, welche daten ich in Welche Register packen muss, habe ich das ASM-programm in C übersetzt.
    Funktioniert NICHT

    mein asm-prog:
    Code:
    .include "m32def.inc"
    
    ldi r16, LOW(RAMEND)
    out SPL, r16
    ldi r16, HIGH(RAMEND)
    out SPH, r16
    
    
    ; timerinterrupt erstellen
    clr r16
    out TCCR1A, r16
    ldi r16,    3
    out TCCR1B, r16
    in  r16,    TIMSK
    ori r16,    4
    out TIMSK,  r16
    sei
    
    
    ; Port C als ausgabe deklarieren
    ser r16
    out DDRC, r16
    
    
    ; r17 ist jetzt der Zähler
    clr r17
    
    ; endless loop
    loop:
      rjmp loop
    
    
    
    TIMER1_OVF:
      inc r17 ; wenn 0 (0xFF + 1)
      brne intend
      
      in  r16,   PORTC
      com r16
      out PORTC, r16
    
      intend:
         reti
    Mein C-Prog (welches nicht Funktioniert)
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    
    // Prototypen
    void timer1_init();
    
    
    int main()
    {
     
     DDRC  = 0xFF;//An C liegen die LEDs
     
     // Timer1 initialisieren
     timer1_init();
    
     // Interrupts aktivieren
     sei();
    
     while(1);
      
     return 0;
    }
    
    void timer1_init()
    {
     TCCR1A = 0;
     TCCR1B = 3;
      
     //OCR1A = (unsigned short) ((unsigned long) (16 MHZ) / IRQS_PER_SECOND - 1);
     TIMSK  |= 4;
    }
    
    
    int SIGNAL (TIMER1_OVF)
    {
     static uint8_t counter = 0;
     counter++;
    
     if(!counter) PORTC = ~PORTC;
    
     return 0;
    }
    Wo ist der Fehler (im C-Code)??

    ps.: Controller: ATmega32 bei 16MHz externem Takt

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Hallo,

    bei der ISR vor SIGNAL kein int und am ende kein return.

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Die Register habe ich jetzt nicht überprüft, ich denke, die sollten passen.

    Der Fehler liegt wohl im Interrupt.
    Du setzt jedesmal, wenn der Interrupt aufgerufen wird, die variable counter auf 0. In der if-Abfrage ist counter demnach immer 1 und es passiert nichts.

    Lass einfach mal das "= 0" weg. Static-Variablen werden bei C automatisch mit 0 initialisiert, daher ist die Zuweisung nicht nötig.

    Gruß,
    askazo

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569

    Re: timer in C verwenden, 2. Versuch

    Zitat Zitat von RedEagle
    Da ich nun wusste, welche daten ich in Welche Register packen muss,
    Sowas steht übrigens auch im Datenblatt drin ...
    Grundregeln des Forenpostings:
    1. Nutze niemals die Suchfunktion!
    2. Überprüfe niemals die Topics nach Ähnlichkeiten!
    3. Schreibe alles in hellgelb!

  5. #5
    Code:
    SIGNAL (TIMER1_OVF)
    {
     static uint8_t counter = 0;
     counter++;
    
     if(!counter) PORTC = ~PORTC;
    }
    Funktioniert auch nicht ...

    ps.: In meinem Datenblatt steht nur, das ich diese Register verwenden muss, aber nicht, was rein muss, bzw wofür die da sind...

    pss.: bei static-variablen werden nur 1 mal initialisiert!! d.h. dsa =0; sollte nicht stören.

    psss.: avr-gcc schreibt in einer Warnung, das die SIGNAL-Funktion automatisch auf int gesetzt wird => das kann auch nicht der Fehler sein.

  6. #6
    Habe mir nun mal die *.hex angesehen, die der avr-gcc erzeugt.
    die Interruptroutine ist überhaupt nocht vorhanden, und bei timer1_init werden die Werte nicht mit out an die Register gegeben, sondern einfach irgendwo im RAM gelegt

    frg1: Was macht der mit meiner SINGAL-.Funktion??
    frg2: Kann man alternativ zu in/out auch der DMA auf die register zugreifen, oder ist das ein sehr grober fehler beim Kompiliervorgang, oder ein Fehler in den Header-files??

    Code:
    sub_52:
    push    r28
    push    r29
    in      r28, SPL
    in      r29, SPH
    sts     unk_20004F, r1
    ldi     r24, 3
    sts     unk_20004E, r24
    lds     r24, unk_200059
    ori     r24, 4
    sts     unk_200059, r24
    pop     r29
    pop     r28
    ret
    das soll die timer1_init() sein...

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Hallo,
    evtl. solltest du doch auch mal das ein oder andere AVR Datenblatt durchlesen.

    Man kann die IO-Register auch über die SRAM-Adresse ansprechen, das muss also nix heissen.

    Welche GCC-Version verwendest Du.

    Ob die ISR eingetragen ist, sieht man in der ISR-Tabelle, dieser ist beim M32 an 10. Stelle, dort steht ein Sprungbefehl zur eigentlichen ISR.

  8. #8
    Habe die entsprechende Adresse gefunden.
    Wenn ich die lable nachverfolge, zeigen sie nicht auf den RAM, sondern auf den EEPROM !!

    die ISR-Tabelle ist leer...

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Bekommst du Warnungen beim Übersetzen?

    Wo hast die diesen SIGNAL-Name her???
    Zitat Zitat von ./avr/include/avr/iom32.h
    /* Timer/Counter1 Overflow */
    #define TIMER1_OVF_vect _VECTOR(9)
    #define SIG_OVERFLOW1 _VECTOR(9)
    Sieht übersetzt dann etwa so aus (avr-gcc assembler out):

    Code:
    	.lcomm counter.0,1
    .global	__vector_9
    	.type	__vector_9, @function
    __vector_9:
    /* prologue: frame size=0 */
    	push __zero_reg__
    	push __tmp_reg__
    	in __tmp_reg__,__SREG__
    	push __tmp_reg__
    	clr __zero_reg__
    	push r24
    /* prologue end (size=6) */
    	lds r24,counter.0	 ;  tmp42, counter	 
    	subi r24,lo8(-(1))	 ;  tmp42,	 
    	sts counter.0,r24	 ;  counter, tmp42	 
    	tst r24	 ;  tmp42	 
    	brne .L142	 ; ,	 
    	in r24,40-0x20	 ;  tmp46,	 
    	com r24	 ;  tmp46	 
    	out 40-0x20,r24	 ; , tmp46	 
    .L142:
    /* epilogue: frame size=0 */
    	pop r24
    	pop __tmp_reg__
    	out __SREG__,__tmp_reg__
    	pop __tmp_reg__
    	pop __zero_reg__
    	reti
    /* epilogue end (size=6) */
    /* function __vector_9 size 22 (10) */
    	.size	__vector_9, .-__vector_9
    Disclaimer: none. Sue me.

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Für ähnlichen Beispielcode guckst du

    http://www.roboternetz.de/wissen/ind...LED_blinken%29
    Disclaimer: none. Sue me.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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