Verarbeitung/Weitergabe dreier gewandelter Messwerte

Gast #558286
Lesenswert?

Hallo Leute!

ich führe den Betreff mal weiter, damit ihr wisst, worum es geht:

Verarbeitung der Daten eines 3-achs Beschleunigungssensors mittels im 
Atmega 8 integriertem ADC zur Anzeige von g-Werten und Betätigung einer 
Notausschalt-Software bei Grenzwerüberschreitung für einen schnell 
drehenden Versuchsstand zur Ermittlung des Einflusses der Fliehkraft auf 
Piezoaktoren.

So. Das war mal das Grobe.Programmiert wird der Atmega8 auf dem STK 500 
mit c++ (AVR Studio4). Wie schon erwähnt bekomme ich drei analoge Werte 
(in X,Y,Z -Richtung) vom Sensor.
Alles gelötet und angeschlossen an ADC (PC) 1-3.
Das einzige, was im AVR passieren soll ist Wandlung der drei Werte und 
Ausgabe über RS232.
Die Weiterverarbeitung und Notaus wird in Visual C++ realisiert.
Tja und ich komm einfach nicht weiter.... Recherchen bringen nichts.
Vielleicht habt ihr ja mal Lust auf das Programm zu schauen...

Wäre super!

Viele Grüße

D.Brouwer
1
#include <avr/io.h>
2
#include <stdlib.h>
3

4

5
#ifndef F_CPU
6
#define F_CPU 8000000
7
#endif
8

9
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)       //Definition der Frequnz des Baudratenregisters
10

11
#define UART_BAUD_RATE 9600                         //Baudrate einstellen
12

13

14

15

16
        //Definieren der Variablen
17

18
//uint8_t  data  = 0;//
19
uint8_t  h  = 0;  
20
uint8_t  i  = 0;
21
uint16_t z  = 0; 
22
uint16_t  sensor_X = 0;
23
uint16_t  sensor_Y=  0;
24
uint16_t  sensor_Z=  0;
25
char ident_sensor;
26

27

28
        //USART initalisieren nach Handbuch Atmega8, S.138ff
29

30

31

32
#define FOSC 1843200    
33
        // Clock Speed
34

35

36
#define BAUD 9600  //Wie auch in der Systemsteuerung
37
#define MYUBRR FOSC/16/BAUD - 1
38

39

40

41
void main (void) 
42

