Forum: Mikrocontroller und Digitale Elektronik USART ATmega Falsche Zeichen


von Simon (Gast)


Lesenswert?

Hallo miteinander

Ein alt bekanntes Problem und ich hab viel nachgeschaut und bekomm schon 
graue haare..

Ich krieg das einfach nicht hin. Ich möchte ein Zeichen über USART1 
senden aber hyperterminal zeigt mir ein falsches Zeichen:

/* INCLUDE 
======================================================================== 
==*/

#include <avr/io.h>




/* DEFINES 
======================================================================== 
==*/

#define CPU        14745600
#define BAUD_USER    115200
#define BAUD_CHIP    115200

#define HOST_TX_ON     PORTC |= 0x02
#define HOST_TX_OFF   PORTC &= ~0x02
#define HOST_RX_ON     PORTC |= 0x01
#define HOST_RX_OFF   PORTC &= ~0x01
#define HOST_SHDN_ON   PORTD |= 0x80
#define HOST_SHDN_OFF   PORTD &= ~0x80


/* EXTERNAL VARIABLES 
===============================================================*/


/* FUNCTION PROTOTYPING 
=============================================================*/


void SetupSystem(void);              // HW-haufen anfahren..
void uart_putc(unsigned char);          // Transmit USART1 Character


/* MAIN 
======================================================================== 
=====*/

int main (void)
{

   SetupSystem();

   uart_putc('B');

   while(1)
   {
   /* Endlos Schleife*/
   }


   return 0;
}

/* FUNCTIONS 
======================================================================== 
*/
void SetupSystem()
{
  //Ausgänge definieren
  DDRA |= 0x01;  // PA0 (RST)
  DDRB  = 0x00;  // Kein Ausgang
  DDRC |= 0x03;  // PC0 (RXENABLE), PC1 (TXENABLE)
  DDRD |= 0x8C;  // PD1 (TXD0), PD3 (TXD1), PD7 (SHDN)

  //Ausgänge Initialisieren
  HOST_TX_ON;
  HOST_RX_ON;
  HOST_SHDN_OFF;

  //USART0 (Chip) definieren


  //USART1 (Host) definieren
  UBRR1L  = 0x07;  // Baudrate Register auf 7 weil fosc/16*BAUD - 1 
(115200)
  UBRR1H  = 0x00;
  UCSR1A &= ~0x02;
  UCSR1C = 0x06;  // 8 Data, 1 Stop, No parity
  UCSR1B |= 0x08;  // TX Enable

    // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger 
Werte)
    do
    {
        UDR1;
    }
    while (RXC1);
}

void uart_putc(unsigned char c)
{
    while (!(UDRE1))          /* warten bis Senden moeglich */
    {
    }

    UDR1 = c;                      /* sende Zeichen */
}


Die Fuses sind gesetzt  CKSEL=1111 SUT=11

Ich weis einfach nicht was ich falsch mache. Habt Ihr noch eine Idee?
Hab auch schon probiert den jtagicemkII nach dem programmieren zu 
entfernen und funktioniert auch nicht. Hab auch 1 zu 1 die Beispiele 
kopiert und passiert immer das gleiche. Kabel habe ich auch schon 
gewechselt. Aber es muss doch etwas mit der Baud zu tun haben.. Hab 
leider kein KO in der nähe nur ein billiges Multimeter :)

Ich danke für eure Hilfe!

Grüsse
Simon

von Johannes M. (johnny-m)


Lesenswert?

>     do
>    {
>        UDR1;
>    }
Was sagt der Compiler eigentlich dazu?

von Simon (Gast)


Lesenswert?

Alle i.o  Das habe ich vom Beispiel übernommen. :)

von mehrfacher STK500-Besitzer (Gast)


Lesenswert?

Um welchen Compiler handelt es sich denn eigentlich?

von Simon (Gast)


Lesenswert?

avr-gcc

