同以往文章一样,会附上几个讲理论的优质博客链接,本文重点讲怎么用代码实现。

  • 按键:

lcd_showint8(0,0,P37);

 p37接一个按键,按键没按下显示0,按下显示1;这个很简单,但是怎么用呢?

假如我想按一次按键,屏幕刷新一次,如果我这样写,会发生什么?

if(P37==1)lcd_clear();

如果我按一下按键,理论上会有P37==0,P37==1,P37==0,三个阶段,

按键P37==1的时候会一直刷新,没有达到只刷新一次的要求,

所以我们通常检测按键的动作并不是检测一个固定的电平值,而是检测电平值的变化,即按键在按下和弹起这两种状态之间的变化,只要发生了这种变化就说明现在按键产生动作了。

 51单片机入门——矩阵按键_倾晨灬雨曦的博客-CSDN博客_矩阵按键

三行代码按键消抖 独立按键 矩阵按键 长按 短按 双击_#法外狂徒张三的博客-CSDN博客_按键三行代码

 上面两篇文章对按键讲的很详细,下面我来讲一下,如何用代码来实现按键扫描——长按,短按,没按。

先建立一个枚举,表示按键的三种状态

typedef enum
{
    nopress = 0,
    onepress,
    holdpress,
} KeyStateEnum;
 
extern KeyStateEnum Key1;
 
#define KEY_ONE     P37
void KeyParams_Init(void)//按键初始化
{
    Key1 = nopress;
 
}

     按键扫描函数,放进中断里

    void KeyScanInt(void)
    {
        static uint8 KeyPressNum = 0;
        static uint16 KeyPressTime = 0;
        static uint8 SomeKeyPress_Flag = 0;//0 松开 1按下  2:消抖 3:长按
        #define AlwaysPressTime 1600//一直按检测时间
        #define debouncing  5
        if(SomeKeyPress_Flag == 0 && (KEY_ONE == 0))
        {
             SomeKeyPress_Flag = 1;
        }
        if(SomeKeyPress_Flag > 0)
        {
            KeyPressTime ++;
            //5ms消抖
            if(SomeKeyPress_Flag == 1 && KeyPressTime >= debouncing)
            {
                SomeKeyPress_Flag = 2;
                if(KEY_ONE == 0)
                    KeyPressNum = 1;//¼ì²â°´¼ü°´ÏÂ
            }
            //按一下松开
            if((KEY_ONE == 1) && KeyPressTime < AlwaysPressTime && SomeKeyPress_Flag == 2)
            {
                SomeKeyPress_Flag = 0;//°´¼üËÉ¿ªÁË
                if(KeyPressNum == 1)
                    Key1 = onepress;
            }
            //长按
            if(KeyPressTime >= AlwaysPressTime && SomeKeyPress_Flag == 2)
            {
                if(KeyPressNum == 1)      Key1 = holdpress;
                if(KEY_ONE == 1)
                {
                    SomeKeyPress_Flag = 0;
                    KeyPressTime = 0;
                    Key1 = nopress;
                }
            }
        }
    }
    
    
      
      

       这个是一个按键的按键扫描,如果有多个按键按,读懂代码之后加几个&&和||就行

      按键扫描模块,.c.h文件-C文档类资源-CSDN下载

      我这里的文件是写了四个按键,有需要的自己拿就行。

      使用:

      将KeyParams_Init放在初始化位置

      将KeyScanInt放在定时器中断

      应用:这是我写的按键调参的一部分

      //应用
      if(KeyRight == onepress)
      {
          KeyRight = nopress;
          now -= step * 10;
      }
      while(KeyCenter == holdpress)
      {
          now += step;
          delay_ms(5);
          ips114_showint16(pos_x,pos_y,now);
      }


      •  按键调参:

      uint8 ParamsAdjustUint16(uint16 *p,uint16 pos_x,uint16 pos_y,short step)
      {
          //读取
          uint16 now = *p;
          IPS114_PENCOLOR = PURPLE;
          while(KeyNext != onepress)
          {
              if(KeyLeft == onepress)
              {
                  KeyLeft = nopress;
                  now += step * 10;
              }
              if(KeyRight == onepress)
              {
                  KeyRight = nopress;
                  now -= step * 10;
              }
      		while(KeyCenter == holdpress)
      		{
      		now += step;
      		delay_ms(50);
      		ips114_showuint16(pos_x,pos_y,now);
      		}
              if(KeyUp == onepress)
              {
                  KeyUp = nopress;
                  now += step;
              }
              if(KeyDown == onepress)
              {
                  KeyDown = nopress;
                  now -= step;
              }
              ips114_showuint16(pos_x,pos_y,now);
          }
          KeyNext = nopress;
          IPS114_PENCOLOR = RED;
          *p = now;
       
          return 1;
      }
      
      
      
      
      
      

      这是调Uint16类型数据的函数,其他的你按照这个改就行,

      这里是按KeyNext(按键)进入调参页面,上下左右中,对应执行数据的增减,这里按照你们的按键数量改就行。

      //使用
      ParamsAdjustUint16(&IslandSpeed,120,3,5);

      我这里整理了,这些常见的,限于篇幅

      uint8 ParamsAdjustFloat(float *p,uint16 pos_x,uint16 pos_y,float step);		//调整float参数
      uint8 ParamsAdjustShort(short *p,uint16 pos_x,uint16 pos_y,short step);		//调整short参数
      uint8 ParamsAdjustUint16(uint16 *p,uint16 pos_x,uint16 pos_y,short step);	//调整uint16参数
      uint8 ParamsAdjustUint8(uint8 *p,uint16 pos_x,uint16 pos_y,uint8 step);		//调整uint8参数
      uint8 ParamsAdjustInt(int *p,uint16 pos_x,uint16 pos_y,short step);//调整int参数
      uint8 StateAdjust(uint8 *p,uint16 pos_x,uint16 pos_y);	//调整'T''F'参数 为是或者否
      uint8 DirAdjust(uint8 *p,uint16 pos_x,uint16 pos_y);	//调整'L''R'参数 为左或者右
      float Float_QuZheng(float xiaoshu,uint8 mode);//小数点后取整

      有需要的自己拿就行。