Atmega88 Code kompiliert ohne Fehler und läuft nicht

#6664303
Lesenswert?

Nabend zusammen,

habe endlich mein Mini-Beispiel für eine funktionierende USART 
Schnittstelle hinbekommen.
1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
#define BAUD 9600UL
5
#define UBRR_VALUE ((F_CPU+BAUD*8)/(BAUD*16)-1)
6
#define BAUD_REAL (F_CPU/(16*(UBRR_VALUE+1)))
7
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
8

9
int main( void ){
10
    if ((BAUD_REAL < 990)||(BAUD_ERROR > 1010)){
11
        DDRD |= (1<<PD6);
12
        PORTD |= (1<<PD6);
13
    }
14

15
    UBRR0H = (uint8_t)(UBRR_VALUE >> 8);
16
    UBRR0L = (uint8_t)UBRR_VALUE;
17
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
18
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
19

20
    while(1){
21
        UDR0 = 'B';
22
        _delay_ms(2000);
23
    }   
24
}

Funktioniert und macht genau das was es soll. Ich verwende hier einen 
sh-u09c5 zum Lesen.

Jetzt wollte ich das Ganze natürlich erweitern auf Strings und habe 
folgende Funktionen hinzugefügt:
1
int uart_putc(unsigned char c);
2
void uart_puts(char *s);
3

4
int uart_putc(unsigned char c)
5
{
6
    return 0;
7
}
8

9
void uart_puts (char *s)
10
{
11
    while (*s)
12
    {
13
        uart_putc(*s);
14
        s++;
15
    }
16
}
Es kompiliert-ich bekomme per avrdude keine Fehler o.Ä. Aber es wird 
nichts mehr gesendet. Ich rufe beide Funktionen nicht einmal auf und 
dennoch macht es irgendwie alles kaputt.
Wenn ich die beiden Funktionen lösche und den Atmega erneut bespiele 
klappt alles wieder wunderbar. Ich kann es mir absolut nicht erklären. 
Ich hoffe ihr könnt mir einen Tipp geben.
#6664414
Lesenswert?

pnp schrieb:
> Schau dir mal genau an, was putc() macht :-)

In meinem Fall macht es natürlich nichts außer direkt raus zu springen 
aber das ist ja nur dafür gedacht um zu zeigen, dass der eigentliche 
Code nicht mehr funktioniert obwohl doch die Funktionen nirgendwo 
aufgerufen werden.

Ich hatte das aus dem Tutorial: 
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART#Senden_einer_Zeichenkette_.28String.29 
und die Funktionen sahen vorher so aus:
1
int uart_putc(unsigned char c)
2
{
3
    while (!(UCSR0A & (1<<UDRE0))){}
4
    UDR0 = c;
5
    return 0;
6
}
7

8

9
void uart_puts (char *s)
10
{
11
    while (*s)
12
    {   
13
        uart_putc(*s);
14
        s++;
15
    }
16
}
Da dies aber zum selben Ergebnis führte - nämlich dass nichts mehr 
gesendet wird (obwohl beide Funktionen erneut nirgendwo aufgerufen 
wurden) - habe ich die while Schleife aus uart_putc entfernt. Ich 
dachte, dass ich irgendwas mit UCSR0A oder UDRE0 falsch mache und habs 
dann auf das nötigste reduziert.
#6664427
Lesenswert?

Sehr gerne
1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
#define BAUD 9600UL                  
5
#define UBRR_VALUE ((F_CPU+BAUD*8)/(BAUD*16)-1)
6
#define BAUD_REAL (F_CPU/(16*(UBRR_VALUE+1)))
7
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
8
#define TX_BUFFER_SIZE 128
9
 
10
int uart_putc(unsigned char c);
11
void uaart_puts(char *s);
12

13
int main( void )
14
{
15
    if ((BAUD_REAL < 990)||(BAUD_ERROR > 1010)){
16
        DDRD |= (1<<PD6);
17
        PORTD |= (1<<PD6);
18
    }
19

20
    UBRR0H = (uint8_t)(UBRR_VALUE >> 8);       
21
    UBRR0L = (uint8_t)UBRR_VALUE;            
22
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);  
23
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
24

25
    while(1){
26
        UDR0 = 'B';
27
  _delay_ms(2000);
28
    }
29
    
30
}
31
int uart_putc(unsigned char c)
32
{
33
    return 0;
34
}
35

