一。更高效的使用觸控螢幕
penirq引腳在沒有觸控時都是高電平,只要有觸控就是低電平,直到沒有觸控。用中斷檢測penirq引腳,當產生下降沿中斷時就去讀取座標。但是觸控螢幕也會象按鍵一樣發生抖動,會產生很多上公升沿或下降沿,會引起誤判。這裡我們使用狀態機的方式去處理,使用狀態機還有乙個好處就是可以很方便的去判斷長按,短按,雙擊等狀態。
當觸控螢幕有觸點按下時,penirq 引腳會輸出低電平,直到沒有觸控的時候,它才會輸出高電平;而且 stm32 的中斷只支援邊沿觸發(上公升沿或下降沿),不支援電平觸發,在觸控螢幕上存在類似機械按鍵的訊號抖動,所以如果使用中斷的方式來檢測觸控狀態並不適合,難以辨別觸控按下及釋放的情況。
狀態機程式設計是一種非常高效的程式設計方式,它非常適合應用在涉及狀態轉換的過程控制中,上述**採用狀態機的程式設計方式對觸控狀態進行檢測,主要涉及觸控的按下、消抖及釋放這三種狀態轉換。在應用時,本函式需要在迴圈體裡呼叫,或定時呼叫(如每隔 10ms呼叫一次)。
通過讀取penirq引腳,內部有三種狀態,當觸控還沒有被按下的時候的狀態為:release狀態,是高電平,被按下後penirq引腳變成低電平,進入消抖狀態,還要等待一段時間,也就是消抖的過程,當第一次變成低電平的時候記錄乙個標誌i++,記錄它變成低電平一次了,然後等待一下,過了一段時間再去檢測,如果還是低電平,就確認是從高電平變成低電平,確認觸控被持續按下,進入pressed狀態,達到了消抖的目的。
這個等待的狀態叫做waiting狀態。pressed狀態就是低電平的狀態。會在這三種狀態之間轉換,同時對外輸出最終的結果。
如果在pressed狀態再來檢測可以檢測觸控是否是一直被按下,這時候可以判斷長按或短按。如果在pressed狀態下檢測到penirq變成高電平,就轉入release狀態,同時對外輸出這個觸控沒有被按下。在消抖以後檢測到penirq是低電平或在pressed狀態檢測到penirq是低電平,對外輸出touch_pressed。
程式:1. touch.h標頭檔案
//用狀態機程式設計處理觸控螢幕操作
//檢測:觸控螢幕的按下和釋放
#define touch_not_pressed 0
//釋放的時候返回0
#define touch_pressed 1
//按下時返回1
typedef
enum
touch_state;
//觸控檢測狀態機
u8 touch_dectect
(void);
//用狀態機程式設計進行處理
2. touch.c檔案
//用狀態機程式設計處理觸控螢幕操作
//檢測:觸控螢幕的按下和釋放
#define touch_not_pressed 0 //釋放的時候返回0
#define touch_pressed 1 //按下時返回1
//觸控檢測狀態機
u8 touch_dectect(void)
static touch_state touch_state = xpt2046_state_release;
u8 result; //用了記錄狀態的輸出
static u8 i; //記錄檢測到penirq引腳為低電平
switch(touch_state) //狀態處理
case xpt2046_state_release:
if(pen == 0)
touch_state = xpt2046_state_waiting; //切換到消抖等待的狀態
result = touch_not_pressed; //在消抖等待狀態仍輸出沒有被按下
else
touch_state = xpt2046_state_release; //切換到消抖等待的狀態
result = touch_not_pressed; //在消抖等待狀態仍輸出沒有被按下
break;
case xpt2046_state_waiting:
if(pen == 0)
i++; //在while迴圈中使用,比如間隔2ms檢測一次
if( i > 10) //如果檢測10次以後penirq還是低電平,相當於檢測20ms之內一直處於低電平,消抖。
touch_state = xpt2046_state_pressed; //切換到觸控螢幕被按下的狀態
result = touch_pressed; //輸出觸控螢幕被按下
else
touch_state = xpt2046_state_waiting; //切換到消抖等待的狀態
result = touch_not_pressed; //在消抖等待狀態仍輸出沒有被按下
else //檢測到penirq為高電平
i = 0;
touch_state = xpt2046_state_release; //切換到觸控螢幕沒有被按下的狀態
result = touch_not_pressed; //輸出沒有被按下
break;
case xpt2046_state_pressed:
if(pen == 0)
touch_state = xpt2046_state_pressed; //一直處於被按下狀態,在這裡可以檢測是否長按
result = touch_pressed; //輸出觸控螢幕被按下
else
touch_state = xpt2046_state_release; //如果檢測到高電平就認為被釋放了
result = touch_not_pressed; //輸出沒有被按下
break;
return result;
3.main.c
#include 「stdio.h」
#include 「led.h」
#include 「delay.h」
#include 「key.h」
#include 「sys.h」
#include 「lcd.h」
#include 「usart.h」
#include 「24cxx.h」
#include 「flash.h」
#include 「touch.h」
//alientek戰艦stm32開發板實驗26
//觸控螢幕 實驗
//技術支援:www.openedv.com
//廣州市星翼電子科技****
void load_drow_dialog(void)
lcd_clear(white);//清屏
point_color=blue;//設定字型為藍色
lcd_showstring(216,0,200,16,16,「rst」);//顯示清屏區域
point_color=red;//設定畫筆藍色
int main(void)
u8 key;
u8 i=0;
delay_init(); //延時函式初始化
nvic_configuration(); //設定nvic中斷分組2:2位搶占優先順序,2位響應優先順序
uart_init(9600); //串列埠初始化為9600
led_init(); //led埠初始化
lcd_init();
key_init();
point_color=red;//設定字型為紅色
lcd_showstring(60,50,200,16,16,「warship stm32」);
lcd_showstring(60,70,200,16,16,「touch test」);
lcd_showstring(60,90,200,16,16,「atom@alientek」);
lcd_showstring(60,110,200,16,16,「2012/9/11」);
lcd_showstring(60,130,200,16,16,「press key0 to adjust」);
tp_dev.init();
delay_ms(1500);
load_drow_dialog();
while(1)
if( touch_dectect() == touch_pressed)
printf("\r\n 觸控被按下");
else
printf("\r\n 觸控未被按下");
delay_ms(2); //在這裡使用了延時函式每2ms檢測一次狀態,實際使用中要用定時器
i++;
if(i==200)
i=0;
led0=!led0;
分享:釋放潛能:學習效率提公升、程式設計能力提公升
軟硬通吃,嵌入式高薪人才的必殺技
(stm32串列埠應用)
老司機傾囊相授-pcb大牛修煉秘籍
觸控螢幕驅動程式設計
觸控螢幕作為一種輸入裝置,是目前最簡單 方便的一種人機互動方式,具有堅固耐用 反應速度快 節省空間 易於交流等優點。從技術原理來分,觸控螢幕可以分為以下幾類 電阻式觸控螢幕 電容式觸控螢幕 紅外線技術觸控螢幕 表面聲波技術觸控螢幕 向量壓力感測技術觸控螢幕 常用的有電阻式觸控螢幕和電容式觸控螢幕。電...
觸控螢幕程式設計要點
專案實戰派 觸控螢幕程式設計要點 觸控螢幕作為一種更為直接的人機互動方式,現在廣泛運用於智慧型手機 工業控制 場景展示等許多場合。作為程式設計師,如何理解觸控螢幕程式設計?如何做好的觸控螢幕程式設計?現在已經有的資源包括那些?藉著專案牽引,我對這個問題進行一定探索,經驗有限,歡迎批評交流。一 如何理...
ADC觸控螢幕程式設計
根據圖示,我們可知以後程式需要做的事 本節中做的事情是 a.初始化adc b.讀資料 c.在串列埠上顯示出來 根據晶元手冊建立adc.c並新增如下內容 include s3c2440 soc.h void adc init void int adc read ain0 void 新增adc測試函式 ...