mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mit Auslagerung funktionierts nicht mehr


Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe mir ein kleines Versuchsboard gebastelt um in die Matherie C
wieder reinzukommen.
Ein Atmega8581 getaktet mit 4MhZ Quarz 4 Tastern und 4 LED's.

Ich arbeite mit dem AVR-Studio und dem GCC Compiler.

Ein kleines Program habe ich auch schon geschrieben:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
//#include "warten.h"


//Ein - Ausgänge

#define    Taster1    PA0
#define    Taster2    PA1
#define    Taster3    PA2
#define    Taster4    PA3
#define    Taster    PINA

#define    LED1    PC0
#define    LED2    PC1
#define    LED3    PC2
#define    LED4    PC3
#define    LED5    PC4
#define    LED6    PC5
#define    LED7    PC6
#define    LED8    PC7
#define    LED      PORTC




//Allgemeine Variable

volatile uint8_t timer;
volatile uint8_t timer_m;
volatile uint8_t taster;
volatile uint16_t halt;


ISR(TIMER0_OVF_vect)
{
  /* Interrupt Aktion alle
  (4000000/64)/125 Hz = 2ms
  */
    TCNT0 = 0x83;           //Timer mit 131 vorladen
  timer_m ++;
  timer ++;

  if (!(Taster &(1<<Taster1)))  //Taster 1 gedrückt
  {
    taster = 1;
  }

  if (!(Taster &(1<<Taster2)))  //Taster 2 gedrückt
  {
    taster = 2;
  }

  if (!(Taster &(1<<Taster3)))  //Taster 3 gedrückt
  {
    taster = 3;
  }

  if (!(Taster &(1<<Taster4)))  //Taster 4 gedrückt
  {
    taster = 4;
  }
}


//Hauptprogram

int main(void)
{
  //Ein - Ausgänge Definieren

DDRC  = 0xff;    //PORTC Ausgang
PORTA = 0xff;    //PORTA Pullup aktivieren

// Timer 0 konfigurieren
    TCCR0 = (1<<CS01)| (1<<CS00);  // Prescaler 64

// Overflow Interrupt erlauben
    TIMSK |= (1<<TOIE0);

//Interupt starten
sei();


//Eigene Funktionen:

//Eigene Delay-Schleife


void warte_m(uint16_t halt)    //Mit Tasterabfrage
{
  timer_m=0;
  uint8_t halb;
  halb = halt/2;

  while (!(timer_m == halb))
  {
  
    if (!(Taster &(1<<Taster1)))
    {
      return;
    }

    if (!(Taster &(1<<Taster2)))
    {
      return;
    }

    if (!(Taster &(1<<Taster3)))
    {
      return;
    }

    if (!(Taster &(1<<Taster4)))
    {
      return;
    }  
  }
  return;
}


void warte(uint16_t halt)    //Ohne Tasterabfrage
{
  timer=0;
  uint8_t halb;
  halb = halt/2;

  while (!(timer == halb))
  {
  
  }
  return;
}

//Hauptschleife

  while (1)
  {



    if (taster == 1)
    {
        LED = 0x00;
        LED |= (1<< LED4) | (1<< LED8);
        LED &= ~((1<< LED2) | (1<< LED6));
        warte_m(500);
        warte_m(500);
        LED &= ~((1<< LED4) | (1<< LED8));
        LED |= (1<< LED2) | (1<< LED6);
        warte_m(500);
        warte_m(500);
    }
    
    if (taster == 2)
    {

        LED = 0b00000000;
        warte_m(200);
        LED = 0b11111111;
        warte_m(500);
        warte_m(500);
    }
    
    if (taster == 3)
    {
      
      LED = 0x00;
      LED = 0b00000010;
      warte_m(500);
      LED = 0b00001000;
      warte_m(500);
      LED = 0b00100000;
      warte_m(500);
      LED = 0b10000000;
      warte_m(500);
    }
    
    if (taster == 4)
    {
      
      LED = 0x00;
      LED = 0b11111101;
      warte_m(300);
      LED = 0b11110111;
      warte_m(500);
      LED = 0b11011111;
      warte_m(300);
      LED = 0b01111111;
      warte_m(500);
    }      
  }

}

Das funktioniert auch so wie ichs will.
Jetzt möchte ich die Funktion "void warte_m(uint16_t halt)" und "void 
warte(uint16_t halt)" auslagern. Bin folgender massen vorgegangen.
Hab eine Datei warten.h angelegt. Diese sieht so aus.
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>


