Forum: Mikrocontroller und Digitale Elektronik Header .c .h einbinden funktioniert nicht ?


von Michael H. (h_m)


Lesenswert?

Guten Tag,

ich versuche mir einen eigene Libary zu erstellen aus einer .h Datei und 
einer .c Datei allerdings wenn ich diese ins Hauptprogramm einbinden 
will bekomme ich nach dem Compilieren eine Reihe von Fehlermeldungen.

Könnte mir Bitte jemand sagen was ich hier verkehrt gemacht habe ?

und Bitte nachsicht mit mir das ist meine erste Header Datei

Nachfolgend

.h Datei
.c Datei
-Hauptprogramm (einbinden)
-Fehlerliste

.h Datei
1
#ifndef I2C_H
2
#define I2C_H
3
4
#define START           0x08    // A START condition has been transmitted
5
#define R_START         0x10    // A REPEATED START condition has been transmitted
6
#define SLA_W           0xC0    // Slave Address & Write 1100 0000 A0 ist auf GND gelegt
7
#define SLA_R           0xC1    // Slave Address & Read 1100 0001
8
#define MT_SLA_ACK      0x18    // Master Transmit SLA + W has been transmitted & ACK has been received
9
#define MT_DATA_ACK     0x0000    // Master Transmit Data byte has been transmitted & ACK has been received
10
#define MR_SLA_ACK      0x40    // Master Receive SLA + R has been transmitted & ACK has been received
11
#define MR_SLA_NACK     0x48    // Master Receive SLA + R has been transmitted & ACK has been received
12
#define MR_DATA_ACK     0x50    // Master Receive Data byte has been transmitted & ACK has been returned
13
#define MR_DATA_NACK    0x58    // Master Receive Data byte has been transmitted & NACK has been returned
14
#define BIT_RATE        56      // Set value for the bit rate register TWBR
15
16
void ERROR(void);               // Prototyping of function "ERROR"
17
18
/*** Function to send a START Condition ***/
19
void TWI_START(void);
20
21
/*** Function to send the Slave Address with ACK in Master Transmit Mode ***/
22
void TWI_MT_SLA_ACK(void);
23
24
/*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
25
void TWI_MT_DATA_ACK(uint8_t data);
26
27
/*** Function to send a REPEATED START condition **/
28
void TWI_R_START(void);
29
30
/*** Function to send the Slave Address in Master Receive Mode with Acknowledge **/
31
void TWI_MR_SLA_ACK(void);
32
33
/*** Function to send the Slave Address in Master Receive Mode without Acknowledge **/
34
void TWI_MR_SLA_NACK(void);
35
36
/*** Function to read one Databyte in Master Receive Mode and send NACK ***/
37
uint8_t TWI_READ_DATABYTE_NACK(void);
38
39
/*** Function to read one Databyte in Master Receive Mode and send ACK ***/
40
uint8_t TWI_READ_DATABYTE_ACK(void);
41
42
/*** function to send a STOP condition ***/
43
void TWI_STOP(void);
44
45
/*** function to show a bus error ***/
46
void ERROR(void);
47
48
#endif




