Forum: Mikrocontroller und Digitale Elektronik ATMega32 Problem (kanns nicht besser formulieren)


von Johannes H. (jhuebner)


Lesenswert?

Hallo,

ich habe vor 3 Tagen meine erste Atmega-Schaltung gebaut. Davor habe ich 
immer nur mit fertigen Eval-Boards gearbeitet.

Also erstmal zur Hardware
ATmega32 auf Steckbrett. Nur Programmer (PROG-S) (MOSI, MISO, SCK, 
RESET), 2xGND, Vcc, AVcc und eine LED an PORTD[0]. LED an Vcc und über 
470R am Port, also an wenn PORT=0.
Ablockkondensatoren direkt an Pins (Vcc und AVcc), ansonsten noch ein 
47µ Elko. Versorgung mit 4 AA Akkus (5,2V).

Als erstes habe ich das obligatorische Blinkprogramm draufgeladen:

int main(void)
{
    DDRD = 0xFF;
    PORTA = 0xFF;

    while(1)
    {
       PORTD = ~PORTD;
       _delay_ms(50);
    }

    return 0;
}

Das tut auch was es soll, selbst wenn ich alle Kondensatoren rausziehe. 
Dann habe ich losprogrammiert (will 4 Pins über eine Art 1-Wire 
Protokoll versenden). Das tat dann überhaupt nichts. Ich habe dann 
probiert und probiert und folgendes funktioniert dann schon nicht mehr 
(LED bleibt dunkel):

int main(void)
{
    DDRD = 0xFF;
    PORTA = 0xFF;

    while(1)
    {
       PORTD = 0x0;
       _delay_ms(50);
       PORTD = 0xFF;
       _delay_ms(50);
    }

    return 0;
}

Sobald ich das erste Programm wieder drauflade, blinkts. Geschossen hab 
ich also nichts. Es gibt auch noch diverse andere Konstellationen die 
nicht funktionieren, z.B. wenn ich die Sequenz PORTD = ~PORTD; 
_delay_ms(50); in eine Unterfunktion (Schachteltiefe 2) verlege.

Fusebits sind auf Factory default (E1 99) also 1MHz interner Takt. Als 
Stromversorgung hatte ich auch schon mein Labornetzteil mit genau 5V 
dran. Ändert auch nichts.

Was ist da los?

von Johannes H. (jhuebner)


Lesenswert?

Ich antworte mir selbst... Also der Unterschied zwischen geht/geht 
nicht: sobald eine Unterroutine entsteht (weil nicht inlined wird), 
läufts nicht mehr. Also mich wundert das auch nicht:


bin/Release/bms-tiny.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000036  00000000  00000000  00000054  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

Disassembly of section .text:

00000000 <delay_ms.clone.0>:
   0:  82 e3         ldi  r24, 0x32  ; 50
   2:  90 e0         ldi  r25, 0x00  ; 0
   4:  06 c0         rjmp  .+12       ; 0x12 <__zero_reg__+0x11>
   6:  e9 ef         ldi  r30, 0xF9  ; 249
   8:  f0 e0         ldi  r31, 0x00  ; 0
   a:  31 97         sbiw  r30, 0x01  ; 1
   c:  f1 f7         brne  .-4        ; 0xa <__zero_reg__+0x9>
   e:  00 c0         rjmp  .+0        ; 0x10 <__zero_reg__+0xf>
  10:  00 00         nop
  12:  01 97         sbiw  r24, 0x01  ; 1
  14:  ff ef         ldi  r31, 0xFF  ; 255
  16:  8f 3f         cpi  r24, 0xFF  ; 255
  18:  9f 07         cpc  r25, r31
  1a:  a9 f7         brne  .-22       ; 0x6 <__zero_reg__+0x5>
  1c:  08 95         ret