void warte_m(uint16_t halt)
void warte(uint16_t halt)

Dan eine Datei warten.c
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include "warten.h"

void warte_m(uint16_t halt)    //Mit Tasterabfrage
{
  timer_m=0;
  uint8_t halb;
  halb = halt/2;

  while (!(timer_m == halb))
  {
  
    if (!(Taster &(1<<Taster1)))
    {
      return;
    }

    if (!(Taster &(1<<Taster2)))
    {
      return;
    }

    if (!(Taster &(1<<Taster3)))
    {
      return;
    }

    if (!(Taster &(1<<Taster4)))
    {
      return;
    }  
  }
  return;
}


void warte(uint16_t halt)    //Ohne Tasterabfrage
{
  timer=0;
  uint8_t halb;
  halb = halt/2;

  while (!(timer == halb))
  {
  
  }
  return;
}

Und die Hauptdatei versuch.c habe ich wie folgt geändert:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include "warten.h"


//Ein - Ausgänge

#define    Taster1    PA0
#define    Taster2    PA1
#define    Taster3    PA2
#define    Taster4    PA3
#define    Taster    PINA

#define    LED1    PC0
#define    LED2    PC1
#define    LED3    PC2
#define    LED4    PC3
#define    LED5    PC4
#define    LED6    PC5
#define    LED7    PC6
#define    LED8    PC7
#define    LED      PORTC




//Allgemeine Variable

volatile uint8_t timer;
volatile uint8_t timer_m;
volatile uint8_t taster;
volatile uint16_t halt;


ISR(TIMER0_OVF_vect)
{
  /* Interrupt Aktion alle
  (4000000/64)/125 Hz = 2ms
  */
    TCNT0 = 0x83;           //Timer mit 131 vorladen
  timer_m ++;
  timer ++;

  if (!(Taster &(1<<Taster1)))  //Taster 1 gedrückt
  {
    taster = 1;
  }

  if (!(Taster &(1<<Taster2)))  //Taster 2 gedrückt
  {
    taster = 2;
  }

  if (!(Taster &(1<<Taster3)))  //Taster 3 gedrückt
  {
    taster = 3;
  }

  if (!(Taster &(1<<Taster4)))  //Taster 4 gedrückt
  {
    taster = 4;
  }
}


//Hauptprogram

int main(void)
{
  //Ein - Ausgänge Definieren

DDRC  = 0xff;    //PORTC Ausgang
PORTA = 0xff;    //PORTA Pullup aktivieren

// Timer 0 konfigurieren
    TCCR0 = (1<<CS01)| (1<<CS00);  // Prescaler 64

// Overflow Interrupt erlauben
    TIMSK |= (1<<TOIE0);

//Interupt starten
sei();


//Eigene Funktionen:

//Eigene Delay-Schleife



//Hauptschleife

  while (1)
  {



    if (taster == 1)
    {
        LED = 0x00;
        LED |= (1<< LED4) | (1<< LED8);
        LED &= ~((1<< LED2) | (1<< LED6));
        warte_m(500);
        warte_m(500);
        LED &= ~((1<< LED4) | (1<< LED8));
        LED |= (1<< LED2) | (1<< LED6);
        warte_m(500);
        warte_m(500);
    }
    
    if (taster == 2)
    {

        LED = 0b00000000;
        warte_m(200);
        LED = 0b11111111;
        warte_m(500);
        warte_m(500);
    }
    
    if (taster == 3)
    {
      
      LED = 0x00;
      LED = 0b00000010;
      warte_m(500);
      LED = 0b00001000;
      warte_m(500);
      LED = 0b00100000;
      warte_m(500);
      LED = 0b10000000;
      warte_m(500);
    }
    
    if (taster == 4)
    {
      
      LED = 0x00;
      LED = 0b11111101;
      warte_m(300);
      LED = 0b11110111;
      warte_m(500);
      LED = 0b11011111;
      warte_m(300);
      LED = 0b01111111;
      warte_m(500);
    }      
  }

}

Wenn ich jetzt compilieren möchte kommt folgene Fehlermeldung:

