中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

【LTDC】RGB LCD 電容觸摸屏(ping)的配置和(he)程序

引言

配(pei)置好(hao) RGB LCD 的顯示之后,就可(ke)以配(pei)置其觸(chu)摸的功能(neng)了。電容觸(chu)摸屏的驅動方式格外的簡單,下面由我一(yi)一(yi)道來(lai)(觸(chu)摸檢測的本質上(shang)就是電容交互式的感應,然(ran)后通過(guo) IC 的通訊協議(yi)來(lai)傳輸(shu)寄存器上(shang)的數據。

主控板

STM32H743開發板 核心板 小系統板 反客 STM32H743IIT6

image

屏幕

正點原子 4.3寸 RGB LCD 交互電容式接觸顯示屏 ST7262E43
正點原(yuan)子的屏幕要接上反客的 RGB 接口(kou)則需(xu)要一(yi)個轉接板,可(ke)以(yi)自己花,當(dang)然反客家也有,需(xu)要單獨購買。

image

觸摸屏 IC:GT1151Q

數據手冊:

編程指南:

觸控引腳

主控引腳

不同主(zhu)控(kong)板(ban)的(de)引腳位置會有所不同,我使用的(de)是反客家的(de) STM32H743IIT6,這里(li)使用的(de)引腳是:

TOUCH_RST ---- PH4(復位引腳)
TOUCH_INT ---- PG3(中斷引腳)
TOUCH_SCLK ---- PI11(IIC 時鐘線)
TOUCH_SDA ---- PI8(IIC 數據線)

下圖是反客所提供的接口原理圖:

image

CubeMX 配置

查看了一下觸控對應引腳的功能,發現并沒有復用做 IIC 功能的,說明我們需要使用軟件 IIC 去讀取觸摸的數據。

image

SDA ---- 開漏輸出 低速 上拉
SCL ---- 開漏輸出 低速 上拉
RST ---- 推挽輸出 超高速 上拉
INT ---- 輸入模(mo)式 浮空

  1. 由于在配置中 SDA 對應引腳只有低速模式,為了匹配 SDA 的速度保證通訊的穩定性,SCL 也選擇了低速,而且也只是讀取觸摸數據,50MHz 也足夠用了。
  2. 復位引腳初始化為上拉,方便后續拉低來復位。
  3. INT 為中斷引腳,給主控芯片發送中斷讀取信號,如果要使用的話,這個引腳則要開啟 EXTI,否則就是單純的阻塞式讀取。

程序編寫

這個 IC 廠家提供了一份編程指南(在上面),我們可以跟著寫就好,假如對于商家提供的已經寫好的驅動程序,我們配合著這個指南,也更好理解。下面是我修改好的程序,想要讀懂程序則需要配合著此 IC 手冊和指南,要熟悉 IC 中的某些寄存器,程序大體上無非就是:讀取 IC 寄存器、寫入 IC 寄存器、初始化接口程序,以及掃描讀取程序。仔細閱讀下來半個小時就明白了!

touch_800x480.c

點擊查看代碼
#include "touch_800x480.h"

GTXXXX_TouchTypeDef gtxxxx_dev; /* 觸摸屏設備結構體 */

/* 注意: 除了GT9271支持10點觸摸之外, 其他觸摸芯片只支持 5點觸摸 */
volatile uint8_t g_gt_tnum = 5; /* 默認支持的觸摸屏點數(5點觸摸) */

/* GTXXXX 10個觸摸點(最多) 對應的寄存器表 */
const uint16_t GTXXXX_TPX_TBL[10] =
    {
        GTXXXX_TP1_REG,
        GTXXXX_TP2_REG,
        GTXXXX_TP3_REG,
        GTXXXX_TP4_REG,
        GTXXXX_TP5_REG,
        GTXXXX_TP6_REG,
        GTXXXX_TP7_REG,
        GTXXXX_TP8_REG,
        GTXXXX_TP9_REG,
        GTXXXX_TP10_REG,
};

/**
 * @brief       向GTXXXX寫入一次數據
 * @param       reg : 起始寄存器地址
 * @param       buf : 數據緩緩存區
 * @param       len : 寫數據長度
 * @retval      0, 成功; 1, 失敗;
 */
uint8_t gtxxxx_wr_reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
    uint8_t i;
    uint8_t ret = 0;
    bsp_iic_start();
    bsp_iic_send_byte(GTXXXX_CMD_WR); /* 發送寫命令 */
    bsp_iic_wait_ack();
    bsp_iic_send_byte(reg >> 8); /* 發送高8位地址 */
    bsp_iic_wait_ack();
    bsp_iic_send_byte(reg & 0XFF); /* 發送低8位地址 */
    bsp_iic_wait_ack();

    for (i = 0; i < len; i++)
    {
        bsp_iic_send_byte(buf[i]); /* 發數據 */
        ret = bsp_iic_wait_ack();

        if (ret)
            break;
    }

    bsp_iic_stop(); /* 產生一個停止條件 */
    return ret;
}

