Forum: Mikrocontroller und Digitale Elektronik Fehler Meldung beim 1. Build


von Niko (Gast)


Lesenswert?

Hallo,

ich bekomme immer beim ersten Build eine Warning Meldung:

Severity  Code  Description  Project  File  Line
Warning    control reaches end of non-void function [-Wreturn-type] 
TWI_I2C_MASTER  G:\AtmelStudio\TWI_I2C_MASTER\TWI_I2C_MASTER\main.c
führe ich ein 2. Build durch ist es weg.

Das hier ist der Code, nur ich versteh nicht warum er meckert:
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <util/twi.h>
5
#include <util/delay.h>
6
#include <stdlib.h>
7
8
#define F_SCL 400000L
9
10
#define TWCR_START  0xA4 //send start condition
11
#define TWCR_STOP   0x94 //send stop condition   
12
#define TWCR_RACK   0xC4 //receive byte and return ack to slave
13
#define TWCR_RNACK  0x84 //receive byte and return nack to slave
14
#define TWCR_SEND   0x84 //pokes the TWINT flag in TWCR and TWEN
15
16
/* SLAVE ADRESSEN*/
17
#define GENERAL_CALL  0x00
18
#define SLAVE      0x7F
19
#define SLAVE1      0x7E
20
21
22
void I2C_INIT()
23
{
24
   TWSR = 0;                         
25
   TWBR = ((F_CPU/F_SCL)-16)/2;  
26
}
27
28
void I2C_ERROR()
29
{
30
  /* Hier Code für ERROR fall*/
31
}
32
33
void MASTER_START (uint8_t add_SLAVE,uint8_t TM_STATUS)
34
{
35
  while(1)
36
  {
37
    TWCR = TWCR_START;            /* Start*/
38
  
39
    while (!(TWCR & (1<<TWINT))  );    /* Warten bis Start ausgeführt*/
40
    if(!(TW_STATUS == TW_START))    /* Start erfolgreich: Ja weiter im Programm / Nein :ERROR*/
41
    {
42
      I2C_ERROR();
43
    }
44
  
45
    TWDR = (add_SLAVE<<1|TM_STATUS);
46
    TWCR = TWCR_SEND;
47
  
48
    while (!(TWCR & (1<<TWINT)));      
49
    switch (TW_STATUS)
50
    {
51
      case TW_SR_GCALL_ACK:
52
        break;
53
      
54
      case TW_MT_SLA_ACK:
55
        break;
56
        
57
      
58
      case TW_MT_SLA_NACK:
59
        TWCR = TWCR_STOP;
60
        while(TWCR & (1<<TWSTO));
61
        continue;
62
      
63
      case TW_MR_SLA_ACK:
64
        break;
65
      
66
      case TW_MR_DATA_NACK:
67
        TWCR = TWCR_STOP;
68
        while(TWCR & (1<<TWSTO));
69
        continue;
70
      
71
      default:
72
        I2C_ERROR();
73
          
74
    }
75
    break;
76
  }
77
}
78
79
80
void MASTER_STOP()
81
{
82
    TWCR = TWCR_STOP;
83
    
84
    while(TWCR & (1<<TWSTO));
85
}
86
87
void MASTER_DATA_WIRTE(uint8_t DATA)
88
{
89
  TWDR = DATA;
90
  TWCR = TWCR_SEND;
91
  
92
  while(!(TWCR & (1<<TWINT)));
93
  switch (TW_STATUS)
94
  {
95
    case TW_MT_DATA_ACK:
96
      break;
97
    
98
    case  TW_MT_DATA_NACK:
99
      MASTER_STOP();
100
      break;
101
    
102
    default:
103
      I2C_ERROR();  
104
  }
105
}
106
107
void MASTER_DATA_READ_ACK(uint8_t DATA)
108
{
109
  TWCR = TWCR_RNACK;
110
  while(!(TWCR & (1<<TWINT)));
111
  
112
  DATA = TWDR;
113
}
114
115
void MASTER_DATA_READ_NACK(uint8_t DATA)
116
{
117
  TWCR = TWCR_RACK;
118
  while(!(TWCR & (1<<TWINT)));
119
  
120
  DATA = TWDR;
121
}
122
123
int main(void)
124
{
125
    I2C_INIT();      /* I2C Initialisierung Durchführen*/
126
    while (1) 
127
    {
128
    }
129
}

von Jim M. (turboj)


Lesenswert?

Mach aus dem "int main(" ein "void main(",
oder füge ein "return 0" hinter der (Endlos) Schleife ein.

