PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : timer in C verwenden, 2. Versuch



RedEagle
03.02.2007, 12:33
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:

.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)


#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

linux_80
03.02.2007, 13:33
Hallo,

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

askazo
03.02.2007, 13:39
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

Hanni
03.02.2007, 14:02
Da ich nun wusste, welche daten ich in Welche Register packen muss,

Sowas steht übrigens auch im Datenblatt drin ...

RedEagle
03.02.2007, 14:07
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.

RedEagle
03.02.2007, 14:30
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??



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...

linux_80
03.02.2007, 16:11
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.

RedEagle
03.02.2007, 16:36
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...

SprinterSB
03.02.2007, 16:40
Bekommst du Warnungen beim Übersetzen?

Wo hast die diesen SIGNAL-Name her???

/* Timer/Counter1 Overflow */
#define TIMER1_OVF_vect _VECTOR(9)
#define SIG_OVERFLOW1 _VECTOR(9)

Sieht übersetzt dann etwa so aus (avr-gcc assembler out):


.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

SprinterSB
03.02.2007, 16:51
Für ähnlichen Beispielcode guckst du

https://www.roboternetz.de/wissen/index.php/Hallo_Welt_f%C3%BCr_AVR_%28LED_blinken%29

RedEagle
03.02.2007, 16:57
Der Code Funktioniert genau so wenig...
mit dem habe ich es als erstes versucht...

Den Fehlern nach zu urteilen, gabs da das selbe problem (Es wurde damals ebenfalls nicht die SIGNAL-Funktion ausgeführt)

RedEagle
03.02.2007, 17:02
Warnungen:



SIGNAL (TIMER1_OVF)
{ //../test3.c:42: warning: return type defaults to `int'

static uint8_t counter = 0;
counter++;

if(!counter) PORTC = ~PORTC;

} //../test3.c:49: warning: control reaches end of non-void function

SprinterSB
03.02.2007, 17:03
Wo hast die diesen SIGNAL-Name her???

SprinterSB
03.02.2007, 17:05
Welche avr-gcc Version verwendest du?

Hat's damit zu tun?

https://www.roboternetz.de/wissen/index.php/Avr-gcc#Inkompatibilit.C3.A4t

RedEagle
03.02.2007, 17:17
versiom:
AvrPluginavrgccplugin 1, 0, 0, 6

laut WinAVR

Den SIGNAL-Name habe ich aus der Doku.; wurde aber auch bei Assembly so verwendet...

RedEagle
03.02.2007, 17:42
Merke gerade das ich nur die Pluginversion angegeben haben...
Der Compiler liegt in der Version 3.4.1 vor

habe nun den header avr/signal.h mit eingebunden - SIGNAL wird immer nooch nicht mitkompiliert

SprinterSB
03.02.2007, 18:08
Atmal AVR-Assembler ist nicht GNU AVR-Assembler!

Irgendwo ist da der Wurm drin!

Gib mal auf Console ein:

avr-gcc -S -fverbose-asm -mmcu=atmega32 -Os -save-temps -v deine-datei.c

Und poste das *.i und das *.s und die Console-Ausgabe.

Hast du den SIGNAL-Name auf einen der von mir angegebenen Werte gestellt? Am besten den zweiten SIG_**** ich weiß net ob 3.4.1 den anderen schon kennt.

izaseba
03.02.2007, 18:41
Hallo,
in meinen Augen (die gerade auf den Header der Version 4.1.0 schauen)
muß der Interrupt entweder
SIGNAL (SIG_OVERFLOW1)

oder

ISR (TIMER1_OVF_vect)

heißen, besser ist die zweite Version.
Bei Dir ist es irgendwie eine bunte Mischung aus beiden.

Gruß Sebastian

RedEagle
03.02.2007, 18:50
sry habe das mit SIG_OVERFLOW1 überlesen...
Wenn ich es einsetze Funktionierts;

VIELEN DANK!!