mikrocontroller.net

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


Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
#include <avr/io.h>
#include <stdlib.h>


#ifndef F_CPU
#define F_CPU 8000000
#endif

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

#define UART_BAUD_RATE 9600                         //Baudrate einstellen




        //Definieren der Variablen

//uint8_t  data  = 0;//
uint8_t  h  = 0;  
uint8_t  i  = 0;
uint16_t z  = 0; 
uint16_t  sensor_X = 0;
uint16_t  sensor_Y=  0;
uint16_t  sensor_Z=  0;
char ident_sensor;


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



#define FOSC 1843200    
        // Clock Speed


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



void main (void) 

{   



void USART_Init ( unsigned int ubrr )


{
        // Setzen der Baud-Rate


UBRRH = (unsigned char) (ubrr>>8);
UBRRL = (unsigned char)  ubrr;

                                    
        //"Anschalten" von Reciever und Transmitter

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

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

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

}


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


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

//Setzen von allen PCx auf EINGANG

DDRC=0x00;



//ADC einschalten und Dummyreadout machen:   

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

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

ADCSRA |= (1<<ADSC);
//Warten, bis die Konvertierung fertig ist...
while (ADCSRA & (1<<ADSC) )
{
  ;;

}



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



            /// ENLOSSCHEIFE:

              while(1)
        
{




//////////////////////////////////////////////////Sensor_X //////////////////////////////////////////////////////////////


///Kanal wählen:

ADMUX |= (1<<MUX0);

for (i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC);
    while (ADCSRA & (1<<ADSC)) 
    { 
    ;
    }
  sensor_X=sensor_X+ADCW;

  }

//ADC deaktivieren

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

sensor_X = sensor_X / 4;

return sensor_X;

//Daten senden:

int uart_putc_X (unsigned char sensor_X)                ///unsigned char
{

  while (!(UCSRA & (1<<UDRE)))
                                    ///da fehlt noch etwas!
  UDR = sensor_X;  
  
  return 0;

void uart_puts (char *s)

{
  while (*s)
  {
    uart_putc_X(*s);
    s++;

  }
}


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

  ident_sensor =  'x' ;

  ///Senden der Kontrollvariablen:

  int uart_putc (unsigned char ident_sensor)

{

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

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

  ///LEDs wieder aus:

  PORTD = 0x00;
  
  return 0;

}

///gesetzte MUX wieder löschen


ADMUX = 0x00;

//////////////////////////////////////////////////Sensor Y //////////////////////////////////////////////////////////////


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

for (i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC);
    while (ADCSRA & (1<<ADSC)) 
    { 
    ;
    }
  sensor_Y=sensor_Y+ADCW;

  }

//ADC deaktivieren

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

sensor_Y = sensor_Y / 4;

return sensor_Y;

//Daten senden:

int uart_putc_Y (unsigned char sensor_Y)                  ///unsigned char
{

  while (!(UCSRA & (1<<UDRE)))
                                    ///da fehlt noch etwas!
  UDR = sensor_Y;  
  
  return 0;

void uart_puts (char *s)

{
  while (*s)
  {
    uart_putc(*s);
    s++;

  }
}


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

  ident_sensor =  'y' ;

  ///Senden der Kontrollvariablen:

  int uart_putc (unsigned char ident_sensor)

{

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

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

  ///LEDs wieder aus:

  PORTD = 0x00;
  
  return 0;

}

///gesetzte MUX wieder löschen


ADMUX = 0x00;



//////////////////////////////////////////////////Sensor Z //////////////////////////////////////////////////////////////


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


for (i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC);
    while (ADCSRA & (1<<ADSC)) 
    { 
    ;
    }
  sensor_Z=sensor_Z+ADCW;

  }

//ADC deaktivieren

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

sensor_Z = sensor_Z / 4;

return sensor_Z;

//Daten senden:

int uart_putc_Z (unsigned char sensor_Z)                ///unsigned char
{

  while (!(UCSRA & (1<<UDRE)))
                                    ///da fehlt noch etwas!
  UDR = sensor_Z;  
  
  return 0;

void uart_puts (char *s)

{
  while (*s)
  {
    uart_putc(*s);
    s++;

  }
}


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

  ident_sensor =  'z' ;

  ///Senden der Kontrollvariablen:

  int uart_putc (unsigned char ident_sensor)

{

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

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

  ///LEDs wieder aus:

  PORTD = 0x00;
  
  return 0;

}

///gesetzte MUX wieder löschen


ADMUX = 0x00;

}


for (i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC);
    while (ADCSRA & (1<<ADSC)) 
    { 
    ;
    }
  sensor_Z=sensor_Z+ADCW;

  }
  //ADC deaktivieren

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

  sensor_Z = sensor_Z / 4;

  return sensor_Z;

  //Daten senden

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

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

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

  ident_sensor =  'z' ;
                  
  UDR = ident_sensor;                          

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


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

  ///LEDs wieder aus:

  PORTD = 0x00;

  return 0;
  
}



}return 0;
}