/**
 * @brief       從GTXXXX讀出一次數據
 * @param       reg : 起始寄存器地址
 * @param       buf : 數據緩緩存區
 * @param       len : 讀數據長度
 * @retval      無
 */
void gtxxxx_rd_reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
    uint8_t i;
    bsp_iic_start();
    bsp_iic_send_byte(GTXXXX_CMD_WR); /* 發送寫命令 */
    bsp_iic_wait_ack();
    bsp_iic_send_byte(reg >> 8); /* 發送高8位地址 */
    bsp_iic_wait_ack();
    bsp_iic_send_byte(reg & 0XFF); /* 發送低8位地址 */
    bsp_iic_wait_ack();
    bsp_iic_start();
    bsp_iic_send_byte(GTXXXX_CMD_RD); /* 發送讀命令 */
    bsp_iic_wait_ack();

    for (i = 0; i < len; i++)
    {
        buf[i] = bsp_iic_read_byte(i == (len - 1) ? 0 : 1); /* 讀取數據 */
    }

    bsp_iic_stop(); /* 產生一個停止條件 */
}

/**
 * @brief       初始化GTXXXX觸摸屏
 * @param       無
 * @retval      0, 初始化成功; 1, 初始化失敗;
 */
uint8_t gtxxxx_init(void)
{
    ///////////////// 復位操作 /////////////////
    bsp_iic_init(); /* 初始化電容屏的I2C總線 */
    GTXXXX_RST(0);  /* 復位 */
    delay_ms(10);   /* 復位保持10ms以上 */
    GTXXXX_RST(1);  /* 釋放復位 */
    delay_ms(40);   /* 最低40ms,否則以上操作不成功,后續無法讀取 */

    ///////////////// 讀取id /////////////////
    gtxxxx_rd_reg(GTXXXX_PID_REG, gtxxxx_dev.id, ID_LENGTH); /* 讀取產品ID */
    /* 判斷一下是否是特定的觸摸屏 */
    if (strcmp((char *)gtxxxx_dev.id, "911") && strcmp((char *)gtxxxx_dev.id, "9147") && strcmp((char *)gtxxxx_dev.id, "1158") && strcmp((char *)gtxxxx_dev.id, "9271"))
    {
        return 1; /* 若不是觸摸屏用到的GT911/9147/1158/9271,則初始化失敗,需硬件查看觸摸IC型號以及查看時序函數是否正確 */
    }
    printf("CTP ID:%s\r\n", gtxxxx_dev.id);         /* 打印ID */
    if (strcmp((char *)gtxxxx_dev.id, "9271") == 0) /* 假如ID==9271, 支持10點觸摸 */
        g_gt_tnum = 10;                             /* 支持10點觸摸屏 */

    gtxxxx_dev.id[0] = 0X02;                          /* 差值原始值(校準) */
    gtxxxx_wr_reg(GTXXXX_CTRL_REG, gtxxxx_dev.id, 1); /* 軟復位GTXXXX */

    delay_ms(10); /* 復位后延時 */

    gtxxxx_dev.id[0] = 0X00;                          /* 讀坐標狀態 */
    gtxxxx_wr_reg(GTXXXX_CTRL_REG, gtxxxx_dev.id, 1); /* 結束復位, 進入讀坐標狀態 */

    return 0;
}

/**
 * @brief       掃描觸摸屏(采用查詢方式)
 * @param       無
 */