0000001e <main>:
  1e:  1f 93         push  r17
  20:  8f ef         ldi  r24, 0xFF  ; 255
  22:  81 bb         out  0x11, r24  ; 17
  24:  8b bb         out  0x1b, r24  ; 27
  26:  1f ef         ldi  r17, 0xFF  ; 255
  28:  12 ba         out  0x12, r1  ; 18
  2a:  0e 94 00 00   call  0  ; 0x0 <delay_ms.clone.0>
  2e:  12 bb         out  0x12, r17  ; 18
  30:  0e 94 00 00   call  0  ; 0x0 <delay_ms.clone.0>
  34:  f9 cf         rjmp  .-14       ; 0x28 <main+0xa>

Sollte main nicht auf Adresse 0 liegen?

von iekelig (Gast)


Lesenswert?

Johannes Hübner schrieb:
>  sobald eine Unterroutine entsteht (weil nicht inlined wird),
> läufts nicht mehr.
Das klingt nach einem Problem mit dem Stack. Richtigen µP ausgewählt?

> Sollte main nicht auf Adresse 0 liegen?
An Adresse 0 im Flash liegt die (Achtung langes Wort) 
Interruptvektorentabelle.

von Johannes H. (jhuebner)


Lesenswert?

Danke für die schnell Antwort!

Also auf dem Controller steht ATMEGA32 und dem Compiler gebe ich 
-mmcu=atmega32 mit. Sollte doch stimmen?

Wenn ich meine Hilfsroutine mit

   DDRD = 0xFF;
   PORTD = 0;
   _delay_ms(500);
   PORTD = 0xFF;
   _delay_ms(500);

befülle, dann blinkts. Als ob er direkt da reinläuft statt in die main.

von iekelig (Gast)


Lesenswert?

Johannes Hübner schrieb:
> Danke für die schnell Antwort!
>
> Also auf dem Controller steht ATMEGA32 und dem Compiler gebe ich
> -mmcu=atmega32 mit. Sollte doch stimmen?
Ja.


Was verstehst du unter
> Hilfsroutine
?

Läuft der Wachhund? (Watchdog)

von Johannes H. (jhuebner)


Lesenswert?

Mit Hilfsroutine meine ich folgendes:

static void SetTxPin(uint16_t onTm)
{
   DDRD = 0xFF;
   PORTD = 0;
   _delay_ms(500);
   PORTD = 0xFF;
   _delay_ms(500);
}

static void SendBit(char bit)
{
   if (bit)
   {
      SetTxPin(ONE_TIME);
   }
   else
   {
      SetTxPin(ZERO_TIME);
   }
}

static void SendByte(char byte)
{
   int bit = 0;
   for (; bit < 8; bit++, byte>>=1)
   {
      SendBit(byte & 1);
   }
}

int main(void)
{
    DDRD = 0xFF;
    PORTA = 0xFF;

    while(1)
    {
       SendByte(PINA);
    }

    return 0;
}

SendByte und SendBit werden inlined, SetTxPin nicht weil es 2x 
aufgerufen wird. Lasse ich das DDRD in SetTxPin weg, so blinkt nix. 
Drehe ich die LED sinngemäß rum (an wenn PORT=1) dann blinkt es dunkel 
über den Pullup. Das kann doch nicht wahr sein?? So ein Bug wäre ja wohl 
schon jemand aufgefallen.

von Johannes H. (jhuebner)


Lesenswert?

Nachtrag: wenn ich den Code aus SetTxPin direkt in SendBit kopiere:

static void SendBit(char bit)
{
   if (bit)
   {
      PORTD = 0;
      _delay_ms(500);
      PORTD = 0xFF;
      _delay_ms(100);
   }
   else
   {
      PORTD = 0;
      _delay_ms(100);
      PORTD = 0xFF;
      _delay_ms(500);
   }
}

entsteht eine große main und das Programm läuft wie gewünscht.

von Jannis C. (kabelwurm)


Lesenswert?

JTAG an PORTD deaktiviert?
Gruß Jannis

von Johannes H. (jhuebner)


Lesenswert?

Ok, habs gefunden. Dem Linker muss man auch sagen, welche MCU man nutzt. 
Und das hat CodeBlocks verrafft. Da stand nur

-mmcu=

habe ein

-mmcu=atmega32

draus gemacht und schon geht alles. Jetzt ist auch die Vektortabelle da, 
die hat vorher gefehlt.

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.