1 | // ARM 32-bit CORTEX-M3 - STM32F103RB8
|
2 | // EVA-Borad "STM32-P103" / Olimex
|
3 | // Quarz: 8MHz, PLL: 72MHz
|
4 | // Speicher: 128KB FLASH, 20KB SRAM
|
5 | // TOUCH (analog, 4 Anschlüsse)
|
6 | //***********************************************************************************************
|
7 |
|
8 | //***********************************************************************************************
|
9 | // TOUCH Initialisierung
|
10 | // AD-Wandler 12-Bit, 1-Kanal-Mode
|
11 | //***********************************************************************************************
|
12 | void init_touch (void) {
|
13 | ADC_InitTypeDef ADC_InitStructure; // ADC Struktur
|
14 | ADC_DeInit(ADC1); // ADC auf Init-Werte rücksetzen
|
15 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // ADC Takt freigeben
|
16 |
|
17 | ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // Arbeitsweise unabhängig
|
18 | ADC_InitStructure.ADC_ScanConvMode = DISABLE; // kein Scan-Mode (nur 1 Kanal verwendet)
|
19 | ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // kontinuierliche Abtastung
|
20 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // keine externe Triggerung
|
21 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // Datenformat der Wandlung (rechtsbündig 12-Bit)
|
22 | ADC_InitStructure.ADC_NbrOfChannel = 1; // 1 Kanal
|
23 | ADC_Init(ADC1, &ADC_InitStructure); // ADC initialisieren
|
24 |
|
25 | ADC_Cmd(ADC1, ENABLE); // ADC freigeben
|
26 |
|
27 | ADC_ResetCalibration(ADC1); // ADC Kalibrierungswerte rücksetzen
|
28 | while(ADC_GetResetCalibrationStatus(ADC1)); // Ende abwarten
|
29 |
|
30 | ADC_StartCalibration(ADC1); // ADC Kalibrierung
|
31 | while(ADC_GetCalibrationStatus(ADC1)); // Ende abwarten
|
32 |
|
33 | ADC_SoftwareStartConvCmd(ADC1, ENABLE); // ADC Abtastung starten
|
34 |
|
35 | // Touch Variablen rücksetzen
|
36 | touch.x = 0;
|
37 | touch.y = 0;
|
38 |
|
39 | // Später im FLASH
|
40 | touch.x_offset = TOUCH_OFFSET_X_DEFALUT;
|
41 | touch.x_gain = TOUCH_GAIN_X_DEFALUT;
|
42 | touch.y_offset = TOUCH_OFFSET_Y_DEFALUT;
|
43 | touch.y_gain = TOUCH_GAIN_Y_DEFALUT;
|
44 |
|
45 | touch.taste = 0;
|
46 | }
|
47 |
|
48 | //***********************************************************************************************
|
49 | // TOUCH Test auf Touch-Druck (Position wird nicht ermittel!)
|
50 | // Rückgabe: 1: Touch gedrückt
|
51 | // 0: Touch nicht gedrückt
|
52 | //***********************************************************************************************
|
53 | uint8_t touch_pressed (void) {
|
54 | GPIO_InitTypeDef GPIO_InitStructure;
|
55 |
|
56 | GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_2); // Ausgänge
|
57 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Pin-Mode
|
58 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung
|
59 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung
|
60 |
|
61 | GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_1 | GPIO_Pin_3); // Eingänge
|
62 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // Pin-Mode (Pull-Up)
|
63 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung
|
64 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung
|
65 |
|
66 | TOUCH_PIN1_L;
|
67 | TOUCH_PIN3_L;
|
68 | delay_us(1000); // ca. 80us
|
69 |
|
70 | return (!TOUCH_PIN2);
|
71 | }
|
72 |
|
73 | //***********************************************************************************************
|
74 | // TOUCH X-Wert ermitteln
|
75 | // Rückgabe: ADC-Wert der X-Koordinate (0000 - 0FFF)
|
76 | //***********************************************************************************************
|
77 | uint16_t touch_x (void) {
|
78 | GPIO_InitTypeDef GPIO_InitStructure;
|
79 |
|
80 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // Ausgang
|
81 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // Pin-Mode
|
82 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung
|
83 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung
|
84 |
|
85 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // Ausgang
|
86 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Pin-Mode
|
87 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung
|
88 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung
|
89 |
|
90 | GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_1 | GPIO_Pin_3); // analoge Eingänge
|
91 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // Pin Mode
|
92 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung
|
93 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung
|
94 |
|
95 | TOUCH_PIN1_L; // Spannungsteiler für X
|
96 | TOUCH_PIN3_H;
|
97 |
|
98 | // 1Cycles5, 7Cycles5, 13Cycles5, 28Cycles5, 41Cycles5, 55Cycles5, 71Cycles5, 239Cycles5
|
99 | ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_28Cycles5); // Kanalauswahl 11=PC1
|
100 | delay_us(1000); // ca. 80us Pause
|
101 |
|
102 | while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
|
103 | return ADC_GetConversionValue(ADC1); // ADC-Daten (int) abholen, gleichzeitig wird EOC rückgesetzt
|
104 | }
|
105 |
|
106 | //***********************************************************************************************
|
107 | // TOUCH Y-Wert ermitteln
|
108 | // Rückgabe: ADC-Wert der Y-Koordinate (0000 - 0FFF)
|
109 | //***********************************************************************************************
|
110 | uint16_t touch_y (void) {
|
111 | GPIO_InitTypeDef GPIO_InitStructure;
|
112 |
|
113 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // Ausgang
|
114 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Pin-Mode
|
115 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung
|
116 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung
|
117 |
|
118 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // Ausgang
|
119 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // Pin-Mode
|
120 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung
|
121 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung
|
122 |
|
123 | GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_2); // analoge Eingänge
|
124 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // Pin Mode
|
125 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung
|
126 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung
|
127 |
|
128 | TOUCH_PIN2_H; // Spannungsteiler für Y
|
129 | TOUCH_PIN4_L;
|
130 |
|
131 | ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_28Cycles5); // Kanalauswahl 12=PC2
|
132 | delay_us(1000); // ca. 80us Pause
|
133 |
|
134 | while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
|
135 | return ADC_GetConversionValue(ADC1); // ADC-Daten (int) abholen, gleichzeitig wird EOC rückgesetzt
|
136 | }
|
137 |
|
138 | //***********************************************************************************************
|
139 | // TOUCH Koordinaten und Tastencode ermitteln
|
140 | // Rückgabe 1: Touch gedrückt und Koordinate gültig
|
141 | // 0: keine Touchaktivität
|
142 | //***********************************************************************************************
|
143 | uint8_t get_touch (void) {
|
144 |
|
145 | if (touch_pressed()) {
|
146 | // Touchaktivität
|
147 |
|
148 | touch.x = ((320 * touch_x() / 4096) - touch.x_offset) * touch.x_gain / 100;
|
149 | touch.y = ((240 * touch_y() / 4096) - touch.y_offset) * touch.y_gain / 100;
|
150 |
|
151 | return 1;
|
152 | } else {
|
153 | // keine Touchaktivität
|
154 | touch.x = 0;
|
155 | touch.y = 0;
|
156 | touch.taste = 0;
|
157 | return 0;
|
158 | }
|
159 | }
|
160 |
|
161 | ....
|
162 |
|
163 | MAIN
|
164 |
|
165 |
|
166 | #define TOUCH_PIN1_H GPIO_SetBits(GPIOC,GPIO_Pin_0)
|
167 | #define TOUCH_PIN1_L GPIO_ResetBits(GPIOC,GPIO_Pin_0)
|
168 |
|
169 | #define TOUCH_PIN2_H GPIO_SetBits(GPIOC,GPIO_Pin_1)
|
170 | #define TOUCH_PIN2_L GPIO_ResetBits(GPIOC,GPIO_Pin_1)
|
171 |
|
172 | #define TOUCH_PIN3_H GPIO_SetBits(GPIOC,GPIO_Pin_2)
|
173 | #define TOUCH_PIN3_L GPIO_ResetBits(GPIOC,GPIO_Pin_2)
|
174 |
|
175 | #define TOUCH_PIN4_H GPIO_SetBits(GPIOC,GPIO_Pin_3)
|
176 | #define TOUCH_PIN4_L GPIO_ResetBits(GPIOC,GPIO_Pin_3)
|
177 |
|
178 | #define TOUCH_PIN1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)
|
179 | #define TOUCH_PIN2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)
|
180 | #define TOUCH_PIN3 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)
|
181 | #define TOUCH_PIN4 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)
|
182 |
|
183 | #define TOUCH_KAL_X_DEFAULT 3800
|
184 | #define TOUCH_KAL_Y_DEFAULT 3700
|
185 |
|
186 | #define TOUCH_OFFSET_X_DEFALUT 30 /* Offsetwert X in Pixel */
|
187 | #define TOUCH_OFFSET_Y_DEFALUT 30 /* Offsetwert Y in Pixel */
|
188 | #define TOUCH_GAIN_X_DEFALUT 125 /* Verstärkung X (Faktor 100) 125 = 1.25 */
|
189 | #define TOUCH_GAIN_Y_DEFALUT 133 /* Verstärkung Y (Faktor 100) */
|
190 |
|
191 | // Touch-Werte
|
192 | struct touch_struc {
|
193 | volatile uint16_t x; // X-Koordinate (0...319)
|
194 | volatile uint16_t y; // Y-Koordinate (0...239)
|
195 | volatile uint8_t x_offset; // Kalibrierung in X Offset
|
196 | volatile uint8_t y_offset; // Kalibrierung in Y Offset
|
197 | volatile uint8_t x_gain; // Kalibrierung in X Verstärkung
|
198 | volatile uint8_t y_gain; // Kalibrierung in Y Verstärkung
|
199 | volatile uint8_t taste; // Tastencode
|
200 | };
|
201 |
|
202 | struct touch_struc touch; // Touch Variablen
|
203 |
|
204 | ....
|
205 |
|
206 |
|
207 | // Abfrage
|
208 | if (get_touch()) {
|
209 | touch.x touch.y; enthalten die Koordinaten des Druckpunktes
|
210 | }
|