Forum: Mikrocontroller und Digitale Elektronik Verarbeitung/Weitergabe dreier gewandelter Messwerte


von D.Brouwer (Gast)


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
}







von Koko Lores (Gast)


Lesenswert?

In dem Fall wiederum halte ich angebracht zu Fragen, womit er nicht 
weiterkommt. Gesagt, was passieren soll, aber unpräzise gefragt.

von Timo (Gast)


Lesenswert?

Unpräzise gefragt???

Ich sehe nicht mal eine Frage!

von D.Brouwer (Gast)


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.

von Koko Lores (Gast)


Lesenswert?

Es sei denn natürlich, jemand hat die Muße, sich in das Programm 
einzuarbeiten.. was aber auf mich nicht zutrifft.

Es scheint mir aber recht lang, für die Aufgabe.

von Karl H. (kbuchegg)


Lesenswert?

Und ein vernünftiges Einrückschema ist auch kein Luxus.
So hab ich ehrlich gesagt keine Lust, durch den Code zu gehen
und zu erraten, was denn nun das Problem sein könnte.

von Karl H. (kbuchegg)


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.

von Koko Lores (Gast)


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. :-)

von D.Brouwer (Gast)


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

von Karl H. (kbuchegg)


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.

von D.Brouwer (Gast)


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 ! :)

von D.Brouwer (Gast)


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)

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


Lesenswert?

> Irgendwie hab ich das Gefühl, der Code wurde in einem
> Rutsch herunterprogrammiert

Das nehme ich zurück.
Der Code wurde nicht herunterprogrammiert.
Der Code wurde herunter-ge-copy&pasted

von Koko Lores (Gast)


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.

von D.Brouwer (Gast)


Lesenswert?

Ok! Danke! Dann fang ich mal an - ich poste sobald fertig !

von schönesWetterheute (Gast)


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ß,



von Karl H. (kbuchegg)


Lesenswert?

So.
Ich bin jetzt soweit durch, dass sich Folgendes abzeichnet.
Dein 'Programm' ist eine möglichst komplexe und verwirrende
Form von

void main(void)
{
  DDRC=0x00;
}

und das das nicht viel macht, ist unmittelbar ersichtlich.

von D.Brouwer (Gast)


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
}

von Karl H. (kbuchegg)


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!

von Karl H. (kbuchegg)


Lesenswert?

Sowas

>       return 0;
>
> }
>
> return 0;
>
> }


kann schon mal überhaupt nicht sein. Wenn das return
die letzte Anweisung in einer Funktion ist, dann kann
die abschliessende } nur um 2 Stellen links vom return
sein.

von Karl H. (kbuchegg)


Lesenswert?

Sieh dir das hier an

>    ///gesetzte MUX wieder löschen
>    ADMUX = 0x00;
>
>      }
>
>
>    for (i=0;i<4;i++)
>      {

da passen die Einrückregeln überhaupt nicht.

Und so gibt es viele Stellen.

PS: Vor dem main() werden bei dir mindestens 5 Funktionen
herauskommen.

von Karl H. (kbuchegg)


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.

von D.Brouwer (Gast)


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
}

von Karl H. (kbuchegg)


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]

von D.Brouwer (Gast)


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)

von Karl H. (kbuchegg)


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
}

  

von D.Brouwer (Gast)


Lesenswert?

Schick mir bitte an d.brouwer@gmx.de deine Adresse, damit ich dir ne 
schöne Flasche schicken kann ! (Wein rot oder weiß oder was du willst) 
!!!! :)


von D.Brouwer (Gast)


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
}

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

D.Brouwer wrote:
> uint16_t sende(uint16_t 1)

Das ist eine Eins, sollte aber wahrscheinlich ein l sein, so wie hier:

>   itoa(l, phrase, 10);

von D.Brouwer (Gast)


Lesenswert?

Ach du meine Güte.. ich bin aber auch bescheuert....

DANKE vielmals! Das wars!

Viele Grüße und einen schönen Abend noch!

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.