Beim 2. Build wird main.c offenbar nicht mehr kompiliert. Ist also nur 
"make" und kein komplettes re-build.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Deine Funktion main ist als Funktion mit einem Rückgabewert definiert 
- es fehlt aber genau das, die Rückgabe eines Wertes.

Zwar wird die Funktion wegen der enthaltenen Endlosschleife nie einen 
Wert zurückgeben (da sie sich nie beendet), wenn Du aber vor die letzte 
schließende geschweifte Klammer ein

  return 0;

setzt, verschwindet die Warnung und ihr Beide, Du und Dein Compiler, 
seid zufrieden.

von Niko (Gast)


Lesenswert?

Super hat geklappt, aber warum hatte ich bisher die Fehlermeldung nicht, 
diese müsste ja bei jedem Programm kommen.

von Niko (Gast)


Lesenswert?

mal so ne kleine frage zu dem Code, will jetzt nicht extra ein neuen 
Beitrag öffnen:

und zwar müsste er doch nach den 2. Durchlauf nur noch 7 lesen und 
schreiben (also DATA=DATA1=DATA2=7)

warum schreibt er ab den 2. Durchlauf DATA = DATA1=3 und DATA2 =7?
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <util/twi.h>
5
#include <util/delay.h>
6
#include <stdlib.h>
7
8
#define F_SCL 400000L
9
10
#define TWCR_START  0xA4 //send start condition
11
#define TWCR_STOP   0x94 //send stop condition   
12
#define TWCR_RACK   0xC4 //receive byte and return ack to slave
13
#define TWCR_RNACK  0x84 //receive byte and return nack to slave
14
#define TWCR_SEND   0x84 //pokes the TWINT flag in TWCR and TWEN
15
16
/* SLAVE ADRESSEN*/
17
#define GENERAL_CALL  0x00
18
#define SLAVE      0x7F
19
#define SLAVE1      0x7E
20
21
22
void I2C_INIT()
23
{
24
   TWSR = 0;                         
25
   TWBR = ((F_CPU/F_SCL)-16)/2;  
26
}
27
28
void I2C_ERROR()
29
{
30
  /* Hier Code für ERROR fall*/
31
}
32
33
void MASTER_START (uint8_t add_SLAVE,uint8_t TM_STATUS)
34
{
35
  while(1)
36
  {
37
    TWCR = TWCR_START;            /* Start*/
38
  
39
    while (!(TWCR & (1<<TWINT))  );    /* Warten bis Start ausgeführt*/
40
    if(!(TW_STATUS == TW_START))    /* Start erfolgreich: Ja weiter im Programm / Nein :ERROR*/
41
    {
42
      I2C_ERROR();
43
    }
44
  
45
    TWDR = (add_SLAVE<<1|TM_STATUS);
46
    TWCR = TWCR_SEND;
47
  
48
    while (!(TWCR & (1<<TWINT)));      
49
    switch (TW_STATUS)
50
    {
51
      case TW_SR_GCALL_ACK:
52
        break;
53
      
54
      case TW_MT_SLA_ACK:
55
        break;
56
        
57
      
58
      case TW_MT_SLA_NACK:
59
        TWCR = TWCR_STOP;
60
        while(TWCR & (1<<TWSTO));
61
        continue;
62
      
63
      case TW_MR_SLA_ACK:
64
        break;
65
      
66
      case TW_MR_DATA_NACK:
67
        TWCR = TWCR_STOP;
68
        while(TWCR & (1<<TWSTO));
69
        continue;
70
      
71
      default:
72
        I2C_ERROR();
73
          
74
    }
75
    break;
76
  }
77
}
78
79
80
void MASTER_STOP()
81
{
82
    TWCR = TWCR_STOP;
83
    
84
    while(TWCR & (1<<TWSTO));
85
}
86
87
void MASTER_DATA_WIRTE(uint8_t DATA)
88
{
89
  TWDR = DATA;
90
  TWCR = TWCR_SEND;
91
  
92
  while(!(TWCR & (1<<TWINT)));
93
  switch (TW_STATUS)
94
  {
95
    case TW_MT_DATA_ACK:
96
      break;
97
    
98
    case  TW_MT_DATA_NACK:
99
      MASTER_STOP();
100
      break;
101
    
102
    default:
103
      I2C_ERROR();  
104
  }
105
}
106
107
void MASTER_DATA_READ_ACK(uint8_t DATA)
108
{
109
  TWCR = TWCR_RACK;
110
  while(!(TWCR & (1<<TWINT)));
111
  
112
  DATA = TWDR;
113
  
114
  switch (TW_STATUS)
115
  {
116
    case TW_MR_DATA_ACK:
117
      break;
118
    
119
    default:
120
      I2C_ERROR();
121
  }
122
}
123
124
void MASTER_DATA_READ_NACK(uint8_t DATA)
125
{
126
  TWCR = TWCR_RNACK;
127
  while(!(TWCR & (1<<TWINT)));
128
  
129
  DATA = TWDR;
130
  
131
  switch (TW_STATUS)
132
  {
133
    case TW_MR_DATA_NACK:
134
      MASTER_STOP();
135
      break;
136
    
137
    default:
138
      I2C_ERROR();
139
  }
140
}
141
142
void MT_SLAVE(uint8_t DATA, uint8_t DATA1, uint8_t DATA2)
143
{
144
  
145
  MASTER_START(SLAVE,TW_WRITE);
146
  MASTER_DATA_WIRTE(DATA);
147
  MASTER_DATA_WIRTE(DATA1);
148
  MASTER_DATA_WIRTE(DATA2);
149
  MASTER_STOP();
150
}
151
152
void MR_SLAVE(uint8_t DATA)
153
{
154
  MASTER_START(SLAVE,TW_READ);
155
  MASTER_DATA_READ_ACK(DATA);
156
  MASTER_DATA_READ_ACK(DATA);
157
  MASTER_DATA_READ_ACK(DATA);
158
  MASTER_DATA_READ_ACK(DATA);
159
  MASTER_DATA_READ_NACK(DATA);
160
  
161
}
162
163
int main(void)
164
{
165
    I2C_INIT();      /* I2C Initialisierung Durchführen*/
166
  uint8_t DATA = 1;
167
  uint8_t DATA1 = 3;
168
  uint8_t DATA2 = 7;
169
    while (1) 
170
    {
171
    
172
    MT_SLAVE(DATA,DATA1,DATA2);
173
    MR_SLAVE(DATA1);
174
    DATA = DATA1;
175
    
176
    }
177
  return 0;
178
}

