www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Analoge Schnittstelle C167


Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe den Mikrocontroller C167 von Infenion und möchte eine einfache 
Aufgabe schaffen.
Über den analogen Eingang am PIN 5.0 soll eine Analogspannung angelegt 
werden.
Diese soll dann gewandelt werden und der Spannungswert soll mit der 
printf -Funktion ausgegeben werden.

Die Wandlung geschieht in der Funktion messen. Der Rückgabewert soll aus 
dem Register ADDAT ausgelesen werden.
Mit der Funktion auswerten soll aus den Werten 0 ... 1023 wieder eine 
Spannung ausgegeben werden.
Leider funktioniert das überhaupt nicht und ich kann mir nicht erklären, 
woran das liegt.
Die Funktion init enthält die Parameter für die RS232 Schnittstelle, die 
habe ich weggelassen, da sie nur aus dem Beispiel Hello World ist, 
ausserdem funktioniert die printf - Funktion.

Hier der Code:

************************************************************************ 
**
int messen(int kanal){
ADCON = 0xf080 | kanal;
while(!ADCIR);
ADCIR = 0;
return  (ADDAT & 0x03ff);
}

float auswerten(wert){
unsigned int uein;
uein = wert*(5/1023);
return uein;
}

void main (void){
int wert;

float uein;
init();

while (1){
  wert = messen(0);
  uein = auswerten(wert);
  zeichen_senden('s');
  printf("Eingangsspannung ist: %f\n", uein);

  }
}
************************************************************************ 
**

Wäre super, wenn mir jemand helfen könnte

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Leider funktioniert das überhaupt nicht und ich kann mir nicht erklären,
> woran das liegt.

Das liegt vielleicht an Syntax Fehlern in deinem Pgm

