ATMega32 Problem (kanns nicht besser formulieren)

OP #2932030
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?
OP #2932103
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?
OP #2932169
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.
OP #2932178
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren