Forum: Mikrocontroller und Digitale Elektronik Serielle Schnittstelle


von Torsten (Gast)


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.
1
#include <inttypes.h>
2
#include <stdio.h>
3
#include <avr/io.h>
4
5
6
volatile uint8_t  UART_Byte;
7
volatile uint8_t  UART_Byte_Status;
8
9
10
static FILE uart_str = FDEV_SETUP_STREAM(RS232_putchar, NULL, _FDEV_SETUP_RW);
11
12
static int RS232_putchar (char c, FILE *stream);
13
14
void RS232_Init (void)
15
  {
16
/*
17
** Enable TXEN and RXEN in register UCSRB
18
*/
19
  UCSRB |= (1 << TXEN);
20
  UCSRB |= (1 << RXEN);
21
22
  UCSRC |= (1 << URSEL)|(3<<UCSZ0);
23
/*
24
** Set baud rate
25
*/
26
    UBRRH = (uint8_t) ((SYSCLOCK / (BAUD_RATE * 16L) - 1)>>8);
27
    UBRRL = (uint8_t) (SYSCLOCK / (BAUD_RATE * 16L) - 1);
28
/*
29
** Open a channel for printf
30
*/
31
  stdout = &uart_str;
32
  fdevopen (RS232_putchar, NULL);
33
/*
34
** Set the UART CMD bytes
35
*/
36
  UART_Byte = 0;
37
  UART_Byte_Status = 0;
38
  }
39
40
int RS232_putchar (char c, FILE *stream)
41
  {
42
/*
43
** Check on NEWLINE
44
*/
45
  if (c == '\n')
46
      {
47
    RS232_putchar ('\r', stream);
48
    }
49
/*
50
** Wait until previous character is sent
51
*/  
52
  loop_until_bit_is_set(UCSRA, UDRE);
53
/*
54
** Send character to UART
55
*/
56
  UDR = c;
57
58
  return 0;
59
  }
60
61
//*******************************************************
62
63
void RS232_PutByte (uint8_t Byte)
64
  {
65
/*
66
** Wait until previous character is sent
67
*/
68
  while (!(UCSRA & (1<<UDRE)));
69
/*
70
** Send byte to UART
71
*/
72
  UDR = Byte;
73
74
  return;
75
  }
76
77
//*******************************************************
78
79
void RS232_Put_unit16 (uint16_t *Word)
80
  {
81
  uint8_t   i;
82
  uint8_t    *py;
83
84
  py = (uint8_t*) Word;
85
  for (i=0;i<2;i++)
86
    {
87
    RS232_PutByte (*py++);
88
    }
89
90
  return;
91
  }
92
//*******************************************************
93
94
void RS232_Put_unit32 (uint32_t *DWord)
95
  {
96
  uint8_t   i;
97
  uint8_t    *py;
98
99
  py = (uint8_t*) DWord;
100
101
  for (i=0;i<4;i++)
102
    {
103
    RS232_PutByte (*py++);
104
    }
105
106
  return;
107
  }
108
109
//*******************************************************
110
uint8_t RS232_GetByte (void)
111
  {
112
/*
113
** Wait until byte is available
114
*/
115
  while (!(UCSRA &(1<<RXC)));
116
/*
117
** Get and return the byte from UART
118
*/  
119
  return UDR;
120
  }

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?

von Stromverdichter (Gast)


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.

von Torsten (Gast)


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

von visitor (Gast)


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?

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Codelesa (Gast)


Lesenswert?

Ob das ein gute Idee ist?
1
int RS232_putchar (char c, FILE *stream)
2
{
3
  /*  Check on NEWLINE  */
4
  if (c == '\n')
5
  {
6
    RS232_putchar ('\r', stream);
7
  }
8
  /*  Wait until previous character is sent  */
9
  loop_until_bit_is_set(UCSRA, UDRE);
10
  /*  Send character to UART  */
11
  UDR = c;
12
13
  return 0;
14
}

RS232_putchar sich selbst aufrufen?

von Wolfgang (Gast)


Lesenswert?

Codelesa schrieb:
> RS232_putchar sich selbst aufrufen?

Und was stört dich daran?

von Draco (Gast)


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.

