Forum: Mikrocontroller und Digitale Elektronik Software UART und dereferencing pointer to incomplete type


von Frederik K. (n0ll4k)


Lesenswert?

Hallo,

ich habe versuche grade in mein Projekt ein Software UART zu 
implementieren, da der Hardware UART bereits für den LIN Bus belegt ist.

Hierzu brauche ich 8-Bit Timmer, da der 16-Bit Timer für die PWM 
benötigt wird.

Ich versuche nun die Methoden aus Peter Daneggers LCD1Wire und I2C 
Sniffer einzubauen.

Angefangen habe ich mit den RX Routinen aus der LCD1Wire allerdings habe 
ich nun beim kompilieren einen Fehler.

../suart.c:41: error: dereferencing pointer to incomplete type

bzw tritt dieser 3 mal an den entsprechenden Stellen auf.

Hier erstmal der Code
1
#include "suart.h"
2
#include "main.h"
3
4
#ifdef RX_INVERT
5
#define get_rxd()  (RXD_PIN == 0)
6
#else
7
#define get_rxd()  (RXD_PIN == 1)
8
#endif
9
10
uint8_t srx_tmp;
11
uint8_t srx_data;
12
uint8_t srx_mask;
13
volatile uint8_t srx_done;
14
15
16
void suart_init( void )
17
{
18
  srx_done = 0;
19
20
  srx_mask = 0;        // also change direction flag
21
  PCMSK2 = 1<<RXD_INT;      // enable start detection pin
22
  PCIFR = 1<<PCIF2;
23
24
  TCCR0A = 0;
25
  TCCR0B = 0;
26
  OCR0A = BIT_TIME;
27
  TIMSK0 = 1<<OCIE0A;
28
}
29
30
31
uint8_t sgetchar( void )
32
{
33
  while( !srx_done );
34
  srx_done = 0;
35
  return srx_data;
36
}
37
38
39
ISR( PCINT2_vect )
40
{
41
  if( get_rxd() == 0 ){      // if start bit
42
    TCNT0 = 256 - (BIT_TIME/2); // 1.5 bit time until compare
43
    TCCR0A |= ( 1<<WGM01 );
44
  TCCR0B |= ( 1<<CS01 );    // start T1 with XTAL / 8
45
    srx_tmp = 0;        // clear bit storage
46
    srx_mask = 1;        // start with LSB
47
    PCMSK2 = 0;          // disable start detection
48
  }
49
}
50
51
52
ISR( TIMER0_COMPA_vect )
53
{
54
  if( srx_mask ){
55
    if( get_rxd() == 1 )
56
      srx_tmp |= srx_mask;
57
    srx_mask <<= 1;
58
    return;
59
  }
60
  if( get_rxd() == 1 ){      // Stop bit valid
61
    srx_done = 1;      // mark rx data valid
62
    srx_data = srx_tmp;      // store rx data
63
    TCCR0A = 0;        // stop T1
64
  TCCR0B = 0;
65
    PCMSK2 = 1<<RXD_INT;      // enable further start detection
66
  }
67
}

Controller ist ein ATA6613 bzw ein ATmega168

von Mark B. (markbrandis)


Lesenswert?

1
#ifdef RX_INVERT
2
#define get_rxd()  (RXD_PIN == 0)
3
#else
4
#define get_rxd()  (RXD_PIN == 1)
5
#endif
1
if( get_rxd() == 0 )
1
if( get_rxd() == 1 )

Solche Makros lieb ich ja.
Nicht ganz klar ist mir jedenfalls, wo hier ein Zeiger dereferenziert 
wird. Diesen Fehler kenne ich auch eher in Zusammenhang mit einer 
struct. Von einer solchen ist ebenfalls nüscht zu sehn.

von Karl H. (kbuchegg)


Lesenswert?

Mark Brandis schrieb:

> Nicht ganz klar ist mir jedenfalls, wo hier ein Zeiger dereferenziert
> wird. Diesen Fehler kenne ich auch eher in Zusammenhang mit einer
> struct. Von einer solchen ist ebenfalls nüscht zu sehn.

Es sei denn hinter RXD_PIN versteckt sich ein Pointer auf eine struct.
PeDa benutzt ja ein System, wie er in so einem Makro gleichzeitig Port 
und Pin im Port codiert.

Wahrscheinlich fehlt nur irgendein #include

von Frederik K. (n0ll4k)


Lesenswert?

