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


von SoLaLa (Gast)


Lesenswert?

hallöle,
ich hab hier ein echtes Problem und weiß nich weiter:
1
SIGNAL(SIG_ADC)
2
{  
3
  if (state==0)      
4
  {  ADMUX=VPIN|(1<<REFS0);
5
    DDRF&=~(_BV(VPIN));
6
    PORTF&=~(_BV(VPIN));    //VPIN als Eingang und pullup aus
7
    state=3;
8
    ADCSRA|=_BV(ADSC);
9
  }
10
11
  if (state==3)
12
  {  voltage=ADC;
13
    ADMUX=YP|(1<<REFS0);
14
    if (status==PRESSED)
15
      x=x-x/32+ADC;    //x=ADCspannungswert an XP===> Y-koordinate!!!
16
      
17
    DDRF&=~(_BV(YP));    //Y Eingang
18
    DDRF&=~(_BV(YN));
19
    PORTF|=_BV(YP);      //Y Pullup
20
    PORTF&=~(_BV(YN));
21
    PORTF&=~(_BV(XP));    //X auf Low
22
    PORTF&=~(_BV(XN));
23
    DDRF|=_BV(XP);      //X auf Ausgang
24
    DDRF|=_BV(XN);      
25
    state=4;
26
    ADCSRA|=_BV(ADSC);
27
  }
28
29
  else if (state==4)
30
  {  if (PINF&(1<<YP))    //Messen ob Verbindung X-Y
31
      status=OPEN;
32
    else
33
      status=PRESSED;
34
    PORTF&=~(_BV(YP));    //Y Pullup aus
35
    PORTF|=_BV(XP);      //X Spannung anlegen
36
    state=5;
37
    ADCSRA|=_BV(ADSC);
38
  }
39
  else if (state==5)    // Spannung an Y anlegen: an X die Spannung messen: Y Koordinate
40
  {  ADMUX=XP|(1<<REFS0);
41
    if (status==PRESSED)
42
      y=y-y/32+ADC;    //y=ADCspannungswert an YP===> X-koordinate!!!!
43
    DDRF&=~(_BV(XP));    //X Eingang
44
    DDRF&=~(_BV(XN));
45
    PORTF|=_BV(XP);      //X Pullup
46
    PORTF&=~(_BV(XN));
47
    PORTF&=~(_BV(YP));    //Y auf Low
48
    PORTF&=~(_BV(YN));
49
    DDRF|=_BV(YP);      //Y auf Ausgang
50
    DDRF|=_BV(YN);
51
    state=6;
52
    ADCSRA|=_BV(ADSC);
53
  }
54
  else if (state==6)
55
  {  if (PINF&(1<<XP))  //Messen ob Verbindung X-Y
56
      status=OPEN;
57
    else
58
      status=PRESSED;
59
    PORTF&=~(_BV(XP));    //X Pullup aus
60
    PORTF|=_BV(YP);      //Y Spannung anlegen
61
    state=0;
62
    ADCSRA|=_BV(ADSC);
63
  }
64
}
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?

von SoLaLa (Gast)


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

von Stefan E. (sternst)


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.

von SoLaLa (Gast)


Lesenswert?

ja, Danke vielmals... für nen absoluten C-Neuling ist das doch alles 
recht klompiziert :-)
das ganze sieht jetzt so aus:
1
SIGNAL(SIG_ADC)
2
{  static unsigned char state;
3
  
4
  if (state==0)      
5
  {  if (status==PRESSED)    //Messung PF7 überspringen
6
      state=3;    //wenn touchscreen aktiv
7
    else
8
    {
9
    ADMUX=VPIN|(1<<REFS0);    
10
    DDRF&=~(_BV(VPIN));    
11
    PORTF&=~(_BV(VPIN));    //VPIN Eingang, pullup aus
12
    state=2;
13
    }
14
    ADCSRA|=_BV(ADSC);
15
  }
16
17
  else if (state==2)
18
  {
19
  voltage=ADC;
20
  status=OPEN;        //Falschzuweisung an x für nächsten
21
  state=3;        //Durchlauf unterdrücken
22
  ADCSRA|=_BV(ADSC);
23
  }
24
25
  else if (state==3)
26
  {  ADMUX=YP|(1<<REFS0);
27
    if (status==PRESSED)
28
      x=x-x/32+ADC;    
29
....
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?

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.