.c Datei
1
#include "I2C.h"
2
3
4
/*** Function to send a START Condition ***/
5
void TWI_START(void)
6
{
7
  // Send a START condition
8
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
9
  // Wait for TWINT Flag set. This indicates that the START condition has been transmitted
10
  while (!(TWCR & (1<<TWINT)));
11
  // Check value of TWI statusregister. Mask prescaler bits. If status different from START go to ERROR if ((TWSR & 0xF8) != START)
12
  ERROR();
13
}
14
15
/*** Function to send the Slave Address with ACK in Master Transmit Mode ***/
16
void TWI_MT_SLA_ACK(void)
17
{
18
  // Load Slave Address + Write into TWDR Register
19
  TWDR = SLA_W;
20
  // Clear TWINT bit in TWCR to start transmission
21
  TWCR = (1<<TWINT) | (1<<TWEN);
22
  // Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
23
  while (!(TWCR & (1<<TWINT)));
24
  // Check value of TWI status register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR
25
  if ((TWSR & 0xF8) != MT_SLA_ACK)
26
  ERROR();
27
}
28
29
/*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
30
void TWI_MT_DATA_ACK(uint8_t data)
31
{
32
  // Load DATA into TWDR register
33
  TWDR = data;
34
  // Clear TWINT bit in TWCR to start transmission
35
  TWCR = (1<<TWINT) | (1<<TWEN);
36
  // Wait for TWINT flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received.
37
  while (!(TWCR & (1<<TWINT)));
38
  // Check value of TWI status register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
39
  if ((TWSR & 0xF8) != MT_DATA_ACK)
40
  ERROR();
41
}
42
43
/*** Function to send a REPEATED START condition **/
44
void TWI_R_START(void)
45
{
46
  // Send a START condition
47
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
48
  // Wait for TWINT Flag set. This indicates that the START condition has been transmitted
49
  while (!(TWCR & (1<<TWINT)));
50
  // Check value of TWI statusregister. Mask prescaler bits. If status different from R_START go to ER-ROR
51
  if ((TWSR & 0xF8) != R_START)
52
  ERROR();
53
}
54
55
*** Function to send the Slave Address in Master Receive Mode with Acknowledge **/
56
void TWI_MR_SLA_ACK(void)
57
{
58
// Load Slave Address + Read into TWDR Register
59
TWDR = SLA_R;
60
// Clear TWINT bit in TWCR to start transmission
61
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
62
// Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
63
while (!(TWCR & (1<<TWINT)));
64
// Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_ACK go to ERROR
65
if ((TWSR & 0xF8) != MR_SLA_ACK)
66
ERROR();
67
}
68
69
/*** Function to send the Slave Address in Master Receive Mode without Acknowledge **/
70
void TWI_MR_SLA_NACK(void)
71
{
72
  // Load Slave Address + Read into TWDR Register
73
  TWDR = SLA_R;
74
  // Clear TWINT bit in TWCR to start transmission
75
  TWCR = (1<<TWINT) | (1<<TWEN);
76
  // Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
77
  while (!(TWCR & (1<<TWINT)));
78
  // Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_NACK go to ERROR
79
  if ((TWSR & 0xF8) != MR_SLA_NACK)
80
  ERROR();
81
}
82
83
/*** Function to read one Databyte in Master Receive Mode and send NACK ***/
84
uint8_t TWI_READ_DATABYTE_NACK(void)
85
{
86
  // Clear TWINT bit in TWCR to start transmission with NACK
87
  TWCR = (1<<TWINT) | (1<<TWEN);
88
  // Wait for TWINT flag set. This indicates that the DATA has been received
89
  while (!(TWCR & (1<<TWINT)));
90
  // Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_NACK go to ERROR
91
  if ((TWSR & 0xF8) != MR_DATA_NACK)
92
  ERROR();
93
  return TWDR; // Return the value of data register
94
}
95
96
/*** Function to read one Databyte in Master Receive Mode and send ACK ***/
97
uint8_t TWI_READ_DATABYTE_ACK(void)
98
{
99
  // Clear TWINT bit in TWCR to start transmission with ACK
100
  TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
101
  // Wait for TWINT flag set. This indicates that the DATA has been received
102
  while (!(TWCR & (1<<TWINT)));
103
  // Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_ACK go to ERROR
104
  if ((TWSR & 0xF8) != MR_DATA_ACK)
105
  ERROR();
106
  return TWDR; // Return the value of data register
107
}
108
109
/*** function to send a STOP condition ***/
110
void TWI_STOP(void)
111
{
112
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Transmit STOP condition
113
}
114
115
/*** function to show a bus error ***/
116
void ERROR(void)
117
{
118
  PORTB |= (1<<PB1); // ERROR LED ON
119
}

Hauptprogramm
1
/*
2
 * Header_Test.c
3
 *
4
 * Created: 01.03.2019 09:27:29
5
 * Author : USER
6
 */ 
7
8
#include <avr/io.h>
9
#include "I2C.h"
10
11
12
int main(void)
13
{
14
    /* Replace with your application code */
15
    while (1) 
16
    {
17
    }
18
}


