Forum: Compiler & IDEs UART-Übertragung erzeugt "Abweichung" um 0x40


von Tobias H. (taranis)


Lesenswert?

Hallo zusammen,
ich versuche gerade eine UART-Übertragung zu meinem PC (Win 7, 64 bit, 
HTerm 0.8.1beta und uCon 7.1 als Terminals, WinAVR vom 13.03.2009, 
Code::Blocks als IDE, AVRDude zum flashen).
Der ATMega 8515L sitzt auf einem STK 500.
Den Init-Code habe ich zum großteil aus dem Datenblat von Atmel 
übernommen bzw. Angepasst. Insgesamt sollte ein Frame 8 Datenbits, 2 
Stopbits und keine Parität haben. Die Baudrate von 9600 sollte auch 
stimmen.

Das Problem ist, dass ich statt der erwarteten Zahlen von 0 bis 9 die 
Buchstaben 'p' bis 'y' empfange. Sprich, der ASCII-Code weißt 
irgendwoher eine Art "Offset" von 0x40 auf. Weiß einer von Euch woran 
das liegen kann oder was ich falsch gemacht hab?

Hier 'mein' Quelltext:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#ifndef F_CPU
4
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
5
#define F_CPU 4000000UL  // Systemtakt in Hz - Definition als unsigned long beachten
6
                         // Ohne ergeben sich unten Fehler in der Berechnung
7
#endif
8
9
#define BAUD 9600UL      // Baudrate
10
11
// Berechnungen
12
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
13
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
14
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
15
16
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
17
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
18
#endif
19
20
void uart_init(void)
21
{
22
    UBRRH = UBRR_VAL >> 8;
23
    UBRRL = UBRR_VAL & 0xFF;
24
    UCSRB |= (1 << TXEN);
25
    UCSRC |= (1<<URSEL) |(1<<USBS) | (1<< UCSZ0) |(1<<UCSZ1) | (0 << UCSZ2);
26
    UCSRC |= (0 << UMSEL);
27
    UCSRC |= (0<< UPM1) | (0 << UPM0);
28
}
29
30
void allg_init(void)
31
{
32
    DDRB = 0xFF;
33
    PORTB = 0xFF;
34
}
35
36
int uart_putc(unsigned char c)
37
{
38
    while(! (UCSRA & (1 <<UDRE))){
39
        ;
40
    }
41
    uint8_t i = (uint8_t) c;
42
    UDR = c;
43
    PORTB = ~i;
44
    return 0;
45
}
46
47
int main(void)
48
{
49
    uart_init();
50
    allg_init();
51
    unsigned char c;
52
    uint8_t i;
53
    for(i = 0; i < 10; i++){
54
        c =(unsigned char) (i + 0x30);
55
        PORTB = ~i;
56
        uart_putc(c);
57
        _delay_ms(900);
58
        _delay_ms(900);
59
        _delay_ms(900);
60
        PORTB = ~(i +0x30);
61
        _delay_ms(900);
62
        _delay_ms(900);
63
        _delay_ms(900);
64
    }
65
    c = (unsigned char) (0 + 0x30);
66
    PORTB = ~(0+0x30);
67
    uart_putc(c);
68
    while(1)
69
    {
70
        ;
71
    }
72
    return 0;
73
}

von Falk B. (falk)


Lesenswert?


von Tobias H. (taranis)


Lesenswert?

Sorry, aber auch nach mehrmaligem Lesen und durchsehen der Checkliste 
weiß ich gerade nicht, wie mir das weiterhilft oder auf was du hinaus 
willst.
Die Verbindung steht ja definitiv, der Quarz (dürfte der Externe sein) 
läuft auf ca. 4MHz (zumindest blinkt die LED dann mit _delay_ms(1000) im 
Sekundentakt).
Kannst du bitte etwas konkreter werden?

von Daniel V. (danvet)


Lesenswert?

STK Manual:

"When the XTAL1 jumper is mounted, the STK500 internal clock system is 
used as main clock to the target AVR. The internal clock system can 
either use a crystal in the on-board crystal socket or a 
software-generated clock from the master microcontroller.
The frequency of the software-generated clock can be set from 0 to 3.68 
MHz. The default value is 3.68 MHz. Section 5.3.5.3 on page 5-7 explains 
how to set the clock frequency from AVR Studio."

Bist du sicher, dass du mit der richtigen CPU-Frequenz arbeitest?
Hast du die Fuses auf externen Quarz umgestellt?

von Tobias H. (taranis)


Lesenswert?

Also ich habe jetzt den Jumper XTAL1 gesteckt gelassen, OSCSEL so 
gesteckt dass der "Onboard XTAL Oscillator" ausgewählt ist (Kontakt 2 
und 3 gebrückt). In den Crystalsocket hab ich einen 12 MHz Quarz 
gesteckt und den Wert im Programm entsprechend angepasst.
Im AVR-Studio hab ich bei den Fuses im SUT_CKSEL Ext.Crystal/Resonater 
High Freq.: Start-up time: 16 CK + 64ms eingestellt.
Jetzt bekomm ich nur noch Schrott im HTerm, bzw. die Lücke zu den 
erwarteten Werten hat sich vergrößert.

von Karl H. (kbuchegg)


Lesenswert?

Tobias Hipp schrieb:
> Also ich habe jetzt den Jumper XTAL1 gesteckt gelassen, OSCSEL so
> gesteckt dass der "Onboard XTAL Oscillator" ausgewählt ist (Kontakt 2
> und 3 gebrückt). In den Crystalsocket hab ich einen 12 MHz Quarz
> gesteckt und den Wert im Programm entsprechend angepasst.
> Im AVR-Studio hab ich bei den Fuses im SUT_CKSEL Ext.Crystal/Resonater
> High Freq.: Start-up time: 16 CK + 64ms eingestellt.
> Jetzt bekomm ich nur noch Schrott im HTerm, bzw. die Lücke zu den
> erwarteten Werten hat sich vergrößert.

Gegentest:
Den OSCSEL abziehen. Der µC muss schlagartig stehen.
Tut er das nicht (arbeitet er also weiter), dann arbeitet er auch nicht 
mit dem Onboard XTAL Oscillator.

von Tobias H. (taranis)


Lesenswert?

Habe jetzt im HTerm mit der Baudrate rumgespielt. und die scheint nicht 
9600 zu betragen sondern 28800.
Kommt das durch eine Falsche F_CPU Definition?

von Tobias H. (taranis)


Lesenswert?

Gnarf
Danke für eure Hilfe. Das war eine richtige, ekelige, doofe 
PEBKAC-Situation.
Hatte in den Projektoptionen von Code::Blocks angegeben, dass F_CPU = 
4000000UL sei. Und das vergessen. Also hat die Clock nicht gepasst und 
meine Definition im Sourcecode war für'n Hintern...

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.