36
void uart_puts (char *s)
37
{
38
    while (*s)
39
    {
40
        uart_putc(*s);
41
        s++;
42
    }
43
}
Filename uart_verysimple.c
1
avr-gcc -mmcu=atmega88a -Wall -Os -DF_CPU=8000000UL -c uart_verysimple.c -o uart_verysimple.o;
2
avr-gcc uart_verysimple.o -o uart_verysimple.elf;
3
avr-objcopy -O ihex -j .text -j .data uart_verysimple.elf uart_verysimple.hex;
4
avrdude -c usbasp -pm88 -U flash:w:uart_verysimple.hex:a;
ckdiv8 Bit ist ausgeschaltet (auf 1 gesetzt)
Moderator (Firma: Titel) Persönliche Seite #6664445
Lesenswert?

Thomas F. schrieb:
> Vergleich mal Zeile 11 mit Zeile 36.
Im obigen Original war das noch anders.
Ja, da wäre es manchmal sinnvoller, einfach die *.c Datei anzuhängen...

Udo F. schrieb:
> Sehr gerne
Und was tut jetzt der Code? Oder was erwartest du dass der tut?

Udo F. schrieb:
> habe ich die while Schleife aus uart_putc entfernt. Ich dachte, dass ich
> irgendwas mit UCSR0A oder UDRE0 falsch mache und habs dann auf das nötigste
> reduziert.
Genau das, was du da entfernt hast, ist "das Nötigste", denn diese Zeile 
sorgt dafür, dass der UART nicht einfach überfahren, sondern die 
Übertragung jedes einzelnen Bytes abgewartet wird.
In dem ganz Code vom ersten Post übernimmt das Delay das Abwarten auf 
das Freiwerden des UART-TX-Registers.
#6664455
Lesenswert?

Hugo H. schrieb:
> Thomas F. schrieb:
>> Vergleich mal Zeile 11 mit Zeile 36.
>
> Ja - und praktisch ist auch immer, wenn man Funktionen, die ausgeführt
> werden sollen, (aus MAIN heraus) aufruft :-)
>
> Dann funktioniert das Beispiel auch ...
>
> Nicht genutzter Code / Variablen werden nicht compiliert - macht ja auch
> wenig Sinn.

Nein weil genau das will ich ja damit zeigen. Es gibt Funktionen, die 
eben nicht aufgerufen werden und es aber nicht mehr funktioniert.
Ich erwarte doch, dass wenn ich Code habe, der nicht aufgerufen wird, 
somit nicht compiliert wird, keine Änderung im Programm bewirkt.
Ohne die beiden uart Funktionen wird alle 2 Sekunden ein B geschrieben 
was ich auch mittels sh-u09c5 und hterm lesen/sehen kann.
Mit diesen Funktionen, die ja nichts machen und auch nicht aufgerufen 
werden wird nichts mehr vom Controller geschickt. Obwohl die main ja 
unangetastet ist.
#6664462
Lesenswert?

Udo F. schrieb:
> Es gibt Funktionen, die
> eben nicht aufgerufen werden und es aber nicht mehr funktioniert.

Nach Änderung mit den unsinnigen Funktionen:
1
uart.elf:     file format elf32-avr
2

3
Sections:
4
Idx Name          Size      VMA       LMA       File off  Algn
5
  0 .data         00000000  00800100  00800100  000000d0  2**0
6
                  CONTENTS, ALLOC, LOAD, DATA
7
  1 .text         0000007c  00000000  00000000  00000054  2**1
8
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
9
  2 .comment      00000030  00000000  00000000  000000d0  2**0
10
                  CONTENTS, READONLY
11
  3 .note.gnu.avr.deviceinfo 0000003c  00000000  00000000  00000100  2**2
12
                  CONTENTS, READONLY
13
  4 .debug_aranges 00000030  00000000  00000000  0000013c  2**0
14
                  CONTENTS, READONLY, DEBUGGING
15
  5 .debug_info   00000764  00000000  00000000  0000016c  2**0
16
                  CONTENTS, READONLY, DEBUGGING
17
  6 .debug_abbrev 000006b7  00000000  00000000  000008d0  2**0
18
                  CONTENTS, READONLY, DEBUGGING
19
  7 .debug_line   0000029a  00000000  00000000  00000f87  2**0
20
                  CONTENTS, READONLY, DEBUGGING
21
  8 .debug_frame  00000044  00000000  00000000  00001224  2**2
22
                  CONTENTS, READONLY, DEBUGGING
23
  9 .debug_str    00000388  00000000  00000000  00001268  2**0
24
                  CONTENTS, READONLY, DEBUGGING
25
 10 .debug_loc    00000056  00000000  00000000  000015f0  2**0
26
                  CONTENTS, READONLY, DEBUGGING
27
 11 .debug_ranges 00000020  00000000  00000000  00001646  2**0
