Forum: Mikrocontroller und Digitale Elektronik Resistiver Touchscreen an ADS7843


von Dennis H. (somebuddy)


Lesenswert?

Guten "Abend",

Bekomme meinen Touchscreen an einem ADS7843 nicht so recht zum laufen.

MPU: STM32F103
SPI2

ansprechen funktioniert soweit. Lediglich an der Kalibrierung scheint es 
zu scheitern.

Anbei ein Bild des Touchscreens. Evtl. könnt ihr Anhand des Bildes 
erkennen ob ich die TS Kontakte korrekt an den ADS7843 angeschlossen 
habe.

http://www.pic-upload.de/view-18330990/2013-02-28-23.36.51.jpg.html

von Links nach Rechts :   X-, Y-, X+, Y+

Somit könnte ich wenigstens einen Anschlussfehler ausschließen.

Vielen Dank !

Grüße
Dennis

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

Anschluss ist ok. Was kommen denn für Messwerte raus?

Sascha

von Dennis H. (somebuddy)


Lesenswert?

Okay. Zunächst mal vielen Dank !
Also liegt es doch an der Umsetzung.

Ich bin leider noch nicht dazu gekommen den Logic dran zu hängen und zu 
überprüfen was wirklich über die Leitung geht.

Ich habe mir folgende Lib angeschaut :

http://mikrocontroller.bplaced.net/wordpress/?page_id=564

Dort wurde SPI allerdings via Software über die GPIOS nachgebildet. Da 
der ADS auf meinem Board an SPI2 ( Hardware ) angeschlossen ist, habe 
ich "versucht" die Software implementierung auf Hardware zu übersetzen.

Werde sie mal posten, vielleicht findet jemand auf den ersten Blick 
schon einen Fehler:

Original :
1
//--------------------------------------------------------------
2
// interne Funktion
3
// Sendet einen 24bit Frame an den ADS7843
4
// und empfangt einen 12Bit Datenwert
5
//--------------------------------------------------------------
6
uint16_t P_Touch_Frame(uint32_t frame) {
7
  uint16_t n;
8
  uint32_t maske_out=0x800000; // 24Bit Maske fuer Data-Out
9
  uint16_t maske_in=0x800;     // 12Bit Maske fuer Data-In
10
  uint16_t data_in=0x00;
11
12
  // kleine Pause
13
  P_Touch_Delay(UB_TOUCH_MESS_DELAY);
14
15
  // Chip-Select Lo
16
  P_Touch_CS(Bit_RESET);
17
  P_Touch_Delay(UB_TOUCH_CLK_DELAY);
18
  // einen Frame mit 24 Bit ausgeben
19
  for(n=0;n<24;n++) {
20
    // Data vor der High-Flanke anlegen
21
    if((frame & maske_out)==0) {
22
      P_Touch_DOUT(Bit_RESET);
23
    }
24
    else {
25
      P_Touch_DOUT(Bit_SET);
26
    }
27
    // Clock-High Flanke
28
    P_Touch_CLK(Bit_SET);
29
    // Daten nach der Hi-Flanke einlesen
30
    if((n>=9) && (n<=20)) {
31
      if(P_Touch_DIN()!=Bit_RESET) {
32
        data_in|=maske_in;
33
      }
34
      // Maske weiterschalten
35
      maske_in = (maske_in>>1);
36
    }
37
    P_Touch_Delay(UB_TOUCH_CLK_DELAY);
38
    // Clock-Lo Flanke
39
    P_Touch_CLK(Bit_RESET);
40
    P_Touch_Delay(UB_TOUCH_CLK_DELAY);
41
    // Maske weiterschalten
42
    maske_out = (maske_out>>1);
43
  }
44
  // Chip-Select Hi
45
  P_Touch_Delay(UB_TOUCH_CLK_DELAY);
46
  P_Touch_CS(Bit_SET);
47
  P_Touch_Delay(UB_TOUCH_CLK_DELAY);
48
49
  return(data_in);
50
}