uint8_t gtxxxx_scan(void)
{
    uint8_t mode;
    uint8_t buf[4];
    uint8_t i = 0;
    uint8_t res = 0; /* 返回值 */
    uint16_t temp;
    uint16_t tempsta;
    static uint8_t t = 0; /* 控制查詢間隔,從而降低CPU占用率 */
    t++;

    if ((t % 10) == 0 || t < 10) /* 空閑時,每進入10次CTP_Scan函數才檢測1次,從而節省CPU使用率 */
    {
        gtxxxx_rd_reg(GTXXXX_GSTID_REG, &mode, 1);        /* 讀取觸摸點的狀態 */
        if ((mode & 0X80) && ((mode & 0XF) <= g_gt_tnum)) /* 觸點數量小于g_gt_tnum == 5 */
        {
            i = 0;
            gtxxxx_wr_reg(GTXXXX_GSTID_REG, &i, 1); /* 清標志 */
        }

        if ((mode & 0XF) && ((mode & 0XF) <= g_gt_tnum)) /* 觸點數量小于g_gt_tnum == 5 */
        {
            temp = 0XFFFF << (mode & 0XF); /* 將點的個數轉換為1的位數,匹配tp_dev.sta定義 */
            printf("temp = %X\r\n", temp); /* 調試:temp*/
            tempsta = gtxxxx_dev.sta;      /* 保存當前的tp_dev.sta值 */
            gtxxxx_dev.sta = (~temp) | TP_PRES_DOWN | TP_CATH_PRES;
            gtxxxx_dev.x[g_gt_tnum - 1] = gtxxxx_dev.x[0]; /* 保存觸點0的數據,保存在最后一個上 */
            gtxxxx_dev.y[g_gt_tnum - 1] = gtxxxx_dev.y[0];

            for (i = 0; i < g_gt_tnum; i++)
            {
                if (gtxxxx_dev.sta & (1 << i)) /* 觸摸有效? */
                {
                    /* 讀取XY坐標值 */
                    gtxxxx_rd_reg(GTXXXX_TPX_TBL[i], buf, 4);
                    gtxxxx_dev.x[i] = ((uint16_t)buf[1] << 8) + buf[0];
                    gtxxxx_dev.y[i] = ((uint16_t)buf[3] << 8) + buf[2];
                    printf("x[%d]:%d,y[%d]:%d\r\n", i, gtxxxx_dev.x[i], i, gtxxxx_dev.y[i]);
                }
            }
            printf("被按下后狀態變化\r\n");
            printf("sta & (TP_PRES_DOWN >> 15) = %X\r\n", gtxxxx_dev.sta & (TP_PRES_DOWN >> 15));
            res = 1;

            if (gtxxxx_dev.x[0] > PWIDTH || gtxxxx_dev.y[0] > PHEIGHT) /* 非法數據(坐標超出了) */
            {
                if ((mode & 0XF) > 1) /* 有其他點有數據,則復第二個觸點的數據到第一個觸點. */
                {
                    gtxxxx_dev.x[0] = gtxxxx_dev.x[1];
                    gtxxxx_dev.y[0] = gtxxxx_dev.y[1];
                    t = 0; /* 觸發一次,則會最少連續監測10次,從而提高命中率 */
                }
                else /* 非法數據,則忽略此次數據(還原原來的) */
                {
                    gtxxxx_dev.x[0] = gtxxxx_dev.x[g_gt_tnum - 1];
                    gtxxxx_dev.y[0] = gtxxxx_dev.y[g_gt_tnum - 1];
                    mode = 0X80;
                    gtxxxx_dev.sta = tempsta; /* 還原sta狀態 */
                }
            }
            else
            {
                t = 0; /* 觸發一次,則會最少連續監測10次,從而提高命中率 */
            }
        }
    }

    if ((mode & 0X8F) == 0X80) /* 無觸摸點按下 */
    {
        if (gtxxxx_dev.sta & (TP_PRES_DOWN >> 15)) /* 之前是被按下的 */
        {
            gtxxxx_dev.sta &= ~(TP_PRES_DOWN >> 15); /* 標記按鍵松開 */
            printf("被按下后再標記按鍵松開狀態\r\n");
            printf("sta & (TP_PRES_DOWN >> 15) = %X\r\n", gtxxxx_dev.sta & (TP_PRES_DOWN >> 15));
        }
        else /* 之前就沒有被按下 */
        {
            gtxxxx_dev.x[0] = 0xffff;
            gtxxxx_dev.y[0] = 0xffff;
            gtxxxx_dev.sta &= 0XE000; /* 清除點有效標記 */
        }
    }
    if (t > 240)
        t = 10; /* 重新從10開始計數 */

    return res;
}

touch_800x480.h

點擊查看代碼
#ifndef __TOUCH_800X480_H__
#define __TOUCH_800X480_H__

#include "headers.h"

#define TP_PRES_DOWN 0x8000 /* 觸屏被按下 */
#define TP_CATH_PRES 0x4000 /* 有按鍵按下了 */
#define CT_MAX_TOUCH 10     /* 電容屏支持的點數,固定為5點 */
#define ID_LENGTH 4         /* 4字節ID */

