Variable in der Headerdatei

Gast #2694406
Lesenswert?

das ist keine Variable, sonder nur eine Ersetzung


Welche Sprache soll das sein? Wenn C dann so z.B.


in H-Datei:

extern int globaleVariable;

in C-Datei:

int globaleVariable = 0;


void main(void) {
 globaleVariable = 1;
}
Gast #2694414
Lesenswert?

Danke für deinen Tipp =)

Ja verwende C, kann man auch die 'Ersetzung' ändern?
Kann ich vom Hauptprogramm die Ersetzung in Headerdatei ändern.
Möchte nämlich zu Beginn PD1 verwenden und während des Progammes möchte 
ich sie gerne auf PD2 setzen. Geht das?
#2694418
Lesenswert?

Sabine F. schrieb:
> Kann ich vom Hauptprogramm die Ersetzung in Headerdatei ändern.
> Möchte nämlich zu Beginn PD1 verwenden und während des Progammes möchte
> ich sie gerne auf PD2 setzen. Geht das?

Du begreifst es nicht.
ein define ist KEINE Variable, das ist eine Textersetzung, die vor dem 
compilieren durch den Präprozessor erfolgt.
Zur Laufzeit kannst du nur in Variablen etwas ändern
Du brauchst ein C Buch!
Gast #2694439
Lesenswert?

"Vor" dem kompilieren ist das Stichwort. Ist das Programm erst einmal 
auf dem Controller, lässt sich an einer festen #define Zuweisung nichts 
mehr ändern. (Das # Zeichen bezeichnet Präprozessoranweisungen, die bei 
der Erzeugung des Maschinencodes als erste behandelt werden).

Warum nimmst du nicht einfach eine zweite Zeile á la "#define 
STX_initial PD1" hinzu, verwendest diese Zuweisung eben nur einmal beim 
Start und danach immer STX (dem zu PD2 zugewiesen hast)? Es gibt sicher 
auch noch andere Lösungen, aber deine ursprüngliche Idee ist definitiv 
keine davon.
Gast #2694443
Lesenswert?

Wie kann man dieses Problem sonst lösen?

#define STX    PD5

Möchte PD5 auf PD4 ändern können, damit ich zweimal das selbe auf zwei 
Software - UARTs senden kann.

Wie könnte dies funktionieren?
1
#include "main.h"
2
#include "suart.h"
3

4

5

6
#define BIT_TIME  (u8)((XTAL / BAUD) / PRESCALE)
7

8

9
volatile u8 stx_count;
10
u8 stx_data;
11

12
volatile u8 srx_done;
13
u8 srx_data;
14
u8 srx_mask;
15
u8 srx_tmp;
16

17
void suart_init( void )
18
{
19
  SBIT(PORTD,STX) = 1;
20
  // OCR0A = TCNT0 + 1;    // force first compare
21
  // TCCR0A = 0;        // Default: Normal port operation
22
  TCCR0B = 1 << CS01 | 1<<CS00;  // clk/64
23
  // TIFR0 = 1<<ICF1;      // clear pending interrupt
24
  TIMSK0 = 1 << OCIE0A;    // enable output compare interrupt
25

26
  EICRA = 1 << ISC01;      // falling edge
27
  EIMSK = 1 << INT0;      // enable edge interrupt
28

29
  stx_count = 0;        // nothing to sent
30
  srx_done = 0;            // nothing received
31
  STXDDR |= 1 << STX;      // TX output
32
}
33

34

35
u8 sgetchar (void)      // get byte
36
{
37
  while (!srx_done);      // wait until byte received
38
  srx_done = 0;
39
  return srx_data;
40
}
41

42

43
ISR (INT0_vect)    // rx start
44
{
45
  OCR0B = TCNT0 + (u8)((BIT_TIME * 3) / 2);// scan 1.5 bits after start
46

47
  srx_tmp = 0;        // clear bit storage
48
  srx_mask = 1;        // bit mask
49
  if( !(SRXPIN & 1<<SRX))  {  // still low
50
    EIMSK &= ~(1 << INT0);      // disable edge interrupt
51
    TIMSK0 = 1<<OCIE0A^1<<OCIE0B;  // wait for first bit
52
}
53
  TIFR0 = 1<<OCF0B;      // clear pending interrupt ? why does that output compare int occur?
54
EIFR |= (1 << INTF0);    // clear any pending edge interrupt
55
}
56

57