43
{   
44

45

46

47
void USART_Init ( unsigned int ubrr )
48

49

50
{
51
        // Setzen der Baud-Rate
52

53

54
UBRRH = (unsigned char) (ubrr>>8);
55
UBRRL = (unsigned char)  ubrr;
56

57
                                    
58
        //"Anschalten" von Reciever und Transmitter
59

60
UCSRB = (1<<RXEN)|(1<<TXEN);
61

62
        //"FRAME_FOMAT" : 8data, 2 stop - bits
63

64
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
65

66
}
67

68

69
//*ADC ~Wandlung~*
70
//Handbuch: "In single conversion mode, always select the channel, before starting the conversion  !"
71
//ADMUX-Register "Analog Channel Selection Bits": The Value of these bits selects which analog inputs are connected to the ADC..." Handbuch S. 206
72
//Sensoren an:  1. (Sensor_X) MUX: 0001   ->  ADC1  ->  (PC1)  
73
//        2. (Sensor_Y) MUX: 0010    ->   ADC2  ->  (PC2)      
74
//        3. (Sensor_Z) MUX: 0011    ->  ADC3  ->  (PC3)
75

76

77
//Pinbelegung der AD -Eingänge an PC1 ... PC3
78

79
//Setzen von allen PCx auf EINGANG
80

81
DDRC=0x00;
82

83

84

85
//ADC einschalten und Dummyreadout machen:   
86

87
uint16_t ReadChannel (uint8_t mux)
88
{
89
  uint8_t i;
90
  ADCSRA = (1<<ADEN) | ( 1<<ADPS1) | (1<<ADPS0);
91
  ADMUX=mux;                                      //gilt das mux nur für den Dummyreadout?
92

93
//Als Referenzspannung die interne Referenzspannung nutzen
94
  ADMUX |=(1<<REFS1) | (1<<REFS0);   
95
//Nun Dummyreadout zum "Warmlaufen":
96

97
ADCSRA |= (1<<ADSC);
98
//Warten, bis die Konvertierung fertig ist...
99
while (ADCSRA & (1<<ADSC) )
100
{
101
  ;;
102

103
}
104

105

106

107
//Die eigentliche Messung beginnt:
108
//Mittelwert bilden und die Sensoren " nacheinander " abarbeiten....
109

110

111

112
            /// ENLOSSCHEIFE:
113

114
              while(1)
115
        
116
{
117

118

119

120

121
//////////////////////////////////////////////////Sensor_X //////////////////////////////////////////////////////////////
122

123

124
///Kanal wählen:
125

126
ADMUX |= (1<<MUX0);
127

128
for (i=0;i<4;i++)
129
  {
130
    ADCSRA |= (1<<ADSC);
131
    while (ADCSRA & (1<<ADSC)) 
132
    { 
133
    ;
134
    }
135
  sensor_X=sensor_X+ADCW;
136

137
  }
138

139
//ADC deaktivieren
140

141
//ADCSRA &= ~(1<<ADEN);
142

143
sensor_X = sensor_X / 4;
144

145
return sensor_X;
146

147
//Daten senden:
148

149
int uart_putc_X (unsigned char sensor_X)                ///unsigned char
150
{
151

152
  while (!(UCSRA & (1<<UDRE)))
153
                                    ///da fehlt noch etwas!
154
  UDR = sensor_X;  
155
  
156
  return 0;
157

158
void uart_puts (char *s)
159

160
{
161
  while (*s)
162
  {
163
    uart_putc_X(*s);
164
    s++;
165

166
  }
167
}
168

169

170
  ///Das Empfängerprogramm muss erkennen, welcher der (X,Y,Z) - Messdaten er im Moment empfängt; also "Erkennungszeichen" 
171
  ///gleich hinterhersenden ('x' bzw. 'y' oder 'z')
172

173
  ident_sensor =  'x' ;
174

175
  ///Senden der Kontrollvariablen:
176

177
  int uart_putc (unsigned char ident_sensor)
178

179
{
180

181
  while (!(UCSRA & (1<<UDRE)));
182

183
  UDR = ident_sensor;
184
  ///Blinken einer entsprechenen LED zum Programmtest:
185
  ///Setzten von PBx als Ausgang (Bei X - Signal sollen Leuchten: LED 0 und 1) :
186
  ///Aktivieren der Ports
187
  DDRB = (1<<DDB0) | (1<<DDB1) ;
188
  PORTD = (1<<PD0) | (1<<PD1)  ;
189

190
  ///LEDs wieder aus:
191

192
  PORTD = 0x00;
193
  
194
  return 0;
195

196
}
197

198
///gesetzte MUX wieder löschen
199

200

201
ADMUX = 0x00;
202

203
//////////////////////////////////////////////////Sensor Y //////////////////////////////////////////////////////////////
204

205

206
ADMUX |= (1<<MUX1) | (1<<MUX0);
207

208
for (i=0;i<4;i++)
209
  {
210
    ADCSRA |= (1<<ADSC);
211
    while (ADCSRA & (1<<ADSC)) 
212
    { 
213
    ;
214
    }
215
  sensor_Y=sensor_Y+ADCW;
216

217
  }
218

219
//ADC deaktivieren
220

221
//ADCSRA &= ~(1<<ADEN);
222

223
sensor_Y = sensor_Y / 4;
224

225
return sensor_Y;
226

227
//Daten senden:
228

229
int uart_putc_Y (unsigned char sensor_Y)                  ///unsigned char
230
{
231

232
  while (!(UCSRA & (1<<UDRE)))
233
                                    ///da fehlt noch etwas!
234
  UDR = sensor_Y;  
235
  
236
  return 0;
237

238
void uart_puts (char *s)
239

240
{
241
  while (*s)
242
  {
243
    uart_putc(*s);
244
    s++;
245

246
  }
247
}
248

249

250
  ///Das Empfängerprogramm muss erkennen, welcher der (X,Y,Z) - Messdaten er im Moment empfängt; also "Erkennungszeichen" 
251
  ///gleich hinterhersenden ('x' bzw. 'y' oder 'z')
252

253
  ident_sensor =  'y' ;
254

255
  ///Senden der Kontrollvariablen:
256

257
  int uart_putc (unsigned char ident_sensor)
258

259
{
260

261
  while (!(UCSRA & (1<<UDRE)));
262

263
  UDR = ident_sensor;
264
  ///Blinken einer entsprechenen LED zum Programmtest:
265
  ///Setzten von PBx als Ausgang (Bei X - Signal sollen Leuchten: LED 2 und 3) :
266
  ///Aktivieren der Ports
267
  DDRB = (2<<DDB0) | (3<<DDB1) ;
268
  PORTD = (2<<PD0) | (3<<PD1)  ;
269

270
  ///LEDs wieder aus:
271

272
  PORTD = 0x00;
273
  
274
  return 0;
275

276
}
277

278
///gesetzte MUX wieder löschen
279

280

281
ADMUX = 0x00;
282

283

284

285
//////////////////////////////////////////////////Sensor Z //////////////////////////////////////////////////////////////
286

287

288
ADMUX |= (1<<MUX1) | (1<<MUX0);
289

290

291
for (i=0;i<4;i++)
292
  {
293
    ADCSRA |= (1<<ADSC);
294
    while (ADCSRA & (1<<ADSC)) 
295
    { 
296
    ;
297
    }
298
  sensor_Z=sensor_Z+ADCW;
299

300
  }
301

302
//ADC deaktivieren
303

304
//ADCSRA &= ~(1<<ADEN);
305

306
sensor_Z = sensor_Z / 4;
307

308
return sensor_Z;
309

310
//Daten senden:
311

312
int uart_putc_Z (unsigned char sensor_Z)                ///unsigned char
313
{
314

315
  while (!(UCSRA & (1<<UDRE)))
316
                                    ///da fehlt noch etwas!
317
  UDR = sensor_Z;  
318
  
319
  return 0;
320

321
void uart_puts (char *s)
322

323
{
324
  while (*s)
325
  {
326
    uart_putc(*s);
327
    s++;
328

329
  }
330
}
331

332

333
  ///Das Empfängerprogramm muss erkennen, welcher der (X,Y,Z) - Messdaten er im Moment empfängt; also "Erkennungszeichen" 
334
  ///gleich hinterhersenden ('x' bzw. 'y' oder 'z')
335

336
  ident_sensor =  'z' ;
337

338
  ///Senden der Kontrollvariablen:
339

340
  int uart_putc (unsigned char ident_sensor)
341

342
{
343

344
  while (!(UCSRA & (1<<UDRE)));
345

346
  UDR = ident_sensor;
347
  ///Blinken einer entsprechenen LED zum Programmtest:
348
  ///Setzten von PBx als Ausgang (Bei X - Signal sollen Leuchten: LED 4 und 5) :
349
  ///Aktivieren der Ports
350
  DDRB = (1<<DDB0) | (1<<DDB1) ;
351
  PORTD = (1<<PD0) | (1<<PD1)  ;
352

353
  ///LEDs wieder aus:
354

355
  PORTD = 0x00;
356
  
357
  return 0;
358

359
}
360

361
///gesetzte MUX wieder löschen
362

363

364
ADMUX = 0x00;
365

366
}
367

368

369
for (i=0;i<4;i++)
370
  {
371
    ADCSRA |= (1<<ADSC);
372
    while (ADCSRA & (1<<ADSC)) 
373
    { 
374
    ;
375
    }
376
  sensor_Z=sensor_Z+ADCW;
377

378
  }
379
  //ADC deaktivieren
380

381
  //ADCSRA &= ~(1<<ADEN);
382

383
  sensor_Z = sensor_Z / 4;
384

385
  return sensor_Z;
386

387
  //Daten senden
388

389
int uart_putc3 (unsigned char sensor_Z)                      //geht das??????//
390
{    
391

392
  while (!(UCSRA & (1<<UDRE)))
393
  UDR = sensor_Z;
394

395
  ///Das Empfängerprogramm muss erkennen, welcher der (X,Y,Z) - Messdaten er im Moment empfängt; also "Erkennungszeichen" 
396
  ///gleich hinterhersenden ('x' bzw. 'y' oder 'z')
397

398
  ident_sensor =  'z' ;
399
                  
400
  UDR = ident_sensor;                          
401

402
  ///Blinken einer entsprechenen LED zum Programmtest:
403
  ///Setzten von PBx als Ausgang (Bei Z - Signal sollen Leuchten: LED 4 und 5) :
404
  ///Aktivieren der Ports
405

406

407
  DDRB = (1<<DDB4) | (1<<DDB5) ;
408
  PORTD = (1<<PD4) | (1<<PD5)  ;
409

410
  ///LEDs wieder aus:
411

412
  PORTD = 0x00;
413

414
  return 0;
415
  
416
}
417

418

419

420
}return 0;
421
}






Gast #558303
Lesenswert?

Naja - ich empange keine daten im Empfangsprogramm - es kommt nichts 
über (leider, leider...).

Kompilerfehler habe ich eigentlich keine - seid heute wieder einen aber 
das sollte nicht SOOO das Problem sein.
#558309
Lesenswert?

> Naja - ich empange keine daten im Empfangsprogramm

Dann solltest du vielleicht mal den ganzen ADC Kram
über Bord werfen und dich nur mal mit der UART Kommunikation
beschäftigen.
Irgendwie hab ich das Gefühl, der Code wurde in einem
Rutsch herunterprogrammiert ohne dass Zwischenziele
angesteuert und ausgiebig getestet wurden. Genau so sieht
das nämlich aus.
Gast #558312
Lesenswert?

Wo vermutest Du das Problem?
Was hat bisher funktioniert?

Was machst Du, um Fehler zu einzugrenzen?

Ich würde schrittweise vorgehen:

- Zeichen ausgeben per USART, nur das, sonst nix.

wenn das klappt:

- einen Sensor abfragen, Wert schicken.

wenn das klappt:

- Schleife schreiben, die den 2ten Schritt für die drei Sensoren 
ausführt.

Fertig. :-)
Gast #558313
Lesenswert?

Hmm.. Ja. Das stimmt mit Sicherheit. Wenn ich gut programmieren könnte 
würde ich ja dieses Programm hier nicht reinstellen.
Die Tatsache kenne ich übrigens selbst.
Ich habe genau sechs mal 1,5 Studen C-Kurs gemacht und arbeite mich halt 
im Moment ernsthaft (seid einiger Zeit und aus beruflichen Gründen ein).

Viele Grüße
#558317
Lesenswert?

Was mir auffällt:
gcc, und damit WinAvr, erlaubt zwar als Erweiterung
lokale Funktionen. Ich denke aber, dass du dich damit
selbst ausgetrickst hast.
Also: Halte dich an Standard-C

Nachtrag: Ich hab grade versucht, das mal etwas zu
bereinigen um zu sehen ob in main() noch irgendwas Sinnvolles
übrigbleibt. Aber durch die nicht vorhandene Formatierung
ist das gar nicht so einfach.
Gast #558322
Lesenswert?

Lieber Karl-Heinz,

schade, dass du mir einfach so irgendwelche Vorwürfe machst.
Ich habe mich in der Tat ernsthaft damit auseinander gesetzt und den 
Code nich einfach so "runtergeschrieben" - dafür fehlt mir übrigens auch 
eindeutig das Wissen.

Also einzelne Zeichen über RS 232 klappt - danach habe ich dann 
weitergetüftelt. Seid ich die zwei weiteren Werte mit reingenommen habe 
klappts halt leider nicht mehr.
Ist das Schema denn prinzipiell richtig? Auch mit den Kontrollvariablen? 
Die Funktion "int uart_putc_Y (unsigned char sensor_Y) " z.B macht die 
was es soll? (es wurde ja das "_Y" hinzugefügt....)


Nochmal Viele Grüße ! :)
Gast #558327
Lesenswert?

Hallo Karl-Heinz!


Vielen Dank fürs Anschauen!
Also ohne diese "Makros" bin ich glaube ich völlig aufgeschmissen, 
mangels C - Kentnissen....

Ich will es dir gerne etwas formatieren! Gibt es denn da spezielle 
Regeln?
(Sowas wie Richtlinien)
#558331
Lesenswert?

Das hat alles keinen Sinn.
Ich sitzt jetzt schon seit Minuten an dem Code und versuche
den mal vernünftig umzuformatieren.

Du machst jetzt mal folgendes:
Du formatierst als erstes mal den Code.

Folgende Regeln:

* Bei einem { rückt die nächste Zeile um 2 Zeichen nach
  rechts ein
* Bei einem } rückt die nächste Zeile um 2 Zeichen nach
  links aus
* Wenn eine Funktion nicht am linken Rand (Also Einrückungstiefe: 0)
  anfängt, dann nimmst du den Code Block der Funktion und
  schiebst ihn vor die main() und entwirrst dadurch die lokale
  Funktionshierarchie.
* Mehrfach hintereinander gesetzte Leerzeilen reduzierst du
  auf 1 Leerzeile.

Das kann zb so aussehen:
1
#include <avr/io.h>
2
#include <stdlib.h>
3

4
#ifndef F_CPU
5
#define F_CPU 8000000
6
#endif
7

8
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)       //Definition der Frequnz des Baudratenregisters
9
#define UART_BAUD_RATE 9600                         //Baudrate einstellen
10

