Hallo, folgender Code: char text[] ="HelloAVR"; text[0]='H'; text[1]='e'; for(int ci=0; text[ci] != '\0'; ++ci) { putch(text[ci]); } putch('\n'); (putch gibt das Zeichen auf dem uart aus, geht auch) erzeugt folgende Ausgabe auf dem Terminal: Heì\0x01\0x0f\0x01\0x03\0x02 Das verstehe ich nicht. warum funktioniert die Zuweisung in der initialisierung nicht? Vielleicht kann mir jemand einen Tip geben? Danke! MFG Martin
Das ist kein komplettes Programm. Die Ursache kann in dem nicht angegebenen Teil stecken.
#include <avr/io.h> // I/O Funktionen #include <stdint.h> // Datentypen z.B. uint32_t #include <avr/pgmspace.h> #define F_CPU 14745600UL #include <util/delay.h> #include <string.h> #define HW_VER 0x02 #define SW_MAJOR 0x01 #define SW_MINOR 0x12 #define BAUD_RATE 115200 #define DECRYPT 0 #define ENCRYPT 1 #define SIG1 0x1E #define SIG2 0x97 #define SIG3 0x02 #define PAGE_SIZE 0x80U //128 words #define UART1 #define LED_DDR DDRB #define LED_PORT PORTB #define LED_PIN PINB #define LED PINB7 #define SW_DDR DDRF #define SW_PORT PORTF #define SW_PIN PINF #define SW0 PINF7 //Schalter0 an Pin 7 #define SW1 PINF6 //Schalter1 an Pin 6 #define mswait 10 struct flags_struct { unsigned flag_1 : 1; // Schalter; 0: SW0 1: SW1 unsigned flag_2 : 1; unsigned flag_3 : 1; unsigned flag_4 : 1; unsigned flag_5 : 1; unsigned flag_6 : 1; unsigned flag_7 : 1; unsigned flag_8 : 1; } flags; void wait10ms(uint16_t xms); void inituart(void); void lese_Schalter(void); void putch(char ch); char getch(void); int main(void) { flags.flag_2 = 0; SW_DDR &= ~(1 << SW0); //Ausgang=1 Eingang=0 daher l?schen SW_DDR &= ~(1 << SW1); SW_PORT |= (1 << SW0); //Bei Eingang steuer Port die Pull-up-Widerst?nde! SW_PORT |= (1 << SW1); // hier: Pull-up auf EIN! asm volatile("nop\n\t"); LED_DDR |= (1 << LED); // LED auf Ausgang LED_PORT &= ~(1 << LED); // LED EIN inituart(); for (;;) { char text[] = "HelloAVR"; //PGM_P text = {"HelloAVR"}; text[0]='H'; text[7]='R'; for(int ci=0; text[ci] != '\0'; ++ci) { putch(text[ci]); } putch('\n'); } } } void inituart() { UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; UCSR1A = 0x00; // UCSR1C = 0x06; UCSR1B = _BV(TXEN1)|_BV(RXEN1); // bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A while (!(UCSR1A & (1<<UDRE))) // warten bis Senden moeglich { } PGM_P welcome = {"HelloAVR; Matthias Vogt - build 070106\n\r"}; for(int i=0; welcome[i] != '\0'; ++i) { putch(welcome[i]); } } void putch(char ch) { while (!(UCSR1A & _BV(UDRE1))); UDR1 = ch; } char getch(void) { while(!(UCSR1A & _BV(RXC1))); return (UDR1); }
Neuere Versin, sorry. Diese geht aber genausoenig! #include <avr/io.h> // I/O Funktionen #include <stdint.h> // Datentypen z.B. uint32_t #include <avr/pgmspace.h> #define F_CPU 14745600UL #include <util/delay.h> #include <string.h> #define HW_VER 0x02 #define SW_MAJOR 0x01 #define SW_MINOR 0x12 #define BAUD_RATE 115200 #define DECRYPT 0 #define ENCRYPT 1 #define SIG1 0x1E #define SIG2 0x97 #define SIG3 0x02 #define PAGE_SIZE 0x80U //128 words #define UART1 #define LED_DDR DDRB #define LED_PORT PORTB #define LED_PIN PINB #define LED PINB7 #define SW_DDR DDRF #define SW_PORT PORTF #define SW_PIN PINF #define SW0 PINF7 //Schalter0 an Pin 7 #define SW1 PINF6 //Schalter1 an Pin 6 #define mswait 10 void wait10ms(uint16_t xms); void inituart(void); void lese_Schalter(void); void putch(char ch); char getch(void); int main(void) { SW_DDR &= ~(1 << SW0); //Ausgang=1 Eingang=0 daher l?schen SW_DDR &= ~(1 << SW1); SW_PORT |= (1 << SW0); //Bei Eingang steuer Port die Pull-up-Widerst?nde! SW_PORT |= (1 << SW1); // hier: Pull-up auf EIN! asm volatile("nop\n\t"); LED_DDR |= (1 << LED); // LED auf Ausgang LED_PORT &= ~(1 << LED); // LED EIN inituart(); for (;;) { char text[] = "HelloAVR"; text[0]='H'; text[7]='R'; for(int ci=0; text[ci] != '\0'; ++ci) { putch(text[ci]); } putch('\n'); } } void inituart() { UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; UCSR1A = 0x00; // UCSR1C = 0x06; UCSR1B = _BV(TXEN1)|_BV(RXEN1); } void putch(char ch) { while (!(UCSR1A & _BV(UDRE1))); UDR1 = ch; } char getch(void) { while(!(UCSR1A & _BV(RXC1))); return (UDR1); }
Den Code des Programmes hab ich übrigens hauptsächlihc aus Beispielen aus dem Internet zusammenkopiert, auch den Teil mit dem String,daher könnte der Fehler auch irgendwo anders liegen. Gruß Martin
mit der EZuweisung scheint aber was fault zu sein. char text[] = "HelloAVR"; hier: text[0]='H'; text[7]='R'; habe ich das ja eingefügt, und "H" und "R" kommen an. nur der Rest der nicht nochmal neu zugewiesen wird wird "zerstückelt": "aH%ì\0x01\0x0f\0x01\0x03R" als Hexdump: 0x61 a 0x48 H 0x25 EM 0xec 0x01 SOH 0x0f SI 0x01 SOH 0x03 ETX 0x52 R 0x0a LF a,H,R,LF sind OK.
Ich rate anhand der Namen der IO-Register, dass es für einen Atmega128 sein soll. Sourcecode #2 kompiliert nicht mit: AVR Studio 4.12.498 Service Pack 4 GUI Version 4, 12, 0, 491 AVR Simulator 1, 0, 1, 8 ATMEGA8 243 Operating System Major 4 Minor 10 PlatformID 1 Build 67766446 A Plugins: AVRPLUGINAVRASMOBJECT 1, 0, 0, 43 STK500DLL 1, 0, 1, 0 AVRPLUGINAVRGCCPLUGIN 1, 0, 0, 6 Fehlermeldungen im Build-Fenster: Build started 7.1.2007 at 16:49:44 avr-gcc.exe -mmcu=atmega128 -Wall -gdwarf-2 -O0 -fsigned-char -MD -MP -MT martin_text.o -MF dep/martin_text.o.d -c ../martin_text.c ../martin_text.c: In function `main': ../martin_text.c:57: error: 'for' loop initial declaration used outside C99 mode make: *** [martin_text.o] Error 1 Ich habe statt dem for ein while benutzt
1 | for (;;) |
2 | {
|
3 | char text[] = "HelloAVR"; |
4 | text[0]='H'; |
5 | text[7]='R'; |
6 | #if 0
|
7 | for(int ci=0; text[ci] != '\0'; ++ci)
|
8 | {
|
9 | putch(text[ci]);
|
10 | }
|
11 | #else
|
12 | {
|
13 | int ci = 0; |
14 | while(text[ci] != '\0') |
15 | {
|
16 | putch(text[ci]); |
17 | ci += 1; |
18 | }
|
19 | }
|
20 | #endif
|
21 | putch('\n'); |
22 | }
|
Damit funktioniert die Routine im AVR Simulator.
Der C99 Fehlermeldung bin ich nachgegangen und danach die Source wieder abgeändert:
1 | #if 1
|
2 | {
|
3 | int ci; |
4 | for(ci=0; text[ci] != '\0'; ++ci) |
5 | {
|
6 | putch(text[ci]); |
7 | }
|
8 | }
|
9 | #else
|
10 | {
|
11 | int ci = 0; |
12 | while(text[ci] != '\0') |
13 | {
|
14 | putch(text[ci]); |
15 | ci += 1; |
16 | }
|
17 | }
|
18 | #endif
|
Funktioniert im AVR Simulator auch.
Hallo, danke für die Mühe. Aber kannst du dir vorstellen, wo der Fehler sein kann? Wenn ich jeden Buchstaben einzeln zuweise: char text[10]; text[0]='H'; text[1]='e'; text[2]='l'; text[3]='l'; text[4]='o'; text[5]='A'; text[6]='V'; text[7]='R'; text[8]='\0'; geht es auch: HelloAVR Es liegt also an der Zuweisung: char text[] = "HelloAVR"; :confused: MFG Martin
Ich kann im Moment nicht live auf einem Atmega128 testen. Läuft dein Projekt im AVR Simulator und kannst du das Fehlverhalten dort auch beobachten? Ich kann den Fehler provozieren, wenn ich den falschen AVR Typ im AVR Studio einstelle (beim AVR Simulator und/oder im Projekt). Bitte kontrolliere deine Projekteinstellungen zum Prozessortyp beim Kompilieren.
Hab' mir einen ATmega128 in den STK gesteckt und die Baudrate auf 9600 geändert, weil das gerade mein angeklemmtest Terminal macht:
1 | loAVR |
2 | HelloAVR |
3 | HelloAVR |
4 | HelloAVR |
5 | HelloAVR |
6 | HelloAVR |
7 | HelloAVR |
8 | HelloAVR |
9 | HelloAVR |
10 | HelloAVR |
usw. usf. Da du offenbar Probleme mit den initialisierten Daten hast, vermute ich die Ursache eher in deinem avr-objcopy-Kommando. (Ich habe deine zweite Version genommen, mit -std=gnu99 compiliert auf einem AVR-GCC 4.1.1.)
Hallo, meine Optionen: Compiler: avr-gcc -c -fmessage-length=0 -Wall -Wstrict-prototypes -I/usr/avr/include -mmcu=atmega128 -minit-stack=__stack -O0 -fshort-enums -fpack-struct -funsigned-char -funsigned-bitfields -std=gnu99 -g2 Linker: -lm -Wl,-Map=$(@:%.elf=%.map) --cref --oformat=elf32-avr Objectcopy: avr-objcopy -O ihex HelloAVR.elf HelloAVR.hex MFG
Im AVRSimulator läuft es auch mit diesen Optionen. Ich habe das Projekt gepackt und angefügt, vielleicht ist das "funktionierende" HEX-File interessant für dich. Toolchain war WinAVR-20060125 aus AVRStudio heraus bedient. Bei mir heisst das Projekt anders. Leider kann man damit nur auf ASM-Ebene in AVRStudio debuggen. Ich habe es auf die Schnelle nicht geschafft, das externe Makefile so anzupassen, dass AVRStudio die C-Source akzeptiert. Aber das bisschen ASM-Code hat man auch schnell so im Blick.
> Ich habe es auf die Schnelle nicht geschafft, das externe Makefile so > anzupassen, dass AVRStudio die C-Source akzeptiert. Hab's raus: Es ist ein schädlicher Zeilenumbruch in der Zeile mit den CFGLAS drin ;-) Das muss alles in eine Zeile... Jetzt geht in diesem Projekt auch Debugging auf C-Source Ebene in AVRStudio. Merke: Makefiles nicht mit beliebigen Editoren bearbeiten! Wenn der Editor auf automatische Zeilenumbrüche eingestellt ist oder Tabs in Leerzeichen wandelt oder \n zu \r\n macht, kann es schwer auffindbaren Ärger geben...
Alles sowas sollte ein Editor ja auch nicht machen... Zeilen im Makefile kann man umbrechen, indem man am Ende ein \ notiert (aber dann direkt danach das Newline!).
Hallo, danke euch! Das Hex File läuft bei mir auch. Nur weiß ich leider immer noch nicht wie ich es selbst compilieren kann. Deine AVRStudio-Files kann ich leider nicht gebrauchen, da ich unter LINUX arbeite. Aber wenn die Flags so auch bei dir gehen, kann das ja der Fehler auch nicht sein. wisst ihr vielleicht noch eine "Schraube" an der ich drehen kann? Danke und Grüße Martin
Macht deine Toolchain unter Linux auch die *.lss und *.map Dateien? Wie sehen die im Vergleich zur funktionierenden Version aus? Aus dem Listing (*.lss) kann man sehen wie char text[] gefüllt wird und aus dem Map-File (*.map), wo die Daten herkommen. Bei deinem Programm stammt "HelloAVR" ja aus dem FLASH-ROM, wird von dort von __do_copy_data ins SRAM kopiert (.data Bereich zwischen __data_start und __data_end) und wird dann in main() über Register auf den Stack kopiert. Wie Jörg schon schrieb, ist da irgendwas faul. Was findest du vielleicht anhand der funktionierenden Variante heraus. Achtung: Ich habe allerdings noch zwei globale char Variablen vom Debuggen her im Programm vergessen. Die Zuweisungen sind zwar auskommentiert, aber der Platz wird noch angelegt.
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.