Forum: Mikrocontroller und Digitale Elektronik C167 External A/D-Wandler


von Ciek S. (cierish)


Lesenswert?

Hallo,

ich habe Einbaurechner mit dem Microkontroller C167 drin. Der Rechner
hat 2 analogen Eingänge, die durch 12 Bit externen A/D-Wandler und dann
mit dem Port 0 verbunden sind.
Von den beiden Eingänge würde ich Werte von einem Frequenzrichter und
von einem Sensor ablesen.
Hat jemand einen Vorschlag, wie ich programmieren soll?

Wie funktioniert Timer eigentlich? Muss die Pins von diesem Timer
erstmal belegt sein?

Vielen Dank für die Hilfe

MfG,
ciek

von Jörg S. (joerg-s)


Lesenswert?

>Hat jemand einen Vorschlag, wie ich programmieren soll?
Am besten fehlerfrei, dann funktioniert es immer am besten.

Im Ernst: Ein wenig mehr Infos über das genaue Problem wären schon 
nötig.

von Ciek S. (cierish)


Lesenswert?

Hallo,

der Rechner hat 2 analogen Eingänge über Port0.
Ich weiß noch nicht, welche Register soll ich benutzen und wie ich die 
Eingangswerte wechselnd (zwi. Eingang 1 und 2) ausgeben kann.

Danke für die Hilfe.

MfG,
Ciek

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ciek Sup wrote:
> der Rechner hat 2 analogen Eingänge über Port0.
> Ich weiß noch nicht, welche Register soll ich benutzen und wie ich die
> Eingangswerte wechselnd (zwi. Eingang 1 und 2) ausgeben kann.
Das sagt genau das selbe aus wie im ersten Post.

> die durch 12 Bit externen A/D-Wandler
Welcher Wandler?
Hast du einen Schaltplan?

> Eingangswerte wechselnd (zwi. Eingang 1 und 2) ausgeben kann.
Du kannst auf einem Eingang nichts ausgeben :-/

Lies dir deine Fragestellung vor dem Absenden nochmal so durch, als ob 
du dein Problem nicht kennen würdest, und stell dir die Frage: Sind 
genug Informationen für eine sinnvolle Antwort mit angegeben?

von Ciek S. (cierish)


Lesenswert?

Lothar Miller wrote:
> Du kannst auf einem Eingang nichts ausgeben :-/

ach Entschuldigung.
Ich meinte, die Eingangswerte werden in Port 0 gespeichert und ich 
möchte diese Werte im Terminal anzeigen lassen.

> Welcher Wandler?
> Hast du einen Schaltplan?

2 mal AD7892AN, den Schaltplan habe ich, aber kann nicht jetzt scannen 
und hochladen.


Danke.

MfG,
Ciek

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ciek Sup wrote:
> Ich meinte, die Eingangswerte werden in Port 0 gespeichert und ich
> möchte diese Werte im Terminal anzeigen lassen.
Dass die im Port 0 gespeichert werden, da wäre ich mir noch nicht ganz 
so sicher: P0 ist auch der Adress- und Datenbus. hängen da auch noch 
andere Bausteine dran. Und dann werden deine AD-Wandler sicher auch 
Memory-Mapped angesprochen werden. Wo sind die Signale RD und CS deiner 
AD-Wandler angeschlossen?

> 2 mal AD7892AN,
Du startest eine Wandlung mit CONVST.
Danach kannst du warten oder das Ende der Wandlung über EOC abfragen.

von Ciek S. (cierish)


Lesenswert?

Lothar Miller wrote:

> Dass die im Port 0 gespeichert werden, da wäre ich mir noch nicht ganz
> so sicher: P0 ist auch der Adress- und Datenbus. hängen da auch noch
> andere Bausteine dran. Und dann werden deine AD-Wandler sicher auch
> Memory-Mapped angesprochen werden. Wo sind die Signale RD und CS deiner
> AD-Wandler angeschlossen?

die 12 Bit Daten vom Wandler (DB0-DB11) sind mit D0-D11 angeschlossen.
RD mit /RD

/CONVST1 (8:0008H)
/CS-ADC1 (8:000AH)
/CONVST2 (8:000CH)
/CS-ADC2 (8:000EH)
sind mit Demux 74LS138 angeschlossen.

A, B, C von 74LS138 sind mit A1-A3 (Port 1), G2A mit CS2 (Port6) 
angeschlossen.