11
        //Definieren der Variablen
12

13
//uint8_t  data  = 0;//
14
uint8_t  h  = 0;  
15
uint8_t  i  = 0;
16
uint16_t z  = 0; 
17
uint16_t  sensor_X = 0;
18
uint16_t  sensor_Y=  0;
19
uint16_t  sensor_Z=  0;
20
char ident_sensor;
21

22
//USART initalisieren nach Handbuch Atmega8, S.138ff
23

24
#define FOSC 1843200              // Clock Speed
25
#define BAUD 9600                 // Wie auch in der Systemsteuerung
26
#define MYUBRR FOSC/16/BAUD - 1
27

28
void USART_Init ( unsigned int ubrr )
29
{
30
  // Setzen der Baud-Rate
31
  UBRRH = (unsigned char) (ubrr>>8);
32
  UBRRL = (unsigned char)  ubrr;
33

34
  //"Anschalten" von Reciever und Transmitter
35
  UCSRB = (1<<RXEN)|(1<<TXEN);
36
  //"FRAME_FOMAT" : 8data, 2 stop - bits
37
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
38
}
39

40
void uart_puts (char *s)
41
{
42
  while (*s)
43
  {
44
    uart_putc_X(*s);
45
    s++;
46
  }
47
}
48

49
int uart_putc (unsigned char ident_sensor)
50
{
51
  while (!(UCSRA & (1<<UDRE)));
52

53
  UDR = ident_sensor;
54
  ///Blinken einer entsprechenen LED zum Programmtest:
55
  ///Setzten von PBx als Ausgang (Bei X - Signal sollen Leuchten: LED 0 und 1) :
56
  ///Aktivieren der Ports
57
  DDRB = (1<<DDB0) | (1<<DDB1) ;
58
  PORTD = (1<<PD0) | (1<<PD1)  ;
59

60
  ///LEDs wieder aus:
61
  PORTD = 0x00;
62
  
63
  return 0;
64
}
65