/* GTXXXX INT 和 RST 引腳 定義 */
#define GTXXXX_RST_GPIO_PORT GPIOH
#define GTXXXX_RST_GPIO_PIN GPIO_PIN_4
#define GTXXXX_RST_GPIO_CLK_ENABLE()  \
    do                                \
    {                                 \
        __HAL_RCC_GPIOI_CLK_ENABLE(); \
    } while (0) /* PI口時鐘使能 */

#define GTXXXX_INT_GPIO_PORT GPIOG
#define GTXXXX_INT_GPIO_PIN GPIO_PIN_3
#define GTXXXX_INT_GPIO_CLK_ENABLE()  \
    do                                \
    {                                 \
        __HAL_RCC_GPIOH_CLK_ENABLE(); \
    } while (0) /* PH口時鐘使能 */

/* 與電容觸摸屏連接的芯片引腳(未包含IIC引腳)
 * IO操作函數
 */
#define GTXXXX_RST(x)                                                                                                                                    \
    do                                                                                                                                                   \
    {                                                                                                                                                    \
        x ? HAL_GPIO_WritePin(TOUCH_RST_GPIO_Port, TOUCH_RST_Pin, GPIO_PIN_SET) : HAL_GPIO_WritePin(TOUCH_RST_GPIO_Port, TOUCH_RST_Pin, GPIO_PIN_RESET); \
    } while (0) /* 復位引腳 */

#define GTXSXXX_INT HAL_GPIO_ReadPin(TOUCH_INT_GPIO_Port, TOUCH_INT_Pin) /* 讀取中斷引腳 */

/* IIC讀寫命令 */
#define GTXXXX_CMD_WR 0X28 /* 寫命令 */
#define GTXXXX_CMD_RD 0X29 /* 讀命令 */

/* GT9XXX 部分寄存器定義  */
#define GTXXXX_CTRL_REG 0X8040  /* GTXXXX控制寄存器 */
#define GTXXXX_CFGS_REG 0X8047  /* GTXXXX配置起始地址寄存器 */
#define GTXXXX_CHECK_REG 0X80FF /* GTXXXX校驗和寄存器 */
#define GTXXXX_PID_REG 0X8140   /* GTXXXX產品ID寄存器 */

#define GTXXXX_GSTID_REG 0X814E /* GTXXXX當前檢測到的觸摸情況 */
#define GTXXXX_TP1_REG 0X8150   /* 第一個觸摸點數據地址 */
#define GTXXXX_TP2_REG 0X8158   /* 第二個觸摸點數據地址 */
#define GTXXXX_TP3_REG 0X8160   /* 第三個觸摸點數據地址 */
#define GTXXXX_TP4_REG 0X8168   /* 第四個觸摸點數據地址 */
#define GTXXXX_TP5_REG 0X8170   /* 第五個觸摸點數據地址 */
/* 僅僅9271支持十個觸點 */
#define GTXXXX_TP6_REG 0X8178  /* 第六個觸摸點數據地址 */
#define GTXXXX_TP7_REG 0X8180  /* 第七個觸摸點數據地址 */
#define GTXXXX_TP8_REG 0X8188  /* 第八個觸摸點數據地址 */
#define GTXXXX_TP9_REG 0X8190  /* 第九個觸摸點數據地址 */
#define GTXXXX_TP10_REG 0X8198 /* 第十個觸摸點數據地址 */

typedef struct
{
    uint16_t x[CT_MAX_TOUCH];      /* 觸摸點X坐標 */
    uint16_t y[CT_MAX_TOUCH];      /* 觸摸點Y坐標 */
    uint16_t last_x[CT_MAX_TOUCH]; /* 上一次觸摸點X坐標 */
    uint16_t last_y[CT_MAX_TOUCH]; /* 上一次觸摸點Y坐標 */
    uint8_t sta;                   /* 觸摸狀態 */
    uint8_t id[ID_LENGTH];         /* 觸摸屏id */
} GTXXXX_TouchTypeDef;

extern GTXXXX_TouchTypeDef gtxxxx_dev; /* 觸摸屏設備結構體 */

uint8_t gtxxxx_wr_reg(uint16_t reg, uint8_t *buf, uint8_t len);
void gtxxxx_rd_reg(uint16_t reg, uint8_t *buf, uint8_t len);
uint8_t gtxxxx_init(void);
uint8_t gtxxxx_scan(void);

#endif //__TOUCH_800X480_H__

博客導航

博客導航

posted @ 2025-11-04 10:27  膝蓋中箭衛兵  閱讀(13)  評論(0)    收藏  舉報