>> 2 mal AD7892AN,
> Du startest eine Wandlung mit CONVST.
> Danach kannst du warten oder das Ende der Wandlung über EOC abfragen.

#define ADC_CS 0x8000A0
#define ADC_CONVST 0x800080
#define ADC_ANZ 2

extern int idata AD_val_raw[ADC_ANZ+1];
extern int idata AD_count;

void raw2int(void) {

  int i;
  // externer AD-Wandler
  for(i=1; i<=2; i++) {

    AD_val[i] = AD_val_raw[i] & 0x07FF;
    if(AD_val_raw[i] & 0x0800)
    AD_val[i] -= 2048;
  }

}

void ADC_EXT_INTR (void) interrupt 0x30 {

  int *adcs = ADC_CS;
  int idata i;
  for(i=1; i<=2; i++) {
      AD_val_raw[i] = *adcs;
      AD_count++;
  }

}

Was ist mit diesem Conversion? Ist es richtig so?

Vielen Dank,

MfG,
Ciek

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Was ist mit diesem Conversion? Ist es richtig so?
Funktioniert es so?
Wenn ja: richtig,
wenn nein: falsch.
Ich tippe auf "nein".

1
  extern int idata AD_val_raw[ADC_ANZ+1];
2
  :
3
  for(i=1; i<=2; i++) {
4
     :
5
  }
So vergeudest du den Speicherplatz 0 deines Arrays.

Richtig und üblich wäre wohl:
1
  extern int idata AD_val_raw[ADC_ANZ]; // Speicherplatz für zwei Wandler
2
  :
3
  for(i=0; i<2; i++) {...

Wie passt das zusammen:
> /CS-ADC1 (8:000AH)
> #define ADC_CS 0x8000A0
ich hätte da eher
#define ADC_CS 0x8000A
vermutet.
1
void TIMER(void) interrupt 0x30 { // kontrollieren: richtig so?
2
  int idata i,j;
3
  for(i=0; i<2; i++) {
4
      *(int*)(ADC_CONVST+(i*4)) = 1; // Zugriff auf Adresse startet Wandlung
5
      for(j=0; j<100; j++);          // Während der Wandlung: Zeit verplempern
6
      AD_val_raw[i] = *(int*)(ADC_CS+(i*4)); // Wert vom ADC holen
7
      AD_count++;  // ???
8
  }
9
}

von Ciek S. (cierish)


Lesenswert?

> Funktioniert es so?
Ich habe das Programm noch nicht fertig geschrieben.
Wo werden eigentlich die Umwandlung im Mikrocontroller gespeichert?
Könntest Du vielleicht helfen?

> Richtig und üblich wäre wohl:
>>   extern int idata AD_val_raw[ADC_ANZ]; // Speicherplatz für zwei
> Wandler
>   :
>   for(i=0; i<2; i++) {...
>

> #define ADC_CS 0x8000A
> vermutet.

danke für Deine Korrektur!
> void TIMER(void) interrupt 0x30 { // kontrollieren: richtig so?
>   int idata i,j;
>   for(i=0; i<2; i++) {
>       *(int*)(ADC_CONVST+(i*4)) = 1; // Zugriff auf Adresse startet
> Wandlung

wieso ist hier mit 4 multipliziert?


Vielen Dank für die Hilfe.

MfG,
Ciek

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Wo werden eigentlich die Umwandlung im Mikrocontroller gespeichert?
In deinem Array AD_val_raw[].

> wieso ist hier mit 4 multipliziert?
Ausgehend von
> /CS-ADC1 (8:000AH)
> /CS-ADC2 (8:000EH)
ist der eine ADC_CS auf 0x8000A+0 = 0x8000A
und der zweite auf 0x8000A+4 = 0x8000E
Erkennst du die Zahlen wieder?

von Ciek S. (cierish)


Lesenswert?

Hallo,

Danke für die schnelle Antwort.
Ich bin noch verwirrt mit der Ausgabe auf Terminal.

> Ausgehend von
>> /CS-ADC1 (8:000AH)
>> /CS-ADC2 (8:000EH)
> ist der eine ADC_CS auf 0x8000A+0 = 0x8000A
> und der zweite auf 0x8000A+4 = 0x8000E
> Erkennst du die Zahlen wieder?
Ja, jetzt verstehe ich.

Könntest Du vielleicht mit dem Timer helfen?
Beitrag "C167 Drehzahlmessung mit Timer 3"

Danke sehr.

MfG,
Ciek

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.