66
void main (void) 
67
{   
68
  //*ADC ~Wandlung~*
69
  //Handbuch: "In single conversion mode, always select the channel, before starting the conversion  !"
70
  //ADMUX-Register "Analog Channel Selection Bits": The Value of these bits selects which analog inputs are connected to the ADC..." Handbuch S. 206
71
  //Sensoren an:  1. (Sensor_X) MUX: 0001   ->  ADC1  ->  (PC1)  
72
  //        2. (Sensor_Y) MUX: 0010    ->   ADC2  ->  (PC2)      
73
  //        3. (Sensor_Z) MUX: 0011    ->  ADC3  ->  (PC3)
74

75

76
  //Pinbelegung der AD -Eingänge an PC1 ... PC3
77

78
  //Setzen von allen PCx auf EINGANG
79

80
  DDRC=0x00;
81

82
  ...

Der spannende Teil kommt unmittelbar dahinter.
Da hast du derartig viele Funktionen ineinandergeschachtelt,
dass einem beim Versuch das zu entwirren schwindlig wird.
Gast #558334
Lesenswert?

Ich habe mir den ersten teil angesehen..

//gilt das mux nur für den Dummyreadout?

Du solltest die Funktion ReadChannel so belassen wie sie ist, und sie 
von deinem eigentlich Programm aus aufrufen.. Da steht ja eine Menge 
'Kram' drin.

Das 'mux' wird ja der funktion übergeben, und steht für den ADC-Kanal.
Danach würde dann der AD 'mux' ausgelesen, und das Ergebnis als 
Rückgabewert der Funktion zurückkommen, aber da wuselst du ja mit dem 
Rest drin rum...
Deswegen hat die Funktion gar keinen richtigen Sinn mehr.
Gast #558346
Lesenswert?

Irgentwie kommt es mir vor als ob du nur Funktionen deklarierst, Sie 
aber garnicht aufrufst ...
Z.b. die Funktion zum Senden via RS232 kannst du auf eine einzige 
beschrenken.. Du brauchst doch nicht für jede Variable die du bekommst 
ne eigene Funktion( die nicht aufgerufen wird ) schreiben.


In dieser Funktion wird dann der String Zeichen für Zeichen an eine 
Funktion übergeben die das Zeichen sendet.
Die ADC Wandlungsfunktion wird auch nicht aufgerufen. Du hast jede Menge 
funktionen, aber keine wird auf gerufen.
Dein Programm könnte so aussehen:
int main(void){

    erg_x = ReadChannel(0);
    uart_puts(erg_x);
    uart_putc("x");


    erg_y = ReadChannel(1);
    uart_puts(erg_y);
.
.
.
Dann kannst du später immernoch die Blöcke für die Kanäle in Funktionen 
verpacken.
Am besten du führst dir das AVR-GCC-Tutorial mal zu Gemüte.
Viel Erfolg.
Gruß,


Gast #558378
Lesenswert?

So. Formatiert hab ich es. Hmm... was ihr mir da sagt stimmt mich nicht 
gerade fröhlich.. Ich bin euch jedoch super dankbar für die Hilfe!

Werde die Ratschläge beherzigen und falls ihr möchtet, die Fortschritte 
posten. Bin im Moment deswegen sehr gestresst, da ich das ganze neben 
der eigentlichen Arbeit fristgerecht fertig haben muss...

Zu Copy-Paste - ja einige Sachen schon.... ist sowas verpönt?
Also Karl-Heinz: Danke nochmal! Etwas schroff aber recht konstruktiv! :)

Der Code

1
#include <avr/io.h>
2
#include <stdlib.h>
3

4

5
#ifndef F_CPU
6
#define F_CPU 8000000
7
#endif
8

9
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)       //Definition der Frequnz des Baudratenregisters
10

11
#define UART_BAUD_RATE 9600                         //Baudrate einstellen
12

13

14

15

16
//Definieren der Variablen
17

18
//uint8_t  data  = 0;//
19
uint8_t  h  = 0;  
20
uint8_t  i  = 0;
21
uint16_t z  = 0; 
22
uint16_t  sensor_X = 0;
23
uint16_t  sensor_Y=  0;
24
uint16_t  sensor_Z=  0;
25
char ident_sensor;
26

27

28
//USART initalisieren nach Handbuch Atmega8, S.138ff
29
#define FOSC 1843200    
30
// Clock Speed
31
//Wie auch in der Systemsteuerung
32
#define BAUD 9600  
33
#define MYUBRR FOSC/16/BAUD - 1
34

35

36
void USART_Init ( unsigned int ubrr )
37

38
  {
39
  // Setzen der Baud-Rate
40
  UBRRH = (unsigned char) (ubrr>>8);
41
  UBRRL = (unsigned char)  ubrr;
42
                                    
43
  //"Anschalten" von Reciever und Transmitter
44
  UCSRB = (1<<RXEN)|(1<<TXEN);
45

46
  //"FRAME_FOMAT" : 8data, 2 stop - bits
47
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
48

49
  }
50