28
                  CONTENTS, READONLY, DEBUGGING
29

30
Disassembly of section .text:
31

32
00000000 <__vectors>:
33
   0:  19 c0         rjmp  .+50       ; 0x34 <__ctors_end>
34
   2:  20 c0         rjmp  .+64       ; 0x44 <__bad_interrupt>
35
   4:  1f c0         rjmp  .+62       ; 0x44 <__bad_interrupt>
36
   6:  1e c0         rjmp  .+60       ; 0x44 <__bad_interrupt>
37
   8:  1d c0         rjmp  .+58       ; 0x44 <__bad_interrupt>
38
   a:  1c c0         rjmp  .+56       ; 0x44 <__bad_interrupt>
39
   c:  1b c0         rjmp  .+54       ; 0x44 <__bad_interrupt>
40
   e:  1a c0         rjmp  .+52       ; 0x44 <__bad_interrupt>
41
  10:  19 c0         rjmp  .+50       ; 0x44 <__bad_interrupt>
42
  12:  18 c0         rjmp  .+48       ; 0x44 <__bad_interrupt>
43
  14:  17 c0         rjmp  .+46       ; 0x44 <__bad_interrupt>
44
  16:  16 c0         rjmp  .+44       ; 0x44 <__bad_interrupt>
45
  18:  15 c0         rjmp  .+42       ; 0x44 <__bad_interrupt>
46
  1a:  14 c0         rjmp  .+40       ; 0x44 <__bad_interrupt>
47
  1c:  13 c0         rjmp  .+38       ; 0x44 <__bad_interrupt>
48
  1e:  12 c0         rjmp  .+36       ; 0x44 <__bad_interrupt>
49
  20:  11 c0         rjmp  .+34       ; 0x44 <__bad_interrupt>
50
  22:  10 c0         rjmp  .+32       ; 0x44 <__bad_interrupt>
51
  24:  0f c0         rjmp  .+30       ; 0x44 <__bad_interrupt>
52
  26:  0e c0         rjmp  .+28       ; 0x44 <__bad_interrupt>
53
  28:  0d c0         rjmp  .+26       ; 0x44 <__bad_interrupt>
54
  2a:  0c c0         rjmp  .+24       ; 0x44 <__bad_interrupt>
55
  2c:  0b c0         rjmp  .+22       ; 0x44 <__bad_interrupt>
56
  2e:  0a c0         rjmp  .+20       ; 0x44 <__bad_interrupt>
57
  30:  09 c0         rjmp  .+18       ; 0x44 <__bad_interrupt>
58
  32:  08 c0         rjmp  .+16       ; 0x44 <__bad_interrupt>
59

60
00000034 <__ctors_end>:
61
  34:  11 24         eor  r1, r1
62
  36:  1f be         out  0x3f, r1  ; 63
63
  38:  cf ef         ldi  r28, 0xFF  ; 255
64
  3a:  d4 e0         ldi  r29, 0x04  ; 4
65
  3c:  de bf         out  0x3e, r29  ; 62
66
  3e:  cd bf         out  0x3d, r28  ; 61
67
  40:  02 d0         rcall  .+4        ; 0x46 <main>
68
  42:  1a c0         rjmp  .+52       ; 0x78 <_exit>
69

70
00000044 <__bad_interrupt>:
71
  44:  dd cf         rjmp  .-70       ; 0x0 <__vectors>
72