58
ISR (TIMER0_COMPB_vect)
59
{
60
  u8 in = SRXPIN;      // scan rx line
61
  // PORTB = 0x00;
62
  if (srx_mask) {
63
      if (in & 1 << SRX)
64
      srx_tmp |= srx_mask;
65
    srx_mask <<= 1;
66
    OCR0B += BIT_TIME;      // next bit slice
67
  } else {
68
    srx_done = 1;      // mark rx data valid
69
    srx_data = srx_tmp;      // store rx data
70
    // TIFR0 = 1<<ICF1;      // clear pending interrupt
71
    TIMSK0 = 1<<OCIE0A;        // enable tx and wait for start
72
    EIFR |= (1 << INTF0);    // clear any pending edge interrupt: This hinders the in0-vect from beeing triggerd again just now which may occur by falling edges in the serial data bits
73
    EIMSK = 1 << INT0;  // reenable edge interrupt
74
  }
75
    // PORTB = 0x02;
76
}
77

78

79
void sputchar (u8 val)      // send byte
80
{
81
  while (stx_count);      // until last byte finished
82
  stx_data = ~val;      // invert data for Stop bit generation
83
  stx_count = 10;      // 10 bits: Start + data + Stop
84
}
85

86

87
void sputs (u8 *txt)      // send string
88
{
89
  while (*txt)
90
    sputchar (*txt++);
91
}
92

93

94
ISR (TIMER0_COMPA_vect)    // tx bit
95
{
96
  u8 dout;
97
  u8 count;
98

99
  OCR0A += BIT_TIME;      // next bit slice
100
  count = stx_count;
101

102
  if (count) {
103
    stx_count = --count;    // count down
104
    // ??? dout = 1<<COM0A1;      // set low on next compare
105
    dout = 0;
106
    if (count != 9) {      // no start bit
107
      if (!(stx_data & 1))    // test inverted data
108
        //??? dout = 1<<COM0A1^1<<COM0A0;  // set high on next compare
109
        dout = 1;
110
          stx_data >>= 1;      // shift zero in from left
111
    }
112
    // TCCR0A = dout;
113
    // STX = (dout == 0) ? 1 : 0;
114
    SBIT(PORTD,STX) = dout;
115
  }
116
}
#2694477
Lesenswert?

> Möchte PD5 auf PD4 ändern können, damit ich zweimal das selbe auf
> zwei Software - UARTs senden kann.
>
> Wie könnte dies funktionieren?

Indem du das implementierst, was das logischte ist:
eine 2.te Software UART

HIer ist deine erste
1
void suart_init_1( void )
2
{
3
  SBIT(PORTD,STX_1) = 1;
4
  // OCR0A = TCNT0 + 1;    // force first compare
5
  // TCCR0A = 0;        // Default: Normal port operation
6
  TCCR0B = 1 << CS01 | 1<<CS00;  // clk/64
7
  // TIFR0 = 1<<ICF1;      // clear pending interrupt
8
  TIMSK0 = 1 << OCIE0A;    // enable output compare interrupt
9

10
  EICRA = 1 << ISC01;      // falling edge
11
  EIMSK = 1 << INT0;      // enable edge interrupt
12

13
  stx_count = 0;        // nothing to sent
14
  srx_done = 0;            // nothing received
15
  STXDDR_1 |= 1 << STX_1;      // TX output
16
}

und sukzessive für alle anderen Funktionen: Allem was UART spezifisch 
ist, verpasst du eine angehängte _1. Aus STX wird STX_1, aus suart_init 
wird suart_init_1, aus sputchar wird sputchar_1, etc. etc.

und dann implementierst du alles nochmal, wobei du anstelle der _1 dann 
eben eine _2 hast.

Voila: 2 Software UART, die sauber in allen Belangen voneinander 
getrennt sind.

Edit: In den höhreren Software Schichten könnte man das auch ein wenig 
eleganter machen, aber im Hinblick auf deine C-Kentnisse nehme ich davon 
mal Abstand. Einfach realisierbar und für dich durchschaubar lautet die 
Devise.
Moderator Persönliche Seite #2694479
Lesenswert?

Sabine F. schrieb:
> Möchte PD5 auf PD4 ändern können, damit ich zweimal das selbe auf zwei
> Software - UARTs senden kann.

Dann schmeiß STX und SRX komplett aus der Headerdatei raus um
sicherzustellen, dass sie tatsächlich auch sonst niemand benutzt.

In der Implementierungsdatei schreibst du dann:
1
#define STX PD5
2
#define SRX PD6
3

4
// Implementierung der 1. Software-UART
5

6
#undef STX
7
#undef SRX
8

9
#define STX PD4
10
#define SRX PD3
11

12
// Implementierung der 2. Software-UART
13

