• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

CST816S触摸驱动

武飞扬头像
Distance_90
帮助1

本文针对淘宝所购买的1.69寸LCD触摸屏驱动进行讲解。

学新通

屏幕购买链接如下:

1.69寸全视角IPSTFT彩屏 液晶显示屏SPI位接口ST7789V驱动工业屏-淘宝网 (taobao.com) 

我们先搞一下IIC驱动

  1.  
    #define CST816_SCL_Clr() HAL_GPIO_WritePin(TP_SCL_GPIO_Port,TP_SCL_Pin, GPIO_PIN_RESET)//SCL=SCLK
  2.  
    #define CST816_SCL_Set() HAL_GPIO_WritePin(TP_SCL_GPIO_Port,TP_SCL_Pin, GPIO_PIN_SET)
  3.  
     
  4.  
    #define CST816_SDA_IN() GPIO_InitStruct.Pin = TP_SDA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(TP_SDA_GPIO_Port, &GPIO_InitStruct)
  5.  
    #define CST816_SDA_Get() HAL_GPIO_ReadPin(TP_SDA_GPIO_Port,TP_SDA_Pin)
  6.  
     
  7.  
    #define CST816_SDA_OUT() GPIO_InitStruct.Pin = TP_SDA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(TP_SDA_GPIO_Port, &GPIO_InitStruct)
  8.  
    #define CST816_SDA_Clr() HAL_GPIO_WritePin(TP_SDA_GPIO_Port,TP_SDA_Pin, GPIO_PIN_RESET)
  9.  
    #define CST816_SDA_Set() HAL_GPIO_WritePin(TP_SDA_GPIO_Port,TP_SDA_Pin, GPIO_PIN_SET)

由于我所用到的是HAL库,所以这里针对IIC驱动做了宏定义。

用标准库的开发者可以根据需要进行改动。

  1.  
    //模拟IIC部分的函数声明
  2.  
    void CST816_IIC_ACK(void);
  3.  
    void CST816_IIC_NACK(void);
  4.  
    unsigned char CST816_IIC_Wait_ACK(void);
  5.  
    void CST816_IIC_Start(void);
  6.  
    void CST816_IIC_Stop(void);
  7.  
    void CST816_IIC_SendByte(unsigned char byte);
  8.  
    void CST816_IIC_WriteREG(unsigned char reg,unsigned char date);
  9.  
    unsigned char CST816_IIC_ReadREG(unsigned char reg);
  10.  
    unsigned char CST816_IIC_RecvByte(void);

我们IIC的目的是对CST816的寄存器进行读写,所以根据手册内容,我们做出下面的寄存器声明

  1.  
    //CST816寄存器
  2.  
    #define GestureID 0x01 //手势寄存器
  3.  
    #define FingerNum 0x02 //手指数量
  4.  
    #define XposH 0x03 //x高四位
  5.  
    #define XposL 0x04 //x低八位
  6.  
    #define YposH 0x05 //y高四位
  7.  
    #define YposL 0x06 //y低八位
  8.  
    #define ChipID 0xA7 //芯片型号
  9.  
    #define MotionMask 0xEC //触发动作
  10.  
    #define AutoSleepTime 0xF9 //自动休眠
  11.  
    #define IrqCrl 0xFA //中断控制
  12.  
    #define AutoReset 0xFB //无手势休眠
  13.  
    #define LongPressTime 0xFC //长按休眠
  14.  
    #define DisAutoSleep 0xFE //使能低功耗模式

多数寄存器我们是不需要去打理的,我们最关心的是XposH、XposL、YposH、YposL用于读取手指触摸位置的坐标,以及FingerNum用于读取触摸状态

  1.  
    typedef struct
  2.  
    {
  3.  
    unsigned char chipID;
  4.  
    unsigned int X_Pos; //X坐标
  5.  
    unsigned int Y_Pos; //Y坐标
  6.  
    unsigned char Sta; //记录触摸状态
  7.  
    }CST816_Info;

接下来我们创建触摸屏实例,用于触摸屏的信息管理,内容包括芯片ID,X\Y坐标,以及触摸状态等。