Ja ich hab das von Peter 1:1 übernommen und dann die Ports angepasst, 
dann werd ich das gleich nochmal umschreiben und nochmal testen.

von Karl H. (kbuchegg)


Lesenswert?

Frederik Krämer schrieb:
> Ja ich hab das von Peter 1:1 übernommen und dann die Ports angepasst,
> dann werd ich das gleich nochmal umschreiben und nochmal testen.

Schau einfach noch, wo und wie das Makro RXD_PIN definiert wird (müsste 
eigentlich ein Makro sein, da alles in Grossbuchstaben).
Du siehst dir die Definition dazu an und siehst nach was du alles dazu 
brauchst. Dann suchst du weiter, wo diese Einzelteile wieder herkommen. 
Irgendwann wirst du auf einen Teil stossen, für den es in suart.c keinen 
include (weder direkt noch indirekt) gibt.

von Frederik K. (n0ll4k)


Lesenswert?

Ne ich hab eben die struct entdeckt mit der es vermutlich zusammenhängt
1
#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)

Das Makro ist dann wie folgt definiert.
1
#define  RXD_PIN    SBIT( PIND, 4 )

Wenn ich das ganze nun irgendwie ohne die struct definiere sollte es ja 
funktionieren.

Ich werd mich da mal dran versuchen.

von Mark B. (markbrandis)


Lesenswert?

Aus einem Makro ein Makro machen und daraus ein Makro ist ganz toll. Als 
nächstes will ich rekursive Makros. Unbedingt.

von Peter D. (peda)


Lesenswert?

Warscheinlich fehlt ein Include (io.h) und deshalb kann er "DIND" nicht 
auflösen.


Mark Brandis schrieb:
> Aus einem Makro ein Makro machen und daraus ein Makro ist ganz toll.

Wenn Du mal in größere Programme schaust, dann ist das hier noch 
vollkommen harmlos.


> Als
> nächstes will ich rekursive Makros. Unbedingt.

Sowas habe ich auch schon gesehen, über rekursive Includes.
Da sitzt man Stunden davor, um es zu verstehen.


Peter

von Frederik K. (n0ll4k)


Lesenswert?

Also das io ist in der suart.h eingebunden.

Aber ich verstehen grad irgendwie das SBIT Makro auch nicht, also kann 
ich es nicht umschreiben.

von Karl H. (kbuchegg)


Lesenswert?

Frederik Krämer schrieb:
> Also das io ist in der suart.h eingebunden.
>
> Aber ich verstehen grad irgendwie das SBIT Makro auch nicht, also kann
> ich es nicht umschreiben.

?
So schwer ist das nicht.
Es gibt nur 2 Möglichkeiten

SBIT    Set BIT
SBIT    Is Bit Set

Da das ganze in einer Abfrage verwendet wird, was wird es daher sein?


Peters Code hat nur einen Vorteil:
Er kann das SBIT sowohl zur Abfrage als auch zum Setzen von Bits 
benutzen. Entweder du siehst den restlichen Code durch, ob SBIT auch in 
der anderen Form benutzt wird, oder du benutzt seine Mechanismus einfach 
weiter.

von Frederik K. (n0ll4k)


Lesenswert?

Ahh alles klar, dann schau ich mir den code nochmal an und vergleiche 
mit dem original weil den kann ich kompilieren.

von Mark B. (markbrandis)


Lesenswert?

Peter Dannegger schrieb:
> Wenn Du mal in größere Programme schaust, dann ist das hier noch
> vollkommen harmlos.

Och, ich hab schon lecker Sachen gesehen. Zum Beispiel meinte jemand, 
aus dem "else if" plus der Bedingung ein Makro machen zu müssen. Klar 
flog das im Code Review sofort raus.

> Sowas habe ich auch schon gesehen, über rekursive Includes.
> Da sitzt man Stunden davor, um es zu verstehen.

Dass es das gibt, heißt ja noch nicht, dass es auch gut ist und 
unbedingt so gemacht werden sollte.

von Frederik K. (n0ll4k)


Lesenswert?

Also kompilieren klappt nun. Hatte irgendwie vergessen die passende 
struct Definition auch mitzukopieren.

Jetzt muss nur noch das gesendete ankommen, aber ich denke mal das 
bekomme ich nu auch noch hin.

von Frederik K. (n0ll4k)


Lesenswert?

So das ganze läuft nun, morgen werd ich mich dann mal an den TX Teil 
setzen, hoffe das ich da etwas schneller vorran komme.

Danke für die Hilfe.

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.