PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fehler beim compilieren ... Anfänger braucht hilfe



klucky
31.10.2004, 12:41
Also ich habe mal nen kleines Programm in C geschrieben mit nem Timer als verzögerung. Der rest vom Programm funktioniert einwandfrei nur seitdem ich den Timer eingebaut habe schmeiß mich der Compiler mit Fehlermeldungen tot. Ich sehe die Fehler leider net so auf anhieb und brauche recht lange bis ich da mal was entdeckt habe, vielleicht können sich die Experten unter euch das ja mal anschauen und mir ein wenig helfen. Als Plattform dient bei mir ein Atmege128 mit 16 Mherz aber das sollte für das Programm bis auf bei der berechnung der zeit ja keine rolle spielen ;).


#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;

BYTE byte_timer;

void timer_init(void)
{
/*Clear Timer on Compare Match (Initialwert des Bits ist 0)
Wenn dieses Bit gesetzt ist wird nach Übereinstimmung des Datenregisters mit dem
Vergleichswert das Datenregister auf 0 gesetzt.

Clock Select Bits (Intitialwerte der Bits sind alle 0)
Diese 3 Bits bestimmen die Quelle für den Timer
CS10(Bit 0) CS11(Bit 1) CS12(Bit 2) Aktion
0 0 0 Timer wird angehalten
1 0 0 CPU-Takt
0 1 0 CPU-Takt/8
1 1 0 CPU-Takt/64
0 0 1 CPU-Takt/256
1 0 1 CPU-Takt/1024
0 1 1 Externer Pin T0, fallende Flanke
1 1 1 Externer Pin T0, steigende Flanke*/
TCCR1B|=(1<<CS10)|(1<<CS12)|(1<<CTC1);

/*Output Compare Match Interupt Enable (Initialwert des Bits ist 0)
Wenn dieses Bit gesetzt ist wird beim erreichen des Vergleichswertes ein Interupt ausgelöst.*/
TIMSK|=(1<<OCIE1A);

/*Output Compare Register beschreiben*/
cli()
OCR1=15625;

/*Timer Datenregister zurrücksetzen*/
TCNT1=0;
sei()
}

SIGNAL(SIG_OUTPUT_COMPARE)
{
cli()
/*Timer anhalten*/
TCCR1B&=~((1<<CS10)|(1<<CS12));
byte_timer=1;
}

int main(void)
{
/*Alle LEDs als Ausgänge*/

DDRA=0xFF;
DDRB=0xFF;
DDRC=0xFF;
DDRD=0xFF;
DDRE=0xFF;
DDRF=0xFF;
DDRG=0xFF;

/*Alle LEDs an PORTA an bis auf die letzte,alle LEDs an PORTD auf
bis auf die letzte und alle LEDs an PORTG an.*/

PORTA=0x7E;
PORTB=0x80;
PORTC=0x0;
PORTD=0x0;
PORTE=0x0;
PORTF=0x0;
PORTG=0xFF;

/*Led 0,2,4 an PORTA aus*/

PORTA&=~((1<<DDA0)|(1<<DDA2)|(1<<DDA4));

timer_init()
while(byte_timer=0){}

/*LED 0,2,4 an PORTB an*/

PORTB|=((1<<DDB0)|(1<<DDB2)|(1<<DDB4));

while(1){}
}


> "make.exe" all

-------- begin --------
avr-gcc (GCC) 3.4.1
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Size before:
test.elf :
section size addr
.data 0 8388864
.text 268 0
.bss 0 8388864
.noinit 0 8388864
.eeprom 0 8454144
.stab 756 0
.stabstr 1240 0
Total 2264




Compiling: test.c
avr-gcc -c -mmcu=atmega128 -I. -gstabs -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=test.lst -std=gnu99 -Wp,-M,-MP,-MT,test.o,-MF,.dep/test.o.d test.c -o test.o
test.c: In function `timer_init':
test.c:28: error: `CTC1' undeclared (first use in this function)
test.c:28: error: (Each undeclared identifier is reported only once
test.c:28: error: for each function it appears in.)
test.c:36: error: parse error before "OCR1"
test.c:41: error: parse error before '}' token
test.c: In function `SIG_OUTPUT_COMPARE':
test.c:47: error: parse error before '(' token
test.c: In function `timer_init':
test.c:52: warning: 'main' is normally a non-static function
test.c: In function `main':
test.c:79: error: parse error before "while"
test.c: In function `timer_init':
test.c:86: error: parse error at end of input
make.exe: *** [test.o] Error 1

> Process Exit Code: 2

martin
31.10.2004, 12:50
Hallo,