Meine Umsetzung:
1
//--------------------------------------------------------------
2
// interne Funktion
3
// Sendet einen 24bit Frame an den ADS7843
4
// und empfangt einen 12Bit Datenwert
5
//--------------------------------------------------------------
6
uint16_t P_Touch_Frame(uint8_t frame) {
7
8
  //P_Touch_Delay(UB_TOUCH_MESS_DELAY);
9
10
  uint16_t temp =0;
11
  uint16_t data_in=touch_Get_Status(frame);
12
  temp = (data_in>>4);
13
  //temp = temp & 0x0FFF;
14
  char str1[20];
15
  uint16_to_hex(str1,temp);
16
  //GLCD_Zeichenkette(3,1,str1);
17
18
19
  return temp;
20
}
21
22
23
uint8_t touch_Write_Byte(uint8_t byte)
24
{
25
26
  //P_Touch_Delay(UB_TOUCH_CLK_DELAY);
27
  /* nSS signal activation - low */
28
  GPIO_ResetBits(GPIOB, GPIO_Pin_13);
29
30
  /* SPI byte send */
31
    SPI_I2S_SendData(SPI2, byte);
32
  /* Wait for SPIx Busy flag */
33
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
34
  /* nSS signal deactivation - high */
35
  GPIO_SetBits(GPIOB, GPIO_Pin_13);
36
  return (uint8_t)(SPI_I2S_ReceiveData(SPI2));
37
}
38
39
40
uint16_t touch_Get_Status(uint8_t byte)
41
{
42
  uint16_t temp = 0;
43
  uint16_t rx = 0;
44
45
46
  
47
  touch_Write_Byte(byte);
48
  P_Touch_Delay(UB_TOUCH_MESS_DELAY);
49
  /* Send zero byte / receive MSByte  */
50
  temp = touch_Write_Byte((uint8_t)(0x00));
51
  temp = temp << 8;
52
  rx |= temp;
53
  /* Send zero byte / receive LSByte  */
54
  temp = touch_Write_Byte((uint8_t)(0x00));
55
  rx |= temp;
56
57
58
  return rx;
59
}


Die Funktion zum auslesen habe ich unberührt belassen:
1
//--------------------------------------------------------------
2
// Kommandos an den Touch-Controller
3
// Länge = 24Bit
4
// MSB = CMD-Byte
5
//--------------------------------------------------------------
6
#define  UB_TOUCH_CMD_CH3  0x90   // CH=X+, Mode=12bit, DiffEnded, PwrDown
7
#define  UB_TOUCH_CMD_CH4  0xD0  // CH=Y+, Mode=12bit, DiffEnded, PwrDown
8
9
10
//--------------------------------------------------------------
11
// interne Funktion
12
// Einlesen der Roh-Touch-Daten
13
//--------------------------------------------------------------
14
void P_Touch_ReadRaw(void)
15
{
16
  uint16_t n,wert;
17
  uint32_t xp=0,yp=0;
18
19
  // Mittelwert aus 4 Messungen bilden
20
  for(n=0;n<4;n++) {
21
    // CH-4 (X) einlesen
22
  wert=P_Touch_Frame(UB_TOUCH_CMD_CH4);
23
  xp+=wert;
24
  // CH-3 (Y) einlesen
25
  wert=P_Touch_Frame(UB_TOUCH_CMD_CH3);
26
  yp+=wert;
27
  }
28
  Touch_Kal.raw.xp=(xp>>2);
29
  Touch_Kal.raw.yp=(yp>>2);
30
}

Vielleicht sind auch 0x90 und 0xD0  für meine Anwendung / Anschluss 
falsch.

Vielen Dank !

von Dennis H. (somebuddy)


Lesenswert?

