<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

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

      引言

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

      主控板

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

      image

      屏幕

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

      image

      觸摸屏 IC:GT1151Q

      數據手冊:

      GT1151Q 帶自定義手勢喚醒功能的電容觸控芯片

      編程指南:

      GT1151Q 編程指南

      觸控引腳

      主控引腳

      不同主控板的引腳位置會有所不同,我使用的是反客家的 STM32H743IIT6,這里使用的引腳是:

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

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

      image

      CubeMX 配置

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

      image

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

      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  膝蓋中箭衛兵  閱讀(11)  評論(0)    收藏  舉報
      ORCID iD icon https://orcid.org/0000-0001-5102-772X
      主站蜘蛛池模板: 阿克苏市| 日韩大片看一区二区三区| 不卡高清AV手机在线观看 | 亚洲久悠悠色悠在线播放| 国产一级小视频| 精品乱码一区二区三四五区| 国产亚洲欧美精品久久久| 天堂国产一区二区三区| 亚洲欧洲日产国产 最新| 国产精品老熟女乱一区二区| 蜜桃无码一区二区三区| 国产无人区码一区二区| 天堂资源在线| 蜜桃伦理一区二区三区| 国产免费无遮挡吃奶视频| 久久精品国产99亚洲精品| 欧美成人精品三级在线观看| 真人抽搐一进一出视频| 国产91精品一区二区亚洲| 亚洲av激情久久精品人| 亚洲AV无码破坏版在线观看| 日本丶国产丶欧美色综合| 国产精品色内内在线观看| 少妇人妻偷人精品免费| 亚洲性日韩精品一区二区三区| 一区二区在线观看成人午夜| 国产欧美精品一区aⅴ影院| 日本精品极品视频在线| 亚洲国产在一区二区三区| 尹人香蕉久久99天天拍| 国产一区| 中国老太婆video| 人人妻人人爽人人澡av| 精品久久丝袜熟女一二三| 免费a级毛片无码av| 扒开女人内裤猛进猛出免费视频| 亚洲国产精品成人综合色在| 国产一区二区不卡在线| 亚洲日本中文字幕乱码中文| 亚洲午夜爱爱香蕉片| 黄网站色视频免费观看|