1、 触摸屏驱动
触摸屏驱动的原理非常简单,从硬件得到坐标数据,数据加工(适配屏幕分辨率,偏移量调整),最后调用rtgui_server_post_event()函数向GUI服务端发送坐标信息。
奋斗板V3,使用的AD芯片是XPT2046,是RTGUI bsp/stm32f10x下的ADS7846芯片的下一代产品,功能及硬件连接上完全兼容。因此,我们只要确认与MCU的管脚连接,在代码上正确配置即可。
注:奋斗板的源代码是以模数转换(ADS)方式直接读取的,而RTGUI里,则是以SPI方式读取,并采用中断(EXT INT)方式。另外,SPI1上接了三个设备,分别是触摸屏,10M LAN, 2M Flash,使用了三根MCU管脚作为片选(CS)。RTT中,使用的CS脚是PC4,IRQ是PB1,而奋斗板的CS是PB7,IRQ是PB6。
驱动代码对比:
touch.c |
touch.rtt.c |
||
1 |
#include <stdbool.h> |
1 |
#include <stdbool.h> |
2 |
#include "stm32f10x.h" |
2 |
#include "stm32f10x.h" |
3 |
|
3 |
|
4 |
#include "board.h" |
4 |
#include "board.h" |
5 |
#include "touch.h" |
5 |
#include "touch.h" |
6 |
|
6 |
|
7 |
#include <rtthread.h> |
7 |
#include <rtthread.h> |
8 |
#include <rtgui/event.h> |
8 |
#include <rtgui/event.h> |
9 |
#include <rtgui/kbddef.h> |
9 |
#include <rtgui/kbddef.h> |
10 |
#include <rtgui/rtgui_server.h> |
10 |
#include <rtgui/rtgui_server.h> |
11 |
#include <rtgui/rtgui_system.h> |
11 |
#include <rtgui/rtgui_system.h> |
12 |
|
12 |
|
13 |
/* |
13 |
/* |
14 |
MISO PA6 |
14 |
MISO PA6 |
15 |
MOSI PA7 |
15 |
MOSI PA7 |
16 |
CLK PA5 |
16 |
CLK PA5 |
17 |
CS PB7 |
17 |
CS PC4 |
18 |
*/ |
18 |
*/ |
19 |
|
19 |
|
20 |
#define CS_0() GPIO_ResetBits(GPIOB,GPIO_Pin_7) |
20 |
#define CS_0() GPIO_ResetBits(GPIOC,GPIO_Pin_4) |
21 |
#define CS_1() GPIO_SetBits(GPIOB,GPIO_Pin_7) |
21 |
#define CS_1() GPIO_SetBits(GPIOC,GPIO_Pin_4) |
22 |
|
22 |
|
23 |
/* |
23 |
/* |
24 |
7 6 - 4 3 2 1-0 |
24 |
7 6 - 4 3 2 1-0 |
25 |
s A2-A0 MODE SER/DFR PD1-PD0 |
25 |
s A2-A0 MODE SER/DFR PD1-PD0 |
26 |
*/ |
26 |
*/ |
27 |
#define TOUCH_MSR_Y 0x90 //读X轴坐标指令 addr:1 |
27 |
#define TOUCH_MSR_Y 0x90 //读X轴坐标指令 addr:1 |
28 |
#define TOUCH_MSR_X 0xD0 //读Y轴坐标指令 addr:3 |
28 |
#define TOUCH_MSR_X 0xD0 //读Y轴坐标指令 addr:3 |
29 |
|
29 |
|
30 |
structrtgui_touch_device |
30 |
structrtgui_touch_device |
31 |
{ |
31 |
{ |
32 |
structrt_deviceparent; |
32 |
structrt_deviceparent; |
33 |
|
33 |
|
34 |
rt_timer_tpoll_timer; |
34 |
rt_timer_tpoll_timer; |
35 |
rt_uint16_tx, y; |
35 |
rt_uint16_tx, y; |
36 |
|
36 |
|
37 |
rt_bool_tcalibrating; |
37 |
rt_bool_tcalibrating; |
38 |
rt_touch_calibration_func_tcalibration_func; |
38 |
rt_touch_calibration_func_tcalibration_func; |
39 |
|
39 |
|
40 |
rt_uint16_tmin_x, max_x; |
40 |
rt_uint16_tmin_x, max_x; |
41 |
rt_uint16_tmin_y, max_y; |
41 |
rt_uint16_tmin_y, max_y; |
42 |
}; |
42 |
}; |
43 |
staticstructrtgui_touch_device *touch = RT_NULL; |
43 |
staticstructrtgui_touch_device *touch = RT_NULL; |
44 |
|
44 |
|
45 |
externunsignedcharSPI_WriteByte(unsignedchardata); |
45 |
externunsignedcharSPI_WriteByte(unsignedchardata); |
46 |
rt_inlinevoidEXTI_Enable(rt_uint32_tenable); |
46 |
rt_inlinevoidEXTI_Enable(rt_uint32_tenable); |
47 |
|
47 |
|
48 |
structrt_semaphorespi1_lock; |
48 |
structrt_semaphorespi1_lock; |
49 |
|
49 |
|
50 |
voidrt_hw_spi1_baud_rate(uint16_tSPI_BaudRatePrescaler) |
50 |
voidrt_hw_spi1_baud_rate(uint16_tSPI_BaudRatePrescaler) |
51 |
{ |
51 |
{ |
52 |
SPI1->CR1 &= ~SPI_BaudRatePrescaler_256; |
52 |
SPI1->CR1 &= ~SPI_BaudRatePrescaler_256; |
53 |
SPI1->CR1 |= SPI_BaudRatePrescaler; |
53 |
SPI1->CR1 |= SPI_BaudRatePrescaler; |
54 |
} |
54 |
} |
55 |
|
55 |
|
56 |
uint8_tSPI_WriteByte(unsignedchardata) |
56 |
uint8_tSPI_WriteByte(unsignedchardata) |
57 |
{ |
57 |
{ |
58 |
//Wait until the transmit buffer is empty |
58 |
//Wait until the transmit buffer is empty |
59 |
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); |
59 |
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); |
60 |
// Send the byte |
60 |
// Send the byte |
61 |
SPI_I2S_SendData(SPI1, data); |
61 |
SPI_I2S_SendData(SPI1, data); |
62 |
|
62 |
|
63 |
//Wait until a data is received |
63 |
//Wait until a data is received |
64 |
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); |
64 |
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); |
65 |
// Get the received data |
65 |
// Get the received data |
66 |
data = SPI_I2S_ReceiveData(SPI1); |
66 |
data = SPI_I2S_ReceiveData(SPI1); |
67 |
|
67 |
|
68 |
// Return the shifted data |
68 |
// Return the shifted data |
69 |
returndata; |
69 |
returndata; |
70 |
} |
70 |
} |
71 |
|
71 |
|
72 |
//SPI写数据 |
72 |
//SPI写数据 |
73 |
staticvoidWriteDataTo7843(unsignedcharnum) |
73 |
staticvoidWriteDataTo7843(unsignedcharnum) |
74 |
{ |
74 |
{ |
75 |
SPI_WriteByte(num); |
75 |
SPI_WriteByte(num); |
76 |
} |
76 |
} |
77 |
|
77 |
|
78 |
#define X_WIDTH 480 |
78 |
#define X_WIDTH 240 |
79 |
#define Y_WIDTH 272 |
79 |
#define Y_WIDTH 320 |
80 |
|
80 |
|
81 |
staticvoidrtgui_touch_calculate() |
81 |
staticvoidrtgui_touch_calculate() |
82 |
{ |
82 |
{ |
83 |
if (touch != RT_NULL) |
83 |
if (touch != RT_NULL) |
84 |
{ |
84 |
{ |
85 |
rt_sem_take(&spi1_lock, RT_WAITING_FOREVER); |
85 |
rt_sem_take(&spi1_lock, RT_WAITING_FOREVER); |
86 |
/* SPI1 configure */ |
86 |
/* SPI1 configure */ |
87 |
rt_hw_spi1_baud_rate(SPI_BaudRatePrescaler_64);/* 72M/64=1.125M */ |
87 |
rt_hw_spi1_baud_rate(SPI_BaudRatePrescaler_64);/* 72M/64=1.125M */ |
88 |
|
88 |
|
89 |
//读取触摸值 |
89 |
//读取触摸值 |
90 |
{ |
90 |
{ |
91 |
rt_uint16_ttmpx[10]; |
91 |
rt_uint16_ttmpx[10]; |
92 |
rt_uint16_ttmpy[10]; |
92 |
rt_uint16_ttmpy[10]; |
93 |
unsignedinti; |
93 |
unsignedinti; |
94 |
|
94 |
|
95 |
/* From the datasheet: |
95 |
/* From the datasheet: |
96 |
* When the very first CLK after the control byte comes in, the |
96 |
* When the very first CLK after the control byte comes in, the |
97 |
* DOUT of ADS7843 is not valid. So we could only get 7bits from |
97 |
* DOUT of ADS7843 is not valid. So we could only get 7bits from |
98 |
* the first SPI_WriteByte. And the got the following 5 bits from |
98 |
* the first SPI_WriteByte. And the got the following 5 bits from |
99 |
* another SPI_WriteByte.(aligned MSB) |
99 |
* another SPI_WriteByte.(aligned MSB) |
100 |
*/ |
100 |
*/ |
101 |
for(i=0; i<10; i++) |
101 |
for(i=0; i<10; i++) |
102 |
{ |
102 |
{ |
103 |
CS_0(); |
103 |
CS_0(); |
104 |
WriteDataTo7843(TOUCH_MSR_X); |
104 |
WriteDataTo7843(TOUCH_MSR_X); |
105 |
tmpx[i] = (SPI_WriteByte(0x00) & 0x7F) << 5; |
105 |
tmpx[i] = (SPI_WriteByte(0x00) & 0x7F) << 5; |
106 |
tmpx[i] |= (SPI_WriteByte(TOUCH_MSR_Y) >> 3) & 0x1F; |
106 |
tmpx[i] |= (SPI_WriteByte(TOUCH_MSR_Y) >> 3) & 0x1F; |
107 |
|
107 |
|
108 |
tmpy[i] = (SPI_WriteByte(0x00) & 0x7F) << 5; |
108 |
tmpy[i] = (SPI_WriteByte(0x00) & 0x7F) << 5; |
109 |
tmpy[i] |= (SPI_WriteByte(0x00) >> 3) & 0x1F; |
109 |
tmpy[i] |= (SPI_WriteByte(0x00) >> 3) & 0x1F; |
110 |
|
110 |
|
111 |
WriteDataTo7843( 1<<7 ); /* 打开中断 */ |
111 |
WriteDataTo7843( 1<<7 ); /* 打开中断 */ |
112 |
CS_1(); |
112 |
CS_1(); |
113 |
} |
113 |
} |
114 |
|
114 |
|
115 |
//去最高值与最低值,再取平均值 |
115 |
//去最高值与最低值,再取平均值 |
116 |
{ |
116 |
{ |
117 |
rt_uint32_tmin_x = 0xFFFF,min_y = 0xFFFF; |
117 |
rt_uint32_tmin_x = 0xFFFF,min_y = 0xFFFF; |
118 |
rt_uint32_tmax_x = 0,max_y = 0; |
118 |
rt_uint32_tmax_x = 0,max_y = 0; |
119 |
rt_uint32_ttotal_x = 0; |
119 |
rt_uint32_ttotal_x = 0; |
120 |
rt_uint32_ttotal_y = 0; |
120 |
rt_uint32_ttotal_y = 0; |
121 |
unsignedinti; |
121 |
unsignedinti; |
122 |
|
122 |
|
123 |
for(i=0;i<10;i++) |
123 |
for(i=0;i<10;i++) |
124 |
{ |
124 |
{ |
125 |
if( tmpx[i] < min_x ) |
125 |
if( tmpx[i] < min_x ) |
126 |
{ |
126 |
{ |
127 |
min_x = tmpx[i]; |
127 |
min_x = tmpx[i]; |
128 |
} |
128 |
} |
129 |
if( tmpx[i] > max_x ) |
129 |
if( tmpx[i] > max_x ) |
130 |
{ |
130 |
{ |
131 |
max_x = tmpx[i]; |
131 |
max_x = tmpx[i]; |
132 |
} |
132 |
} |
133 |
total_x += tmpx[i]; |
133 |
total_x += tmpx[i]; |
134 |
|
134 |
|
135 |
if( tmpy[i] < min_y ) |
135 |
if( tmpy[i] < min_y ) |
136 |
{ |
136 |
{ |
137 |
min_y = tmpy[i]; |
137 |
min_y = tmpy[i]; |
138 |
} |
138 |
} |
139 |
if( tmpy[i] > max_y ) |
139 |
if( tmpy[i] > max_y ) |
140 |
{ |
140 |
{ |
141 |
max_y = tmpy[i]; |
141 |
max_y = tmpy[i]; |
142 |
} |
142 |
} |
143 |
total_y += tmpy[i]; |
143 |
total_y += tmpy[i]; |
144 |
} |
144 |
} |
145 |
total_x = total_x - min_x - max_x; |
145 |
total_x = total_x - min_x - max_x; |
146 |
total_y = total_y - min_y - max_y; |
146 |
total_y = total_y - min_y - max_y; |
147 |
touch->y = total_x / 8; |
147 |
touch->x = total_x / 8; |
148 |
touch->x = total_y / 8; |
148 |
touch->y = total_y / 8; |
149 |
}//去最高值与最低值,再取平均值 |
149 |
}//去最高值与最低值,再取平均值 |
150 |
}//读取触摸值 |
150 |
}//读取触摸值 |
151 |
|
151 |
|
152 |
rt_sem_release(&spi1_lock); |
152 |
rt_sem_release(&spi1_lock); |
153 |
|
153 |
|
154 |
rt_kprintf("physical position: (%d, %d)\n", touch->x, touch->y); |
|
|
155 |
|
|
|
156 |
/* if it's not in calibration status */ |
154 |
/* if it's not in calibration status */ |
157 |
if (touch->calibrating != RT_TRUE) |
155 |
if (touch->calibrating != RT_TRUE) |
158 |
{ |
156 |
{ |
159 |
if (touch->max_x > touch->min_x) |
157 |
if (touch->max_x > touch->min_x) |
160 |
{ |
158 |
{ |
161 |
touch->x = (touch->x - touch->min_x) * X_WIDTH/(touch->max_x - touch->min_x); |
159 |
touch->x = (touch->x - touch->min_x) * X_WIDTH/(touch->max_x - touch->min_x); |
162 |
} |
160 |
} |
163 |
elseif (touch->max_x < touch->min_x) |
161 |
elseif (touch->max_x < touch->min_x) |
164 |
{ |
162 |
{ |
165 |
touch->x = (touch->min_x - touch->x) * X_WIDTH/(touch->min_x - touch->max_x); |
163 |
touch->x = (touch->min_x - touch->x) * X_WIDTH/(touch->min_x - touch->max_x); |
166 |
} |
164 |
} |
167 |
|
165 |
|
168 |
if (touch->max_y > touch->min_y) |
166 |
if (touch->max_y > touch->min_y) |
169 |
{ |
167 |
{ |
170 |
touch->y = (touch->y - touch->min_y) * Y_WIDTH /(touch->max_y - touch->min_y); |
168 |
touch->y = (touch->y - touch->min_y) * Y_WIDTH /(touch->max_y - touch->min_y); |
171 |
} |
169 |
} |
172 |
elseif (touch->max_y < touch->min_y) |
170 |
elseif (touch->max_y < touch->min_y) |
173 |
{ |
171 |
{ |
174 |
touch->y = (touch->min_y - touch->y) * Y_WIDTH /(touch->min_y - touch->max_y); |
172 |
touch->y = (touch->min_y - touch->y) * Y_WIDTH /(touch->min_y - touch->max_y); |
175 |
} |
173 |
} |
176 |
|
174 |
|
177 |
// normalize the data |
175 |
// normalize the data |
178 |
if (touch->x & 0x8000) |
176 |
if (touch->x & 0x8000) |
179 |
touch->x = 0; |
177 |
touch->x = 0; |
180 |
elseif (touch->x > X_WIDTH) |
178 |
elseif (touch->x > X_WIDTH) |
181 |
touch->x = X_WIDTH - 1; |
179 |
touch->x = X_WIDTH - 1; |
182 |
|
180 |
|
183 |
if (touch->y & 0x8000) |
181 |
if (touch->y & 0x8000) |
184 |
touch->y = 0; |
182 |
touch->y = 0; |
185 |
elseif (touch->y > Y_WIDTH) |
183 |
elseif (touch->y > Y_WIDTH) |
186 |
touch->y = Y_WIDTH - 1; |
184 |
touch->y = Y_WIDTH - 1; |
187 |
} |
185 |
} |
188 |
} |
186 |
} |
189 |
} |
187 |
} |
190 |
|
188 |
|
191 |
voidtouch_timeout(void* parameter) |
189 |
voidtouch_timeout(void* parameter) |
192 |
{ |
190 |
{ |
193 |
staticunsignedinttouched_down = 0; |
191 |
staticunsignedinttouched_down = 0; |
194 |
structrtgui_event_mouseemouse; |
192 |
structrtgui_event_mouseemouse; |
195 |
staticstruct_touch_previous |
193 |
staticstruct_touch_previous |
196 |
{ |
194 |
{ |
197 |
rt_uint32_tx; |
195 |
rt_uint32_tx; |
198 |
rt_uint32_ty; |
196 |
rt_uint32_ty; |
199 |
} touch_previous; |
197 |
} touch_previous; |
200 |
|
198 |
|
201 |
/* touch time is too short and we lost the position already. */ |
199 |
/* touch time is too short and we lost the position already. */ |
202 |
if ((!touched_down) && GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) != 0) |
200 |
if ((!touched_down) && GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) != 0) |
203 |
return; |
201 |
return; |
204 |
|
202 |
|
205 |
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) != 0) |
203 |
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) != 0) |
206 |
{ |
204 |
{ |
207 |
inttmer = RT_TICK_PER_SECOND/8 ; |
205 |
inttmer = RT_TICK_PER_SECOND/8 ; |
208 |
EXTI_Enable(1); |
206 |
EXTI_Enable(1); |
209 |
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; |
207 |
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; |
210 |
emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP); |
208 |
emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP); |
211 |
|
209 |
|
212 |
/* use old value */ |
210 |
/* use old value */ |
213 |
emouse.x = touch->x; |
211 |
emouse.x = touch->x; |
214 |
emouse.y = touch->y; |
212 |
emouse.y = touch->y; |
215 |
|
213 |
|
216 |
/* stop timer */ |
214 |
/* stop timer */ |
217 |
rt_timer_stop(touch->poll_timer); |
215 |
rt_timer_stop(touch->poll_timer); |
218 |
rt_kprintf("touch up: (%d, %d)\n", emouse.x, emouse.y); |
216 |
rt_kprintf("touch up: (%d, %d)\n", emouse.x, emouse.y); |
219 |
touched_down = 0; |
217 |
touched_down = 0; |
220 |
|
218 |
|
221 |
if ((touch->calibrating == RT_TRUE) && (touch->calibration_func != RT_NULL)) |
219 |
if ((touch->calibrating == RT_TRUE) && (touch->calibration_func != RT_NULL)) |
222 |
{ |
220 |
{ |
223 |
/* callback function */ |
221 |
/* callback function */ |
224 |
touch->calibration_func(emouse.x, emouse.y); |
222 |
touch->calibration_func(emouse.x, emouse.y); |
225 |
} |
223 |
} |
226 |
rt_timer_control(touch->poll_timer , RT_TIMER_CTRL_SET_TIME , &tmer); |
224 |
rt_timer_control(touch->poll_timer , RT_TIMER_CTRL_SET_TIME , &tmer); |
227 |
} |
225 |
} |
228 |
else |
226 |
else |
229 |
{ |
227 |
{ |
230 |
if(touched_down == 0) |
228 |
if(touched_down == 0) |
231 |
{ |
229 |
{ |
232 |
inttmer = RT_TICK_PER_SECOND/20 ; |
230 |
inttmer = RT_TICK_PER_SECOND/20 ; |
233 |
/* calculation */ |
231 |
/* calculation */ |
234 |
rtgui_touch_calculate(); |
232 |
rtgui_touch_calculate(); |
235 |
|
233 |
|
236 |
/* send mouse event */ |
234 |
/* send mouse event */ |
237 |
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; |
235 |
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; |
238 |
emouse.parent.sender = RT_NULL; |
236 |
emouse.parent.sender = RT_NULL; |
239 |
|
237 |
|
240 |
emouse.x = touch->x; |
238 |
emouse.x = touch->x; |
241 |
emouse.y = touch->y; |
239 |
emouse.y = touch->y; |
242 |
|
240 |
|
243 |
touch_previous.x = touch->x; |
241 |
touch_previous.x = touch->x; |
244 |
touch_previous.y = touch->y; |
242 |
touch_previous.y = touch->y; |
245 |
|
243 |
|
246 |
/* init mouse button */ |
244 |
/* init mouse button */ |
247 |
emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN); |
245 |
emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN); |
248 |
|
246 |
|
249 |
// rt_kprintf("touch down: (%d, %d)\n", emouse.x, emouse.y); |
247 |
// rt_kprintf("touch down: (%d, %d)\n", emouse.x, emouse.y); |
250 |
touched_down = 1; |
248 |
touched_down = 1; |
251 |
rt_timer_control(touch->poll_timer , RT_TIMER_CTRL_SET_TIME , &tmer); |
249 |
rt_timer_control(touch->poll_timer , RT_TIMER_CTRL_SET_TIME , &tmer); |
252 |
} |
250 |
} |
253 |
else |
251 |
else |
254 |
{ |
252 |
{ |
255 |
/* calculation */ |
253 |
/* calculation */ |
256 |
rtgui_touch_calculate(); |
254 |
rtgui_touch_calculate(); |
257 |
|
255 |
|
258 |
#define previous_keep 8 |
256 |
#define previous_keep 8 |
259 |
//判断移动距离是否小于previous_keep,减少误动作. |
257 |
//判断移动距离是否小于previous_keep,减少误动作. |
260 |
if( |
258 |
if( |
261 |
(touch_previous.x<touch->x+previous_keep) |
259 |
(touch_previous.x<touch->x+previous_keep) |
262 |
&& (touch_previous.x>touch->x-previous_keep) |
260 |
&& (touch_previous.x>touch->x-previous_keep) |
263 |
&& (touch_previous.y<touch->y+previous_keep) |
261 |
&& (touch_previous.y<touch->y+previous_keep) |
264 |
&& (touch_previous.y>touch->y-previous_keep) ) |
262 |
&& (touch_previous.y>touch->y-previous_keep) ) |
265 |
{ |
263 |
{ |
266 |
return; |
264 |
return; |
267 |
} |
265 |
} |
268 |
|
266 |
|
269 |
touch_previous.x = touch->x; |
267 |
touch_previous.x = touch->x; |
270 |
touch_previous.y = touch->y; |
268 |
touch_previous.y = touch->y; |
271 |
|
269 |
|
272 |
/* send mouse event */ |
270 |
/* send mouse event */ |
273 |
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON ; |
271 |
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON ; |
274 |
emouse.parent.sender = RT_NULL; |
272 |
emouse.parent.sender = RT_NULL; |
275 |
|
273 |
|
276 |
emouse.x = touch->x; |
274 |
emouse.x = touch->x; |
277 |
emouse.y = touch->y; |
275 |
emouse.y = touch->y; |
278 |
|
276 |
|
279 |
/* init mouse button */ |
277 |
/* init mouse button */ |
280 |
emouse.button = (RTGUI_MOUSE_BUTTON_RIGHT |RTGUI_MOUSE_BUTTON_DOWN); |
278 |
emouse.button = (RTGUI_MOUSE_BUTTON_RIGHT |RTGUI_MOUSE_BUTTON_DOWN); |
281 |
// rt_kprintf("touch motion: (%d, %d)\n", emouse.x, emouse.y); |
279 |
// rt_kprintf("touch motion: (%d, %d)\n", emouse.x, emouse.y); |
282 |
} |
280 |
} |
283 |
} |
281 |
} |
284 |
|
282 |
|
285 |
/* send event to server */ |
283 |
/* send event to server */ |
286 |
if (touch->calibrating != RT_TRUE) |
284 |
if (touch->calibrating != RT_TRUE) |
287 |
rtgui_server_post_event(&emouse.parent, sizeof(structrtgui_event_mouse)); |
285 |
rtgui_server_post_event(&emouse.parent, sizeof(structrtgui_event_mouse)); |
288 |
} |
286 |
} |
289 |
|
287 |
|
290 |
staticvoidNVIC_Configuration(void) |
288 |
staticvoidNVIC_Configuration(void) |
291 |
{ |
289 |
{ |
292 |
NVIC_InitTypeDefNVIC_InitStructure; |
290 |
NVIC_InitTypeDefNVIC_InitStructure; |
293 |
|
291 |
|
294 |
/* Enable the EXTI9_5 Interrupt */ |
292 |
/* Enable the EXTI0 Interrupt */ |
295 |
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; |
293 |
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; |
296 |
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; |
294 |
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; |
297 |
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; |
295 |
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; |
298 |
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
296 |
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
299 |
NVIC_Init(&NVIC_InitStructure); |
297 |
NVIC_Init(&NVIC_InitStructure); |
300 |
} |
298 |
} |
301 |
|
299 |
|
302 |
rt_inlinevoidEXTI_Enable(rt_uint32_tenable) |
300 |
rt_inlinevoidEXTI_Enable(rt_uint32_tenable) |
303 |
{ |
301 |
{ |
304 |
EXTI_InitTypeDefEXTI_InitStructure; |
302 |
EXTI_InitTypeDefEXTI_InitStructure; |
305 |
|
303 |
|
306 |
/* Configure EXTI */ |
304 |
/* Configure EXTI */ |
307 |
EXTI_InitStructure.EXTI_Line = EXTI_Line6; |
305 |
EXTI_InitStructure.EXTI_Line = EXTI_Line1; |
308 |
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; |
306 |
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; |
309 |
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//Falling下降沿 Rising上升 |
307 |
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//Falling下降沿 Rising上升 |
310 |
|
308 |
|
311 |
if (enable) |
309 |
if (enable) |
312 |
{ |
310 |
{ |
313 |
/* enable */ |
311 |
/* enable */ |
314 |
EXTI_InitStructure.EXTI_LineCmd = ENABLE; |
312 |
EXTI_InitStructure.EXTI_LineCmd = ENABLE; |
315 |
} |
313 |
} |
316 |
else |
314 |
else |
317 |
{ |
315 |
{ |
318 |
/* disable */ |
316 |
/* disable */ |
319 |
EXTI_InitStructure.EXTI_LineCmd = DISABLE; |
317 |
EXTI_InitStructure.EXTI_LineCmd = DISABLE; |
320 |
} |
318 |
} |
321 |
|
319 |
|
322 |
EXTI_Init(&EXTI_InitStructure); |
320 |
EXTI_Init(&EXTI_InitStructure); |
323 |
EXTI_ClearITPendingBit(EXTI_Line6); |
321 |
EXTI_ClearITPendingBit(EXTI_Line1); |
324 |
} |
322 |
} |
325 |
|
323 |
|
326 |
staticvoidEXTI_Configuration(void) |
324 |
staticvoidEXTI_Configuration(void) |
327 |
{ |
325 |
{ |
328 |
/* PB6 touch INT */ |
326 |
/* PB1 touch INT */ |
329 |
{ |
327 |
{ |
330 |
GPIO_InitTypeDefGPIO_InitStructure; |
328 |
GPIO_InitTypeDefGPIO_InitStructure; |
331 |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); |
329 |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); |
332 |
|
330 |
|
333 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; |
331 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; |
334 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; |
332 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; |
335 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; |
333 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; |
336 |
GPIO_Init(GPIOB,&GPIO_InitStructure); |
334 |
GPIO_Init(GPIOB,&GPIO_InitStructure); |
337 |
} |
335 |
} |
338 |
|
336 |
|
339 |
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6); |
337 |
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); |
340 |
|
338 |
|
341 |
/* Configure EXTI */ |
339 |
/* Configure EXTI */ |
342 |
EXTI_Enable(1); |
340 |
EXTI_Enable(1); |
343 |
} |
341 |
} |
344 |
|
342 |
|
345 |
/* RT-Thread Device Interface */ |
343 |
/* RT-Thread Device Interface */ |
346 |
staticrt_err_trtgui_touch_init (rt_device_tdev) |
344 |
staticrt_err_trtgui_touch_init (rt_device_tdev) |
347 |
{ |
345 |
{ |
348 |
NVIC_Configuration(); |
346 |
NVIC_Configuration(); |
349 |
EXTI_Configuration(); |
347 |
EXTI_Configuration(); |
350 |
|
348 |
|
351 |
// enable touch, disable other SPI1 device |
349 |
/* PC4 touch CS */ |
352 |
{ |
350 |
{ |
353 |
GPIO_InitTypeDefGPIO_InitStructure; |
351 |
GPIO_InitTypeDefGPIO_InitStructure; |
354 |
|
352 |
|
355 |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB, ENABLE); |
353 |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); |
356 |
|
354 |
|
357 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; |
355 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; |
358 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
356 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
359 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; |
357 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; |
360 |
GPIO_Init(GPIOA,&GPIO_InitStructure); |
|
|
361 |
GPIO_Init(GPIOC,&GPIO_InitStructure); |
358 |
GPIO_Init(GPIOC,&GPIO_InitStructure); |
362 |
|
359 |
CS_1(); |
363 |
GPIO_SetBits(GPIOA, GPIO_Pin_4); // disable ENC28J60(LAN) |
|
|
364 |
GPIO_SetBits(GPIOB, GPIO_Pin_4); // disable SST25VF016B(2M Flash) |
|
|
365 |
|
|
|
366 |
/* PB7 touch CS */ |
|
|
367 |
{ |
|
|
368 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; |
|
|
369 |
GPIO_Init(GPIOB,&GPIO_InitStructure); |
|
|
370 |
CS_1(); |
|
|
371 |
} |
|
|
372 |
} |
360 |
} |
373 |
|
361 |
|
374 |
CS_0(); |
362 |
CS_0(); |
375 |
WriteDataTo7843( 1<<7 ); /* 打开中断 */ |
363 |
WriteDataTo7843( 1<<7 ); /* 打开中断 */ |
376 |
CS_1(); |
364 |
CS_1(); |
377 |
|
365 |
|
378 |
returnRT_EOK; |
366 |
returnRT_EOK; |
379 |
} |
367 |
} |
380 |
|
368 |
|
381 |
staticrt_err_trtgui_touch_control (rt_device_tdev, rt_uint8_tcmd, void *args) |
369 |
staticrt_err_trtgui_touch_control (rt_device_tdev, rt_uint8_tcmd, void *args) |
382 |
{ |
370 |
{ |
383 |
switch (cmd) |
371 |
switch (cmd) |
384 |
{ |
372 |
{ |
385 |
caseRT_TOUCH_CALIBRATION: |
373 |
caseRT_TOUCH_CALIBRATION: |
386 |
touch->calibrating = RT_TRUE; |
374 |
touch->calibrating = RT_TRUE; |
387 |
touch->calibration_func = (rt_touch_calibration_func_t)args; |
375 |
touch->calibration_func = (rt_touch_calibration_func_t)args; |
388 |
break; |
376 |
break; |
389 |
|
377 |
|
390 |
caseRT_TOUCH_NORMAL: |
378 |
caseRT_TOUCH_NORMAL: |
391 |
touch->calibrating = RT_FALSE; |
379 |
touch->calibrating = RT_FALSE; |
392 |
break; |
380 |
break; |
393 |
|
381 |
|
394 |
caseRT_TOUCH_CALIBRATION_DATA: |
382 |
caseRT_TOUCH_CALIBRATION_DATA: |
395 |
{ |
383 |
{ |
396 |
structcalibration_data* data; |
384 |
structcalibration_data* data; |
397 |
|
385 |
|
398 |
data = (structcalibration_data*) args; |
386 |
data = (structcalibration_data*) args; |
399 |
|
387 |
|
400 |
//update |
388 |
//update |
401 |
touch->min_x = data->min_x; |
389 |
touch->min_x = data->min_x; |
402 |
touch->max_x = data->max_x; |
390 |
touch->max_x = data->max_x; |
403 |
touch->min_y = data->min_y; |
391 |
touch->min_y = data->min_y; |
404 |
touch->max_y = data->max_y; |
392 |
touch->max_y = data->max_y; |
405 |
} |
393 |
} |
406 |
break; |
394 |
break; |
407 |
} |
395 |
} |
408 |
|
396 |
|
409 |
returnRT_EOK; |
397 |
returnRT_EOK; |
410 |
} |
398 |
} |
411 |
|
399 |
|
412 |
void EXTI9_5_IRQHandler(void) |
400 |
void EXTI1_IRQHandler(void) |
413 |
{ |
401 |
{ |
414 |
/* disable interrupt */ |
402 |
/* disable interrupt */ |
415 |
EXTI_Enable(0); |
403 |
EXTI_Enable(0); |
416 |
|
404 |
|
417 |
/* start timer */ |
405 |
/* start timer */ |
418 |
rt_timer_start(touch->poll_timer); |
406 |
rt_timer_start(touch->poll_timer); |
419 |
|
407 |
|
420 |
EXTI_ClearITPendingBit(EXTI_Line6); |
408 |
EXTI_ClearITPendingBit(EXTI_Line1); |
421 |
} |
409 |
} |
422 |
|
410 |
|
423 |
voidrtgui_touch_hw_init(void) |
411 |
voidrtgui_touch_hw_init(void) |
424 |
{ |
412 |
{ |
425 |
/* SPI1 config */ |
413 |
/* SPI1 config */ |
426 |
{ |
414 |
{ |
427 |
GPIO_InitTypeDefGPIO_InitStructure; |
415 |
GPIO_InitTypeDefGPIO_InitStructure; |
428 |
SPI_InitTypeDefSPI_InitStructure; |
416 |
SPI_InitTypeDefSPI_InitStructure; |
429 |
|
417 |
|
430 |
/* Enable SPI1 Periph clock */ |
418 |
/* Enable SPI1 Periph clock */ |
431 |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
419 |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
432 |
| RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1, |
420 |
| RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1, |
433 |
ENABLE); |
421 |
ENABLE); |
434 |
|
422 |
|
435 |
/* Configure SPI1 pins: PA5-SCK, PA6-MISO and PA7-MOSI */ |
423 |
/* Configure SPI1 pins: PA5-SCK, PA6-MISO and PA7-MOSI */ |
436 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; |
424 |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; |
437 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
425 |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
438 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
426 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
439 |
GPIO_Init(GPIOA, &GPIO_InitStructure); |
427 |
GPIO_Init(GPIOA, &GPIO_InitStructure); |
440 |
|
428 |
|
441 |
/*------------------------ SPI1 configuration ------------------------*/ |
429 |
/*------------------------ SPI1 configuration ------------------------*/ |
442 |
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx; |
430 |
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx; |
443 |
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; |
431 |
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; |
444 |
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; |
432 |
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; |
445 |
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; |
433 |
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; |
446 |
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; |
434 |
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; |
447 |
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; |
435 |
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; |
448 |
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;/* 72M/64=1.125M */ |
436 |
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;/* 72M/64=1.125M */ |
449 |
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; |
437 |
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; |
450 |
SPI_InitStructure.SPI_CRCPolynomial = 7; |
438 |
SPI_InitStructure.SPI_CRCPolynomial = 7; |
451 |
|
439 |
|
452 |
SPI_I2S_DeInit(SPI1); |
440 |
SPI_I2S_DeInit(SPI1); |
453 |
SPI_Init(SPI1, &SPI_InitStructure); |
441 |
SPI_Init(SPI1, &SPI_InitStructure); |
454 |
|
442 |
|
455 |
/* Enable SPI_MASTER */ |
443 |
/* Enable SPI_MASTER */ |
456 |
SPI_Cmd(SPI1, ENABLE); |
444 |
SPI_Cmd(SPI1, ENABLE); |
457 |
SPI_CalculateCRC(SPI1, DISABLE); |
445 |
SPI_CalculateCRC(SPI1, DISABLE); |
458 |
|
446 |
|
459 |
if (rt_sem_init(&spi1_lock, "spi1lock", 1, RT_IPC_FLAG_FIFO) != RT_EOK) |
447 |
if (rt_sem_init(&spi1_lock, "spi1lock", 1, RT_IPC_FLAG_FIFO) != RT_EOK) |
460 |
{ |
448 |
{ |
461 |
rt_kprintf("init spi1 lock semaphore failed\n"); |
449 |
rt_kprintf("init spi1 lock semaphore failed\n"); |
462 |
} |
450 |
} |
463 |
} /* SPI1 config */ |
451 |
} /* SPI1 config */ |
464 |
|
452 |
|
465 |
touch = (structrtgui_touch_device*)rt_malloc (sizeof(structrtgui_touch_device)); |
453 |
touch = (structrtgui_touch_device*)rt_malloc (sizeof(structrtgui_touch_device)); |
466 |
if (touch == RT_NULL) return; /* no memory yet */ |
454 |
if (touch == RT_NULL) return; /* no memory yet */ |
467 |
|
455 |
|
468 |
/* clear device structure */ |
456 |
/* clear device structure */ |
469 |
rt_memset(&(touch->parent), 0, sizeof(structrt_device)); |
457 |
rt_memset(&(touch->parent), 0, sizeof(structrt_device)); |
470 |
touch->calibrating = false; |
458 |
touch->calibrating = false; |
471 |
|
459 |
|
472 |
/* init device structure */ |
460 |
/* init device structure */ |
473 |
touch->parent.type = RT_Device_Class_Unknown; |
461 |
touch->parent.type = RT_Device_Class_Unknown; |
474 |
touch->parent.init = rtgui_touch_init; |
462 |
touch->parent.init = rtgui_touch_init; |
475 |
touch->parent.control = rtgui_touch_control; |
463 |
touch->parent.control = rtgui_touch_control; |
476 |
touch->parent.user_data = RT_NULL; |
464 |
touch->parent.user_data = RT_NULL; |
477 |
|
465 |
|
478 |
/* create 1/8 second timer */ |
466 |
/* create 1/8 second timer */ |
479 |
touch->poll_timer = rt_timer_create("touch", touch_timeout, RT_NULL, |
467 |
touch->poll_timer = rt_timer_create("touch", touch_timeout, RT_NULL, |
480 |
RT_TICK_PER_SECOND/8, RT_TIMER_FLAG_PERIODIC); |
468 |
RT_TICK_PER_SECOND/8, RT_TIMER_FLAG_PERIODIC); |
481 |
|
469 |
|
482 |
/* register touch device to RT-Thread */ |
470 |
/* register touch device to RT-Thread */ |
483 |
rt_device_register(&(touch->parent), "touch", RT_DEVICE_FLAG_RDWR); |
471 |
rt_device_register(&(touch->parent), "touch", RT_DEVICE_FLAG_RDWR); |
484 |
} |
472 |
} |
485 |
|
473 |
|
486 |
#ifdef RT_USING_FINSH |
474 |
#ifdef RT_USING_FINSH |
487 |
#include <finsh.h> |
475 |
#include <finsh.h> |
488 |
|
476 |
|
489 |
voidtouch_t( rt_uint16_tx , rt_uint16_ty ) |
477 |
voidtouch_t( rt_uint16_tx , rt_uint16_ty ) |
490 |
{ |
478 |
{ |
491 |
structrtgui_event_mouseemouse ; |
479 |
structrtgui_event_mouseemouse ; |
492 |
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; |
480 |
emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; |
493 |
emouse.parent.sender = RT_NULL; |
481 |
emouse.parent.sender = RT_NULL; |
494 |
|
482 |
|
495 |
emouse.x = x ; |
483 |
emouse.x = x ; |
496 |
emouse.y = y ; |
484 |
emouse.y = y ; |
497 |
/* init mouse button */ |
485 |
/* init mouse button */ |
498 |
emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN ); |
486 |
emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN ); |
499 |
rtgui_server_post_event(&emouse.parent, sizeof(structrtgui_event_mouse)); |
487 |
rtgui_server_post_event(&emouse.parent, sizeof(structrtgui_event_mouse)); |
500 |
|
488 |
|
501 |
rt_thread_delay(2) ; |
489 |
rt_thread_delay(2) ; |
502 |
emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP ); |
490 |
emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP ); |
503 |
rtgui_server_post_event(&emouse.parent, sizeof(structrtgui_event_mouse)); |
491 |
rtgui_server_post_event(&emouse.parent, sizeof(structrtgui_event_mouse)); |
504 |
} |
492 |
} |
505 |
|
493 |
|
506 |
FINSH_FUNCTION_EXPORT(touch_t, x & y ) ; |
494 |
FINSH_FUNCTION_EXPORT(touch_t, x & y ) ; |
507 |
#endif |
495 |
#endif |
508 |
|
496 |
|
补丁:
17c17 < CS PB7 --- > CS PC4 20,21c20,21 < #define CS_0() GPIO_ResetBits(GPIOB,GPIO_Pin_7) < #define CS_1() GPIO_SetBits(GPIOB,GPIO_Pin_7) --- > #define CS_0() GPIO_ResetBits(GPIOC,GPIO_Pin_4) > #define CS_1() GPIO_SetBits(GPIOC,GPIO_Pin_4) 78,79c78,79 < #define X_WIDTH 480 < #define Y_WIDTH 272 --- > #define X_WIDTH 240 > #define Y_WIDTH 320 147,148c147,148 < touch->y = total_x / 8; < touch->x = total_y / 8; --- > touch->x = total_x / 8; > touch->y = total_y / 8; 154,155d153 < rt_kprintf("physical position: (%d, %d)\n", touch->x, touch->y); < 202c200 < if ((!touched_down) && GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) != 0) --- > if ((!touched_down) && GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) != 0) 205c203 < if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) != 0) --- > if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) != 0) 294,295c292,293 < /* Enable the EXTI9_5 Interrupt */ < NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; --- > /* Enable the EXTI0 Interrupt */ > NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; 307c305 < EXTI_InitStructure.EXTI_Line = EXTI_Line6; --- > EXTI_InitStructure.EXTI_Line = EXTI_Line1; 323c321 < EXTI_ClearITPendingBit(EXTI_Line6); --- > EXTI_ClearITPendingBit(EXTI_Line1); 328c326 < /* PB6 touch INT */ --- > /* PB1 touch INT */ 333c331 < GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; --- > GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; 339c337 < GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6); --- > GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); 351c349 < // enable touch, disable other SPI1 device --- > /* PC4 touch CS */ 355c353 < RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB, ENABLE); --- > RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); 360d357 < GPIO_Init(GPIOA,&GPIO_InitStructure); 362,369d358 < < GPIO_SetBits(GPIOA, GPIO_Pin_4); // disable ENC28J60(LAN) < GPIO_SetBits(GPIOB, GPIO_Pin_4); // disable SST25VF016B(2M Flash) < < /* PB7 touch CS */ < { < GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; < GPIO_Init(GPIOB,&GPIO_InitStructure); 372d360 < } 412c400 < void EXTI9_5_IRQHandler(void) --- > void EXTI1_IRQHandler(void) 420c408 < EXTI_ClearITPendingBit(EXTI_Line6); --- > EXTI_ClearITPendingBit(EXTI_Line1); |
在 touch.c 中,第30行定义了一个结构体,其中最后两行,对于每个触摸屏,不同时期,可能采用不同的值才会取得最佳效果,这就是触摸屏校准程序要采集并计算的最佳数据。
struct rtgui_touch_device { struct rt_device parent;
rt_timer_t poll_timer; rt_uint16_t x, y;
rt_bool_t calibrating; rt_touch_calibration_func_t calibration_func;
rt_uint16_t min_x, max_x; rt_uint16_t min_y, max_y; };
|
数值例:
点触摸屏右下角,硬件返回的坐标值:3955, 3463
校准数据:min_x = 208, max_x = 4069, min_y = 187, max_y = 3590
最后,综合硬件值,校准数据,屏幕分辨率,计算出一个相对精确的坐标数据(x, y),如果屏幕分辨率为480 X 640,则x < 480,y < 640。
注1:由于屏幕显示方向与触摸屏方向不一致,在代码的第147行,将 x, y 值对调。
注2:为了屏幕与触摸屏方向保持一致,修改了LCD驱动,将显示方向转了180度。
Ssd1963.c 第188行,参数值改为0x0003
LCD_WR_REG(0x0036); //rotation LCD_WR_DAT(0x0003); |
具体参数意义,请参考PDF文件说明。