Forum: Mikrocontroller und Digitale Elektronik attiny2313 UART bzw. Speicher Initialisierung


von rotrau (Gast)


Lesenswert?

Guten Abend,

ich versuche auf einem attiny2313 per UART Strings zu verschicken.
Das funktioniert auch, solange ich das ganze char für char mache,
allerdings nicht auf zusammenhängendes im Speicher.
1
#include <avr/io.h> 
2
3
#define F_CPU 3686400L
4
#include <util/delay.h>
5
6
void usart_init(unsigned int baud) {
7
    /* Set baud rate */
8
    UBRRH = (unsigned char)(baud>>8);
9
    UBRRL = (unsigned char)baud;
10
    /* Enable receiver and transmitter */
11
    UCSRB = (1<<TXEN);
12
    /* Set frame format: 8data, 1stop bit */
13
    UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
14
}
15
16
void usart_transmit(unsigned char data) {
17
    /* Wait for empty transmit buffer */
18
    while(!(UCSRA & (1<<UDRE)))
19
        ;
20
    /* Put data into buffer, sends the data */
21
    UDR = data;
22
}
23
24
int main() {
25
    char text[] = "hallo welt";
26
    int j = 0;
27
    usart_init(1);
28
29
    while(1) {
30
        _delay_ms(1000);
31
        usart_transmit('a');
32
        for(j = 0; j < sizeof(text); j++) {
33
            usart_transmit('a'+text[j]);
34
        }
35
36
    }
37
    while(1) {}
38
}

Führt zur Ausgabe von a```````````a```````````a```````````a```````````.
Das lässt mich schließen, dass der Speicher nicht initialisiert wird, 
aber warum sollte das so sein?
Compiler ist avr-gcc 4.7.2

Viele Grüße
rot

von Ben (Gast)


Lesenswert?

Grundlagen anschauen: Strings in C

von geier99 (Gast)


Lesenswert?

rotrau schrieb:
> usart_transmit('a'+text[j]);

dann schreib mal das:

usart_transmit(text[j]);

von rotrau (Gast)


Lesenswert?

Hi,

vielen Dank für die Antworten.
Die Tipps ändern nichts an meinen Strings die nicht intialisiert sind,
'a' ist ja nur ein konstanter Offset des Wertes.

von Andreas W. (geier99)


Lesenswert?

rotrau schrieb:
> Hi,
>
> vielen Dank für die Antworten.
> Die Tipps ändern nichts an meinen Strings die nicht intialisiert sind,
> 'a' ist ja nur ein konstanter Offset des Wertes.

Vielleicht liegt es an dem:
(unsigned char data)

, da Dein Text ein char ist. Mach mal aus dem Text auch ein unsigned 
char.

von batman (Gast)


Lesenswert?

'a' als Offset zu 'h'? Macht das einen Sinn?

von Karl H. (kbuchegg)


Lesenswert?

rotrau schrieb:


> Führt zur Ausgabe von a```````````a```````````a```````````a```````````.
> Das lässt mich schließen, dass der Speicher nicht initialisiert wird,