51
void main (void) 
52
{   
53

54
    //*ADC ~Wandlung~*
55
    //Handbuch: "In single conversion mode, always select the channel, before starting the conversion  !"
56
    //ADMUX-Register "Analog Channel Selection Bits": The Value of these bits selects which analog inputs are connected to the ADC..." Handbuch S. 206
57
    //Sensoren an:  1.(Sensor_X) MUX: 0001  ->  ADC1  ->  (PC1)  
58
    //        2.(Sensor_Y) MUX: 0010   ->  ADC2  ->  (PC2)      
59
    //        3.(Sensor_Z) MUX: 0011   ->  ADC3  ->  (PC3)
60

61

62
    //Pinbelegung der AD -Eingänge an PC1 ... PC3
63
    //Setzen von allen PCx auf EINGANG
64

65
    DDRC=0x00;
66

67
    //ADC einschalten und Dummyreadout machen:  
68
 
69
    uint16_t ReadChannel (uint8_t mux)
70
    {
71
      uint8_t i;
72
      ADCSRA = (1<<ADEN) | ( 1<<ADPS1) | (1<<ADPS0);
73
      ADMUX=mux;                                      //gilt das mux nur für den Dummyreadout?
74

75
      //Als Referenzspannung die interne Referenzspannung nutzen
76
      ADMUX |=(1<<REFS1) | (1<<REFS0);   
77
      //Nun Dummyreadout zum "Warmlaufen":
78

79
      ADCSRA |= (1<<ADSC);
80
      //Warten, bis die Konvertierung fertig ist...
81

82

83
        while (ADCSRA & (1<<ADSC) )
84
          {
85
            ;;
86
    
87
          }
88

89
    //Die eigentliche Messung beginnt:
90
    //Mittelwert bilden und die Sensoren " nacheinander " abarbeiten....
91
    /// ENLOSSCHEIFE:
92

93
  while(1)
94
        
95
  {
96

97

98

99

100
//////////////////////////////////////////////////Sensor_X //////////////////////////////////////////////////////////////
101

102

103
      ///Kanal wählen:
104
    ADMUX |= (1<<MUX0);
105

106
      for (i=0;i<4;i++)
107
        {
108
          ADCSRA |= (1<<ADSC);
109
          while (ADCSRA & (1<<ADSC)) 
110
              { 
111
              ;
112
              }
113
          sensor_X=sensor_X+ADCW;
114
    
115
        }
116

117
      //ADC deaktivieren
118
      //ADCSRA &= ~(1<<ADEN);
119

120
      sensor_X = sensor_X / 4;
121

122
      return sensor_X;
123
            
124
      //Daten senden:
125

126
      int uart_putc_X (unsigned char sensor_X)                ///unsigned char
127
        {
128

129
          while (!(UCSRA & (1<<UDRE)))
130
                                    ///da fehlt noch etwas!
131
          UDR = sensor_X;  
132
  
133
          return 0;
134

135
      void uart_puts (char *s)
136

137
        {
138
          while (*s)
139
        {
140
        uart_putc_X(*s);
141
        s++;
142

143
        }
144
    
145
    }
146

147
    ///Das Empfängerprogramm muss erkennen, welcher der (X,Y,Z) - Messdaten er im Moment empfängt; also "Erkennungszeichen" 
148
    ///gleich hinterhersenden ('x' bzw. 'y' oder 'z')
149

150
    ident_sensor =  'x' ;
151

152
    ///Senden der Kontrollvariablen:
153

154
    int uart_putc (unsigned char ident_sensor)
155

156
      {    
157

158
          while (!(UCSRA & (1<<UDRE)));
159

160
          UDR = ident_sensor;
161
          ///Blinken einer entsprechenen LED zum Programmtest:
162
          ///Setzten von PBx als Ausgang (Bei X - Signal sollen Leuchten: LED 0 und 1) :
163
          ///Aktivieren der Ports
164
          DDRB = (1<<DDB0) | (1<<DDB1) ;
165
          PORTD = (1<<PD0) | (1<<PD1)  ;
166

167
          ///LEDs wieder aus:
168
  
169
          PORTD = 0x00;
170
  
171
          return 0;
172

173
        }
174

175
    ///gesetzte MUX wieder löschen
176
    ADMUX = 0x00;
177

178
//////////////////////////////////////////////////Sensor Y //////////////////////////////////////////////////////////////
179

180

181
    ADMUX |= (1<<MUX1) | (1<<MUX0);
182

183
    for (i=0;i<4;i++)
184
      {
185
        ADCSRA |= (1<<ADSC);
186
        while (ADCSRA & (1<<ADSC)) 
187
        { 
188
        ;
189
        }
190
      sensor_Y=sensor_Y+ADCW;
191

192
      }
193

194
    //ADC deaktivieren
195
    //ADCSRA &= ~(1<<ADEN);
196

197
    sensor_Y = sensor_Y / 4;
198

199
    return sensor_Y;
200

201
    //Daten senden:
202
    int uart_putc_Y (unsigned char sensor_Y)                  ///unsigned char
203
    {
204

205
      while (!(UCSRA & (1<<UDRE)))
206
                                    ///da fehlt noch etwas!
207
      UDR = sensor_Y;  
208
  
209
      return 0;
210

211
    void uart_puts (char *s)
212

213
    {
214
      while (*s)
215
      {
216
        uart_putc(*s);
217
        s++;
218

219
      }
220
    }
221

222

223
  ///Das Empfängerprogramm muss erkennen, welcher der (X,Y,Z) - Messdaten er im Moment empfängt; also "Erkennungszeichen" 
224
  ///gleich hinterhersenden ('x' bzw. 'y' oder 'z')
225

226
  ident_sensor =  'y' ;
227

228
  ///Senden der Kontrollvariablen:
229
  int uart_putc (unsigned char ident_sensor)
230

231
  {
232

233
    while (!(UCSRA & (1<<UDRE)));
234
      {
235
        UDR = ident_sensor;
236
        ///Blinken einer entsprechenen LED zum Programmtest:
237
        ///Setzten von PBx als Ausgang (Bei X - Signal sollen Leuchten: LED 2 und 3) :
238
        ///Aktivieren der Ports
239
        DDRB = (2<<DDB0) | (3<<DDB1) ;
240
        PORTD = (2<<PD0) | (3<<PD1)  ;
241
  
242
        ///LEDs wieder aus:
243
  
244
        PORTD = 0x00;
245
  
246
      return 0;
247
      }      
248

249
  }
250

251
    ///gesetzte MUX wieder löschen
252
    ADMUX = 0x00;
253

254

255

256
//////////////////////////////////////////////////Sensor Z //////////////////////////////////////////////////////////////
257

258

259
    ADMUX |= (1<<MUX1) | (1<<MUX0);
260

261

262
    for (i=0;i<4;i++)
263
      {
264
        ADCSRA |= (1<<ADSC);
265
        while (ADCSRA & (1<<ADSC)) 
266
        { 
267
        ;
268
        }
269
      sensor_Z=sensor_Z+ADCW;
270

271
      }
272

273
    //ADC deaktivieren
274
    //ADCSRA &= ~(1<<ADEN);
275

276
    sensor_Z = sensor_Z / 4;
277

278
    return sensor_Z;
279

280
    //Daten senden:
281
    int uart_putc_Z (unsigned char sensor_Z)                
282
    {
283

284
      while (!(UCSRA & (1<<UDRE)))
285
                                    
286
      UDR = sensor_Z;  
287
  
288
      return 0;
289

290
    }
291

292

293
    void uart_puts (char *s)
294

295
    {
296
      while (*s)
297
      {
298
        uart_putc(*s);
299
        s++;
300
      }
301

302
    }
303

304

305
    ///Das Empfängerprogramm muss erkennen, welcher der (X,Y,Z) - Messdaten er im Moment empfängt; also "Erkennungszeichen" 
306
    ///gleich hinterhersenden ('x' bzw. 'y' oder 'z')
307

308
    ident_sensor =  'z' ;
309

310
    ///Senden der Kontrollvariablen:
311

312
    int uart_putc (unsigned char ident_sensor)
313

314
      {
315
  
316
        while (!(UCSRA & (1<<UDRE)));
317

318
        UDR = ident_sensor;
319
        ///Blinken einer entsprechenen LED zum Programmtest:
320
        ///Setzten von PBx als Ausgang (Bei X - Signal sollen Leuchten: LED 4 und 5) :
321
        ///Aktivieren der Ports
322
        DDRB = (1<<DDB0) | (1<<DDB1) ;
323
        PORTD = (1<<PD0) | (1<<PD1)  ;
324

325
        ///LEDs wieder aus:
326
        PORTD = 0x00;
327
  
328
        return 0;
329
      
330
      }
331

332

333
    ///gesetzte MUX wieder löschen
334
    ADMUX = 0x00;
335

336
      }
337

338

339
    for (i=0;i<4;i++)
340
      {
341
        ADCSRA |= (1<<ADSC);
342
        while (ADCSRA & (1<<ADSC)) 
343
          { 
344
            ;
345
          }
346
      sensor_Z=sensor_Z+ADCW;
347

348
      }
349

350
      //ADC deaktivieren
351
      //ADCSRA &= ~(1<<ADEN);
352

353
      sensor_Z = sensor_Z / 4;
354

355
      return sensor_Z;
356

357
      //Daten senden
358

359
    int uart_putc3 (unsigned char sensor_Z)                      //geht das??????//
360
    {    
361

362
      while (!(UCSRA & (1<<UDRE)))
363
      UDR = sensor_Z;
364

365
      ///Das Empfängerprogramm muss erkennen, welcher der (X,Y,Z) - Messdaten er im Moment empfängt; also "Erkennungszeichen" 
366
      ///gleich hinterhersenden ('x' bzw. 'y' oder 'z')
367
      ident_sensor =  'z' ;
368
                  
369
      UDR = ident_sensor;                          
370

371
      ///Blinken einer entsprechenen LED zum Programmtest:
372
      ///Setzten von PBx als Ausgang (Bei Z - Signal sollen Leuchten: LED 4 und 5) :
373
      ///Aktivieren der Ports
374
      DDRB = (1<<DDB4) | (1<<DDB5) ;
375
      PORTD = (1<<PD4) | (1<<PD5)  ;
376

377
      ///LEDs wieder aus:
378

379
      PORTD = 0x00;
380

381
      return 0;
382
  
383
}
384

385
return 0;
386

387
}
#558384
Lesenswert?

D.Brouwer wrote:
> So. Formatiert hab ich es.

Schau dir das bitte noch mal durch.

>     uint16_t ReadChannel (uint8_t mux)
>     {

ist die Vereinbarung einer Funktion. Und laut Regeln fangen
Funktionen immer am linken Rand an. Daher können vor dem
uint16_t keine 4 Leerzeichen sein.

> Also Karl-Heinz: Danke nochmal! Etwas schroff aber recht konstruktiv! :)

Ich hab das einfach schon zu oft erlebt.
Ein Einrückschema ist eben kein Luxus und hat nicht nur den Zweck,
dass es optisch schöner aussieht. Ein Einrückschema ist ein vitales
Instrument um Fehler zu finden!
#558389
Lesenswert?

Karl heinz Buchegger wrote:
> D.Brouwer wrote:
>> So. Formatiert hab ich es.
>
> Schau dir das bitte noch mal durch.
>
>>     uint16_t ReadChannel (uint8_t mux)
>>     {
>
> ist die Vereinbarung einer Funktion. Und laut Regeln fangen
> Funktionen immer am linken Rand an. Daher können vor dem
> uint16_t keine 4 Leerzeichen sein.

Das heist jetzt aber nicht, dass du einfach die Zeile an
den linken Rand rutscht und sonst alles andere beim alten lässt.
Der springende Punkt ist:
Ohne gröbere Umgestaltungsmassnahmen, und das schliesst Code
woanders hinschieben (nach vorne, vors main()) mit ein,
wird das nichts.

Tut mir leid, aber da musst du durch.
Einen Sauhaufen in einer Lagerhalle kann man nicht dadurch
aufräumen, indem man die Seife am Waschbecken von der einen
Seite auf die andere legt. Da muss man schon mit dem Gabelstapler
reingehen und umräumen. Oder aber man achtet von vorne herein
darauf, dass man eine gewisse Ordnung einhält.
Gast #558400
Lesenswert?

Jo. Ich habe es verstanden. Und meinetwegen entschuldige ich mich gerne 
nochmal. Nun weiß ich schon als schwitzender Anfänger über die 
Einrückregeln bescheid und werde sie demnächst beachten - es ist in der 
Tat übersichtlicher ich gebe es gerne zu.
Ich poste hier mal eine frühere Version des "Programms".
Mal sehen was ihr dazu meint:
1
#include <avr/io.h> 
2
#include <stdlib.h>
3

4
#ifndef F_CPU
5
#define F_CPU 8000000
6
#endif
7

8
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)  //Definition der Frequnz des Baudratenregisters
9

10
#define UART_BAUD_RATE 9600                    //Baudrate einstellen
11

12
uint8_t h = 0;
13
uint8_t i = 0;
14
uint16_t z = 0; 
15

16
void init_io(void) 
17
{ 
18
     UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
19
  UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );    
20

21
  //DDRC = 0xFF;      //PortD wird als Ausgang definiert 
22
     //DDRB = 0x00;      /* Pin PA0 als Eingang */
23
     //PORTA |= (1<<PA0);   //Pullup-Wiederstand von PortA Pin0 wird aktiviert 
24
} 
25

26

27
uint16_t readADC(uint8_t channel) 
28
{
29
  uint16_t result = 0;  
30
  // Den ADC aktivieren und Teilungsfaktor auf 64 stellen
31
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
32
  // Kanal des Multiplexers waehlen
33
  ADMUX = channel;
34
  // Interne Referenzspannung verwenden (also 2,56 V)
35
  ADMUX |= (1<<REFS1) | (1<<REFS0);
36
    // Den ADC initialisieren und einen sog. Dummyreadout machen
37
  ADCSRA |= (1<<ADSC);
38

39

40
  while(ADCSRA & (1<<ADSC));
41
  //Jetzt 3x die analoge Spannung and Kanal channel auslesen
42
  //und dann Durchschnittswert ausrechnen.
43
  for(i=0; i<5; i++) 
44
  {
45
    // Eine Wandlung
46
    ADCSRA |= (1<<ADSC);
47
    // Auf Ergebnis warten...
48
    while(ADCSRA & (1<<ADSC));
49
    
50
    result += ADCW;
51
  }
52
  //ADC wieder deaktivieren
53
  //ADCSRA &= ~(1<<ADEN);
54
  
55
  result /= 5;
56
  
57
  return result;
58
}
59

60

61

62
int uart_putc(unsigned char c)
63
{
64
  while (!(UCSRA & (1 << UDRE)))
65
  {
66
  }
67
  UDR = c;
68
  return 0;
69
}
70

71
void uart_puts(char *s)
72
{
73
  while (*s)
74
  {
75
    uart_putc(*s);
76
    s++;
77
  }
78
  uart_putc(*s);
79
}
80

81

82

83
uint16_t sende(uint16_t l) 
84
{
85
  uint16_t result = 0;
86
  
87
  char phrase[7];
88

89
  itoa(l, phrase, 10);
90

91
  uart_puts(phrase);
92

93
  return result;
94
}
95

96

97

98

99

100
  
101
void main(void) 
102
{ 
103
    init_io();                           //Ruft die Funktion init_io() auf 
104
     init_adc();                       //init des adc 
105

106

107
    while(1) 
108
   {                    
109
         
110
        h = readADC(0);                //lese analogen wert aus channel 0 in c 
111
        UCSRB |= (1<<TXEN);        //aktiviert den UART (Senden)
112
    UCSRC |= (1<<URSEL) | (3<<UCSZ0);//Einstellung 8,n,1
113

114
    while (!(UCSRA & (1<<UDRE)))  //warten, bis sendebereit
115
    {
116
    }    
117
    z = sende(h);
118

119
    while (!(UCSRA & (1<<UDRE)))  //warten, bis sendebereit
120
    
121
    }
122
    UDR = 0xa; // 0xd        //Beschreiben des Senderegisters mit EINER Zahl / EINEM Buchstaben
123
    /*
124
    while (!(UCSRA & (1<<UDRE)))  //warten, bis sendebereit
125
    {
126
    }
127
    UDR = 0xd; // 0xd        //Beschreiben des Senderegisters mit EINER Zahl / EINEM Buchstaben
128

129

130
    /*
131
    PORTC=0x00;            //PWM, c zwischen 0 und 255 einstellbar
132
    for (i=0;i<c;i++);
133

134
    PORTC=0xFF;
135
    for (i=0;i<255-c;i++);
136
    */
137
                
138
   }
139
}
#558411
Lesenswert?

D.Brouwer wrote:

> Ich poste hier mal eine frühere Version des "Programms".
> Mal sehen was ihr dazu meint:

Sieht schon viel besser aus.


> void init_io(void)
> {
>      UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
>   UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
>
>   //DDRC = 0xFF;      //PortD wird als Ausgang definiert
>      //DDRB = 0x00;      /* Pin PA0 als Eingang */
>      //PORTA |= (1<<PA0);   //Pullup-Wiederstand von PortA Pin0 wird
> aktiviert
> }

Das ist aber nur die halbe UART Initialisierung.
Da fehlt noch das Freischalten der Übertragungsrichtung.

>
>
> uint16_t readADC(uint8_t channel)
> {
>   uint16_t result = 0;
>   // Den ADC aktivieren und Teilungsfaktor auf 64 stellen
>   ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
>   // Kanal des Multiplexers waehlen
>   ADMUX = channel;
>   // Interne Referenzspannung verwenden (also 2,56 V)
>   ADMUX |= (1<<REFS1) | (1<<REFS0);
>     // Den ADC initialisieren und einen sog. Dummyreadout machen
>   ADCSRA |= (1<<ADSC);
>
>
>   while(ADCSRA & (1<<ADSC));
>   //Jetzt 3x die analoge Spannung and Kanal channel auslesen
>   //und dann Durchschnittswert ausrechnen.
>   for(i=0; i<5; i++)

Hier stimmen Kommentar und Wirklichkeit nicht überein.
Im Kommentar steht: 3 mal
Im Code wird die Schleife aber 5 mal wiederholt.

>   {
>     // Eine Wandlung
>     ADCSRA |= (1<<ADSC);
>     // Auf Ergebnis warten...
>     while(ADCSRA & (1<<ADSC));
>
>     result += ADCW;
>   }
>   //ADC wieder deaktivieren
>   //ADCSRA &= ~(1<<ADEN);
>
>   result /= 5;
>
>   return result;
> }

ansonten sieht die Funktion beim schnellen drüberlesen nicht
schlecht aus.

>
>
>
> int uart_putc(unsigned char c)
> {
>   while (!(UCSRA & (1 << UDRE)))
>   {
>   }
>   UDR = c;
>   return 0;
> }

Ist ok.
(den return könnte man einsparen, da er sowieso immer 0 ist.
Alternativ würde es sich anbieten anstelle von 0 einfach c
zu retournieren)

>
> void uart_puts(char *s)
> {
>   while (*s)
>   {
>     uart_putc(*s);
>     s++;
>   }
>   uart_putc(*s);
> }

Äh. Nein. Der letzte uart_putc ist überflüssig.
Da wird immer ein '\0' gesendet. Könnte man zwar
zur Synchronisierung auf der Gegenstelle nehmen, ist
aber meist keine gute Idee.

>
> uint16_t sende(uint16_t l)
> {
>   uint16_t result = 0;
>
>   char phrase[7];
>
>   itoa(l, phrase, 10);
>
>   uart_puts(phrase);
>
>   return result;
> }

Ja, ok.
Obowhl ich mich frage was das 'result' da drinnen soll.

>
> void main(void)
> {
>     init_io();                           //Ruft die Funktion init_io()
> auf

init_io ist kein guter Name für diese Funktion. Die Funktion
initialisiert den UART. Man sollte darüber nachdenken, ob man die
Funktion nicht umbenennt.

>      init_adc();                       //init des adc
>
>
>     while(1)
>    {
>
>         h = readADC(0);                //lese analogen wert aus channel
> 0 in c
>         UCSRB |= (1<<TXEN);        //aktiviert den UART (Senden)
>     UCSRC |= (1<<URSEL) | (3<<UCSZ0);//Einstellung 8,n,1

Oooops.
Was haben die beiden hier verloren.
Die beiden Anweisungen konfigurieren die UART. Ergo sollten sie
besser in die init Funktion wandern.
Abgesehen davon ist es wirklich keine gute Idee bei jedem
Schleifendurchlauf die UART neu zu initialisieren. Wer sagt denn
dass da nicht gerade eine Übertragung läuft.

-> Initialiserungen passieren am Anfang des Programmes. Wenn eine
Initialisierung aus mehreren Teilen besteht, dann verschiebt man
diese Teile in eine eigene Funktion. Aber dann auch wirklich
alle Teile in die Funktion mit aufnehmen.

>
>     while (!(UCSRA & (1<<UDRE)))  //warten, bis sendebereit
>     {
>     }
>     z = sende(h);

Das Warten ist hier unnötig.
sende benutzt letztendlich die Funktion uart_puts um die
Ausgabe zu machen. uart_puts benutzt wiederrum die Funktion
uart_putc um einzelne Zeichen auszugeben. Und uart_putc
kümmert isch darum, dass tatsächlich gesendet werden kann.
Es besteht also hier kein Grund auf Sendebereitschaft zu
warten. Ist die UART sendebereit, dann macht letztendlich
uart_putc die Ausgabe der einzelnen Zeichen. Ist sie es nicht,
dann wartet uart_putc bis die Sendebereitschaft da ist.

>
>     while (!(UCSRA & (1<<UDRE)))  //warten, bis sendebereit
>
>     }
>     UDR = 0xa; // 0xd        //Beschreiben des Senderegisters mit EINER
> Zahl / EINEM Buchstaben

Das ist eine schlechte Idee.
Um ein einzelnes Zeichen auszugeben, gibt es eine Funktion
nämlich uart_putc. Diese Funktion, und nur diese Funktion
ist aufzurufen, wenn an einer Stelle eine Ausgabe gemacht
werden soll:

     uart_putc( 0x0a );

>     /*
>     while (!(UCSRA & (1<<UDRE)))  //warten, bis sendebereit
>     {
>     }
>     UDR = 0xd; // 0xd        //Beschreiben des Senderegisters mit EINER
> Zahl / EINEM Buchstaben

Ditto

>
>
>     /*
>     PORTC=0x00;            //PWM, c zwischen 0 und 255 einstellbar
>     for (i=0;i<c;i++);
>
>     PORTC=0xFF;
>     for (i=0;i<255-c;i++);
>     */
>
>    }
> }
>
>
> [/c]
Gast #558425
Lesenswert?