Build started 13.12.2007 at 20:33:25
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" 
--change-section-lma .eeprom=0 --no-change-warnings -O ihex xtse08.elf 
xtse08.eep || exit 0
c:\Programme\Atmel\WinAVR\bin\avr-objcopy.exe: there are no sections to 
be copied!

AVR Memory Usage
----------------
Device: atmega324p

Program:     414 bytes (1.3% Full)
(.text + .data + .bootloader)

Data:          3 bytes (0.1% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...

von Johannes M. (johnny-m)


Lesenswert?

Fusebits korrekt gesetzt?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Simon wrote:
>    do
>    {
>        UDR1;
>    }
>    while (RXC1);
> ...
>     while (!(UDRE1))
> ...
> Alle i.o  Das habe ich vom Beispiel übernommen. :)

Aus welchem?

In dem AVR-GCC-Tutorial steht sowas hoffentlich nicht!

von Simon (Gast)


Lesenswert?

Nein das stimmt war auch nur zum ausprobieren ist wieder original.. :)

    do
    {
        UDR1;
    }
    while (UCSR1A & (1 << RXC1));

while (!( UCSR1A & (1<<UDRE1)))          /* warten bis Senden moeglich 
*/
    {
    }

von Simon (Gast)


Lesenswert?

Ja Fuses sind nach mir richtig gesetzt:

BODLEVEL = 111
CKSEL = 1111 SUT = 11

von mehrfacher STK500-Besitzer (Gast)


Lesenswert?

>  UBRR1L  = 0x07;  // Baudrate Register auf 7 weil fosc/16*BAUD - 1
(115200)
>  UBRR1H  = 0x00;

Sieht nach falscher Reihenfolge aus (manche AVR benutzen die Adresse des 
UBRRxH-Registers mehrfach...

Hast du das Programm schon mal im AVRStudio schrittweise simuliert?

von Simon (Gast)


Lesenswert?

Ja ich habe es gedebuggt also schrittweise durchgegangen und die Werte 
wurden richtig in die Register geschrieben.

Links im AVR Studio steht beim Debug Frequenz aber bei mir ist dieses 
Feld leer sollte da was stehen? :)

von Johannes M. (johnny-m)


Lesenswert?

mehrfacher STK500-Besitzer wrote:
>>  UBRR1L  = 0x07;  // Baudrate Register auf 7 weil fosc/16*BAUD - 1
> (115200)
>>  UBRR1H  = 0x00;
>
> Sieht nach falscher Reihenfolge aus (manche AVR benutzen die Adresse des
> UBRRxH-Registers mehrfach...
Die Reihenfolge ist bei den USART-Baudraten-Registern egal. Und eine 
Mehrfachnutzung von UBRRH (was Du wahrscheinlich meinst) liegt beim 324 
nicht vor.

> Hast du das Programm schon mal im AVRStudio schrittweise simuliert?
Zumindest teilweise keine gute Idee, weil gerade in Sachen USART der 
Simulator ziemlich buggy ist.

von Johannes M. (johnny-m)


Lesenswert?

Ach ja, das mit dem "UDR1;" hab ich mir mal genauer angeschaut: Der 
Compiler macht daraus tatsächlich einen "Dummy-Read"...

von Simon (Gast)


Lesenswert?

Ich hab jetzten keine haare mehr auf dem kopf und ich weis nicht mehr 
weiter, verdrahtet ist richtig sonst würde er nichts empfangen...

von Bensch (Gast)


Lesenswert?

Geh doch erst mal mit dem Scope an den Tx und schau dir die Baudrate an.

von Simon (Gast)


Lesenswert?

Ja bleibt mir nichts anderes übrig als ein scope. Werd mir eins 
ausleihen müssen... :/

von Johannes M. (johnny-m)


Lesenswert?

> while (RXC1);
Fällt mir grad noch auf:
RXC1 ist (vorausgesetzt, Du verwendest den AVR-GCC, was ich mal vermute) 
ein Zahlenwert und hat glaub ich den Wert 7. Dementsprechend wird die 
Schleife bis in alle Ewigkeiten durchlaufen. RXC1 wird nunmal nie 
"falsch"...

Also schreib da mal
1
do
2
{
3
    UDR1;
4
}
5
while(UCSR1A & (1 << RXC1))
Das dürfte Besserung bringen, vorausgesetzt, RXC1 ist nicht irgendwo 
anderweitig definiert...

> Ich hab jetzten keine haare mehr auf dem kopf
Schön, dann haste ja nix mehr zu verlieren....;-)