Fehlerliste
1
Severity  Code  Description  Project  File  Line
2
Error    'PB1' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  118
3
Error    'PORTB' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  118
4
Error    'TWCR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  8
5
Error    'TWCR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  21
6
Error    'TWCR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  47
7
Error    'TWCR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  75
8
Error    'TWCR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  87
9
Error    'TWCR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  100
10
Error    'TWCR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  112
11
Error    'TWDR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  19
12
Error    'TWDR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  73
13
Error    'TWDR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  93
14
Error    'TWDR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  106
15
Error    'TWEA' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  100
16
Error    'TWEN' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  8
17
Error    'TWEN' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  21
18
Error    'TWEN' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  47
19
Error    'TWEN' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  75
20
Error    'TWEN' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  87
21
Error    'TWEN' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  100
22
Error    'TWEN' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  112
23
Error    'TWINT' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  8
24
Error    'TWINT' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  21
25
Error    'TWINT' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  47
26
Error    'TWINT' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  75
27
Error    'TWINT' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  87
28
Error    'TWINT' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  100
29
Error    'TWINT' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  112
30
Error    'TWSR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  25
31
Error    'TWSR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  51
32
Error    'TWSR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  79
33
Error    'TWSR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  91
34
Error    'TWSR' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  104
35
Error    'TWSTA' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  8
36
Error    'TWSTA' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  47
37
Error    'TWSTO' undeclared (first use in this function)  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  112
38
Warning    control reaches end of non-void function [-Wreturn-type]  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  94
39
Warning    control reaches end of non-void function [-Wreturn-type]  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  107
40
Message    each undeclared identifier is reported only once for each function it appears in  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  8
41
Error    expected '=', ',', ';', 'asm' or '__attribute__' before 'to'  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  55
42
Error    recipe for target 'I2C.o' failed  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\Debug\Makefile  86
43
Error    unknown type name 'to'  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  55
44
Error    unknown type name 'uint8_t'  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  30
45
Error    unknown type name 'uint8_t'  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  84
46
Error    unknown type name 'uint8_t'  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.c  97
47
Error    unknown type name 'uint8_t'  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.h  25
48
Error    unknown type name 'uint8_t'  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.h  37
49
Error    unknown type name 'uint8_t'  Header_Test  c:\users\user\Documents\Atmel Studio\7.0\Header_Test\Header_Test\I2C.h  40

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Ohne jetzt genau drüber nachgedacht zu haben, pack mal #include 
<avr/io.h> zusätzlich in die i2c.c
Und die inttypes.h mit in die i2c.h weil du da uint8_t benutzt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Für uint8_t (und Konsorten) eigentlich auch noch
1
#include <stdint.h>

Allerdings wird dieser Header bereits von <avr/io.h> inkludiert, sodass 
man das am Ende nicht weiter merkt, wenn man es selbst vergessen hat. 
Grundregel des Programmierers sollte es allerdings sein, für alles, was 
er selbst verwendet, sich auch um die zugehörige Deklaration zu kümmern.

von Regeln Erklehrbehr (Gast)


Angehängte Dateien:

Lesenswert?

Michael H. schrieb:
> Nachfolgend

Du bist hier lange genug dabei Unfug zu treiben, halte dich
endlich auch an die Regeln.

Du wurdest auch schon daran erinnert.

von M. K. (sylaina)


Lesenswert?

Regeln Erklehrbehr schrieb:
> Michael H. schrieb:
>> Nachfolgend
>
> Du bist hier lange genug dabei Unfug zu treiben, halte dich
> endlich auch an die Regeln.
>
> Du wurdest auch schon daran erinnert.

Sei doch froh, dass er Code-Tags benutzt hat. Ich sehe da kein Problem, 
der Namensvetter hat da IMO alles richtig gemacht.

von M.A. S. (mse2)


Lesenswert?

M. K. schrieb:
> Sei doch froh, dass er Code-Tags benutzt hat. Ich sehe da kein Problem,
> der Namensvetter hat da IMO alles richtig gemacht.

Sehe ich auch so. Und vor allem hat dieser TO alles, was relevant ist, 
sofort angegeben: .h-File, c-File, main.c, Fehlermeldungen. Alles da, 
niemand musste ihm irgendwas aus der Nase ziehen.
Und wirklich lang sind die Sourcen ja nun auch nicht.