Nö.
das lässt mich schliessen, dass die Addition des ASCII-Codes von a (0x61 
oder dez 97= zum ASCII Code von 'h' (0x68 oder dez 104) zu einem Code 
führt (dez 201), der von deinem Terminal nicht bzw. mit einem 
Sonderzeichen dargestellt wird, weil es im Original ASCII Code kein 
dafür vorgesehenes dafrstellbares Zeichen gibt.

Was versprichst du dir von

     'a' + text[j]

> aber warum sollte das so sein?

Ganz genau. Warum sollte das wohl so sein und warum ist das bisher noch 
keinem anderen ausser dir aufgefallen? Hmmmm.
Und warum gibst du den Text nicht erst mal so aus wie er ist, um zu 
sehen, was da rauskommt?
Fragen über Fragen.

von STK500-Besitzer (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Was versprichst du dir von
>
>      'a' + text[j]

Das dürfte die eine vergewaltiget Umwandlung von Dezimalzahlen in 
ASCII-Code sein.

von rotrau (Gast)


Lesenswert?

1
#include <avr/io.h>   
2
 
3
#define F_CPU 3686400L
4
#include <util/delay.h>
5
6
void usart_init(unsigned int baud) {
7
    /* Set baud rate */
8
    UBRRH = (unsigned char)(baud>>8);
9
    UBRRL = (unsigned char)baud;
10
    /* Enable receiver and transmitter */
11
    UCSRB = (1<<TXEN);
12
    /* Set frame format: 8data, 1stop bit */
13
    UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
14
}
15
16
void usart_transmit(char data) {
17
    /* Wait for empty transmit buffer */
18
    while(!(UCSRA & (1<<UDRE)))
19
        ;
20
    /* Put data into buffer, sends the data */
21
    UDR = data;
22
}
23
24
int main() {
25
    volatile char text[] = "hallo";
26
    int j = 0;
27
    usart_init(1);
28
29
    while(1) {
30
        _delay_ms(1000);
31
        for(j = 0; j < sizeof(text); j++) {
32
            usart_transmit(text[j]);
33
        }
34
        text[0] = 'h';
35
        text[1] = 'a';
36
        text[2] = 'l';
37
        text[3] = 'l';
38
        text[4] = 'o';
39
        text[5] = 0;
40
41
42
    }
43
    while(1) {}
44
}

Nochmal ein Beispiel, hier sehe ich auf dem Terminal einmal Mist und 
danach  den String hallo:
???????hallohallohallohallohallohallohallohallohallohallohallohallohallo 
hallohallohallohallohallohallohallohallohallo

Deshalb meine Ueberlegung ob der Speicher nicht initialisiert wird.

von Georg G. (df2au)


Lesenswert?

rotrau schrieb:
> void usart_init(unsigned int baud) {
[...]
>     usart_init(1);

welche Baurate erwartest du da eigentlich?

von Dietrich L. (dietrichl)


Lesenswert?

rotrau schrieb:
> usart_init(1);

Das kommt mir sehr komisch vor. Damit wird
       UBRRH = 0 und UBRRL = 1
Das kann doch keine sinnvolle Einstellung der Baudrate sein !?!

Gruß Dietrich

Edit: zu spät ;-(

von Karl H. (kbuchegg)


Lesenswert?

rotrau schrieb:

> Nochmal ein Beispiel, hier sehe ich auf dem Terminal einmal Mist und
> danach  den String hallo:
> ???????

Dann lass dir halt mal die Hex-Werte der Character ausgeben.

> Deshalb meine Ueberlegung ob der Speicher nicht initialisiert wird.

unwahrscheinlich.
Viel eher, dass in deinem Projekt was nicht stimmt. Den richtigen µC 
hast du eingestellt?

von rotrau (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Viel eher, dass in deinem Projekt was nicht stimmt. Den richtigen µC
> hast du eingestellt?

Denke ich doch:
avr-gcc -Os -std=gnu99 -Wa,-adhlns=foo.lst -mmcu=attiny2313 
-mmcu=attiny2313 -Wall -g -gstabs -I./ -o crap.out foo.c

avr-objcopy -j .text -O ihex crap.out crap.hex

avrdude -p t2313 -c stk500v2 -P /dev/ttyUSB0 -e -U flash:w:crap.hex

Uebersehe ich etwas?

Erwartete Baudrate ist 115200, das funktioniert auch.

Wertausgabe ergibt 0xff fuer alle Bytes.

von Karl H. (kbuchegg)


Lesenswert?

Hast du auf der Empfangsseite irgendwelche Framing-Errors?

Mach mal folgendes:
Gib 1 einzelnes Zeichen aus, dann ein wenig Warten (ein paar 
Millisekunden reichen) und erst danach den Text.


Alternativ:
Hast du schon mal im Simulator nachgesehen, was tatsächlich im Array 
steht?
Das da überall 0xFF drinnen steht, ist mehr als ungewöhnlich.


Sollte es sich tatsächlich wahrhaftig um einen Compilerbug handeln? Auch 
wenn es unwahrscheinlich ist, ausschliessen kann man es zu 100% auch 
nicht. Schon mal eine andere Compilerversion probiert?

von Karl H. (kbuchegg)


Lesenswert?

> avr-objcopy -j .text -O ihex crap.out crap.hex

Hab grad im 4-er Studio nachgesehen. Da wird objcopy so eingesetzt

avr-objcopy -O ihex -R .eeprom  CTC.elf CTC.hex
(CTC ist das Projekt)


das ".text" da in der Command-Line macht mich nervös
und auch avr-objdump gibt bei der Speicherübersicht beim Flash die 
Sektionen .text + .data + .bootloader an.

bootloader ist für dich irrelevant. Aber .data scheint nicht irrelevant 
zu sein. Das würde sich auch mit deinen 0xFF decken, welches der 
Defaultwert eines nicht programmierten Flash darstellt.

von rotrau (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> avr-objcopy -O ihex -R .eeprom  CTC.elf CTC.hex
>
>
> das ".text" da in der Command-Line macht mich nervös

Das wars wohl, danke!

von avr (Gast)


Lesenswert?

Versuchs mal so, dann weiss der Kompiler wie groß das
array ist.
1
volatile char text[6] = "hallo";

avr

von Karl H. (kbuchegg)


Lesenswert?

avr schrieb:
> Versuchs mal so, dann weiss der Kompiler wie groß das
> array ist.

Das weiß er auch so. Die Zeichen eines Initialisierstrings abzuzählen 
ist für deine eine leichte Übung.


Das Problem hat sich geklärt. Er hat seine Toolchain falsch benutzt. 
Wenn der String, mit dem initialisiert werden soll nie im Flash landet, 
dann müht sich der Initialisiercode vergebens ab und kopiert halt das, 
was im Flash steht: lauter 0xFF

von Georg G. (df2au)


Lesenswert?

Initialisierte Variable stehen nicht im .text Segment sondern in .data.
Du hast aber nur das .text Segment in das HEX File überführt.

> avr-objcopy -j .text -O ihex crap.out crap.hex

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
Noch kein Account? Hier anmelden.