von Brummbär (Gast)


Lesenswert?

Niko schrieb:
> warum schreibt er ab den 2. Durchlauf DATA = DATA1=3 und DATA2 =7?

Weil das im Code so steht.

von Brummbär (Gast)


Lesenswert?

Du veränderst doch nur DATA. Und zwar kopierst Du immer nur DATA1 nach 
DATA.
DATA1 und DATA2 bleiben immer gleich.

von Brummbär (Gast)


Lesenswert?

1
void MASTER_DATA_READ_NACK(uint8_t DATA)
2
{
3
  ...  
4
  DATA = TWDR;

DATA ist hier nur eine Kopie des Aufrufparameters.
Wenn Du diesen Wert innerhalb der Prozedur änderst, wird der Aufrufer 
davon nichts mitbekommen.

Entweder, baust Du eine Funktion, also mit Rückgabe.
Oder Du verwendest Zeiger.

von Niko (Gast)


Lesenswert?

Ah Stimmt vollkommen übersehen.

von Niko (Gast)


Lesenswert?

Gibt es noch ne andere Möglichkeit die Variablen ins Hauptprogramm zu 
übernehmen ohne sie als Global zu deklarieren?
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <util/twi.h>
5
#include <util/delay.h>
6
#include <stdlib.h>
7
8
#define F_SCL 400000L
9
10
#define TWCR_START  0xA4 //send start condition
11
#define TWCR_STOP   0x94 //send stop condition   
12
#define TWCR_RACK   0xC4 //receive byte and return ack to slave
13
#define TWCR_RNACK  0x84 //receive byte and return nack to slave
14
#define TWCR_SEND   0x84 //pokes the TWINT flag in TWCR and TWEN
15
16
/* SLAVE ADRESSEN*/
17
#define GENERAL_CALL  0x00
18
#define SLAVE      0x7F
19
#define SLAVE1      0x7E
20
21
volatile uint8_t DATA = 1;
22
volatile uint8_t DATA1 = 3;
23
volatile uint8_t DATA2 = 7;
24
25
void I2C_INIT()
26
{
27
   TWSR = 0;                         
28
   TWBR = ((F_CPU/F_SCL)-16)/2;  
29
}
30
31
void I2C_ERROR()
32
{
33
  /* Hier Code für ERROR fall*/
34
}
35
36
void MASTER_START (uint8_t add_SLAVE,uint8_t TM_STATUS)
37
{
38
  while(1)
39
  {
40
    TWCR = TWCR_START;            /* Start*/
41
  
42
    while (!(TWCR & (1<<TWINT))  );    /* Warten bis Start ausgeführt*/
43
    if(!(TW_STATUS == TW_START))    /* Start erfolgreich: Ja weiter im Programm / Nein :ERROR*/
44
    {
45
      I2C_ERROR();
46
    }
47
  
48
    TWDR = (add_SLAVE<<1|TM_STATUS);
49
    TWCR = TWCR_SEND;
50
  
51
    while (!(TWCR & (1<<TWINT)));      
52
    switch (TW_STATUS)
53
    {
54
      case TW_SR_GCALL_ACK:
55
        break;
56
      
57
      case TW_MT_SLA_ACK:
58
        break;
59
        
60
      
61
      case TW_MT_SLA_NACK:
62
        TWCR = TWCR_STOP;
63
        while(TWCR & (1<<TWSTO));
64
        continue;
65
      
66
      case TW_MR_SLA_ACK:
67
        break;
68
      
69
      case TW_MR_DATA_NACK:
70
        TWCR = TWCR_STOP;
71
        while(TWCR & (1<<TWSTO));
72
        continue;
73
      
74
      default:
75
        I2C_ERROR();
76
          
77
    }
78
    break;
79
  }
80
}
81
82
83
void MASTER_STOP()
84
{
85
    TWCR = TWCR_STOP;
86
    
87
    while(TWCR & (1<<TWSTO));
88
}
89
90
void MASTER_DATA_WIRTE(uint8_t DATA)
91
{
92
  TWDR = DATA;
93
  TWCR = TWCR_SEND;
94
  
95
  while(!(TWCR & (1<<TWINT)));
96
  switch (TW_STATUS)
97
  {
98
    case TW_MT_DATA_ACK:
99
      break;
100
    
101
    case  TW_MT_DATA_NACK:
102
      MASTER_STOP();
103
      break;
104
    
105
    default:
106
      I2C_ERROR();  
107
  }
108
}
109
110
uint8_t MASTER_DATA_READ_ACK(void)
111
{
112
  TWCR = TWCR_RACK;
113
  while(!(TWCR & (1<<TWINT)));
114
  
115
  switch (TW_STATUS)
116
  {
117
    case TW_MR_DATA_ACK:
118
      break;
119
    
120
    default:
121
      I2C_ERROR();
122
  }
123
  return TWDR;
124
}
125
126
127
uint8_t MASTER_DATA_READ_NACK(void)
128
{
129
  
130
  
131
  TWCR = TWCR_RNACK;
132
  while(!(TWCR & (1<<TWINT)));
133
  
134
  
135
  
136
  switch (TW_STATUS)
137
  {
138
    case TW_MR_DATA_NACK:
139
      MASTER_STOP();
140
      
141
      break;
142
    
143
    default:
144
      I2C_ERROR();
145
  }
146
  
147
  return TWDR;
148
}
149
150
151
void MT_SLAVE(uint8_t DATA, uint8_t DATA1, uint8_t DATA2)
152
{
153
  
154
  MASTER_START(SLAVE,TW_WRITE);
155
  MASTER_DATA_WIRTE(DATA);
156
  MASTER_DATA_WIRTE(DATA1);
157
  MASTER_DATA_WIRTE(DATA2);
158
  MASTER_STOP();
159
}
160
161
void MR_SLAVE()
162
{
163
  MASTER_START(SLAVE,TW_READ);
164
  DATA = MASTER_DATA_READ_ACK();
165
  DATA1 = MASTER_DATA_READ_NACK();
166
  
167
  DATA++;
168
  DATA1++;
169
}
170
171
172
173
int main(void)
174
{
175
    I2C_INIT();      /* I2C Initialisierung Durchführen*/
176
  
177
    while (1) 
178
    {
179
    
180
    MT_SLAVE(DATA,DATA1,DATA2);
181
    MR_SLAVE();
182
    
183
    
184
    
185
    }
186
  return 0;
187
}

also hab jetzt die Variablen aus MR_SLAVE global deklaiert um mit ihnen 
weiter zu arbeiten, geht da noch anders? würd gerne die Variablen Lokal 
lieber nutzen und von MR_SLAVE im Main damit weiter arbeiten.

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. F. schrieb:
> Deine Funktion main ist als Funktion mit einem Rückgabewert definiert
> - es fehlt aber genau das, die Rückgabe eines Wertes.

Wobei ab C99 von der main() Funktion in ihrer speziellen Rolle überhaupt 
nicht verlangt wird, explizit einen Wert zurück zu geben. Auch nicht, 
wenn man sie mit Returnwert definiert. In dem Fall wird 0 zurückgegeben.

Frag mich nicht was das soll, aber so steht es im Standard. Übersetze 
mit -std=c99, dann ist die Warnung ebenfalls weg. Ab c99 steht brav ein 
implizites return(0) drin, bei c89/c90 hingegen nicht.

: Bearbeitet durch User
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.