von Torsten (Gast)


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.
1
uint8_t i2c_check(uint8_t address)
2
{
3
  uint8_t retVal = 0;
4
  
5
  TWCR = ((1<<TWINT)|(1<<TWSTA)|(1<<TWEN)); // TWI aktivieren und Start-Condition ausloesen
6
  
7
  TWDR = address & (0xFE);    //Addresse und schreibbit ins Datenregister
8
  TWCR = ((1<<TWINT) | (1<<TWEN)); //senden
9
  while (!(TWCR & (1<<TWEN)));  //Warten auf Ack 
10
  
11
  if((TWSR & 0xF8) !=TW_MT_SLA_ACK) retVal = 2;  //Wenn kein slave abbrechen
12
  
13
  TWCR = ((1<<TWINT) | (1<<TWSTO) | (1<<TWEN));  //Stop
14
  
15
  return retVal;
16
}

Diese Funktion rufe ich dann in einer For-Schleife auf und gehe die 
einzelnen Addressen durch.
1
for (uint8_t i = 0x00; i < 0x41; i++)
2
{
3
  test = i2c_check(0x40);
4
    
5
    if (test == 2)
6
    {
7
      Anzahl_ja =+ 1;
8
      DDRB = (1<<PB1);
9
    }
10
    else
11
    {
12
      Anzahl_Nein =+ 1;
13
      DDRB = (1<<PB0);
14
    }
15
}
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.

von Keksmann (Gast)


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 ?

von Torsten (Gast)


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.

von Eric B. (beric)


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:
1
#include <inttypes.h>
2
#include <avr/io.h>
3
4
5
volatile uint8_t  UART_Byte;
6
volatile uint8_t  UART_Byte_Status;
7
8
void RS232_Init (void)
9
{
10
    /*
11
    ** Enable TXEN and RXEN in register UCSRB
12
    */
13
    UCSRB |= (1 << TXEN);
14
    UCSRB |= (1 << RXEN);
15
16
    UCSRC |= (1 << URSEL)|(3<<UCSZ0);
17
    /*
18
    ** Set baud rate
19
    */
20
    UBRRH = (uint8_t) ((SYSCLOCK / (BAUD_RATE * 16L) - 1)>>8);
21
    UBRRL = (uint8_t) (SYSCLOCK / (BAUD_RATE * 16L) - 1);
22
    /*
23
    ** Set the UART CMD bytes
24
    */
25
    UART_Byte = 0;
26
    UART_Byte_Status = 0;
27
}
28
29
//*******************************************************
30
31
void RS232_PutByte (uint8_t Byte)
32
{
33
    /*
34
    ** Wait until previous character is sent
35
    */
36
    while (!(UCSRA & (1<<UDRE)))
37
        ;
38
    /*
39
    ** Send byte to UART
40
    */
41
    UDR = Byte;
42
}
43
44
//*******************************************************
45
46
void RS232_Put_uint16 (uint16_t *Word)
47
{
48
    uint8_t   i;
49
    uint8_t    *py;
50
51
    py = (uint8_t*) Word;
52
    for (i=0;i<2;i++)
53
    {
54
        RS232_PutByte (*py++);
55
    }
56
}
57
//*******************************************************
58
59
void RS232_Put_uint32 (uint32_t *DWord)
60
{
61
    uint8_t   i;
62
    uint8_t    *py;
63
64
    py = (uint8_t*) DWord;
65
66
    for (i=0;i<4;i++)
67
    {
68
    RS232_PutByte (*py++);
69
    }
70
}
71
72
//*******************************************************
73
74
void RS232_Put_string (char *text)
75
{
76
    uint8_t   i;
77
    uint8_t    *py;
78
79
    while (*text != 0)
80
    {
81
        if(*text == '\n')
82
            RS232_PutByte('\r');
83
        RS232_PutByte (*text++);
84
    }
85
}
86
87
//*******************************************************
88
uint8_t RS232_GetByte (void)
89
{
90
    /*
91
    ** Wait until byte is available
92
    */
93
    while (!(UCSRA &(1<<RXC)));
94
    /*
95
    ** Get and return the byte from UART
96
    */  
97
    return UDR;
98
}

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

: Bearbeitet durch User
von Torsten (Gast)


Lesenswert?

Ja wenn ich Test = 2 bekomme soll er angeben das er keine gefunden hat

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.