Mann Mann Karl - Heinz! Hart aber gerecht und vor allen Dingen schnell!
Danke!
Wenn ich die Fehler ausgemerzt habe melde ich mich nochmal zurück... 
fahr so in der Stunde in den Feierabend und dann hab ich nochmal Ruhe 
dafür.

Schließlich müssen die verflixten drei Kanäle da noch rein.

Bis dann!

(Bin jetzt ernsthaft erleichtert)
#558436
Lesenswert?

D.Brouwer wrote:
> Mann Mann Karl - Heinz! Hart aber gerecht und vor allen Dingen schnell!
> Danke!
> Wenn ich die Fehler ausgemerzt habe melde ich mich nochmal zurück...
> fahr so in der Stunde in den Feierabend und dann hab ich nochmal Ruhe
> dafür.
>
> Schließlich müssen die verflixten drei Kanäle da noch rein.

Das sollte jetzt aber kein grosses Problem mehr sein.
ALle Zutaten sind ja bereits da.

Dein main() müsste dann so aussehen:
1
void main(void) 
2
{ 
3
  init_io();                       // Ruft die Funktion init_io() auf 
4
  init_adc();                      // init des adc 
5

6
  //
7
  // Die nächsten beiden Zeilen sollten besse nach init_io
8
  // verschoben werden, damit die Initialisierung nicht
9
  // auseinandergerissen wird
10
  //
11
  UCSRB |= (1<<TXEN);        //aktiviert den UART (Senden)
12
  UCSRC |= (1<<URSEL) | (3<<UCSZ0);//Einstellung 8,n,1
13

14
  while(1) 
15
  {
16
    //
17
    // ersten ADC Kanal 'X' einlesen und versenden
18
    //
19
    h = readADC( 0 );
20
    uart_putc( 'X' );
21
    sende( h );
22

23
    //
24
    // zweiten ADC Kanal 'Y' einlesen und versenden
25
    //
26
    h = readADC( 1 );
27
    uart_putc( 'Y' );
28
    sende( h );
29

30
    //
31
    // dritten ADC Kanal 'Z' einlesen und versenden
32
    //
33
    h = readADC( 2 );
34
    uart_putc( 'Z' );
35
    sende( h );
36
    
37
    //
38
    // und noch ein CR/LF nachschieben, damit am Terminal
39
    // eine neue Zeile begonnen wird
40
    //
41
    uart_putc( 0x0A );
42
    uart_putc( 0x0D );
43
  }
44
}

  
Gast #558580
Lesenswert?