Build started 25.4.2010 at 14:37:03
../versuch.c: In function 'warte_m':
../versuch.c:30: error: expected '=', ',', ';', 'asm' or '__attribute__' 
before 'volatile'
../versuch.c:36: warning: 'signal' attribute only applies to functions
../versuch.c:36: warning: 'used' attribute ignored
../versuch.c:36: warning: 'externally_visible' attribute ignored
../versuch.c:37: error: expected '=', ',', ';', 'asm' or '__attribute__' 
before '{' token
../versuch.c:70: error: expected '=', ',', ';', 'asm' or '__attribute__' 
before '{' token
../versuch.c:197: error: old-style parameter declarations in prototyped 
function definition
../versuch.c:196: error: expected '{' at end of input
make: *** [versuch.o] Error 1
Build failed with 5 errors and 3 warnings...

Ich sitzte jetzt seit Freitagabend an diesem Problem und grigs nicht 
hin. Kann mir jemand helfen?

Danke, Jürgen

Autor: Christoph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Überfliegen gesehen: in warten.h fehlt in den Zeilen

void warte_m(uint16_t halt)
void warte(uint16_t halt)

das Semikolon am Ende.

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort.

Auch das habe ich schon versucht.
Dann kommt folgende Meldung:

Build started 25.4.2010 at 14:54:05
avr-gcc -mmcu=atmega8515 -Wl,-Map=versuch.map versuch.o     -o 
versuch.elf
versuch.o: In function `main':
D:\Projekte\testboard\versuch\default/../versuch.c:149: undefined 
reference to `warte_m'
D:\Projekte\testboard\versuch\default/../versuch.c:150: undefined 
reference to `warte_m'
D:\Projekte\testboard\versuch\default/../versuch.c:153: undefined 
reference to `warte_m'
D:\Projekte\testboard\versuch\default/../versuch.c:154: undefined 
reference to `warte_m'
D:\Projekte\testboard\versuch\default/../versuch.c:161: undefined 
reference to `warte_m'
versuch.o:D:\Projekte\testboard\versuch\default/../versuch.c:163: more 
undefined references to `warte_m' follow
make: *** [versuch.elf] Error 1
Build failed with 6 errors and 0 warnings...

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Trotzdem sind die Semikolons dort notwendig. Du hast also noch einen 
weiteren Fehler.

Hast du warten.c zum Projekt hinzugefügt, so dass es auch mit kompiliert 
wird?

Autor: hp-freund (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Semikolon in warten.h müssen eingetragen werden.
Des weiteren würde ich die Deklaration:
//Ein - Ausgnge

#define    Taster1    PA0
#define    Taster2    PA1
#define    Taster3    PA2
#define    Taster4    PA3
#define    Taster    PINA

#define    LED1    PC0
#define    LED2    PC1
#define    LED3    PC2
#define    LED4    PC3
#define    LED5    PC4
#define    LED6    PC5
#define    LED7    PC6
#define    LED8    PC7
#define    LED      PORTC


//Allgemeine Variable

volatile uint8_t timer;
volatile uint8_t timer_m;
volatile uint8_t taster;
volatile uint16_t halt;

ebenfalls auslagern z.B. in "vars.h" . Diese dann in warten.h einbinden 
dann klappts...

...
hp-freund

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Jürgen (Gast)

Schon mal was über Netiquette gelesen? Lange Quelltexte gehören in 
den Anhang!!!

MFG
Falk

Autor: Jürgen (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ohh, Entschuldigung.
Werds das nächste mal gleich so machen.

Ich bin hingegangen und habe die Dateien .c und .h in denn selben Ordner 
gelegt wo auch die versuch.c liegt. Muss ich sonnst noch was machen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja.
Du musst natürlich deiner Projektverwaltung auch noch mitteilen, dass 
die Dateien dazugehören

http://www.mikrocontroller.net/articles/FAQ#Ich_ha...

Autor: Christoph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie schon gesagt, Du musst dafür sorgen das warten.c auch kompiliert und 
gelinkt wird. Ich habe hier gerade kein AVR Studio installiert, aber 
falls Du das Projekt vom Studio verwalten lässt (also kein externes 
makefile benutzt) sollte es reichen warten.c als Quelldatei im AVR 
Studio hinzuzufügen.

Und den Kommentar von hp-freund solltest Du auch beachten: Wenn Du 
versuchst warten.c zu kompilieren wird der Compiler maulen weil er die 
ganzen "Taster" Defines nicht kennt.

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Juchu, es funktioniert.
Ich muste die .h Daten im AVR-Studio einbinden und die Definitionen habe 
ich so wie oben beschrieben in eine var.H umgesiedelt.
Danke.

Thread kann geschloßen werden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.