mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Serielle Schnittstelle


Autor: Torsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich sitzte seit Wochen an einem Problem mit der Serielle Schnittstelle, 
habe zwischenzeitlich meine I2C-Bus zum laufen gebracht aber die RS232 
will einfach nicht. Ich bekomme immer eine Fehlermeldung.

Verwendung AtmelStudio 6
Microcontroller Atmega8

Fehler  1  unknown type name 'FILE'  C:\Users\Torsten\Documents\Atmel 
Studio\6.2\Display\Display\RS232.h.

Der Code dazu sieht so aus.
#include <inttypes.h>
#include <stdio.h>
#include <avr/io.h>


volatile uint8_t  UART_Byte;
volatile uint8_t  UART_Byte_Status;


static FILE uart_str = FDEV_SETUP_STREAM(RS232_putchar, NULL, _FDEV_SETUP_RW);

static int RS232_putchar (char c, FILE *stream);

void RS232_Init (void)
  {
/*
** Enable TXEN and RXEN in register UCSRB
*/
  UCSRB |= (1 << TXEN);
  UCSRB |= (1 << RXEN);

  UCSRC |= (1 << URSEL)|(3<<UCSZ0);
/*
** Set baud rate
*/
    UBRRH = (uint8_t) ((SYSCLOCK / (BAUD_RATE * 16L) - 1)>>8);
    UBRRL = (uint8_t) (SYSCLOCK / (BAUD_RATE * 16L) - 1);
/*
** Open a channel for printf
*/
  stdout = &uart_str;
  fdevopen (RS232_putchar, NULL);
/*
** Set the UART CMD bytes
*/
  UART_Byte = 0;
  UART_Byte_Status = 0;
  }

int RS232_putchar (char c, FILE *stream)
  {
/*
** Check on NEWLINE
*/
  if (c == '\n')
      {
    RS232_putchar ('\r', stream);
    }
/*
** Wait until previous character is sent
*/  
  loop_until_bit_is_set(UCSRA, UDRE);
/*
** Send character to UART
*/
  UDR = c;

  return 0;
  }

//*******************************************************

void RS232_PutByte (uint8_t Byte)
  {
/*
** Wait until previous character is sent
*/
  while (!(UCSRA & (1<<UDRE)));
/*
** Send byte to UART
*/
  UDR = Byte;

  return;
  }

//*******************************************************

void RS232_Put_unit16 (uint16_t *Word)
  {
  uint8_t   i;
  uint8_t    *py;

  py = (uint8_t*) Word;
  for (i=0;i<2;i++)
    {
    RS232_PutByte (*py++);
    }

  return;
  }
//*******************************************************

void RS232_Put_unit32 (uint32_t *DWord)
  {
  uint8_t   i;
  uint8_t    *py;

  py = (uint8_t*) DWord;

  for (i=0;i<4;i++)
    {
    RS232_PutByte (*py++);
    }

  return;
  }

//*******************************************************
uint8_t RS232_GetByte (void)
  {
/*
** Wait until byte is available
*/
  while (!(UCSRA &(1<<RXC)));
/*
** Get and return the byte from UART
*/  
  return UDR;
  }

Habe auch schon im Internet recherchiert habe aber nichts anderes 
gefunden bzw. die gleichen beispiele.
Hab ich da was vergessen oder einfach nur einen Fehler drin?

Autor: Stromverdichter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Torsten schrieb:
> static FILE uart_str = FDEV_SETUP_STREAM(RS232_putchar, NULL,
> _FDEV_SETUP_RW);

Hi Thorsten,
du definierst hier den uart_str mit dem Typ FILE, dieser ist deinem 
System aber nicht bekannt. Irgendwo müsste ein typedef für den Typ FILE 
existieren. Suche mal, wo das die anderen machen und füge den Teil 
deinem Projekt hinzu.

Autor: Torsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stromverdichter,

der Typ FILE wird in der stdio.h definiert.


/**
   \c FILE is the opaque structure that is passed around between the
   various standard IO functions.
*/
#define FILE  struct __file

Autor: visitor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wäre es nicht besser statt einer 8Bit,16Bit und 32Bit Put-Funktuin nur 
eine Funktion zu haben, die als Übergabeparameter einen Zeiger auf die 
Daten und eine Längeninformation enthält?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Torsten schrieb:
> der Typ FILE wird in der stdio.h definiert.

Dann musst Du die einbinden, bevor Du Deine "rs232.h" einbindest.

Oder Dir die ganze Chose noch mal durch den Kopf gehen lassen, ob Du auf 
einem kleinen 8-Bitter wirklich mit Dateihandles etc. um Dich werfen 
musst. So viele Schnittstellen sind ja eh' nicht vorhanden, und ein 
Dateisystem wirst Du vermutlich auch nicht verwenden.

Autor: Codelesa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ob das ein gute Idee ist?
int RS232_putchar (char c, FILE *stream)
{
  /*  Check on NEWLINE  */
  if (c == '\n')
  {
    RS232_putchar ('\r', stream);
  }
  /*  Wait until previous character is sent  */
  loop_until_bit_is_set(UCSRA, UDRE);
  /*  Send character to UART  */
  UDR = c;

  return 0;
}

RS232_putchar sich selbst aufrufen?

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Codelesa schrieb:
> RS232_putchar sich selbst aufrufen?

Und was stört dich daran?

Autor: Draco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Codelesa schrieb:
> Ob das ein gute Idee ist?
> ...
> RS232_putchar sich selbst aufrufen?

