STM32 + RT Thread OS 学习笔记[五]
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文件说明。
STM32 + RT Thread OS 学习笔记[五]相关推荐
- 哈工大操作系统学习笔记五——内核级线程实现
哈工大os学习笔记五(内核级线程实现) 文章目录 哈工大os学习笔记五(内核级线程实现) 一. 中断入口.中断出口(前后两段) 1. 从int中断进入内核(中断入口第一段) 2.中断出口(最后一段) ...
- 【OS学习笔记】三十五 保护模式十:中断描述符表、中断门和陷阱门
上一篇文章学习了中断与异常的概念:[OS学习笔记]三十四 保护模式十:中断和异常区别 本片文章接着学习以下内容: 中断描述符表 中断门 陷阱门 1 中断描述符表 我们前面讲了无数次,在实模式下,是由位 ...
- 【OS学习笔记】二十五 保护模式七:任务和特权级保护对应的汇编源代码
本汇编代码是以下两篇文章讲解的内容的内核代码; [OS学习笔记]二十三 保护模式七:保护模式下任务的隔离与任务的特权级概念 [OS学习笔记]二十四 保护模式七:调用门与依从的代码段----特权级保护 ...
- StackExchange.Redis学习笔记(五) 发布和订阅
StackExchange.Redis学习笔记(五) 发布和订阅 原文:StackExchange.Redis学习笔记(五) 发布和订阅 Redis命令中的Pub/Sub Redis在 2.0之后的版 ...
- 【OS学习笔记】四十 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----动态加载的用户程序/任务二代码
本文是以下几篇文章对应的微型动态加载的用户程序/任务二代码: [OS学习笔记]三十四 保护模式十:中断和异常区别 [OS学习笔记]三十五 保护模式十:中断描述符表.中断门和陷阱门 [OS学习笔记]三十 ...
- 【OS学习笔记】三十九 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----动态加载的用户程序/任务一代码
本文是以下几篇文章对应的动态加载的用户程序/任务一代码: [OS学习笔记]三十四 保护模式十:中断和异常区别 [OS学习笔记]三十五 保护模式十:中断描述符表.中断门和陷阱门 [OS学习笔记]三十六 ...
- 【OS学习笔记】三十八 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----微型内核汇代码
本文是以下几篇文章对应的微型内核代码汇编代码: [OS学习笔记]三十四 保护模式十:中断和异常区别 [OS学习笔记]三十五 保护模式十:中断描述符表.中断门和陷阱门 [OS学习笔记]三十六 保护模式十 ...
- 【OS学习笔记】三十七 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----主引导扇区代码
本文是以下几篇文章对应的主引导扇区代码汇编代码: [OS学习笔记]三十四 保护模式十:中断和异常区别 [OS学习笔记]三十五 保护模式十:中断描述符表.中断门和陷阱门 [OS学习笔记]三十六 保护模式 ...
- 【OS学习笔记】三十六 保护模式十:通过中断发起任务切换----中断任务
上一篇文章学习了:OS学习笔记]三十五 保护模式十:中断描述符表.中断门和陷阱门 本篇文章接着上一篇文章学习中断任务. 我们在前面文章中一直在说通过中断发起任务切换,本文就是将之前没有说明白的内容:通 ...
最新文章
- C# Socket系列三 socket通信的封包和拆包
- OEM, ODM, OBM
- python入门必备指南-致Python初学者 Anaconda入门使用指南完整版
- 蓝桥杯 ALGO-42 算法训练 送分啦
- javaweb环境的配置 以及tomcat的安装
- JAVAWeb使用POI做导出Excel
- springzuul本地路由和跨服务器路由问题
- 2022电工杯:5G 网络环境下应急物资配送问题(优化)
- 图片转文字,手机摇身一变就是万能扫描仪!
- 微博评论数据爬取思路及代码分享
- 领导人怎样带领好团队
- python 当天零点的时间戳
- 什么是云计算云计算能干什么?云计算学习笔记工具素材
- 硬件视角看段页式存储
- 基于Java毕业设计写手管理平台源码+系统+mysql+lw文档+部署软件
- 计算机基础知识教程excel单元格拆分,电脑内怎么将excel表格中某个单元格的内容拆分至不同单元格里...
- 电子设计教程29:滞回比较器(施密特触发器)
- Random + Scanner 场景试炼
- 打印机与电脑文件服务器,电脑无法共享局域网打印机和文件的解决方法
- 思考乐教育的荣耀与忧虑:整体增速放缓,异地扩张未见成效
热门文章
- 嵌入式音频架构 - AudioWeaver 整体概念
- 涨握在线收评 | 沪指跌1.73%失守3000点 创两个月最大单日跌幅
- PyCharm中Github的使用
- linux+上的录屏软件下载,Linux下优秀的屏幕录像软件Kazam | 薄荷开源网
- 阿斯汤加瑜伽(Ashtanga Yoga)第一序列学习与实践笔记(一)
- verilog学习笔记- 12)触摸按键控制LED灯实验
- 【THREE源码解析篇】THREE.Matrix4源码详解
- 如何在termius安装linux窗口,XShell的神器—Termius使用ssh教程
- 如何查看声卡型号alc版本号、型号
- Unity 图标字体