Eine Funktion habe ich noch vergessen:
1
//--------------------------------------------------------------
2
// Auslesen vom Touch und fuellen der Struktur "Touch_Data"
3
//    Touch_Data.status => [TOUCH_RELEASED, TOUCH_PRESSED]
4
//    Touch_Data.pos.xp => Xpos der Koordinate
5
//    Touch_Data.pos.yp => YPos der Koordinate
6
//
7
// -> Falls Touch nicht betaetigt,
8
//    sind die Koordinatenwerte nicht gueltig
9
//--------------------------------------------------------------
10
void UB_Touch_Read(void)
11
{
12
  // Pen einlesen
13
  if(P_Touch_PEN()==Bit_RESET) {
14
    Touch_Data.status=TOUCH_PRESSED;
15
    // Touch-Daten einlesen
16
    P_Touch_ReadRaw();
17
    // Touch-Daten in LCD-Koordinaten umrechnen
18
    P_Touch_CalcPos();
19
  }
20
  else {
21
    Touch_Data.status=TOUCH_RELEASED;
22
    // Touch Daten muessen nicht gelesen werden
23
  }
24
}

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

dein Problem ist, das du in "touch_Write_Byte" CS nach jedem Byte wieder 
auf High schaltest. CS muss aber für die Übertragung aller 24 Bits auf 
Low bleiben. Steuere das CS-Signal also besser in "P_Touch_Frame"!

Sascha

von Dennis H. (somebuddy)


Angehängte Dateien:

Lesenswert?

Okay.. Vielen Dank.
Diesen Fehler habe ich vor 20 Minuten auch gefunden. Zusätzlich war auch 
noch der CS Pin Falsch -.-

Die neue get_status sieht nun so aus:
1
uint16_t touch_Get_Status(uint8_t byte)
2
{
3
  uint16_t temp = 0;
4
  uint16_t rx = 0;
5
  uint16_t temp2 =0;
6
7
8
  GPIO_ResetBits(GPIOA, GPIO_Pin_11);
9
  SPI_I2S_SendData(SPI2, byte);
10
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
11
  temp2 = (uint8_t)(SPI_I2S_ReceiveData(SPI2));
12
13
14
15
16
17
  SPI_I2S_SendData(SPI2, 0x00);
18
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
19
    temp = (uint8_t)(SPI_I2S_ReceiveData(SPI2));
20
21
22
23
24
  temp = temp << 8;
25
  rx |= temp;
26
27
  SPI_I2S_SendData(SPI2, 0x00);
28
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
29
    temp = (uint8_t)(SPI_I2S_ReceiveData(SPI2));
30
31
    char str1[20];
32
             uint16_to_hex(str1,temp);
33
                 GLCD_Zeichenkette(3,1,str1);
34
35
36
  rx |= temp;
37
38
39
  GPIO_SetBits(GPIOA, GPIO_Pin_11);
40
41
42
43
  return rx;
44
}

mit dem Logic komme ich auc folgende "Bilder":

"Anhang"


Interessant wären vielleicht auch noch die korrekten Einstellung für die 
Hardware SPI:

Unsicher bin ich bei den folgenden Optionen:

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;

von Dennis H. (somebuddy)


Lesenswert?

Okay.. CS in Touchframe behandeln habe ich "nun" auch.
1
uint16_t P_Touch_Frame(uint8_t frame) {
2
3
  //P_Touch_Delay(UB_TOUCH_MESS_DELAY);
4
  GPIO_ResetBits(GPIOA, GPIO_Pin_11);
5
  uint16_t temp =0;
6
  uint16_t data_in=touch_Get_Status(frame);
7
  temp = (data_in>>4);
8
  //temp = temp & 0x0FFF;
9
10
  GPIO_SetBits(GPIOA, GPIO_Pin_11);
11
12
  return temp;
13
}

In get_data entsprechend entfernt.

Der ADS gibt mir scheinbar nur ein "ECHO" zurück.. ich sende ihm ein D0 
und an DOUT gibt er ein D0 zurück.  selbiges bei 00 und 90. Bin ich 
eventuell zu "schnell" ?

von Dennis H. (somebuddy)


Lesenswert?

Okay.. nun läuft es -.-
Das Problem war "scheinbar" dass der CS pin von dem Schrittmotortreiber 
am gleichen SPI nicht HIGH war zum Zeitpunkt der Touch Abfrage. Sehr 
blöder Fehler.. ich hätte wetten können das überprüft zu haben.

Dennoch waren die Funktionen zu Beginn natürlich falsch !

Vielen Dank !

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.