下面是函数实现

  1.  
    //IIC驱动实现
  2.  
    #include "CST816.h"
  3.  
    #include "math.h"
  4.  
     
  5.  
     
  6.  
    CST816_Info CST816_Instance; //创建CST816实例。
  7.  
     
  8.  
    #define delay_num 4 //宏定义延时时间
  9.  
     
  10.  
     
  11.  
     
  12.  
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  13.  
     
  14.  
    //IIC起始信号
  15.  
    void CST816_IIC_Start(void)
  16.  
    {
  17.  
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  18.  
     
  19.  
    CST816_SDA_OUT();
  20.  
     
  21.  
    CST816_SDA_Set();
  22.  
    CST816_SCL_Set();
  23.  
    delay_us(delay_num);
  24.  
    CST816_SDA_Clr();
  25.  
    delay_us(delay_num);
  26.  
    CST816_SCL_Clr();
  27.  
    }
  28.  
     
  29.  
    //IIC停止信号
  30.  
    void CST816_IIC_Stop(void)
  31.  
    {
  32.  
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  33.  
    CST816_SDA_OUT();
  34.  
     
  35.  
    CST816_SCL_Clr();
  36.  
    CST816_SDA_Clr();
  37.  
    delay_us(delay_num);
  38.  
    CST816_SCL_Set();
  39.  
    CST816_SDA_Set();
  40.  
    delay_us(delay_num);
  41.  
    }
  42.  
     
  43.  
    //发送ACK应答
  44.  
    void CST816_IIC_ACK(void)
  45.  
    {
  46.  
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  47.  
    CST816_SDA_OUT();
  48.  
     
  49.  
    CST816_SCL_Clr();
  50.  
    CST816_SDA_Clr();
  51.  
    delay_us(delay_num);
  52.  
    CST816_SCL_Set();
  53.  
    delay_us(delay_num);
  54.  
    CST816_SCL_Clr();
  55.  
    }
  56.  
     
  57.  
    //发送NACK不应答
  58.  
    void CST816_IIC_NACK(void)
  59.  
    {
  60.  
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  61.  
    CST816_SDA_OUT();
  62.  
     
  63.  
    CST816_SCL_Clr();
  64.  
    CST816_SDA_Set();
  65.  
    delay_us(delay_num);
  66.  
    CST816_SCL_Set();
  67.  
    delay_us(delay_num);
  68.  
    CST816_SCL_Clr();
  69.  
    }
  70.  
     
  71.  
    //等待IIC应答信号
  72.  
    unsigned char CST816_IIC_Wait_ACK(void)
  73.  
    {
  74.  
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  75.  
    unsigned char t = 0;
  76.  
     
  77.  
    CST816_SDA_IN();
  78.  
    CST816_SDA_Set();
  79.  
    delay_us(delay_num);
  80.  
    CST816_SCL_Set();
  81.  
    delay_us(delay_num);
  82.  
    while(CST816_SDA_Get())
  83.  
    {
  84.  
    t ;
  85.  
    if(t>250)
  86.  
    {
  87.  
    CST816_IIC_Stop();
  88.  
    return 1;
  89.  
    }
  90.  
    }
  91.  
    CST816_SCL_Clr();
  92.  
    return 0;
  93.  
    }
  94.  
     
  95.  
     
  96.  
    //IIC发送一字节数据
  97.  
    void CST816_IIC_SendByte(unsigned char byte)
  98.  
    {
  99.  
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  100.  
    unsigned char BitCnt;
  101.  
    CST816_SDA_OUT();
  102.  
    CST816_SCL_Clr();
  103.  
    for(BitCnt=0;BitCnt<8;BitCnt )//要传送的数据长度为8
  104.  
    {
  105.  
    if(byte&0x80) CST816_SDA_Set();//判断发送位
  106.  
    else CST816_SDA_Clr();
  107.  
    byte<<=1;
  108.  
    delay_us(delay_num);
  109.  
    CST816_SCL_Set();
  110.  
    delay_us(delay_num);
  111.  
    CST816_SCL_Clr();
  112.  
    delay_us(delay_num);
  113.  
    }
  114.  
    }
  115.  
     
  116.  
    //IIC接收一字节数据
  117.  
    unsigned char CST816_IIC_RecvByte(void)
  118.  
    {
  119.  
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  120.  
    unsigned char retc;
  121.  
    unsigned char BitCnt;
  122.  
    retc=0;
  123.  
    CST816_SDA_IN();//置数据线为输入方式
  124.  
    for(BitCnt=0;BitCnt<8;BitCnt )
  125.  
    {
  126.  
    CST816_SCL_Clr();
  127.  
    delay_us(delay_num);
  128.  
    CST816_SCL_Set();//置时钟线为高使数据线上数据有效
  129.  
    retc=retc<<1;
  130.  
    if(CST816_SDA_Get()) retc ;//读数据位,接收的数据位放入retc中
  131.  
    delay_us(delay_num);
  132.  
    }
  133.  
    return(retc);
  134.  
    }
  135.  
     
  136.  
    //IIC写入指定寄存器数据
  137.  
    void CST816_IIC_WriteREG(unsigned char reg,unsigned char date)
  138.  
    {
  139.  
    CST816_IIC_Start();
  140.  
    CST816_IIC_SendByte(0x2A);
  141.  
    CST816_IIC_Wait_ACK();
  142.  
    CST816_IIC_SendByte(reg);
  143.  
    CST816_IIC_Wait_ACK();
  144.  
    CST816_IIC_SendByte(date);
  145.  
    CST816_IIC_Wait_ACK();
  146.  
    CST816_IIC_Stop();
  147.  
    HAL_Delay(10);
  148.  
    }
  149.  
     
  150.  
    //IIC读取指定寄存器数据
  151.  
    unsigned char CST816_IIC_ReadREG(unsigned char reg)
  152.  
    {
  153.  
    unsigned char date;
  154.  
    CST816_IIC_Start();
  155.  
    CST816_IIC_SendByte(0x2A);
  156.  
    CST816_IIC_Wait_ACK();
  157.  
    CST816_IIC_SendByte(reg);
  158.  
    CST816_IIC_Wait_ACK();
  159.  
    CST816_IIC_Start();
  160.  
    // delay_us(4);
  161.  
    CST816_IIC_SendByte(0x2B);
  162.  
    CST816_IIC_Wait_ACK();
  163.  
    date=CST816_IIC_RecvByte();
  164.  
    CST816_IIC_ACK();
  165.  
    CST816_IIC_Stop();
  166.  
    // delay_us(5);
  167.  
    return date;
  168.  
    }