mach mal nach den ganzen cli() und sei() Strichpunkte hin, das sollte schon mal die Hälfte der Fehler erledigen.
Und nach timer_init() auch.

Die Frage ist, warum CTC1 undeclared ist, ich kenne den Mega 128 nicht.
Hast du die richtige Header-Datei eingebunden und gibts das Register überhaupt (Schreibfehler?)

Grüsse, Martin

klucky
31.10.2004, 13:25
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;

BYTE byte_timer;

void timer_init(void)
{
/*Clear Timer on Compare Match (Initialwert des Bits ist 0)
Wenn dieses Bit gesetzt ist wird nach Übereinstimmung des Datenregisters mit dem
Vergleichswert das Datenregister auf 0 gesetzt.

Clock Select Bits (Intitialwerte der Bits sind alle 0)
Diese 3 Bits bestimmen die Quelle für den Timer
CS10(Bit 0) CS11(Bit 1) CS12(Bit 2) Aktion
0 0 0 Timer wird angehalten
1 0 0 CPU-Takt
0 1 0 CPU-Takt/8
1 1 0 CPU-Takt/64
0 0 1 CPU-Takt/256
1 0 1 CPU-Takt/1024
0 1 1 Externer Pin T0, fallende Flanke
1 1 1 Externer Pin T0, steigende Flanke*/
TCCR1B|=(1<<CS10)|(1<<CS12)|(1<<CTC1);

/*Output Compare Match Interupt Enable (Initialwert des Bits ist 0)
Wenn dieses Bit gesetzt ist wird beim erreichen des Vergleichswertes ein Interupt ausgelöst.*/
TIMSK|=(1<<OCIE1A);

/*Output Compare Register beschreiben*/
cli();
OCR1=15625;

/*Timer Datenregister zurrücksetzen*/
TCNT1=0;
sei();
}

SIGNAL(SIG_OUTPUT_COMPARE)
{
cli();
/*Timer anhalten*/
TCCR1B&=~((1<<CS10)|(1<<CS12));
byte_timer=1;
}

int main(void)
{
/*Alle LEDs als Ausgänge*/

DDRA=0xFF;
DDRB=0xFF;
DDRC=0xFF;
DDRD=0xFF;
DDRE=0xFF;
DDRF=0xFF;
DDRG=0xFF;

/*Alle LEDs an PORTA an bis auf die letzte,alle LEDs an PORTD auf
bis auf die letzte und alle LEDs an PORTG an.*/

PORTA=0x7E;
PORTB=0x80;
PORTC=0x0;
PORTD=0x0;
PORTE=0x0;
PORTF=0x0;
PORTG=0xFF;

/*Led 0,2,4 an PORTA aus*/

PORTA&=~((1<<DDA0)|(1<<DDA2)|(1<<DDA4));

timer_init();
while(byte_timer=0){}

/*LED 0,2,4 an PORTB an*/

PORTB|=((1<<DDB0)|(1<<DDB2)|(1<<DDB4));

while(1){}
}



> "make.exe" all

-------- begin --------
avr-gcc (GCC) 3.4.1
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Size before:
test.elf :
section size addr
.data 0 8388864
.text 268 0
.bss 0 8388864
.noinit 0 8388864
.eeprom 0 8454144
.stab 756 0
.stabstr 1240 0
Total 2264




Compiling: test.c
avr-gcc -c -mmcu=atmega128 -I. -gstabs -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=test.lst -std=gnu99 -Wp,-M,-MP,-MT,test.o,-MF,.dep/test.o.d test.c -o test.o
test.c: In function `timer_init':
test.c:28: error: `CTC1' undeclared (first use in this function)
test.c:28: error: (Each undeclared identifier is reported only once
test.c:28: error: for each function it appears in.)
test.c:36: error: `OCR1' undeclared (first use in this function)
test.c: In function `main':
test.c:79: warning: suggest parentheses around assignment used as truth value
make.exe: *** [test.o] Error 1

> Process Exit Code: 2


So das sind die fehler die noch auftauchen ... naja CTC1 müsste es eigentlich geben stand in dem Tut von Microcontroller.net/wiki drin ist clear timer on compare match und OCR1 ist das Output Compare register ...

Dino Dieter
31.10.2004, 14:30
Hallo Klucky

Beim Mega 128 gibt es kein CTS1 Flag mehr, heißt jetzt WGM12.

also
TCCR1B|=(1<<CS10)|(1<<CS12)| (1<<WGM12);

OCR1=15625; ist beim MEGA 128 ein 16 BIT Register, also

