Hallo, da ich nun erfolgreich einige dinge ans laufen bekommen habe unter anderem auch ein GLCD wollte ich dieses nun mit einem Touchscreen versehen. Ansteuerung laut datenblatt ausgeführt. An 4 ADC port angeschlossen und in einer while schleife die abfrage ausgeführt. Laut Datenblatt soll ich, MCU: Atmega8 Belegung: Pin1 -> PC1, Pin2 -> PC2, Pin3 -> PC3, Pin4 -> PC4 X-Coordinate Pin1 (X+) auf VCC schalten, Pin2 (X-) auf GND schalten. An Pin4 soll ich dann die Messung vornehmen, Pin3 bleibt unbenutzt. Y-Coordinate Pin3 (Y+) auf VCC schalten, Pin4 (Y-) auf GND schalten. An Pin2 soll ich dann die Messung vornehmen, Pin1 bleibt unbenutzt. Nun läuft das ganze in der while schleife, für X, PC1 auf Ausgang dann auf High PC2 auf Ausgang dann auf Low PC4 auf Eingang und ADC einlesen für Y, PC3 auf Ausgang dann auf High PC4 auf Ausgang dann auf Low PC2 auf Eingang und ADC einlesen Die Werte stehen dann in den variablen xcor und ycor. Solange ich das Touchscreen nicht berühre werde mir auf dem Display die Werte für X und Y mit 1023 ausgegeben, klar, kein widerstand als 5V somit höchster ADC wert. Berühre ich das Touchscreen dann ändern sich die Werte nicht oder "springen", dann werden für einige Sekunden jeweils verschiedene Werte angezeigt also z.b. so: 1023, 6483, 4830, 7473, 0480, 1023. Dann stehen die werte wieder konstant auf 1023 bis ich das Touchscrren wieder berühre, dann werden wieder irgendwelche Werte angezeigt und danach stehen sie wieder auf 1023. Meines wissens nach ist der höchste ADC wert doch 1023, demnach kann ich mir das nicht erklären, und auch das "springen" der Werte, selbst wenn ich ganz ruhig einen Kugelschreiber oder ähnliches benutze springen die Werte. Die Werte gebe ich mittels itoa(xcor, Buffer, 10); und dann lcd_puts(small_font, Buffer); mit der mylcd libraray auf dem Display aus. Genau so auch mit der Y Coordinate. Ich hoffe mir kann da jemand helfen. Danke schonmal.
Klappt ohne Code bestimmt gut. Löscht du das Display bevor du schreibst oder überschreibst du nur?
Stellst du den jeweils ungenutzten Pin auch auf hochohmig? Bei deiner Beschreibung klingt es so, als ob der jeweils ungenutzte Pin auf high bleibt, was natürlich nicht funktionieren kann. Er muss auch als Eingang konfiguriert werden, auch wenn du ihn nicht auswertest.
Hallo, danke erstmal für die antworten. Also vor der neuen ausgabe auf dem Display überschreibe ich die Zahl mit leerzeichen und schreibe dann wieder neu. Also den jeweils nicht genutzten Pin lasse ich so wie er ist/war. Also muss ich den auch als Eingang und dann auf High setzten, richtig?
ok, also schalte ich für x dann die x ports auf ausgang und dann x+ auf high, x- auf low, die ports y- und y+ auf eingang und dann messe ich am y- mittels adc. für y das gleiche nur halt mit den entsprechenden ports.
Tobias N. schrieb: > ok, > > also schalte ich für x dann die x ports auf ausgang und dann x+ auf > high, x- auf low, die ports y- und y+ auf eingang und dann messe ich am > y- mittels adc. für y das gleiche nur halt mit den entsprechenden ports. genau, und an den Eingangsports auf keinen Fall den Pullup aktivieren. Du musst allerdings nicht dauernd messen, sondern nur wenn auch eine Berührung stattfindet. Dazu legst du die eine Achse auf GND (z.B. X+ & X-) und schaltest die andere auf Eingang, wobei du an einem Eingang auch den Pullup einschaltest. Dort kannst du nun abfragen ob eine Berührung stattfindet. Im Ruhezustand hast du durch den Pullup immer H-Pegel, sobald der Touch berührt wird bekommst du L-Pegel und kannst die Messung starten. Und du musst für ein brauchres Ergebnis immer mehrere Messungen machen und den Durchschnitt der Messwerte nehmen. Sascha
Ich habe jetzt so einiges Probiert aber alles ohne erfolg, hier mal der letzte getestete Code.
1 | #include <avr/io.h> |
2 | #include <util/delay.h> |
3 | #include <stdio.h> |
4 | #include <avr/interrupt.h> |
5 | |
6 | #include "ow.h" |
7 | #include "mylcd.h" |
8 | #include "small_font.h" |
9 | #include "mega.h" |
10 | #include "image_load.h" |
11 | |
12 | #define XPLUS PC3 // X+ Port
|
13 | #define XMINUS PC1 // X- Port
|
14 | #define YPLUS PC0 // Y+ Port
|
15 | #define YMINUS PC2 // Y- Port
|
16 | |
17 | |
18 | /* ADC initialisieren */
|
19 | void ADC_Init(void) { |
20 | |
21 | uint16_t result; |
22 | |
23 | // interne Referenzspannung als Refernz für den ADC wählen:
|
24 | ADMUX = (1<<REFS1) | (1<<REFS0); |
25 | |
26 | // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
|
27 | // schon auf 0, also single conversion
|
28 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler |
29 | ADCSRA |= (1<<ADEN); // ADC aktivieren |
30 | |
31 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
32 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
|
33 | |
34 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung |
35 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten |
36 | }
|
37 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
38 | Wandlung nicht übernommen. */
|
39 | result = ADCW; |
40 | }
|
41 | |
42 | /* ADC Einzelmessung */
|
43 | uint16_t ADC_Read( uint8_t channel ) |
44 | {
|
45 | // Kanal waehlen, ohne andere Bits zu beeinflußen
|
46 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); |
47 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" |
48 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten |
49 | }
|
50 | return ADCW; // ADC auslesen und zurückgeben |
51 | }
|
52 | |
53 | |
54 | int main (void) |
55 | {
|
56 | |
57 | char Buffer[20]; |
58 | |
59 | int xcor = 0; |
60 | |
61 | //init lcd
|
62 | lcd_init(); |
63 | lcd_clear(); |
64 | |
65 | lcd_draw_fullscreen_bmp(img); |
66 | |
67 | ADC_Init(); |
68 | |
69 | // Ausgänge
|
70 | DDRC |= (1<<YPLUS); |
71 | DDRC |= (1<<YMINUS); |
72 | |
73 | //Eingänge
|
74 | DDRC &= ~(1<<XPLUS); |
75 | DDRC &= ~(1<<XMINUS); |
76 | |
77 | while(1) |
78 | {
|
79 | // X Coordiante
|
80 | |
81 | |
82 | |
83 | // High / Low
|
84 | PORTC |= (1<<YPLUS); |
85 | PORTC &= ~(1<<YMINUS); |
86 | |
87 | _delay_ms(200); |
88 | xcor = ADC_Read(XPLUS); |
89 | |
90 | itoa( xcor, Buffer, 10 ); |
91 | |
92 | lcd_set_cursor(80,LINE3); |
93 | lcd_puts(small_font, " "); |
94 | lcd_puts(small_font, Buffer); |
95 | _delay_ms(10); |
96 | |
97 | |
98 | // X Coordiate ende
|
99 | }
|
100 | }
|
Also ich würde mir das nicht so umständlich machen. Warum alles in den armen kleinen uC reinhacken? Nimm z.B. einen ADS7846. Der macht das alles und mit den sprichst du über SPI und fertig. Außerdem hat der noch ein paar nützliche Zusatzfunktionen. Und der kann deinen uC per IRQ-Leitung aufwecken wenn am Touch was passiert.
das ist nur mein test µc, hinterher wird dann dann an einem mega32 betrieben, also nur das display und das touch, der soll als "grafikchip" dienen, der komuniziert dann mittels spi, kriegt halt noch eine sd karte und ein paar ds1820 aber mehr soll der mega32 dann nicht machen, also display, touch, sdkarte und ds1820, der rest passiert dann mittels spi. ich will halt das ganze mehr verstehen etc. pp. demnach muss ich mich da wohl durch kämpfen ;) lerning by doing :)
Hi Such mal bei ATMEL nach: AVR341: Four and five-wire Touch screen Controller using tinyAVR and megaAVR devices Da gibte es auch Software. MfG Spess
@Tobias, // interne Referenzspannung als Refernz für den ADC wählen: ADMUX = (1<<REFS1) | (1<<REFS0); Damit kann es ja überhaupt nicht gehen!! Dein Touch wird ja schießlich über die Portpins, also Vcc mit Spannung versorgt, also muss auch die Referenzspannung des ADC Vcc sein! Sascha
naja, also bei ADMUX = (0<<REFS1) | (1<<REFS0); macht er weiter wie bisher gibt mir einfach immer irgendwelche zahlen aus, pendelt sich aber nicht einmal bei 1023 ein. bei ADMUX = (0<<REFS1) | (0<<REFS0); steht er konstant auf 1023 und egal ob ich was drücke oder nicht der wert verändert sich nicht. also irgendwas ist doch hier falsch :(
so, es läuft, also als ich mir dann mal dachte ich lese Y auch noch mit aus, voila, die werte werden angezeigt. alles tutti, aber schon stellt sich mir die nächste frage. ich versuchte also mal "einen" bereich also taste zu nutzen, also ganz viele ifs und wenn es stimmt zeige mir was an, beim wieder drauf drücke mache die anzeige wieder weg. das klappt auch alles soweit aber sehr "langsam" also "schnelles" tippen wird nicht erkannt. "menu" anzeigen geht schneller als "menu" nicht mehr anzeigen. wenn ich halte dann zeigt der mir das etwa im sekunden wechsel an. also text da, text weg, text da, text weg muss/kann man die touch eingaben auch "entprellen" halten ein anderer zustand als tippen? wie kann man einstellen "wie schnell" er reagieren soll, denn ein kurzes tippen wie z.b. beim handy endet mit garkeiner reaktion. es läuft jetzt mit der internen referenzspannung vcc, mit avcc erhalte ich konstand 1023 und keine reaktionen aufs tippen. beim messen mittels multimeter funktioniert aber alles nur er misst halt nicht. danke euch.
100nF zwischen AVCC und AGND und die dann mit 5V vom 7805 beschaltet. Und dann nochmal einen 100nF zwischen AREF und AGND. Die aber dann nicht beschaltet also nur den 100nF dazwischen.
nunja, also wenn es mir vorteile bringt dann natürlich. wenn es mit AVCC gleichgestellt ist dann brauche ich es ja nicht zwingend nutzen, oder?
Tobias N. schrieb: > nunja, also wenn es mir vorteile bringt dann natürlich. wenn es mit AVCC > gleichgestellt ist dann brauche ich es ja nicht zwingend nutzen, oder? Wenn du an Aref eh nur die 5 Volt anschließen würdest ist es besser AVCC zu benutzen. Geh aber eigentlich beides. siehe: http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC#Referenzspannung_AREF
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.