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.