觸控螢幕學習 利用狀態機程式設計

2021-09-29 20:43:59 字數 4358 閱讀 5403

一。更高效的使用觸控螢幕

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測試函式 ...