OCR1A=15625;

SIGNAL(SIG_OUTPUT_COMPARE) gibts beim Mega 128 nicht, also

SIGNAL(SIG_OUTPUT_COMPARE1A) sonst stimmt der Inerrupt einsprung
nicht mehr.

In deiner INT Routine SIGNAL(SIG_OUTPUT_COMPARE1A)
{
cli();
/*Timer anhalten*/
TCCR1B&=~((1<<CS10)|(1<<CS12));
byte_timer=1;
}
schaltest du mit cli(); die Interrupts aus, macht keinen Sinn, da GCC das automatisch macht. Beim verlassen der INT Routine wird es aber wieder eingeschaltet, auch in deinem Fall, also aufpassen.

Deine Abfage while(byte_timer=0){} geht so nicht, vergleiche immer mit == , also while(byte_timer==0){}. Zudem muß die Variable byte_timer mit volatile deklariert werden, sonst wird sie weg optimiert.

volatile BYTE byte_timer;

MFG
Dieter

klucky
31.10.2004, 15:24
Danke für eure hilfe! Jetzt tut es soweit. Mal schaun obs auch das richtige im atmega macht! Aber zumindist schonmal keine fehlermeldungen mehr. Naja nen paar fragen habe ich noch. Die Interupts machen mir doch keine probleme mehr da ich den timer ja ausgeschaltet habe oder sollte ich sie nach der whileschleife nochmal wieder komplett deaktivieren? Dann nochmal zu dem mit dem 16-Bit Registern, wenn ich dasmit dem OCR1A mache schreibt der dann in beide register (high und low)? Also nimmt der das dann einfach als 16 Bit ... obwohls ja eigendlich 2 8-Bit register sind? Und was bewirkt das volatile?

klucky
31.10.2004, 15:35
Naja jetzt geht das mit dem compilieren zwar ohne Fehlermeldungen, aber leider macht das Programm nicht was es soll. Es soll erstmal die Leds 0,2,4 an PORTA aus machen (alle LEDs bis auf die letzte leuchten) dann soll es 1 sec warten und an PORTB die LEDs 0,2,4 an machen (alle LEDs bis auf die letzte sind an) ... das programm läuft bis zu dem Punkt an dem 1 sec gewartet werden soll dann gehts nicht weiter :(.

Dino Dieter
31.10.2004, 18:17
Hallo Klucky

Wenn du keine Interrupts mehr haben möchtest, solltest du sie in deinem Fall nach while(byte_timer==0){} ausschalten.

Bei der Verwendung von OCR1A werden bei Register beschrieben OCR1AL und OCR1AH.

Schreib doch mal, wie du deinen LED angeschlossen hast. Leuchten sie bei LOW am PORT oder bei HIGH am Port.

Mit PORTA=0x7E; leuchtet nicht nur die letzte sondern auch die erste, wenn die LED bei LOW leuchten., ansonsten sind halt anderes rum.

0x7e = 0111 1110

Hast du die Fuse Bit denn eingestellt auf externen Clock ? Oder läuft der uC noch mit 1 MHZ, dann sollte sich ja nach 16 Sekunden was tuen.

MFG
Dieter

klucky
31.10.2004, 18:46
Also die LEDs sind über einen Transistor an die Ports Angeklemmt und Leuchten bei einem High an den Ports. Naja hab es mal angemacht und eine minute gewartet und es tut sich immer noch nix ... das mir dem 0x7e hab ich in 0xfe geändert da hat ich mich vertan ;). Auch das cli(); hab ich jetzt hinter die schleife gesetzt. Die Fuse Bits hab ich als screenshot mal angehängt ...

Dino Dieter
31.10.2004, 19:33
Hallo

Schalte den uC doch mal auf internen Takt 8 MHz um. Oder probiere mal das
CKOPT Bit. Datenblatt Seite 36.

Im Simulator läuft das so, wie gewünscht.
Sonst fällt mir im Moment nichts mehr ein.

MFG
Dieter

klucky
02.11.2004, 14:59
Also ich habe noch 2 Fehler gefunden:

1. byte_timer wird nicht auf 0 gesetzt
2. TCCR1B|=(1<<CS10)|(1<<CS12)|(1<<CTC1); doe cs dürfen erst gesetzt werden wenn alle timerbits so gesetzt sind wie sie sein sollen da sie ja den timer anmachen ...

Naja aber es funktioniert immer noch net ...

klucky
02.11.2004, 15:22
So den letzten fehler hab ich jetzt auch gefunden ... es tut :) ... es war das m103c fuse das durfte nicht gesetzt sein ...