Richtig... er sendet dann: "\r\n" - ist schon korrekt so. Er muss dann 
halt nur aufpassen das er vom String nicht nochmal ein \r sendet. da das 
ja dann im \r\n\r endet.

Autor: Torsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe wieder ein kleine Problem mit meine I2C-Bus Teilnehmern.

Momentan habe ich 3 Teilnehmer am Bus hängen wo mir die Addressen 
bekannte sind. Ich möchte mir jetzt einen I2C-Bus Scanner bauen wo mir 
die Busaddressen Ausgibt, da ich noch andere Bauteile habe wo ich die 
Addresse nicht kenne.

Ich habe mir eine kleines Programm geschrieben wo ich nach der Addresse 
schaue und warte auf ein Ack.
uint8_t i2c_check(uint8_t address)
{
  uint8_t retVal = 0;
  
  TWCR = ((1<<TWINT)|(1<<TWSTA)|(1<<TWEN)); // TWI aktivieren und Start-Condition ausloesen
  
  TWDR = address & (0xFE);    //Addresse und schreibbit ins Datenregister
  TWCR = ((1<<TWINT) | (1<<TWEN)); //senden
  while (!(TWCR & (1<<TWEN)));  //Warten auf Ack 
  
  if((TWSR & 0xF8) !=TW_MT_SLA_ACK) retVal = 2;  //Wenn kein slave abbrechen
  
  TWCR = ((1<<TWINT) | (1<<TWSTO) | (1<<TWEN));  //Stop
  
  return retVal;
}

Diese Funktion rufe ich dann in einer For-Schleife auf und gehe die 
einzelnen Addressen durch.
for (uint8_t i = 0x00; i < 0x41; i++)
{
  test = i2c_check(0x40);
    
    if (test == 2)
    {
      Anzahl_ja =+ 1;
      DDRB = (1<<PB1);
    }
    else
    {
      Anzahl_Nein =+ 1;
      DDRB = (1<<PB0);
    }
}
Die Lampen lass ich mir anzeigen ob er diese gefunden hat oder nicht.
Ich frage jetzt auch nur bestimmt die Teilnehmer Addresse ab wo ich weiß 
das sie auch vorhanden ist "funkioniert". Wenn ich jetzt ander Abfrage 
wo nicht vorhanden sind, werden sie dennoch als vorhanden angezeigt.

Autor: Keksmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Torsten schrieb:
> test = i2c_check(0x40);

Mit dieser Anweisung in der Schleife wird 40 mal die gleiche 
Slave-Addresse abgefragt. Das ist vermutlich nicht das, was du wolltest, 
oder ?

Autor: Torsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein ich habe hier jetzt nur die Feste-Addresse vergeben damit ich weiß 
welche LED das leuchten muss.
Habe jetzt auch die For schleife raus genommen macht aber kein 
Unterschied.

Autor: Eric B. (beric)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Torsten schrieb:
> static FILE uart_str = FDEV_SETUP_STREAM(RS232_putchar, NULL,
> _FDEV_SETUP_RW);
>
> static int RS232_putchar (char c, FILE *stream);

Lass doch das ganze FILE stream Gedöns weg. Ohne geht's auch:
#include <inttypes.h>
#include <avr/io.h>


volatile uint8_t  UART_Byte;
volatile uint8_t  UART_Byte_Status;

void RS232_Init (void)
{
    /*
    ** Enable TXEN and RXEN in register UCSRB
    */
    UCSRB |= (1 << TXEN);
    UCSRB |= (1 << RXEN);

    UCSRC |= (1 << URSEL)|(3<<UCSZ0);
    /*
    ** Set baud rate
    */
    UBRRH = (uint8_t) ((SYSCLOCK / (BAUD_RATE * 16L) - 1)>>8);
    UBRRL = (uint8_t) (SYSCLOCK / (BAUD_RATE * 16L) - 1);
    /*
    ** Set the UART CMD bytes
    */
    UART_Byte = 0;
    UART_Byte_Status = 0;
}

//*******************************************************

void RS232_PutByte (uint8_t Byte)
{
    /*
    ** Wait until previous character is sent
    */
    while (!(UCSRA & (1<<UDRE)))
        ;
    /*
    ** Send byte to UART
    */
    UDR = Byte;
}

//*******************************************************

void RS232_Put_uint16 (uint16_t *Word)
{
    uint8_t   i;
    uint8_t    *py;

    py = (uint8_t*) Word;
    for (i=0;i<2;i++)
    {
        RS232_PutByte (*py++);
    }
}
//*******************************************************

void RS232_Put_uint32 (uint32_t *DWord)
{
    uint8_t   i;
    uint8_t    *py;

    py = (uint8_t*) DWord;

    for (i=0;i<4;i++)
    {
    RS232_PutByte (*py++);
    }
}

//*******************************************************

void RS232_Put_string (char *text)
{
    uint8_t   i;
    uint8_t    *py;

    while (*text != 0)
    {
        if(*text == '\n')
            RS232_PutByte('\r');
        RS232_PutByte (*text++);
    }
}

//*******************************************************
uint8_t RS232_GetByte (void)
{
    /*
    ** Wait until byte is available
    */
    while (!(UCSRA &(1<<RXC)));
    /*
    ** Get and return the byte from UART
    */  
    return UDR;
}

Torsten schrieb:
> if (test == 2)
> {
>   Anzahl_ja =+ 1;
Anzahl_ja += 1;
Und test == 2 soll doch angeben dass der Slave nicht gefunden wurde?

: Bearbeitet durch User
Autor: Torsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja wenn ich Test = 2 bekomme soll er angeben das er keine gefunden hat

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.