Hallo Leute!

So.Ich hoffe das ich euch das letzte Mal damit nerven muss.... Kapiert 
hab ichs (hoff ich mal). AAber:
Der Kompiler gibt mir leider 4 Fehler aus... :(.... die wiederum kapier 
ich   irgendwie nicht....
Habe die unklare Stelle kommentiert...In der Sende Funktion.

Die Meldungen:

../BESCHL_AVR_SENDET_XYZ_WICHTIG.c:89: error: syntax error before 
numeric constant
../BESCHL_AVR_SENDET_XYZ_WICHTIG.c: In function `sende':
../BESCHL_AVR_SENDET_XYZ_WICHTIG.c:95: error: `l' undeclared (first use 
in this function)
../BESCHL_AVR_SENDET_XYZ_WICHTIG.c:95: error: (Each undeclared 
identifier is reported only once
../BESCHL_AVR_SENDET_XYZ_WICHTIG.c:95: error: for each function it 
appears in.)


Schöne Grüße!!!

1
#include <avr/io.h> 
2
#include <stdlib.h>
3

4
#ifndef F_CPU
5
#define F_CPU 8000000
6
#endif
7

8
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)  //Definition der Frequnz des Baudratenregisters
9

10
#define UART_BAUD_RATE 9600                    //Baudrate einstellen
11