float auswerten(wert){

                ****
hier fehlt der Datentyp für 'wert'. Das hätte dir dein Compiler
aber eigentlich sagen müssen.


unsigned int uein;
uein = wert*(5/1023);

Dir ist bewusst, dass die Division 5 / 1023 immer 0 ergibt?
Da ich mal davon ausgehe, dass du genau das nicht wolltest:

     uein = wert * ( 5.0 / 1023.0 );

5/1023 : Da beide Partner in der Division, sowohl 5 als auch 1023
int sind, wird auch die Division selbst im int-Raum gemacht. Wenn
du das anders willst, muss mindestens einer der beiden, oder alle
beide, vom Typ double (oder float) sein.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> float auswerten(wert){
> unsigned int uein;
> uein = wert*(5/1023);
> return uein;
> }

Bist du sicher, dass uein in dieser Funktion vom Typ unsigned
int sein sollte?

Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe den Quellcode verändert, indem ich alle Variablen, ausser der 
Variable "Kanal" auf float gesetzt habe und bei der Division an den 
Zahlen .0 angehängt habe. Den Syntaxfehler aus der Funktion auswerten() 
habe ich auch rausgemacht.
Leider ist es noch das gleiche...

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Leider ist es noch das gleiche...

Dann solltest du mal sagen, was denn unter 'das gleiche' zu
verstehen ist.

Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich das Programm ausführe, erscheint nur der erste Buchstabe in der 
printf - Funktion ("Eingangspannung...") also nur E, sonst nichts, das 
wiederholt sich nach dem reseten

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probier mal folgendes:

while (1){
  wert = messen(0);
  uein = auswerten(wert);
  zeichen_senden('s');
  printf("Eingangsspannung ist: %f (%d)\n", uein, wert);
}

und sieh nach, ob vom ADC überhaupt vernünftige Werte kommen.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn ich das Programm ausführe, erscheint nur der erste Buchstabe in der
> printf - Funktion ("Eingangspannung...")

Sagtest du in deinem Eröffnungsposting nicht, dass printf
funktionieren würde?

Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es kommen von ADC keine vernünftigen Werte.
Es ist so, wie ich oben beschrieben habe

Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moment mal,
ist das überhaupt richtig so?
Ich glaube langsam das da das Problem liegt


********************************************************
void init(void){

 P3  |= 0x0400;
 DP3 |= 0x0400;

  DP3 &= 0xF7FF;

  S0TIC = 0x80;
  S0RIC = 0x00;
  S0BG  = 0x80;
  S0CON = 0x8011;

}

**********************************************************

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Es kommen von ADC keine vernünftigen Werte.

Also: Wenn bei einem
  printf("Eingangsspannung ist: %f (%d)\n", uein, wert);

nur das 'E' auftaucht und sonst nichts, dann hat das erst mal
gar nichts mit dem ADC zu tun. printf ist unabhängig vom
ADC und gibt einfach nur Texte und Variableninhalte aus.
Wo die herkommen ist dem printf sch...egal.
Dein erstes Ziel muss es also mal sein, den printf tatsächlich
funktionsfähig zu kriegen. Alles andere ist stochern im
Nebel.

Dein Testpgm lautet:

int main()
{
  float t = 2.3f;

  while( 1 ) {
    printf( "Test: %f\n", t );
  }
}

und dazu kommt natürlich noch alles was du an Initialisierungen
so brauchst um printf lauffähig zu kriegen. Solange dieses
Programm auf deinem Ausgabemedium nicht immer wieder die
Zeile

  Test: 2.3000

(mit möglicherweise unterschiedlicher Anzahl an Nachkommastellen)
ausgibt, (mglw. steht da auch 2.29999 oder 2.30001) hat alles
andere keinen Sinn.

Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber es müsste doch möglich sein, Werte aus dem Register in eine 
Variable zu schreiben und diese dann über printf auszugeben.

Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe es gerade ausprobiert, die Printf Funktion funktioniert überhaupt 
nicht.
An was kann denn das jetzt liegen?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> An was kann denn das jetzt liegen?

Das kann ich dir nicht sagen, da ich weder den C167, noch den
Compiler den du benutzt, kenne. Aber in der Doku zu deinem
Compiler, müsste ja beschrieben sein, wie du dem printf eine
Ausgabefunktion auf den UART unterjubelst.

Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay,
aber trotzdem vielen Dank, jetzt weiss ich wenigstens, an was es liegt

Autor: sneube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe den Fehler gefunden.
Es war die falsche System Datei eingebunden, so hat die Kommunikation 
mit der RS232 Schnittstelle nicht funktioniert,
aber jetzt funktioniert es wunderbar

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich versuch gerade das ganze hier nachzuvollziehen, da ich sowas 
ähnliches vor habe. Leider bekomm ich immer ne Fehlermeldung je nachdem 
welche Klasse (h-Datei) einbinde.

Habe in dem Beispiel die XC161.h und die stdio.h eingebunden damit 
bekomm ich auch ganz normal ne Anzeige über die Serielleschnittstelle 
wenn ich was über printf ausgebe.
Leider funktioniert das mit der "Erweiterung" von diesem Beitrag noch 
nicht so ganz, bekomme wenn ich das einbinde eine Fehlermeldung. Habe 
schon die reg167.h probiert nur leider funktioniert es damit auch nicht. 
Weiß zufällig jemand welche h-Datei ich für den A/D benötige?

Danke im vorraus.

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Leider funktioniert das mit der "Erweiterung" von diesem Beitrag noch
>nicht so ganz, bekomme wenn ich das einbinde eine Fehlermeldung.
Was bindest du ein? Den Code aus Beitrag 1?

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich nutze das MCB-XC167 Board von Keil und will über den A/D was einen 
Spannungswert einlesen und den über die serielle Schnittstelle ausgeben.

Habe schon folgenden Code zum testen als Beispiel - die Ausgabe an 
Port2.8 ist nur zum testen für mich, also nicht weiter beachten...

Nutze ich den unten angegeben Code, bekomm ich nichts über die 
Schnittstelle raus. Wandel ich aber das S0.. usw. in ASCO... um, dann 
bekomm ich was raus, bekomme aber dann beim einbinden des A/D in den 
Quellcode Fehlermeldungen, das sich die Headerdateien nicht "vertragen".

Für die ASC0.. brauche ich die XC161.h und für den A/D die reg167.h..

Vielleicht ist es ja ganz einfach, nur ich bekomm es irgendwie nicht 
hin.

Danke im vorraus.
#include <reg167.h>          // einbinden der 80C167 Header Datei
#include <stdio.h>          // Standard I/O Funktionen einbinden

sbit P2_8 = P2^8;          // deklaration des zu nutzenden Portpin
sbit DP2_8 = DP2^8;          // deklaration der Richtung

void wait (void) {          // wait Funktion
  unsigned long i;
  for (i=0; i<150000; i++) {;}  // Verzögerungsschleife    
}
        
void ser_init (void) {        // Initialisierungsfunktion für die serielle Schnittstelle
  
  P3 |= 0x0400;          // Port 3.10 auf Output latch (TXD) setzen
  DP3 |= 0x0400;          // Port 3.10 für Output konfigurieren (TXD output)

  DP3 &= 0xF7FF;          // Port 3.11 für Input konfigurieren (RXD input)

  S0TIC = 0x80;          // Transmit Interrupt Flag setzen
  S0RIC = 0x00;          // Receive Interrupt Flag löschen
//  S0BG = 0x80;          // Baudrate auf 9600 einstellen bei 40MHz
//  S0BG = 0x6A;          // Baudrate auf 9600 einstellen bei 33MHz
//  S0BG = 0x50;          // Baudrate auf 9600 einstellen bei 25MHz
  S0BG = 0x40;          // Baudrate auf 9600 einstellen bei 20MHz
  S0CON = 0x8011;          // Serial Mode setzen  
  S0TIR = 1;            // Sendebuffer freigeben
}

void main (void) {
  
  ser_init();            // Aufruf der Init-Funktion für serielle Schnittstelle
  
  DP2_8 = 1;            // Initialisierung der Richtung -> Ausgang
  
  while(1) {            // Endlosschleifen
    
    printf("Hello World\n");  // Ausgabe auf die Serielleschnittstelle  

    P2_8 = 0;          // Port 2.8 aus
    wait();            // Aufruf der wait Funktion

    P2_8 = 1;
    wait();            // Aufruf der wait Funktion
 }
}

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Für die ASC0.. brauche ich die XC161.h und für den A/D die reg167.h..
Dann würde ich mal nachschauen wie in der XC161.h das ADC Control 
Register heisst. Ich tippe auf ADC_CON anstatt ADCON. Die XC161.h hält 
sich wohl an die Namensgebung des User Manuals vom XC167:
http://de.sitestat.com/infineon/infineon/s?infineo...

Vermutlich kannst du daher Programme vom C167 nicht 1:1 für dich 
kopieren. Du musst auf die andere Namensgebung der Register aufpassen!

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.