Forum: Mikrocontroller und Digitale Elektronik ATmega128A Header-Datei


von Martin K. (karls-m)


Lesenswert?

Hallo zusammen,

ich habe bei der Programmierung des ATmega128A mit WinAVR-20100110 
folgendes Problem. Hier ein einfaches Beispiel zur Verdeutlichung.

Folgender Quellcode funktioniert i.O.:
1
#include <avr/io.h>
2
//#include "spi.h"
3
4
void spi_init( void )
5
{
6
  DDRB = 0x01;
7
}
8
9
int main( void )
10
{
11
  spi_init();
12
13
  while ( 1 )
14
  {
15
    PORTB = 0x01;
16
    PORTB = 0x00;
17
  }
18
19
  return 0;
20
}

Lagere ich nun die spi_init-Funktion in eine eigenständige Quell-Datei 
aus und binde sie über eine Header-Datei ein, verändert sich das 
Hex-File und viel schlimmer Pin1 von PortB des ATmega128A bleibt stumm. 
Im Makefile ist alles vorhanden und auch beim Compilieren und Generieren 
des Hex-Files gibt es keine Probleme.

Die Header-Datei sieht recht simpel aus:
1
#ifndef _SPI_H__
2
  #define _SPI_H__
3
4
void spi_init( void ) ;
5
6
#endif

Hat vielleicht jemand eine Ahnung wo das Problem liegen könnte?

von Klaus W. (mfgkw)


Lesenswert?

Es gibt kein Problem, weil du ja deiner Beschreibung nach alles richtig 
gemacht hast.
Daran habe ich natürlich keinen Zweifel, zumindest solange ich nichts 
gegenteiliges sehe.

von Martin K. (karls-m)


Lesenswert?

Bei weiteren Untersuchungen wird der Fehler immer interessanter, jedoch 
tappe ich noch immer im Dunkeln. Alles was ich sagen kann, es hat nichts 
mit der Header-Datei zu tun.

Füge ich der spi_init-Funktion den Befehl DDRB=0x01; erneut hinzu 
vergrößert sich der verwendete Programmspiecher (PMEM) um 4 Byte. Dieses 
Spiel kann ich eine bestimmte Anzahl wiederholen und der verwendete PMEM 
vergößert sich um jeweils 4 Byte. Alledrings beim sechsten hinzufügen 
des Befehls verringert sich der verwendete PMEM wieder um 4 Byte und 
Pin1 von PortB ist wieder stumm. Die Frage ist also was macht der 
Compiler und habe ich vielleicht doch irgendwo eine falsche Einstellung?

Die spi_init-Funktion sieht dann wie folgt aus:
1
void spi_init( void )
2
{
3
  DDRB = 0x01;
4
  DDRB = 0x01;
5
  DDRB = 0x01;
6
  DDRB = 0x01;
7
  DDRB = 0x01; // funzt
8
//  DDRB = 0x01; // funzt nicht
9
}

von Klaus W. (mfgkw)


Lesenswert?

Martin Karl schrieb:
> habe ich vielleicht doch irgendwo eine falsche Einstellung?

Ja.

Die Einstellung ist falsch, daß ein paar Brocken Quelltext
reichen, die deinem Programm ähneln, um daraufhin die Lösung
zu bekommen.

Mit der Einstellung "ich liefere eine komplette Beschreibung
des Problems mit Quelltexten, die nicht irgendwie nur ähnlich
aussehen sowie meine Einstellungen beim Kompilieren und
was alles noch relevant ist" hat man bessere Chancen.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hast du die M103C Fuse geändert, um mit dem Atmega128A zu arbeiten?

Schau dir das Disassemblerlisting des ersten Programms an, ob spi_init() 
vom Compiler als inline Funktion übersetzt wurde.

Bei spi_init() im externen Sourcefile kann der Compiler die Funktion in 
nicht inline machen. Bei gesetzter M103C Fuse (Werkseinstellung) stürzt 
das Programm aber beim Verlassen des spi_init() ab, weil der Stack vom 
WinAVR her für den Atmega128 initialisiert ist, physikalisch aber auf 
einem pseudo-Atmega103 läuft.

von Martin K. (karls-m)


Lesenswert?

Hallo Ihr Beiden!

Vielen Dank für die schnelle Hilfe. Der Fehler war tatsächlich die 
falsch gesetzte M103C Fuse. Mir war nicht bewusst, dass es beim 
ATmega128A solch einen Modus gibt. Tschuldigung falls ich Euch auf die 
falsche Fährte gelockt und dadurch unötige Mühen verursacht habe.

gruss

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.