von Dirk B. (dirkb2)


Lesenswert?

Kurzer Erklärungsversuch:

Jede .c Datei wird für sich alleine übersetzt in eine Object-Datei .o

Da werden vom Preprocessor die #includes eingebunden (statt des #include 
steht dann die ganze .h Datei drin)

Es muss also alles für einen erfolgreichen Übersetzungsvorgang bekannt 
sein.

Wenn dann die I2C.c übersetzt wird ist nur das #include "I2C.h" da.

Die bemängelten Symbole werden nirgends definiert.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Es hätte so schön sein können, Problem->Lösung, evtl. im Anschluss noch 
ne Erklärung warum das passiert und gut. Aber nein, es fehlt wieder 
irgendein Schlaubischlumpf der ein Haar in der Suppe finden muss...

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Also dann nochmal eine Erklärung was gemacht werden muss und warum:

I2C.h:

Da fehlt ein #include <inttypes.h> oder #include <stdint.h> weil du im 
Header uint8_t als Rückgabetyp bzw. als Parameter benutzt. Ein Oder, 
weil die <inttypes.h> die <stdint.h> einbindet und nur etwas erweitert, 
was in deinem Fall aber garnicht nötig ist, also ein #include <stdint.h> 
würde reichen.
Anmerkung noch zu "void TWI_MT_DATA_ACK(uint8_t data);", an dieser 
Stelle hätte es absolut gereicht nur "void TWI_MT_DATA_ACK(uint8_t);" zu 
schreiben, es interessiert hier nur der Datentyp (wegen der Größe) nicht 
wie die Variable später heißt.

I2C.c:

Es fehlen #include <avr/io.h> und #include <stdint.h>, weil du hier 
Definitionen bezüglich der Port-, Registernamen benutzt. Die <stdint.h> 
wieder wegen der Nutzung der Datentypen uint8_t, wobei man sie hier dann 
aber weglassen kann weil sie ja jetzt indirekt über die I2C.h 
eingebunden wird, ich z.B. machs aber trotzdem.

von M. K. (sylaina)


Lesenswert?

Tim T. schrieb:
> Es fehlen #include <avr/io.h> und #include <stdint.h>

Letzters fehlt nicht weil es schon in Ersterem enthalten ist. Also im 
Prinzip fehlte nur das #include <avr/io.h> in der I2C.h ;)

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

M. K. schrieb:
> Tim T. schrieb:
>> Es fehlen #include <avr/io.h> und #include <stdint.h>
>
> Letzters fehlt nicht weil es schon in Ersterem enthalten ist. Also im
> Prinzip fehlte nur das #include <avr/io.h> in der I2C.h ;)

Prinzipiell richtig, aber Jörg hatte schon was dazu geschrieben, ich 
sehe das sehr ähnlich (wobei ich jetzt aber am überlegen bin womit ich 
meine inkonsequente Handlungsweise bei der inttypes.h begründe...)
Bester Erklärungsversuch ist wohl, das ich indirektes Einbinden da 
mitnehme wo es hauptsächlich nur um die Kapselung geht, aber nicht wenns 
nur als Beiwerk mit drin ist.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Tim T. schrieb:
> wobei ich jetzt aber am überlegen bin womit ich meine inkonsequente
> Handlungsweise bei der inttypes.h begründe

<stdint.h> ist eine Art „Abrüstversion“ von <inttypes.h>, beide sind im 
Standard passend definiert. Man darf sich also drauf verlassen, dass es 
genügt, die entsprechenden Deklarationen / Definitionen aus einem von 
beiden zu bekommen.

Im Gegensatz dazu sichert <avr/io.h> nicht zu, dass sie einen davon 
entbindet, sich um <stdint.h> (oder <inttypes.h>) selbst zu kümmern. Das 
ist da nur bereits enthalten, weil es eben von diesen Headern auch 
selbst benutzt wird.

von W.S. (Gast)


Lesenswert?

Michael H. schrieb:
> #define START           0x08
...usw.