14
#undef STX
15
#undef SRX

Edit: unterscheidet sich von Karl-Heinz' Vorschlag nur geringfügig
in der Form, die Grundzüge der Implementierung bleiben zwischen
uns beiden gleich.
#2694556
Lesenswert?

Wobei:

Mit dieser Interrupt getriebenen SW-UART
1
  TCCR0B = 1 << CS01 | 1<<CS00;  // clk/64
2
  // TIFR0 = 1<<ICF1;      // clear pending interrupt
3
  TIMSK0 = 1 << OCIE0A;    // enable output compare interrupt
4

5
  EICRA = 1 << ISC01;      // falling edge
6
  EIMSK = 1 << INT0;      // enable edge interrupt

könnte es interessant werden, eine 2. SW-UART aufzusetzen, die 
Timer-Interrupt getrieben das richtige tut und man keinen funktional 
gleichwertigen Timer mehr übrig hat.

Insofern nehm ich meine implizite Aussage von weiter oben, das das mit 
kleinen Modifikationen geht, wieder zurück. Da hab ich mir das alles 
nicht besonders gut angesehen.
Gast #2694589
Lesenswert?

Ich will nicht zwei Uarts gleichzeitig benützen, es reicht mir auch, 
wenn sie hintereinander etwas senden können, sprich daten auf PD4 und 
dann PD5. Ist es nicht möglich PD4 mit einer Anweisung auf PD5 
umschalten zu können?
#2694599
Lesenswert?

Sabine F. schrieb:
> Ich will nicht zwei Uarts gleichzeitig benützen, es reicht mir auch,
> wenn sie hintereinander etwas senden können, sprich daten auf PD4 und
> dann PD5. Ist es nicht möglich PD4 mit einer Anweisung auf PD5
> umschalten zu können?
nein, dann must du UART-Routinen so umschreiben, das an allen Stellen, 
an denen die define's verwendet werden entweder direkt mit Variablen 
gearbeitet wird. Oder noch mal eine Fallunterscheidung durchgeführt 
wird.

z.B.

uint8 SRX;

...

//UART A
SRX=1<<PD4;

if( !(SRXPIN & SRX))  //PD4 abfragen

//umschalten auf UART B
SRX=1<<PD6;

if( !(SRXPIN & SRX))  //PD6 abfragen


Sascha
Gast #2694764
Lesenswert?

Habe jetzt die Software - Uart in eine neue Klasse geschrieben und eine 
zusätzliche Headerdatei geschrieben. Jedoch bekomme ich beim Ausführen 
einen Error.

make: *** [SoftwareUART.elf] Fehler 1
Gast #2694798
Lesenswert?

Die erste Header - Datei:
1
#define SRX    PD6
2
#define SRXPIN  PIND
3

4
#define STX    PD5    //Pinbelegung Datasheet (OC1A) #define STX    PD4
5
#define STXDDR  DDRD
6

7
extern volatile u8 srx_done;
8

9
#define kbhit()  (srx_done)  // true if byte received
10

11
void suart_init( void );
12
void sputchar( u8 val );
13
u8 sgetchar( void );
14
void sputs( u8 *txt );
15

16
struct bits {
17
  u8 b0:1;
18
  u8 b1:1;
19
  u8 b2:1;
20
  u8 b3:1;
21
  u8 b4:1;
22
  u8 b5:1;
23
  u8 b6:1;
24
  u8 b7:1;
25
} __attribute__((__packed__));
26

27
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
28
#define  SBIT(x,y)  SBIT_(x,y)




Die zweite Header - Datei:
1
#define SRX1 PD6
2
#define SRXPIN1  PIND
3

4
#define STX1 PD4    //Pinbelegung Datasheet (OC1A) #define STX    PD4
5
#define STXDDR1  DDRD
6

7
extern volatile u8 srx_done1;
8

9
#define kbhit()  (srx_done1)  // true if byte received
10

11
void suart_init1( void );
12
void sputchar1( u8 val );
13
u8 sgetchar1( void );
14
void sputs1( u8 *txt );
15

16
struct bits1 {
17
  u8 b0:1;
18
  u8 b1:1;
19
  u8 b2:1;
20
  u8 b3:1;
21
  u8 b4:1;
22
  u8 b5:1;
23
  u8 b6:1;
24
  u8 b7:1;
25
} __attribute__((__packed__));
26

27
#define SBIT_1(port,pin) ((*(volatile struct bits1*)&port).b##pin)
28
#define  SBIT1(x,y)  SBIT_1(x,y)



Darf ich das so machen?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren