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?
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?
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.
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.
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)
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.