BTW: Es wäre günstig (für Dich selbst, aber auch für diejenigen, die Dir 
helfen wollen), wenn Du Dir, anstatt direkt Zahlenwerte zu schreiben, 
generell die Schreibweise mit Bitschiebe-Operatoren (1 << BITNAME) für 
das Setzen/Löschen von Steuerbits angewöhnst. Dann sieht man nämlich 
sofort, was da passiert, und muss nicht erst im Datenblatt nachsehen. 
Außerdem erübrigt sich dadurch i.d.R. auch ein detaillierter Kommentar, 
der ansonsten bei jeder Änderung ebenfalls gewartet werden muss.

von Simon (Gast)


Lesenswert?

Ich hatte es sofort wieder geändert gehabt, war nur zum ausprobieren. 
Aber es will einfach nicht.. :)

Können mir nur noch die Schamhaare ausfallen..

von Karl H. (kbuchegg)


Lesenswert?

1
  UCSR1B |= 0x08;  // TX Enable
2
3
    // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger
4
Werte)
5
    do
6
    {
7
        UDR1;
8
    }
9
    while (RXC1);

Ich frage mich, wie und ob das entfernen von ungültigen
Zeichen aus dem Receiver Buffer funktioniert, wenn die
UART gar nicht auf Emfpang konfiguriert ist.


Häng doch einfach mal eine LED an einen Port und sieh nach,
ob die Sendefunktion überhaupt jemals erreicht wird, oder
ob du da nicht in irgendeiner Schleife hängen bleibst.

von Karl H. (kbuchegg)


Lesenswert?

Ändere das
1
int main (void)
2
{
3
   SetupSystem();
4
5
   uart_putc('B');
6
7
   while(1)
8
   {
9
   /* Endlos Schleife*/
10
   }
11
   return 0;
12
}

mal um, zu
1
int main (void)
2
{
3
   SetupSystem();
4
5
   while(1)
6
   {
7
     uart_putc('B');
8
   }
9
   return 0;
10
}

damit du wenigstens mit einem Voltmeter oder einer LED
überhaupt eine Chance hast, am Tx Pin des Prozessors rumzumessen.

Kabel stimmt (gekreuzt - nicht gekreuzt)?

Mach mall folgenden Versuch:
Nimm den Prozessor aus dem Sockel (wenn das geht). Dann
verbindest du im Sockel den Tx Pin mit dem Rx Pin.
Am Terminal tippst du dann ein paar Zeichen. Die laufen
vom Terminal durch das Kabel, durch den MAX232 zum Sockel,
gehen über deine Brücke auf die andere Leitung und von dort
wieder zurück zum Terminalm, welches sie anzeigt.
(Dazu aber Lokales Echo am Terminal ausschalten! Ebenso
jegliches Handshake ausschalten)

Kommt bei diesem Test im Terminal nichts an, dann hast du
ein Hardwareproblem.

von Simon (Gast)


Lesenswert?

Vielen Dank für eure Hilfe!

Nach dem ich einen Scope auftreiben konnte sah ich der prozessor 
einwandfrei funktioniert und es am rs232 treiber liegt. SHDN war 0 
anstatt 1. Super noob fehler.. :)

Danke euch! :)

Gruss

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.