Autor: Koko Lores (Gast)
Datum:

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

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Unpräzise gefragt???

Ich sehe nicht mal eine Frage!

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Koko Lores (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Koko Lores (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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. :-)

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ! :)

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#include <stdlib.h>

#ifndef F_CPU
#define F_CPU 8000000
#endif

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

        //Definieren der Variablen

//uint8_t  data  = 0;//
uint8_t  h  = 0;  
uint8_t  i  = 0;
uint16_t z  = 0; 
uint16_t  sensor_X = 0;
uint16_t  sensor_Y=  0;
uint16_t  sensor_Z=  0;
char ident_sensor;

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

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

void USART_Init ( unsigned int ubrr )
{
  // Setzen der Baud-Rate
  UBRRH = (unsigned char) (ubrr>>8);
  UBRRL = (unsigned char)  ubrr;

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

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

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

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

  ///LEDs wieder aus:
  PORTD = 0x00;
  
  return 0;
}

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


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

  //Setzen von allen PCx auf EINGANG

  DDRC=0x00;

  ...


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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Koko Lores (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok! Danke! Dann fang ich mal an - ich poste sobald fertig !

Autor: schönesWetterheute (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß,



Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

#include <avr/io.h>
#include <stdlib.h>


#ifndef F_CPU
#define F_CPU 8000000
#endif

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

#define UART_BAUD_RATE 9600                         //Baudrate einstellen




//Definieren der Variablen

//uint8_t  data  = 0;//
uint8_t  h  = 0;  
uint8_t  i  = 0;
uint16_t z  = 0; 
uint16_t  sensor_X = 0;
uint16_t  sensor_Y=  0;
uint16_t  sensor_Z=  0;
char ident_sensor;


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


void USART_Init ( unsigned int ubrr )

  {
  // Setzen der Baud-Rate
  UBRRH = (unsigned char) (ubrr>>8);
  UBRRL = (unsigned char)  ubrr;
                                    
  //"Anschalten" von Reciever und Transmitter
  UCSRB = (1<<RXEN)|(1<<TXEN);

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

  }

void main (void) 
{   

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


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

    DDRC=0x00;

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

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

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


        while (ADCSRA & (1<<ADSC) )
          {
            ;;
    
          }

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

  while(1)
        
  {




//////////////////////////////////////////////////Sensor_X //////////////////////////////////////////////////////////////


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

      for (i=0;i<4;i++)
        {
          ADCSRA |= (1<<ADSC);
          while (ADCSRA & (1<<ADSC)) 
              { 
              ;
              }
          sensor_X=sensor_X+ADCW;
    
        }

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

      sensor_X = sensor_X / 4;

      return sensor_X;
            
      //Daten senden:

      int uart_putc_X (unsigned char sensor_X)                ///unsigned char
        {

          while (!(UCSRA & (1<<UDRE)))
                                    ///da fehlt noch etwas!
          UDR = sensor_X;  
  
          return 0;

      void uart_puts (char *s)

        {
          while (*s)
        {
        uart_putc_X(*s);
        s++;

        }
    
    }

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

    ident_sensor =  'x' ;

    ///Senden der Kontrollvariablen:

    int uart_putc (unsigned char ident_sensor)

      {    

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

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

          ///LEDs wieder aus:
  
          PORTD = 0x00;
  
          return 0;

        }

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

//////////////////////////////////////////////////Sensor Y //////////////////////////////////////////////////////////////


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

    for (i=0;i<4;i++)
      {
        ADCSRA |= (1<<ADSC);
        while (ADCSRA & (1<<ADSC)) 
        { 
        ;
        }
      sensor_Y=sensor_Y+ADCW;

      }

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

    sensor_Y = sensor_Y / 4;

    return sensor_Y;

    //Daten senden:
    int uart_putc_Y (unsigned char sensor_Y)                  ///unsigned char
    {

      while (!(UCSRA & (1<<UDRE)))
                                    ///da fehlt noch etwas!
      UDR = sensor_Y;  
  
      return 0;

    void uart_puts (char *s)

    {
      while (*s)
      {
        uart_putc(*s);
        s++;

      }
    }


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

  ident_sensor =  'y' ;

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

  {

    while (!(UCSRA & (1<<UDRE)));
      {
        UDR = ident_sensor;
        ///Blinken einer entsprechenen LED zum Programmtest:
        ///Setzten von PBx als Ausgang (Bei X - Signal sollen Leuchten: LED 2 und 3) :
        ///Aktivieren der Ports
        DDRB = (2<<DDB0) | (3<<DDB1) ;
        PORTD = (2<<PD0) | (3<<PD1)  ;
  
        ///LEDs wieder aus:
  
        PORTD = 0x00;
  
      return 0;
      }      

  }

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



//////////////////////////////////////////////////Sensor Z //////////////////////////////////////////////////////////////


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


    for (i=0;i<4;i++)
      {
        ADCSRA |= (1<<ADSC);
        while (ADCSRA & (1<<ADSC)) 
        { 
        ;
        }
      sensor_Z=sensor_Z+ADCW;

      }

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

    sensor_Z = sensor_Z / 4;

    return sensor_Z;

    //Daten senden:
    int uart_putc_Z (unsigned char sensor_Z)                
    {

      while (!(UCSRA & (1<<UDRE)))
                                    
      UDR = sensor_Z;  
  
      return 0;

    }


    void uart_puts (char *s)

    {
      while (*s)
      {
        uart_putc(*s);
        s++;
      }

    }


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

    ident_sensor =  'z' ;

    ///Senden der Kontrollvariablen:

    int uart_putc (unsigned char ident_sensor)

      {
  
        while (!(UCSRA & (1<<UDRE)));

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

        ///LEDs wieder aus:
        PORTD = 0x00;
  
        return 0;
      
      }


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

      }


    for (i=0;i<4;i++)
      {
        ADCSRA |= (1<<ADSC);
        while (ADCSRA & (1<<ADSC)) 
          { 
            ;
          }
      sensor_Z=sensor_Z+ADCW;

      }

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

      sensor_Z = sensor_Z / 4;

      return sensor_Z;

      //Daten senden

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

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

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

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

      ///LEDs wieder aus:

      PORTD = 0x00;

      return 0;
  
}

return 0;

}


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h> 
#include <stdlib.h>

#ifndef F_CPU
#define F_CPU 8000000
#endif

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

#define UART_BAUD_RATE 9600                    //Baudrate einstellen

uint8_t h = 0;
uint8_t i = 0;
uint16_t z = 0; 

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 
} 


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



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

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



uint16_t sende(uint16_t l) 
{
  uint16_t result = 0;
  
  char phrase[7];

  itoa(l, phrase, 10);

  uart_puts(phrase);

  return result;
}





  
void main(void) 
{ 
    init_io();                           //Ruft die Funktion init_io() auf 
     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

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

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


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

    PORTC=0xFF;
    for (i=0;i<255-c;i++);
    */
                
   }
}



Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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]

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
void main(void) 
{ 
  init_io();                       // Ruft die Funktion init_io() auf 
  init_adc();                      // init des adc 

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

  while(1) 
  {
    //
    // ersten ADC Kanal 'X' einlesen und versenden
    //
    h = readADC( 0 );
    uart_putc( 'X' );
    sende( h );

    //
    // zweiten ADC Kanal 'Y' einlesen und versenden
    //
    h = readADC( 1 );
    uart_putc( 'Y' );
    sende( h );

    //
    // dritten ADC Kanal 'Z' einlesen und versenden
    //
    h = readADC( 2 );
    uart_putc( 'Z' );
    sende( h );
    
    //
    // und noch ein CR/LF nachschieben, damit am Terminal
    // eine neue Zeile begonnen wird
    //
    uart_putc( 0x0A );
    uart_putc( 0x0D );
  }
}

  

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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) 
!!!! :)


Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!!!

