www.mikrocontroller.net

Forum: Compiler & IDEs Touchpanel und ADC am Mega64, was läuft hier schief?


Autor: SoLaLa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallöle,
ich hab hier ein echtes Problem und weiß nich weiter:
SIGNAL(SIG_ADC)
{  
  if (state==0)      
  {  ADMUX=VPIN|(1<<REFS0);
    DDRF&=~(_BV(VPIN));
    PORTF&=~(_BV(VPIN));    //VPIN als Eingang und pullup aus
    state=3;
    ADCSRA|=_BV(ADSC);
  }

  if (state==3)
  {  voltage=ADC;
    ADMUX=YP|(1<<REFS0);
    if (status==PRESSED)
      x=x-x/32+ADC;    //x=ADCspannungswert an XP===> Y-koordinate!!!
      
    DDRF&=~(_BV(YP));    //Y Eingang
    DDRF&=~(_BV(YN));
    PORTF|=_BV(YP);      //Y Pullup
    PORTF&=~(_BV(YN));
    PORTF&=~(_BV(XP));    //X auf Low
    PORTF&=~(_BV(XN));
    DDRF|=_BV(XP);      //X auf Ausgang
    DDRF|=_BV(XN);      
    state=4;
    ADCSRA|=_BV(ADSC);
  }

  else if (state==4)
  {  if (PINF&(1<<YP))    //Messen ob Verbindung X-Y
      status=OPEN;
    else
      status=PRESSED;
    PORTF&=~(_BV(YP));    //Y Pullup aus
    PORTF|=_BV(XP);      //X Spannung anlegen
    state=5;
    ADCSRA|=_BV(ADSC);
  }
  else if (state==5)    // Spannung an Y anlegen: an X die Spannung messen: Y Koordinate
  {  ADMUX=XP|(1<<REFS0);
    if (status==PRESSED)
      y=y-y/32+ADC;    //y=ADCspannungswert an YP===> X-koordinate!!!!
    DDRF&=~(_BV(XP));    //X Eingang
    DDRF&=~(_BV(XN));
    PORTF|=_BV(XP);      //X Pullup
    PORTF&=~(_BV(XN));
    PORTF&=~(_BV(YP));    //Y auf Low
    PORTF&=~(_BV(YN));
    DDRF|=_BV(YP);      //Y auf Ausgang
    DDRF|=_BV(YN);
    state=6;
    ADCSRA|=_BV(ADSC);
  }
  else if (state==6)
  {  if (PINF&(1<<XP))  //Messen ob Verbindung X-Y
      status=OPEN;
    else
      status=PRESSED;
    PORTF&=~(_BV(XP));    //X Pullup aus
    PORTF|=_BV(YP);      //Y Spannung anlegen
    state=0;
    ADCSRA|=_BV(ADSC);
  }
}
die obige Routine ist hier ja hinreichend bekannt...
ursprünglich wurden in (state=0) bis (state=3) die einzelnen Phasen der 
Touchpanelkoordinatenermittlung durchlaufen. Funktioniert :-)

ich hab nun versucht noch eine Spannungsmessung (Akkuzustand des Geräts) 
hinzuzufügen und dafür die ursprünglichen 4 Durchlaufphasen auf 
(state=3) bis (state=6) "nach hinten" verschoben und versuche in 
(state=0) die Vorbereitungen für die Spannungsmessung und das 
"Anschubsen" des ADC zu realisieren.
Der pin für die Spannungsmessung ist VPIN=PF7=7
Problem:
bei voltage=ADC wird die gemessene Spannung von PF3 zugewiesen und NICHT 
von PF7. Dabei funktioniert die allererste Messung des PF7 korrekt. Erst 
wenn die Touchscreenfunktionen zumindest 1 mal durchlaufen wurden wird 
danach nie wieder PF7 gemessen sondern immer nur PF3.
Wenn ich in (state=3) oder (state=4) den Folgedurchlauf "verbiege" und 
danach wieder mit (state=0) weitermache, dann wird korrekt PF7 gemessen 
(touchpanel wird dann natürlich nicht mehr vollständig ausgewertet)

Ich hab auch schon direkt vor "voltage=ADC;" den Inhalt von ADMUX in ne 
Variable gesichert und ausgeben lassen: 0b01000111
ist m.E. korrekt... der Spannungswert von voltage beinhaltet trotzdem 
den Wert an PF3 und nicht den von PF7...
Hat jemand ne Idee was da falsch läuft?

Autor: SoLaLa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ha...
wenn man das Problem erstmal niederschreibt, dann kommt man auch selber 
drauf...
es war das fehlende "else" :-(
aber wie da nun der Ablauf verkehrt läuft muß ich mir nochmal zu Gemüte 
führen

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SoLaLa wrote:

> es war das fehlende "else" :-(
> aber wie da nun der Ablauf verkehrt läuft muß ich mir nochmal zu Gemüte
> führen

Ohne das "else" wird State 3 direkt nach State 0 ausgeführt, noch im 
selben Interrupt.

Autor: SoLaLa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, Danke vielmals... für nen absoluten C-Neuling ist das doch alles 
recht klompiziert :-)
das ganze sieht jetzt so aus:
SIGNAL(SIG_ADC)
{  static unsigned char state;
  
  if (state==0)      
  {  if (status==PRESSED)    //Messung PF7 überspringen
      state=3;    //wenn touchscreen aktiv
    else
    {
    ADMUX=VPIN|(1<<REFS0);    
    DDRF&=~(_BV(VPIN));    
    PORTF&=~(_BV(VPIN));    //VPIN Eingang, pullup aus
    state=2;
    }
    ADCSRA|=_BV(ADSC);
  }

  else if (state==2)
  {
  voltage=ADC;
  status=OPEN;        //Falschzuweisung an x für nächsten
  state=3;        //Durchlauf unterdrücken
  ADCSRA|=_BV(ADSC);
  }

  else if (state==3)
  {  ADMUX=YP|(1<<REFS0);
    if (status==PRESSED)
      x=x-x/32+ADC;    
....
und funktioniert auch wunderprächtig :-)
Eine Frage hab ich noch zu der Korrektur x=x-x/32+ADC
hat das nen tieferen Sinn? Das Ergebnis sind ja recht "krumme" Werte 
(bei mir ca. 2500 bis 30500). Warum wird das so gemacht?

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.