原创 触摸屏数字键盘的实现方法

2020-12-2 16:42 5168 29 9 分类: MCU/ 嵌入式

基本思路是使用一个图片,定义图片上各个按键的相对位置以及文本框的相对位置。定义键盘的尺寸

当需要显示键盘时,将图片画出来。

当触屏按下时,计算按下的位置,进行相应操作。

所有按键的尺寸一致,定义按键结构,包含左上相对位置,定义数字框,包含上下左右相对位置。

定义所有键值枚举类型

typedef enum { kc,k1,k2,k3,k4,k5,k6,k7,k8,k9,k0,kd,ko} Keyval;

定义一个四边型尺寸结构,长宽数据可以计算得到。这个结构用于定义边框,数字框,按键的外形尺寸。

typedef{

uint16_t left;

uint16_t top;

uint16_t right;

uint16_t down;

}stRectPosTypeDef;


定义外边框尺寸数据,这些数据需要与按键图片对应,且使用相对位置。

const stRectPosTypeDef stKeyBoardFrame = {0,0,417,171};

定义数字框尺寸数据

const stRectPosTypeDef stDigitalBox = {7,6,71,54}; 

定义单个按键的尺寸信息及键值

typedef{

stRectPos keypos;

Keyval key;

}stKeyTypeDef; 


定义实体按键数量及实体按键信息,所有参数都是像素相对值

#define TOTLEKEY 13

const stKeyTypeDef stDigitalKey[TOTLEKEY]={

  {{347,5,411,53},kc},

  {{5,62,69,110},k1},

  {{73,62,137,110},k2},

  {{142,62,206,110},k3},

  {{210,62,274,110},k4},

  {{279,62,343,110},k5},

  {{5,117,69,165},k6},

  {{73,117,137,165},k7},

  {{142,117,206,165},k8},

  {{210,117,274,165},k9},

  {{279,117,343,165},k0},

  {{347,62,411,110},kd},

  {{347,117,411,165},ko}

};


    使用一个字符串保存键入的数值。返回时使用文本到数值的转换,当调用KeyScan函数时,首先在合适位置,画出键盘的图片。然后等待触摸动作,当得到触摸值后,顺序使用RangeCheck检查触摸值是否在按键的范围里。遍历各个按键位置,一旦为直,即进入UpdataDigital,依据键值,改变用于保存数值的字符串。当检测到为回车时,返回数据值。

 

float KeyScan(uint16_t lcdx,uint16_t lcdy,stKeyBoardTypeDef *pkb){

    uint16_t Ax,Ay;

    uint8_t i,tempstr[20];

    float fltemp;

    stRectPosTypeDef hpos;   

    fltemp = 0;

    tempstr[0] = '\0';

      GUI_DrawBitmap(pkb->pbmp,lcdx,lcdy);

      GUI_SetBkColor(GUI_BLACK);

      GUI_SetColor(GUI_WHITE);

      GUI_ClearRect(lcdx+pkb->pdigitalbox->left,lcdy+pkb->pdigitalbox->top,lcdx+pkb->pdigitalbox->right,lcdy+pkb->pdigitalbox->down);

      GUI_SetFont(pkb->pfont);

      // wait for key

      for(;;){

       GetTp(&Ax,&Ay);   // 获取TP的触摸信息

       ConvertTp(&Ax,&Ay);

       Ax -= lcdx;

       Ay -= lcdy;

       for(i = 0;itotlekey;i++){

         hpos.down = pkb->pkey.keypos.down;

         hpos.top = pkb->pkey.keypos.top;

         hpos.left = pkb->pkey.keypos.left;

         hpos.right = pkb->pkey.keypos.right;

         if(RangeCheck(Ax,Ay,&hpos))  // 检查是否在范围内

           break;

       }

       if(i < pkb->totlekey){   // 检测到按键位置

         if(pkb->pkey.key == ko){

           if(strlen(tempstr) != 0){

             fltemp = atof(tempstr);

             return fltemp;

           }          

         }

         if((tempstr[0]=='0')&&(tempstr[1]=='\0'))

           tempstr[0]='\0';

         UpdataDigital(tempstr,pkb->pkey.key);

         GUI_ClearRect(lcdx+pkb->pdigitalbox->left,lcdy+pkb->pdigitalbox->top,lcdx+pkb->pdigitalbox->right,lcdy+pkb->pdigitalbox->down);

         GUI_DispStringAt(tempstr,lcdx + pkb->pdigitalbox->right - GUI_GetStringDistX(tempstr),

                          lcdy + (pkb->pdigitalbox->top + pkb->pdigitalbox->down )/2 - GUI_GetFontSizeY()/2);

       }

      }

}

 

