zl程序教程

您现在的位置是:首页 >  其他

当前栏目

STM32物联网项目-触摸按键

项目 联网 STM32 按键 触摸
2023-09-11 14:21:43 时间

触摸按键

硬件电路图

K1,K2,K3,K4是四个触摸按键,C15、C16、C20、C21电容起到调节灵敏度的作用;TP0、TP1、TP2、TP3是按键输入,TPQ0、TPQ1、TPQ2、TPQ3是信号输出,接到了单片机的PE0 ~ PE3引脚

硬件电路图没有用单片机引脚控制触摸芯片的功能引脚,而是直接用V_3V3和GND对功能引脚进行初始化,由图可知

AHLB = 1,LPMB = 1,SM = 0,MOT0 = 0

在这里插入图片描述

触摸芯片TTP224

在这里插入图片描述

因为该芯片有另一种封装,所以数据手册的引脚与硬件电路图的不太一样,多了几个引脚,但主要功能的引脚一样

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

根据硬件电路图得出的功能管脚电平,以及数据手册的管脚默认状态可得该触摸芯片设置的模式为:

TOG = 0,OD = 1,AHLB = 1:直接模式, CMOS输出,低电平有效

SM = 0:单键模式

LPMB = 1:快速模式

所以触摸芯片不用单片机引脚控制,当检测到触摸按键被触摸时,就会在对应的输出引脚输出低电平,再给到32单片机的引脚,所以在程序中只需将引脚配置为外部中断下降沿检测,检测引脚电平状态就知道哪个触摸按键被按下了

CubeMX GPIO配置

在这里插入图片描述

要记得在NVIC中开启外部中断,因为触摸芯片设置为了单键模式,所以两个按键同时被按下没有效果,中断优先级都可以设一样

在这里插入图片描述

外部中断回调函数

CallBack.c

在外部中断回调函数中改变按键的标志位

/*
* @name   HAL_GPIO_EXTI_Callback
* @brief  外部中断回调函数
* @param  GPIO_Pin:触发外部中断的引脚
* @retval None   
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 switch (GPIO_Pin)
 {
   case KEY1_Pin: KEY1.KEY_Flag = TRUE; break;
   case KEY2_Pin: KEY2.KEY_Flag = TRUE; break;
   case KEY3_Pin: KEY3.KEY_Flag = TRUE; break;
   case KEY4_Pin: KEY4.KEY_Flag = TRUE; break;
   default:printf("错误,外部中断回调函数中,触摸按键键值错误!\r\n\r\n");
 }
}

KEY.c

触摸按键1检测函数,与STC15实战的检测函数一样,这里检测单击和长按2秒,其他按键检测与按键1的一样,只是按键号不同而已

继电器的触发函数在Relay.c文件中,比较简单,单片机引脚输出高电平则继电器吸合,输出低电平则继电器断开,是按键4中的按键动作

/*
* @name   KEY1_Detect
* @brief  触摸按键1检测
* @param  None
* @retval None   
*/
static void KEY1_Detect()
{
    uint8_t i;
    if(KEY1.KEY_Flag == TRUE)	//检测按键状态位是否被改变
    {
        KEY1.Click = FALSE;
        KEY1.Press = TRUE;
        //触摸按键长按检测
        for(i = 0;i < 200;i++)
        {
            HAL_Delay(10);
            if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_SET)
            {
                KEY1.Click = TRUE;
                KEY1.Press = FALSE;
                break;
            }
        }

        //按键动作
        //单击
        if(KEY1.Click == TRUE)
        {
            printf("检测到触摸按键1单击\r\n");
            LED.LED_Fun(LED1,LED_Flip);     //翻转LED1电平状态
        }
        //长按
        if(KEY1.Press == TRUE)
        {
            printf("检测到触摸按键1长按\r\n");
            LED.LED_Fun(LED1,LED_Flip);
            HAL_Delay(200);
            LED.LED_Fun(LED1,LED_Flip);
        }

        //清除标志位
        KEY1.KEY_Flag   = FALSE;
        KEY1.Click      = FALSE;
        KEY1.Press      = FALSE;
    }
}

System.c

系统运行函数中不断检测按键状态

/*
* @name   Run
* @brief  系统运行
* @param  None
* @retval None   
*/
static void Run()
{
  //触摸按键检测
  KEY1.KEY_Detect();
  KEY2.KEY_Detect();
  KEY3.KEY_Detect();
  KEY4.KEY_Detect();
}

实验效果

在这里插入图片描述