Könntest du mal erklären, wozu du diese ganzen #define's in die 
Header-Datei geschrieben hast?

Also, in keiner der von dir in diese Headerdatei geschriebenen 
Funktionen wird irgend einer dieser Defines gebraucht. Also können auch 
alle Programme, die deinen Modul benutzen wollen, mit diesem Zeugs 
nichts anfangen.

Abgesehen davon halte ich deine Namensgebung für nicht sonderlich 
einprägsam und auch das Aufsplitten in argumentlose EInzelfunktionen 
halte ich für eher unglücklich:
uint8_t TWI_READ_DATABYTE_NACK(void);
uint8_t TWI_READ_DATABYTE_ACK(void);

und sowas halte ich für blanken Unsinn:
void TWI_START(void);
void TWI_MT_SLA_ACK(void);

Dahinter steht offenbar, die Start-Cond zu erzeugen und dann die 
Slave-Adresse zu senden - und das kann entweder vom zuständigen Slave 
mit ACK quittiert werden oder es kommt eben ein NAK. Also müßte dein 
Twi-Mt-Sla-Ack wenigstens bool sein.

Ich hatte früher sowas so gemacht:
1
bool Do_I2C_Start (byte Adresse, bool toRead);
2
bool Do_I2C_Write (byte aByte); 
3
byte Do_I2C_Read  (bool Acknowledge);
4
void Do_I2C_Stop  (void);

und die Start-Funktion liefert ein false, wenn kein Slave sich dabei mit 
einem ACK meldet. Sowas MUSS sein, damit die aufrufende Funktion zur 
Kenntnis nehmen kann, wenn etwas nicht geklappt hat. (wer uint8_t lieber 
mag, der möge es halt anstelle 'byte' verwenden)

Aber bei dir gibt es keinerlei Rückmeldung, wenn kein ACK kommt.

Also schmeiße all das aus dem Header raus, was da nicht hingehört und 
überdenke deine Funktionen nochmal.

W.S.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Tim T. schrieb:
> Anmerkung noch zu "void TWI_MT_DATA_ACK(uint8_t data);", an dieser
> Stelle hätte es absolut gereicht nur "void TWI_MT_DATA_ACK(uint8_t);" zu
> schreiben, es interessiert hier nur der Datentyp (wegen der Größe) nicht
> wie die Variable später heißt.

Bei nichttrivialen Funktionen ist es sinnvoll, auch im Prototypen 
sprechende Namen zu verwenden, damit klar ist, was die Parameter 
machen.

In Fällen brauchbar aufgebauter Software genügt dann ein Blick auf die 
Prototypen.

Den Compiler interessiert das natürlich nicht, aber den Menschen, der 
den Kram benutzt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Allerdings besagt die gängige Konvention, dass man Makros (insbesondere 
solche, die wie Funktionen aussehen, aber Seiteneffekte haben können) in 
GROSSBUCHSTABEN schreibt, normale Funktionen eher nicht.

Ich würde W.S. jedoch recht geben (und das mache ich sehr selten :), 
dass eine Abstraktion eine Ebene höher sinnvoller ist, als gewissermaßen 
auf dem Elementar-Level von I²C.

von Regeln Erklehrbehr (Gast)


Lesenswert?

W.S. schrieb:
> Könntest du mal erklären, wozu du diese ganzen #define's in die
> Header-Datei geschrieben hast?

Zur Erklärung: "Er" hat das nicht geschrieben sondern eine einfache
Copy&Paste-Übung gemacht.

Die Quelle ist vermutlich die hier:

http://www.ne555.at/2014/index.php/bilder-zum-buch/520-lm75_tempsensor.html

"Er" weiss nämlich eigentlich nicht so richtig was er tut, deshalb
fragt er hier auch so naiv ....

Ihr könnt ihn sonstwie mit Codier-Regeln zumüllen, er ist froh wenn
er eine vorgefertige Source zum Laufen bringt.

Von Prototypen und Abstraktion ganz zu schweigen, ihr Traumtänzer.

Siehe auch Beitrag "I2C MCP4725 Wert Übertragen"

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jo, dann hat er eben noch etwas Lernkurve vor sich.

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.