12
uint8_t h  = 0;
13
uint8_t i  = 0;
14
uint16_t z = 0; 
15

16
void init_io(void) 
17
{ 
18
     UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
19
  UBRRL = (uint8_t) UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );    
20
  UCSRB |= (1<<TXEN);              //aktiviert den UART (Senden)
21
  UCSRC |= (1<<URSEL) | (3<<UCSZ0);      //Einstellung 8,n,1
22
  UCSRB |= (1<<TXEN);                  //aktiviert den UART (Senden)
23
    UCSRC |= (1<<URSEL) | (3<<UCSZ0);      //Einstellung 8,n,1
24

25

26

27
  //DDRC = 0xFF;      //PortD wird als Ausgang definiert 
28
     //DDRB = 0x00;      /* Pin PA0 als Eingang */
29
     //PORTA |= (1<<PA0);   //Pullup-Wiederstand von PortA Pin0 wird aktiviert 
30
}   //Es fehlt das Freischalten der Übertragungsrichtung
31

32

33
uint16_t readADC(uint8_t channel) 
34
{
35
  uint16_t result = 0;  
36
  // Den ADC aktivieren und Teilungsfaktor auf 64 stellen
37
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
38
  // Kanal des Multiplexers waehlen
39
  ADMUX = channel;
40
  // Interne Referenzspannung verwenden (also 2,56 V)
41
  ADMUX |= (1<<REFS1) | (1<<REFS0);
42
    // Den ADC initialisieren und einen sog. Dummyreadout machen
43
  ADCSRA |= (1<<ADSC);
44

45

46
  while(ADCSRA & (1<<ADSC));
47
  //Jetzt 5x die analoge Spannung and Kanal channel auslesen
48
  //und dann Durchschnittswert ausrechnen.
49
  for(i=0; i<5; i++) 
50
  {
51
    // Eine Wandlung
52
    ADCSRA |= (1<<ADSC);
53
    // Auf Ergebnis warten...
54
    while(ADCSRA & (1<<ADSC));
55
    
56
    result += ADCW;
57
  }
58
  //ADC wieder deaktivieren
59
  //ADCSRA &= ~(1<<ADEN);
60
  
61
  result /= 5;
62
  
63
  return result;
64
}
65

66

67

68
int uart_putc(unsigned char c)
69
{
70
  while (!(UCSRA & (1 << UDRE)))
71
  {
72
  }
73
  UDR = c;
74
  return c;
75
}
76

77
void uart_puts(char *s)
78
{
79
  while (*s)
80
  {
81
    uart_putc(*s);
82
    s++;
83
  }
84

85
}
86

87

88
///////////////////////////////////////////////////////////////////////////////////////////
89
uint16_t sende(uint16_t 1) ///////////////////////////HIER MUSS DER FEHLER LIEGEN !!!!!!!!
90
{
91
  uint16_t result = 0;
92
  
93
  char phrase[7];
94

95
  itoa(l, phrase, 10);
96

97
  uart_puts(phrase);
98
  
99
  return result;
100
  }
101

102

103

104

105

106
  
107
void main(void) 
108
{ 
109
  init_io();                       // Ruft die Funktion init_io() auf 
110
  init_adc();                      // init des adc 
111

112
  
113
  while(1) 
114
  {
115
    //
116
    // ersten ADC Kanal 'X' einlesen und versenden
117
    //
118
    h = readADC( 0 );
119
    uart_putc( 'X' );
120
    sende( h );
121

122
    //
123
    // zweiten ADC Kanal 'Y' einlesen und versenden
124
    //
125
    h = readADC( 1 );
126
    uart_putc( 'Y' );
127
    sende( h );
128

129
    //
130
    // dritten ADC Kanal 'Z' einlesen und versenden
131
    //
132
    h = readADC( 2 );
133
    uart_putc( 'Z' );
134
    sende( h );
135
    
136
    //
137
    // und noch ein CR/LF nachschieben, damit am Terminal
138
    // eine neue Zeile begonnen wird
139
    //
140
    uart_putc( 0x0A );
141
    uart_putc( 0x0D );
142
  }
143
}

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