/*以字符串表示的数据,依据输入按键改变*/

void UpdataDigital(uint8_t *pstr,KeyvalTypeDef key){

  uint16_t temp;

  if(key == ko)

    return;

  if(key == kc){

    pstr[0]='\0';

    return;

  }

  if(key == kd){

    if(strchr(pstr,'.')!=NULL)

      return;

    else{

      if(pstr[0]=='\0')

        strcpy(pstr,"0.");

      else

        strcat(pstr,".");

    }

    return;

  } 

  switch(key){

  case k1:

    strcat(pstr,"1");

    break;

  case k2:

    strcat(pstr,"2");

    break;

  case k3:

    strcat(pstr,"3");

    break;

  case k4:

    strcat(pstr,"4");

    break;

  case k5:

    strcat(pstr,"5");

    break;

  case k6:

    strcat(pstr,"6");

    break;

  case k7:

    strcat(pstr,"7");

    break;

  case k8:

    strcat(pstr,"8");

    break;

  case k9:

    strcat(pstr,"9");

    break;

  case k0:

    if((pstr[0]=='0')&&(pstr[1]=='\0'))

      break;

    else{

      strcat(pstr,"0");

      break;

    }

  default:

    break;

  } 

}


程序初始化GUI 后,在需要改变数值的地方,调用KeyScan,就能获得键入的数据。 



作者: southcreek, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-408807.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

给作者打赏,鼓励TA抓紧创作!

赞赏支持
点赞 29
赞赏0

文章评论1条评论)

登录后参与讨论

curton 2020-12-4 16:38

这个好玩








欢迎点击


论坛> >机器人/工业电子> >工业电子与自动化


https://mbb.eet-china.com/forum/topic/84380_1_1.html
相关推荐阅读
southcreek 2022-11-23 11:04
一个电池掉电报警电路
  有的设备里使用电池作为后备电源,当无交流供电时,切换到电池供电。如果电池未安装,或因为过充、过放保护了。电池无效时,有的设备会有风险。而电池掉电报警电路可以一定程度上降低风险。 此...
southcreek 2022-10-27 09:16
ADC 信号调理电路
ADC 信号调理电路 经常使用MCU中的ADC采集一些信号,成本很低。比如NTC测温、测电源电压、这些都是属于慢变信号。一般使用电阻分压就基本能达到要求。分压电阻的输出阻抗近似等于两个分压电阻并联,对...
southcreek 2022-09-23 16:14
插错电源的后果
这个芯片在上电时冒烟了,表面闪了3个亮点。本来应该3.3V供电的位置被加了20V电压。从3个烧黑的位置分析,这个芯片的管芯被装在正中间,三个烧黑的位置对应芯片供电点。另外C3都鼓成一个小球了。...
southcreek 2022-09-07 13:56
可控硅电路故障的解决过程
     使用晶闸管(也有叫可控硅的)需要交流电过零检测电路。下面这个电路就是做这个过零检测用的。电容C10 D3 D4 D6 D8 C11实际上是阻容降压电路,产生一...
southcreek 2022-08-26 15:56
2022-08-26
看看这个3元包邮镍氢电池充电器是如何做到如此低的成本,还有赚头的。首先看充电器的外观不错的。塑料外壳虽然有点薄,且像是再生料做的,但也中规中矩。尤其是LOGO设计感很强。每个电池位用弹性滑片力度刚好,...
southcreek 2022-08-16 11:24
电路设计中的相对
正常的情况下,79XX是用于负电源系统中,用于产生负的稳定电压。图中当供电电压由-15V 往 -24V变化时,输出电压变化不大,基本上输出接近-12V 确实实现了负电源的稳压功能。 如果板子仅...
我要评论
1
29
1
2
3
4
5
6
7
8
9
0
关闭 热点推荐上一条 /2 下一条