#include <avr/io.h> 
#include <stdlib.h>

#ifndef F_CPU
#define F_CPU 8000000
#endif

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

#define UART_BAUD_RATE 9600                    //Baudrate einstellen

uint8_t h  = 0;
uint8_t i  = 0;
uint16_t z = 0; 

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 );    
  UCSRB |= (1<<TXEN);              //aktiviert den UART (Senden)
  UCSRC |= (1<<URSEL) | (3<<UCSZ0);      //Einstellung 8,n,1
  UCSRB |= (1<<TXEN);                  //aktiviert den UART (Senden)
    UCSRC |= (1<<URSEL) | (3<<UCSZ0);      //Einstellung 8,n,1



  //DDRC = 0xFF;      //PortD wird als Ausgang definiert 
     //DDRB = 0x00;      /* Pin PA0 als Eingang */
     //PORTA |= (1<<PA0);   //Pullup-Wiederstand von PortA Pin0 wird aktiviert 
}   //Es fehlt 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 5x die analoge Spannung and Kanal channel auslesen
  //und dann Durchschnittswert ausrechnen.
  for(i=0; i<5; i++) 
  {
    // Eine Wandlung
    ADCSRA |= (1<<ADSC);
    // Auf Ergebnis warten...
    while(ADCSRA & (1<<ADSC));
    
    result += ADCW;
  }
  //ADC wieder deaktivieren
  //ADCSRA &= ~(1<<ADEN);
  
  result /= 5;
  
  return result;
}



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

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

}