73
00000046 <main>:
74
{
75
  if ((BAUD_REAL < 990)||(BAUD_ERROR > 1010)){
76
    DDRD |= (1<<PD6);
77
    PORTD |= (1<<PD6);
78
  }
79
  UBRR0H = (uint8_t)(UBRR_VALUE >> 8);
80
  46:  10 92 c5 00   sts  0x00C5, r1  ; 0x8000c5 <__TEXT_REGION_LENGTH__+0x7fe0c5>
81
  UBRR0L = (uint8_t)UBRR_VALUE;
82
  4a:  83 e3         ldi  r24, 0x33  ; 51
83
  4c:  80 93 c4 00   sts  0x00C4, r24  ; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7fe0c4>
84
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
85
  50:  86 e0         ldi  r24, 0x06  ; 6
86
  52:  80 93 c2 00   sts  0x00C2, r24  ; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7fe0c2>
87
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
88
  56:  88 e1         ldi  r24, 0x18  ; 24
89
  58:  80 93 c1 00   sts  0x00C1, r24  ; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7fe0c1>
90
  while(1){
91
    UDR0 = 'B';
92
  5c:  e6 ec         ldi  r30, 0xC6  ; 198
93
  5e:  f0 e0         ldi  r31, 0x00  ; 0
94
  60:  82 e4         ldi  r24, 0x42  ; 66
95
  62:  80 83         st  Z, r24
96
  #else
97
    //round up by default
98
    __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
99
  #endif
100

101
  __builtin_avr_delay_cycles(__ticks_dc);
102
  64:  2f ef         ldi  r18, 0xFF  ; 255
103
  66:  33 ed         ldi  r19, 0xD3  ; 211
104
  68:  90 e3         ldi  r25, 0x30  ; 48
105
  6a:  21 50         subi  r18, 0x01  ; 1
106
  6c:  30 40         sbci  r19, 0x00  ; 0
107
  6e:  90 40         sbci  r25, 0x00  ; 0
108
  70:  e1 f7         brne  .-8        ; 0x6a <main+0x24>
109
  72:  00 c0         rjmp  .+0        ; 0x74 <main+0x2e>
110
  74:  00 00         nop
111
  76:  f5 cf         rjmp  .-22       ; 0x62 <main+0x1c>
112

113
00000078 <_exit>:
114
  78:  f8 94         cli
115

116
0000007a <__stop_program>:
117
  7a:  ff cf         rjmp  .-2        ; 0x7a <__stop_program>

Vor Änderung (die Funktionen entfernt):
1
uart.elf:     file format elf32-avr
2

3
Sections:
4
Idx Name          Size      VMA       LMA       File off  Algn
5
  0 .data         00000000  00800100  00800100  000000d0  2**0
6
                  CONTENTS, ALLOC, LOAD, DATA
7
  1 .text         0000007c  00000000  00000000  00000054  2**1
8
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
9
  2 .comment      00000030  00000000  00000000  000000d0  2**0
10
                  CONTENTS, READONLY
11
  3 .note.gnu.avr.deviceinfo 0000003c  00000000  00000000  00000100  2**2
12
                  CONTENTS, READONLY
13
  4 .debug_aranges 00000020  00000000  00000000  0000013c  2**0
14
                  CONTENTS, READONLY, DEBUGGING
15
  5 .debug_info   000006ff  00000000  00000000  0000015c  2**0
16
                  CONTENTS, READONLY, DEBUGGING
17
  6 .debug_abbrev 00000667  00000000  00000000  0000085b  2**0
18
                  CONTENTS, READONLY, DEBUGGING
19
  7 .debug_line   0000026e  00000000  00000000  00000ec2  2**0
20
                  CONTENTS, READONLY, DEBUGGING
21
  8 .debug_frame  00000024  00000000  00000000  00001130  2**2
22
                  CONTENTS, READONLY, DEBUGGING
23
  9 .debug_str    00000374  00000000  00000000  00001154  2**0
24
                  CONTENTS, READONLY, DEBUGGING
25
 10 .debug_ranges 00000010  00000000  00000000  000014c8  2**0
26
                  CONTENTS, READONLY, DEBUGGING
27

28
Disassembly of section .text:
29

30
00000000 <__vectors>:
31
   0:  19 c0         rjmp  .+50       ; 0x34 <__ctors_end>
32
   2:  20 c0         rjmp  .+64       ; 0x44 <__bad_interrupt>
33
   4:  1f c0         rjmp  .+62       ; 0x44 <__bad_interrupt>
34
   6:  1e c0         rjmp  .+60       ; 0x44 <__bad_interrupt>
35
   8:  1d c0         rjmp  .+58       ; 0x44 <__bad_interrupt>
36
   a:  1c c0         rjmp  .+56       ; 0x44 <__bad_interrupt>
37
   c:  1b c0         rjmp  .+54       ; 0x44 <__bad_interrupt>
38
   e:  1a c0         rjmp  .+52       ; 0x44 <__bad_interrupt>
39
  10:  19 c0         rjmp  .+50       ; 0x44 <__bad_interrupt>
40
  12:  18 c0         rjmp  .+48       ; 0x44 <__bad_interrupt>
41
  14:  17 c0         rjmp  .+46       ; 0x44 <__bad_interrupt>
42
  16:  16 c0         rjmp  .+44       ; 0x44 <__bad_interrupt>
43
  18:  15 c0         rjmp  .+42       ; 0x44 <__bad_interrupt>
44
  1a:  14 c0         rjmp  .+40       ; 0x44 <__bad_interrupt>
45
  1c:  13 c0         rjmp  .+38       ; 0x44 <__bad_interrupt>
46
  1e:  12 c0         rjmp  .+36       ; 0x44 <__bad_interrupt>
47
  20:  11 c0         rjmp  .+34       ; 0x44 <__bad_interrupt>
48
  22:  10 c0         rjmp  .+32       ; 0x44 <__bad_interrupt>
49
  24:  0f c0         rjmp  .+30       ; 0x44 <__bad_interrupt>
50
  26:  0e c0         rjmp  .+28       ; 0x44 <__bad_interrupt>
51
  28:  0d c0         rjmp  .+26       ; 0x44 <__bad_interrupt>
52
  2a:  0c c0         rjmp  .+24       ; 0x44 <__bad_interrupt>
53
  2c:  0b c0         rjmp  .+22       ; 0x44 <__bad_interrupt>
54
  2e:  0a c0         rjmp  .+20       ; 0x44 <__bad_interrupt>
55
  30:  09 c0         rjmp  .+18       ; 0x44 <__bad_interrupt>
56
  32:  08 c0         rjmp  .+16       ; 0x44 <__bad_interrupt>
57

58
00000034 <__ctors_end>:
59
  34:  11 24         eor  r1, r1
60
  36:  1f be         out  0x3f, r1  ; 63
61
  38:  cf ef         ldi  r28, 0xFF  ; 255
62
  3a:  d4 e0         ldi  r29, 0x04  ; 4
63
  3c:  de bf         out  0x3e, r29  ; 62
64
  3e:  cd bf         out  0x3d, r28  ; 61
65
  40:  02 d0         rcall  .+4        ; 0x46 <main>
66
  42:  1a c0         rjmp  .+52       ; 0x78 <_exit>
67

68
00000044 <__bad_interrupt>:
69
  44:  dd cf         rjmp  .-70       ; 0x0 <__vectors>
70

71
00000046 <main>:
72
{
73
  if ((BAUD_REAL < 990)||(BAUD_ERROR > 1010)){
74
    DDRD |= (1<<PD6);
75
    PORTD |= (1<<PD6);
76
  }
77
  UBRR0H = (uint8_t)(UBRR_VALUE >> 8);
78
  46:  10 92 c5 00   sts  0x00C5, r1  ; 0x8000c5 <__TEXT_REGION_LENGTH__+0x7fe0c5>
79
  UBRR0L = (uint8_t)UBRR_VALUE;
80
  4a:  83 e3         ldi  r24, 0x33  ; 51
81
  4c:  80 93 c4 00   sts  0x00C4, r24  ; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7fe0c4>
82
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
83
  50:  86 e0         ldi  r24, 0x06  ; 6
84
  52:  80 93 c2 00   sts  0x00C2, r24  ; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7fe0c2>
85
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
86
  56:  88 e1         ldi  r24, 0x18  ; 24
87
  58:  80 93 c1 00   sts  0x00C1, r24  ; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7fe0c1>
88
  while(1){
89
    UDR0 = 'B';
90
  5c:  e6 ec         ldi  r30, 0xC6  ; 198
91
  5e:  f0 e0         ldi  r31, 0x00  ; 0
92
  60:  82 e4         ldi  r24, 0x42  ; 66
93
  62:  80 83         st  Z, r24
94
  #else
95
    //round up by default
96
    __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
97
  #endif
98

99
  __builtin_avr_delay_cycles(__ticks_dc);
100
  64:  2f ef         ldi  r18, 0xFF  ; 255
101
  66:  33 ed         ldi  r19, 0xD3  ; 211
102
  68:  90 e3         ldi  r25, 0x30  ; 48
103
  6a:  21 50         subi  r18, 0x01  ; 1
104
  6c:  30 40         sbci  r19, 0x00  ; 0
105
  6e:  90 40         sbci  r25, 0x00  ; 0
106
  70:  e1 f7         brne  .-8        ; 0x6a <main+0x24>
107
  72:  00 c0         rjmp  .+0        ; 0x74 <main+0x2e>
108
  74:  00 00         nop
109
  76:  f5 cf         rjmp  .-22       ; 0x62 <main+0x1c>
110

111
00000078 <_exit>:
112
  78:  f8 94         cli
113

114
0000007a <__stop_program>:
115
  7a:  ff cf         rjmp  .-2        ; 0x7a <__stop_program>

Zeige mir bitte den Unterschied (außer den Debug-Angaben) - es gibt 
keinen. Du zeigst schlicht nicht alles und damit brauchst Du scheinbar 
auch keine Hilfe.
#6664477
Lesenswert?

Stimmt. Ich verheimliche bei meinem geheimen, komplexen Programm teile 
damit ihr die bloß nicht seht.

Ich bin Anfänger in Mikrokontroller-Entwicklung und komme nicht weiter. 
Ich kenne mich mit höheren Sprachen wir Java etc. aus aber eben nicht 
mit so low level Programmierung. Und deshalb ist ja meine Verwunderung 
so groß, dass Funktionen, die nichts machen, nicht aufgerufen werden, 
dennoch alles kaputt machen.

Es gibt exakt eine c-Datei, die ihr inzwischen vollständig habt.
Dazu gibt es die 4 Zeilen, mit denen ich den Code auf den Atmega88A 
bespiele. Das wars. Mehr ist nicht.

Ich glaube dir ja, dass, nachdem du das File analysiert hast, es keine 
Unterschiede gibt, aber dann kannst du mir doch auch glauben, dass ich 
nichts "verstecke".

Meiner Meinung nach kann es ja dann nur am Atmega88 liegen. Ich habe 
hier nochmal den output von avrdude als Anhang mitgegeben. Keine Ahnung 
ob das weiter hilft.
Angehängte Dateien:
#6664486
Lesenswert?

Udo F. schrieb:
> Meiner Meinung nach kann es ja dann nur am Atmega88 liegen.

Meiner Meinung nach liegt es an Dir und Du nimmst Du das falsche 
Hex-File

"avrdude: writing flash (66 bytes)"

Wenn ich compiliere komme ich auf

"Program Memory Usage   :  124 bytes   1,5 % Full"

Mit _delay... kann es nicht so kurz (66 bytes) sein (Meiner Meinung 
nach).
Gast #6664720
Lesenswert?

Hugo H. schrieb:
> "Program Memory Usage   :  124 bytes   1,5 % Full"
> Mit _delay... kann es nicht so kurz (66 bytes) sein (Meiner Meinung
> nach).

Das Assembler Listing endet bei 0x7a (=122) mit 2 Bytes, kommt also hin. 
Da ist das delay auch drin. Die 124 sind alle belegt, da kann es nicht 
in Ordnung sein, dass er nur 66 Bytes davon in den Flash schreibt.

Ich würde da mal weiter nachforschen, bin ziemlich sicher dass Hugo es 
auf den Punkt gebracht hat.

Die Berechnung der Baudrate überlässt man normalerweise der AVR 
Bibliothek 
https://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html
#6664782
Lesenswert?

Andreas B. schrieb:
> Dazu wäre auch mal interessant wie das compiliert wurde.
> Makefile?
> Und auch wie avrdude aufgerufen wurde.
> Da fehlt das Ganze drumherum.
Das hatte ich bereits geschrieben:
1
avr-gcc -mmcu=atmega88a -Wall -Os -DF_CPU=8000000UL -c uart_verysimple.c -o uart_verysimple.o;
2
avr-gcc uart_verysimple.o -o uart_verysimple.elf;
3
avr-objcopy -O ihex -j .text -j .data uart_verysimple.elf uart_verysimple.hex;
4
avrdude -c usbasp -pm88 -U flash:w:uart_verysimple.hex:a;

Das ganze ist in einem Bash-Skript und wird einfach mittels: 
./doStuff.sh ausgeführt. Es ist somit kein wirkliches Makefile
#6664821
Lesenswert?

Andreas B. schrieb:
> Laß hier mal:
> avrdude -c usbasp -pm88 -U flash:w:uart_verysimple.hex:a;
> das :a am Schluß weg.

Hab ich. Leider selbes Ergebnis.

Bzgl. der Anzahl der Bytes (von weiter oben). Ich habe mal die beiden 
Funktionen entfernt und mit/ohne :a den Chip bespielt.
In beiden Fällen läuft der Code wie geplant und avrdude sagt mir, dass 
er 48 Bytes geschrieben hat. Mit den Funktionen sind es 66.
Gast #6664824
Lesenswert?

Udo F. schrieb:
> In beiden Fällen läuft der Code wie geplant und avrdude sagt mir, dass
> er 48 Bytes geschrieben hat. Mit den Funktionen sind es 66.

Dass der Maschinencode eine andere Größe hat als bei Hugo mag an den 
Compiler Optionen oder der Version liegen.

Bei dir werden die unbenutzten Funktionen offenbar nicht entfernt. Ich 
denke das liegt daran, dass du die sonst üblichen Compiler-und Linker 
Flags nicht verwendet hast. In meinem Makefile sind es diese
1
FLAGS += -ffunction-sections -fdata-sections
2
LDFLAGS += -Wl,--gc-sections

Das erklärt aber noch nicht, warum die größere Datei mit den ungenutzten 
Funktionen nicht funktioniert. Kannst du mal das Assembler-Listing 
zeigen, dass dein Rechner generiert (sie wie Hugo oben seins gezeigt 
hat)?
Gast #6664872
Lesenswert?

Udo F. schrieb:
> Habe es so kompiliert

Leider stehen in dem Listing nicht die Adressen. Aber ich sehe da 
ungefähr 25 Befehle. Die meisten brauchen 2 Bytes, dazu kommt noch die 
Interrupt-Tabelle. Da sind die 66 also schon plausibel.

Das bringt mich aber auf eine Idee: Woher weiß der Linker, wie viel 
Platz er für die Interrupt-Tabelle reservieren muss, obwohl sie nicht im 
Assember Listing enthalten ist?

Kann es sein, dass du beim Linken
> avr-gcc uart_verysimple.o -o uart_verysimple.elf;
den µC Typ angeben musst? Ich mache das jedenfalls immer in meinem 
Makefile.

Vielleicht profitierst du auch davon, ein erprobtes Makefile zu 
benutzen. Meine persönliche Kopiervorlage findest du dort: 
http://stefanfrings.de/avr_hello_world/index.html
#6664919
Lesenswert?

Stefan ⛄ F. schrieb:
> Quatsch
>
> Die Interrupt-Tabelle hat 64 Bytes.
> Der Programmcode hat 66 Bytes.
>
> macht zusammen ungefähr die 124 bytes, die bei dir als
>> "Program Memory Usage   :  124 bytes   1,5 % Full"
> gemeldet wurden.

Und was schiebt AVR-Dude auf den Controller? Nur den Programmcode? 
Spielt die Interrupt-Tabelle keine Rolle? Erhält der MC diese intuitiv?
Gast #6664931
Lesenswert?

Hugo H. schrieb:
> Und was schiebt AVR-Dude auf den Controller? Nur den Programmcode?

Das komplette gelinkte Programm, samt Interrupt Tabelle und 
Initialisierungs-Daten für Variablen (falls vorhanden).

> Spielt die Interrupt-Tabelle keine Rolle?

Ich habe dir doch gerade vorgerechnet, dass der Programmcode + 
Interrupt-Tabelle zusammen die gesamt-Größe ausmachen, die in den Flash 
übertragen werden müssen.
#6664938
Lesenswert?

Stefan ⛄ F. schrieb:
> Ich habe dir doch gerade vorgerechnet, dass der Programmcode +
> Interrupt-Tabelle zusammen die gesamt-Größe ausmachen, die in den Flash
> übertragen werden müssen.

Und warum sind dann die 66 übertragenen Bytes plausibel? Addieren ist 
Dir bekannt?

Du hättest Politiker werden sollen - vielleicht sucht Armin ja noch 
Helfer :-)

Ich glaube, Du wohnst sogar in der Ecke - oder? Dann passt es ja.
#6665173
Lesenswert?

Nu schlagt euch doch nicht die Köpfe ein! Der To hat doch einen völligen 
Humbug gepostet!! Natürlich bin ich auch immer baff, wenn mein Programm 
nicht läuft. Neu ist die Variante, natürlich die hinterhältige Variante, 
dass das geniale Programm kompiliert werden kann und dennoch nicht 
läuft! Wenn das jetzt nicht mal dem Fass den Boden ausschlägt...anders 
herum gehts immer ganz einfach :-) aber sowas habe ich noch nicht 
erlebt!!!
Gruß Rainer
Beitrag #6665179 wurde von einem Moderator gelöscht.
Gast #6665221
Lesenswert?

Rainer V. schrieb:
> Nu schlagt euch doch nicht die Köpfe ein! Der To hat doch einen völligen
> Humbug gepostet!! Natürlich bin ich auch immer baff, wenn mein Programm
> nicht läuft. Neu ist die Variante, natürlich die hinterhältige Variante,
> dass das geniale Programm kompiliert werden kann und dennoch nicht
> läuft! Wenn das jetzt nicht mal dem Fass den Boden ausschlägt...anders
> herum gehts immer ganz einfach :-) aber sowas habe ich noch nicht
> erlebt!!!

GRIN. Wenn's so einfach wäre, dass erfolgreiches Kompilieren schon 
sicher die Programmfunktion herstellen könnte: Wer bräuchte denn dann 
überhaupt noch Programmierer? Code kann man generieren lassen oder 
klauen.

Aber ja, ICH habe schon verstanden, dass dein Beitrag eher sarkastisch 
gemeint war.
#6665232
Lesenswert?

c-hater schrieb:
> Aber ja, ICH habe schon verstanden, dass dein Beitrag eher sarkastisch
> gemeint war.

ist doch aber wirklich kaum anders zu ertragen oder?? Endlich postet 
jemand einen Code, der anstandlos übersetzt wird...und er läuft nicht. 
Ich frage mich jetzt ernsthaft, wie ich das sagen soll...Ich sage "there 
is no understanding in the world" und das ist definitiv im Einklang mit 
den neusten Erkenntnissen von CERN über die wackelige 8te bis 12te 
Stelle im Welbild der momentan geltenden Physik. Ist doch Scheissegal, 
höre ich die Kandidaten schon schreien...aber ist es das wirklich...was 
wäre, wenn es einen Cetaur doch gegeben hätt? OK LG
Rainer
#6665435
Lesenswert?

Ich finds ziemlich krass was hier aus diesem Post - Zitat 'Mikey Maus 
Code' (was er definitiv ist!) - am Ende passiert ist.
Ich wollte mich auf jeden Fall bei euch Allen für die Hilfe bedanken, da 
ich alleine nicht weiter gekommen wäre.
Ich muss zugeben, dass ich bis jetzt nicht weiß, warum das Makefile es 
am Ende gerockt hat. Ich habe definitiv nichts am Code verändert.
Auf jeden Fall werde ich jetzt immer das besagte Makefile nutzen, da ich 
dann zur Not auch alle Informationen wie z.B. das LSS File bekomme und 
es bei weiteren Fragen dann zur Hand habe.
Wie gesagt-ich bin Anfänger und muss noch dazu lernen.
Gast #6665525
Lesenswert?

Udo F. schrieb:
> Ich muss zugeben, dass ich bis jetzt nicht weiß, warum das Makefile es
> am Ende gerockt hat

Sorry, das habe ich wohl nicht deutlich genug erklärt.

Du hast versäumt, beim zweiten Aufruf des gccc (Linker) anzugeben, für 
welchen Mikrocontroller das *.elf File erzuegt werden soll. Deswegen 
fehlte dort die Interrupt-Vektor Tabelle, also dieser ganze Block:
1
00000000 <__vectors>:
2
   0:  19 c0         rjmp  .+50       ; 0x34 <__ctors_end>
3
   2:  20 c0         rjmp  .+64       ; 0x44 <__bad_interrupt>
4
   4:  1f c0         rjmp  .+62       ; 0x44 <__bad_interrupt>
5
   6:  1e c0         rjmp  .+60       ; 0x44 <__bad_interrupt>
6
   8:  1d c0         rjmp  .+58       ; 0x44 <__bad_interrupt>
7
   a:  1c c0         rjmp  .+56       ; 0x44 <__bad_interrupt>
8
   c:  1b c0         rjmp  .+54       ; 0x44 <__bad_interrupt>
9
   e:  1a c0         rjmp  .+52       ; 0x44 <__bad_interrupt>
10
  10:  19 c0         rjmp  .+50       ; 0x44 <__bad_interrupt>
11
  12:  18 c0         rjmp  .+48       ; 0x44 <__bad_interrupt>
12
  14:  17 c0         rjmp  .+46       ; 0x44 <__bad_interrupt>
13
  16:  16 c0         rjmp  .+44       ; 0x44 <__bad_interrupt>
14
  18:  15 c0         rjmp  .+42       ; 0x44 <__bad_interrupt>
15
  1a:  14 c0         rjmp  .+40       ; 0x44 <__bad_interrupt>
16
  1c:  13 c0         rjmp  .+38       ; 0x44 <__bad_interrupt>
17
  1e:  12 c0         rjmp  .+36       ; 0x44 <__bad_interrupt>
18
  20:  11 c0         rjmp  .+34       ; 0x44 <__bad_interrupt>
19
  22:  10 c0         rjmp  .+32       ; 0x44 <__bad_interrupt>
20
  24:  0f c0         rjmp  .+30       ; 0x44 <__bad_interrupt>
21
  26:  0e c0         rjmp  .+28       ; 0x44 <__bad_interrupt>
22
  28:  0d c0         rjmp  .+26       ; 0x44 <__bad_interrupt>
23
  2a:  0c c0         rjmp  .+24       ; 0x44 <__bad_interrupt>
24
  2c:  0b c0         rjmp  .+22       ; 0x44 <__bad_interrupt>
25
  2e:  0a c0         rjmp  .+20       ; 0x44 <__bad_interrupt>
26
  30:  09 c0         rjmp  .+18       ; 0x44 <__bad_interrupt>
27
  32:  08 c0         rjmp  .+16       ; 0x44 <__bad_interrupt>

Den siehst du in deinem C-Quelltext nicht, weil er eben vom Linker 
automatisch ergänzt wird. Aber nur, wen man dem Linker sagt, für welchen 
Mikrocontroller er das tun soll.

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