学新通

 IIC协议部分不展开介绍,我们来看有关CST816寄存器的读取

  1.  
    void CST816_Init(void)
  2.  
    {
  3.  
    //我自己不需要做任何操作,由于习惯就写了Init函数。
  4.  
    //可根据自己需求进行修改
  5.  
    }
  6.  
    unsigned char CST816_Get_ChipID()
  7.  
    {
  8.  
    return CST816_IIC_ReadREG(ChipID); //读取芯片ID
  9.  
    }
  10.  
     
  11.  
     
  12.  
    void CST816_Get_XY()
  13.  
    {
  14.  
     
  15.  
    //这个函数非常值得注意,为什么我没有使用上面提到的直接读取指定寄存器的函数,
  16.  
    //因为这个CST816芯片的原因,当读取过XY坐标四个寄存器之中的任意一个之后,其他寄存器会被清空,得到的数据不准确。
  17.  
    //因此必须连续读取,这样也可以学习下IIC总线的读取逻辑嘛对不对。
  18.  
     
  19.  
    unsigned char temp[4];
  20.  
    unsigned int x,y;
  21.  
     
  22.  
    CST816_IIC_Start();
  23.  
    CST816_IIC_SendByte(0x2A);
  24.  
    CST816_IIC_Wait_ACK();
  25.  
    CST816_IIC_SendByte(0x03);
  26.  
    CST816_IIC_Wait_ACK();
  27.  
    CST816_IIC_Start();
  28.  
    // delay_us(4);
  29.  
    CST816_IIC_SendByte(0x2B);
  30.  
    CST816_IIC_Wait_ACK();
  31.  
    temp[0]=CST816_IIC_RecvByte();
  32.  
    CST816_IIC_ACK();
  33.  
    temp[1]=CST816_IIC_RecvByte();
  34.  
    CST816_IIC_ACK();
  35.  
    temp[2]=CST816_IIC_RecvByte();
  36.  
    CST816_IIC_ACK();
  37.  
    temp[3]=CST816_IIC_RecvByte();
  38.  
    CST816_IIC_ACK();
  39.  
    CST816_IIC_Stop();
  40.  
     
  41.  
    x=(unsigned int)((temp[0]&0x0F)<<8)|temp[1];//(temp[0]&0X0F)<<4|
  42.  
    y=(unsigned int)((temp[2]&0x0F)<<8)|temp[3];//(temp[2]&0X0F)<<4|
  43.  
    if(x<240&&y<280)
  44.  
    {
  45.  
    CST816_Instance.X_Pos = x;
  46.  
    CST816_Instance.Y_Pos = y;
  47.  
    }
  48.  
    }
  49.  
     
  50.  
     
  51.  
     
  52.  
    unsigned char CST816_Get_Sta()
  53.  
    {
  54.  
    unsigned char sta;
  55.  
     
  56.  
    CST816_IIC_Start();
  57.  
    CST816_IIC_SendByte(0x2A);
  58.  
    CST816_IIC_Wait_ACK();
  59.  
    CST816_IIC_SendByte(0x01);
  60.  
    CST816_IIC_Wait_ACK();
  61.  
    CST816_IIC_Start();
  62.  
    // delay_us(4);
  63.  
    CST816_IIC_SendByte(0x2B);
  64.  
    CST816_IIC_Wait_ACK();
  65.  
    CST816_IIC_RecvByte();
  66.  
    CST816_IIC_ACK();
  67.  
    sta=CST816_IIC_RecvByte();
  68.  
    CST816_IIC_ACK();
  69.  
    CST816_IIC_Stop();
  70.  
    if(sta!=255&sta!=0)return 1;
  71.  
    else return 0;
  72.  
    }
学新通

剩下的寄存器用到的情况很少,如果有需要可以自己去定义一个函数。

类似这样,仅做展示,作者并没有测试是否可行,就不帖出来喽~

  1.  
    unsigned char CST816_Get_Sta(void); //更新触摸状态
  2.  
    void CST816_Set_MotionMask(unsigned char Motion);
  3.  
    void CST816_Set_IrqCtrl(unsigned char IRQCtrl);
  4.  
    void CST816_Set_AutoRST(unsigned char time); //设置多长时间无触摸自动复位,默认5s,写0则禁用功能
  5.  
    void CST816_Set_LongPressRST(unsigned char time); //设置长按多长时间复位,默认为10s,写0禁用功能
  6.  
    void CST816_Set_AutoSleep(unsigned char en); //是否使能自动进入低功耗模式
  7.  
     
  8.  
    unsigned char CST816_Get_Gesture(void);

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhicbfba
系列文章
更多 icon
同类精品
更多 icon
继续加载