///////////////////////////////////////////////////////////////////////////////////////////
uint16_t sende(uint16_t 1) ///////////////////////////HIER MUSS DER FEHLER LIEGEN !!!!!!!!
{
  uint16_t result = 0;
  
  char phrase[7];

  itoa(l, phrase, 10);

  uart_puts(phrase);
  
  return result;
  }





  
void main(void) 
{ 
  init_io();                       // Ruft die Funktion init_io() auf 
  init_adc();                      // init des adc 

  
  while(1) 
  {
    //
    // ersten ADC Kanal 'X' einlesen und versenden
    //
    h = readADC( 0 );
    uart_putc( 'X' );
    sende( h );

    //
    // zweiten ADC Kanal 'Y' einlesen und versenden
    //
    h = readADC( 1 );
    uart_putc( 'Y' );
    sende( h );

    //
    // dritten ADC Kanal 'Z' einlesen und versenden
    //
    h = readADC( 2 );
    uart_putc( 'Z' );
    sende( h );
    
    //
    // und noch ein CR/LF nachschieben, damit am Terminal
    // eine neue Zeile begonnen wird
    //
    uart_putc( 0x0A );
    uart_putc( 0x0D );
  }
}



Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht 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);

Autor: D.Brouwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach du meine Güte.. ich bin aber auch bescheuert....

DANKE vielmals! Das wars!

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.