基于STM32F407和TFT电阻屏的触摸屏幕按键发送指令方案

前言

在电赛控制类项目中,功能切换通常需要借助按键指令实现。传统方案多采用外接实体按键,通过检测按键高电平状态来发送指令。针对这一需求,我提出了一种更为高效的按键实现方案。

答案就是触摸屏按键 

触摸屏按键不需要额外接线,同时能快速添加多种需要向串口发送的指令以实现不同的功能

硬件准备

正点原子STM32F407ZGT6核心板,2.8寸TFT触摸屏

代码实现

需要做的就是写好显示和触摸的驱动,然后打开串口,实现把触摸的数据发送到串口的功能

lcd和触摸屏的驱动官方例程会提供,这里不赘述,评论区会提供工程文件

绘制按键代码,可根据需求增加或减少

static void init_keypad(void)
{
    uint16_t w = lcddev.width  / 3;
    uint16_t h = lcddev.height;
    uint16_t xs, ys = 0, xe, ye = h - 1;
    uint8_t  i, num = 1;

    for (i = 0; i < 3; i++)
    {
        xs = i * w;
        xe = xs + w - 1;

        keytab[i].x0  = xs;
        keytab[i].y0  = ys;
        keytab[i].x1  = xe;
        keytab[i].y1  = ye;
        keytab[i].cmd = num;

        // 白底
        LCD_Fill(xs, ys, xe, ye, WHITE);
        // 黑色边框
        LCD_Fill(xs, ys, xe, ys, BLACK);
        LCD_Fill(xs, ye, xe, ye, BLACK);
        LCD_Fill(xs, ys, xs, ye, BLACK);
        LCD_Fill(xe, ys, xe, ye, BLACK);
        // 居中数字
        POINT_COLOR = BLACK;
        LCD_ShowChar(xs + w/2 - 8, (h/2) - 8, '0' + num, 16, 0);

        num++;
    }
}

绘制按键反馈代码(可以判断有无触摸)

static void draw_key(uint8_t idx, uint8_t pressed)
{
    uint16_t bg = pressed ? GREEN : WHITE;
    uint16_t xs = keytab[idx].x0;
    uint16_t ys = keytab[idx].y0;
    uint16_t xe = keytab[idx].x1;
    uint16_t ye = keytab[idx].y1;
    uint16_t w  = xe - xs + 1;
    uint16_t h  = ye - ys + 1;

    // 背景
    LCD_Fill(xs, ys, xe, ye, bg);
    // 边框
    LCD_Fill(xs, ys, xe, ys, BLACK);
    LCD_Fill(xs, ye, xe, ye, BLACK);
    LCD_Fill(xs, ys, xs, ye, BLACK);
    LCD_Fill(xe, ys, xe, ye, BLACK);
    // 数字
    POINT_COLOR = BLACK;
    LCD_ShowChar(xs + w/2 - 8, ys + h/2 - 8, '0' + keytab[idx].cmd, 16, 0);
}

触摸功能实现

static void keypad_test(void)
{
    uint16_t rawX, px;
    uint8_t  cur, prev, pressedIdx;
    uint8_t  i;

    // 初始状态
    prev       = 0;
    pressedIdx = 0xFF;

    init_keypad();

    while (1)
    {
        // 更新触摸
        tp_dev.scan(0);
        cur = (tp_dev.sta & TP_PRES_DOWN) ? 1 : 0;

        // 刚按下(0→1)
        if (cur && !prev)
        {
            rawX = tp_dev.x[0];
            px   = mapX(rawX);

            // 检测哪个按钮
            for (i = 0; i < 3; i++)
            {
                if (px >= keytab[i].x0 && px <= keytab[i].x1)
                {
                    pressedIdx = i;
                    draw_key(i, 1);
                    send_cmd(keytab[i].cmd);
                    break;
                }
            }
        }

        // 刚松开(1→0)
        if (!cur && prev)
        {
            if (pressedIdx < 3)
            {
                draw_key(pressedIdx, 0);
                pressedIdx = 0xFF;
            }
        }

        prev = cur;
        delay_ms(20);
    }
}

主函数

int main(void)
{
    HAL_Init();
    Stm32_Clock_Init(336, 8, 2, 7);
    delay_init(168);
    uart_init(115200);
    LED_Init();
    KEY_Init();
    LCD_Init();
    tp_dev.init();  // 触摸初始化
		LCD_Display_Dir(1);

    POINT_COLOR = RED;
    LCD_ShowString(20, 30, 200, 16, 16, "三键水平测试");
    delay_ms(800);
    LCD_Clear(WHITE);

    keypad_test();
    return 0;
}

由此完成开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值