Forum: Mikrocontroller und Digitale Elektronik Problem mit Struct im Interrupt


von Hakon H. (ickiller)


Lesenswert?

Hallo Forengemeinde,

Ich code zur Zeit ein Programm für einen Thermostat.
Als Regler kommt die PID-Library aus der AVR221 Appnote zum Einsatz.
Die Temperaturerfassung erfolgt mit DS1820 1-Wire Sensoren, für die ich 
den Code von der AVR318 Appnote nutze (Anders als Atmel nutze ich jedoch 
nicht den IAR Compiler, sondern den AVRGCC im AtmelStudio 6.1, sodass 
ich den Code nicht 1:1 übernommen habe).

Nun zum Problem:
Ich will in einer Interruptroutine, die durch den CompareA des Timer1 
ausgelöst wird (CTC-Modus -> Intervall durch OCR1A einstellbar) zunächst 
den zuletzt gemessenen Wert des Sensors abrufen und in einer als 
volatile deklarierten Variable speichern, dann den Regler ausführen und 
zuletzt den Temperatursensor eine neue Messung durchführen lassen.
Die Funktionen für den Temperatursensor funktionieren bereits, den 
Regler werde ich erst testen, sobald ich ihn in der Interruptroutine 
ausführen kann.

Hier ein kleiner Ausschnmitt:
1
typedef volatile struct OWI_device
2
{
3
  unsigned char bus;      //!< A bitmask of the bus the device is connected to.
4
  unsigned char id[8];    //!< The 64 bit identifier.
5
};
6
volatile OWI_device * ds1820;
7
volatile struct PID_DATA pidData; // Element des Struct PID-DATA als Pointer für PID-Lib
8
9
uint16_t NV_P EEMEM = 65535; //EEPROM-Variablen für PID
10
uint16_t NV_I EEMEM = 0;
11
uint16_t NV_D EEMEM = 0;
12
uint16_t NV_PIDfreq EEMEM = 16384; //EEPROM-Variable für PID-Frequenz FCPU/(1024*(PIDfreq+1)) -> 65535 ergibt 0,238Hz
13
14
uint16_t V_P = 0; //flüchtige Variablen für Regler
15
uint16_t V_I = 0;
16
uint16_t V_D = 0;
17
uint16_t V_PIDfreq = 16384; //flüchtige Variable für PID-Frequenz
18
19
volatile float tsoll = 7.00; //Sollwert für Regler
20
volatile float tist = -50.00; //Istwert für Regler
21
22
ISR (TIMER1_COMPA_vect)
23
{
24
  tist = DS1820_ReadTemperature((*ds1820).bus, (*ds1820).id, true, false);
25
  OCR0 = pid_Controller(tsoll, tist, *pidData);
26
  OWI_SkipRom(OWI_PIN_0);
27
  OWI_SendByte(DS1820_START_CONVERSION, OWI_PIN_0);
28
}

Ich bekomme in der Zeile "volatile OWI_device * ds1820;" den Fehler 
"conflicting types for 'ds1820'". Zuvor hatte ich das Struct nicht 
Global erstellt und die Temperatur in der main erfasst, jetzt soll dies 
jedoch im Interrupt möglich sein...

Ausserdem bekomme ich in der Zeile "OCR0 = pid_Controller(tsoll, tist, 
*pidData);" den Fehler "invalid type argument of unary '*' (have 
'volatile struct PID_DATA'). Hier benötigt die Funktion pid_Controller 
einen Pointer auf ein Struct, das sämtliche Variablen für den Regler 
beinhaltet.

Es ist mein erstes Programm mit Interrupt.
Was genau mache ich falsch?

MfG,
Hakon Hennig

von kopfkratzer (Gast)


Lesenswert?

Hakon Hennig schrieb:
> Hier ein kleiner Ausschnmitt:

Und hier liegt das Problem, ALLES posten oder Glaskugeln spendieren ...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hakon Hennig schrieb:
> volatile OWI_device * ds1820;

Das ist nur ein Pointer. Und worauf zeigt der?

> DS1820_ReadTemperature((*ds1820).bus, (*ds1820).id, true, false);

C kennt den Zeigeroperator:

 DS1820_ReadTemperature(ds1820->bus, ds1820->id, true, false);

Ist das nicht lesbarer?

von Hakon H. (ickiller)


Lesenswert?

Hallo Rufus,

Rufus Τ. Firefly schrieb:
> Hakon Hennig schrieb:
>> volatile OWI_device * ds1820;
>
> Das ist nur ein Pointer. Und worauf zeigt der?

Das hatte ich nicht erwähnt. In der main wird die Funktion FindFamily 
ausgeführt. Ihr Rückgabewert ist ein Pointer auf ein struct des typs 
OWI_Device. Als ich  die Zeile aus dem zitat noch in der main hatte und 
die Temperatur nicht im Interruzpt abgefragt hatte funktionierte das so.

Rufus Τ. Firefly schrieb:
>> DS1820_ReadTemperature((*ds1820).bus, (*ds1820).id, true, false);
>
> C kennt den Zeigeroperator:
>
>  DS1820_ReadTemperature(ds1820->bus, ds1820->id, true, false);
>
> Ist das nicht lesbarer?

Ja, ist es. Ich habe es übernommen, danke.
Am Problem hat sich dadurch nichts geändert.

MfG,
Hakon Hennig

von Stefan E. (sternst)


Lesenswert?

1)
1
typedef volatile struct OWI_device
2
{
3
...
4
};
->
1
typedef volatile struct
2
{
3
...
4
} OWI_device;

2)
1
..., *pidData);
->
1
..., &pidData);

von Hakon H. (ickiller)


Lesenswert?

Danke Stefan,

Hakon Hennig schrieb:
> invalid type argument of unary '*' (have
> 'volatile struct PID_DATA')

der Fehler ist jetzt Geschichte.
Aber die globale Definition 'volatile OWI_device * ds1820;' bringt nach 
wie vor "conflicting types for 'ds1820'". Wenn ich hingegen die 
Funktionen für den Temperatursensor in der main ausführe und die oben 
genannte Zeile ebenfalls in der main steht ist alles bestens, da steig 
ich noch nicht durch...

MfG,
Hakon Hennig

von Stefan E. (sternst)


Lesenswert?

Hakon Hennig schrieb:
> Aber die globale Definition 'volatile OWI_device * ds1820;' bringt nach
> wie vor "conflicting types for 'ds1820'".

Dann zeige halt die andere Deklaration von ds1820.

von Hakon H. (ickiller)


Lesenswert?

Es gibt nur die eine globale Definition, die oben erwähnt wurde...

MfG,
Hakon Hennig

von Stefan E. (sternst)


Lesenswert?

Hakon Hennig schrieb:
> Es gibt nur die eine globale Definition, die oben erwähnt wurde...

Du meinst also, der Compiler würde behaupten, dass die zu sich selbst in 
Konflikt steht?

Such die andere Deklaration, es gibt sie irgendwo.

von Hakon H. (ickiller)


Lesenswert?

Stefan Ernst schrieb:
> Such die andere Deklaration, es gibt sie irgendwo.

Größten Dank Stefan, es gab tatsächlich eine NICHT eingebundene Datei im 
Projekt, die ein Array von ds1820 Elementen anderen typs global 
deklarierte, ich muss meine Solution aufräumen...
Ich hatte diese Definition nicht einmal durch die Suchfunktion des 
AtmelStudios finden können.

Der Compiler ist jetzt happy, ich auch :-)

MfG,
Hakon Hennig

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.