CST816S触摸驱动

这篇具有很好参考价值的文章主要介绍了CST816S触摸驱动。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

cst816s,外设驱动,单片机,嵌入式硬件

屏幕购买链接如下:

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

我们先搞一下IIC驱动

	#define CST816_SCL_Clr() 	HAL_GPIO_WritePin(TP_SCL_GPIO_Port,TP_SCL_Pin, GPIO_PIN_RESET)//SCL=SCLK
	#define CST816_SCL_Set() 	HAL_GPIO_WritePin(TP_SCL_GPIO_Port,TP_SCL_Pin, GPIO_PIN_SET)

	#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)
	#define CST816_SDA_Get()	HAL_GPIO_ReadPin(TP_SDA_GPIO_Port,TP_SDA_Pin)

	#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)
	#define CST816_SDA_Clr() 	HAL_GPIO_WritePin(TP_SDA_GPIO_Port,TP_SDA_Pin, GPIO_PIN_RESET)
	#define CST816_SDA_Set() 	HAL_GPIO_WritePin(TP_SDA_GPIO_Port,TP_SDA_Pin, GPIO_PIN_SET)

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

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

//模拟IIC部分的函数声明
void CST816_IIC_ACK(void);
void CST816_IIC_NACK(void);
unsigned char CST816_IIC_Wait_ACK(void);
void CST816_IIC_Start(void);
void CST816_IIC_Stop(void);
void CST816_IIC_SendByte(unsigned char byte);
void CST816_IIC_WriteREG(unsigned char reg,unsigned char date);
unsigned char CST816_IIC_ReadREG(unsigned char reg);
unsigned char CST816_IIC_RecvByte(void);

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

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

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

typedef struct
{
	unsigned char chipID;
	unsigned int X_Pos;			//X坐标
	unsigned int Y_Pos;			//Y坐标
	unsigned char Sta;			//记录触摸状态	
}CST816_Info;

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

下面是函数实现

//IIC驱动实现
#include "CST816.h"
#include "math.h"


CST816_Info	CST816_Instance;			//创建CST816实例。

#define delay_num 4        //宏定义延时时间



GPIO_InitTypeDef GPIO_InitStruct = {0};

//IIC起始信号
void CST816_IIC_Start(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
	
  CST816_SDA_OUT();
	
  CST816_SDA_Set();
  CST816_SCL_Set();
  delay_us(delay_num);	
  CST816_SDA_Clr();
  delay_us(delay_num); 
  CST816_SCL_Clr();
}

//IIC停止信号
void CST816_IIC_Stop(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	CST816_SDA_OUT();
	
	CST816_SCL_Clr(); 
	CST816_SDA_Clr();  
	delay_us(delay_num);	
	CST816_SCL_Set();
	CST816_SDA_Set();
	delay_us(delay_num);
}

//发送ACK应答
void CST816_IIC_ACK(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  CST816_SDA_OUT();
	
  CST816_SCL_Clr();
  CST816_SDA_Clr();
  delay_us(delay_num);     
  CST816_SCL_Set();
  delay_us(delay_num);                  
  CST816_SCL_Clr();   
}

//发送NACK不应答
void CST816_IIC_NACK(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  CST816_SDA_OUT();
	
  CST816_SCL_Clr();
  CST816_SDA_Set();
  delay_us(delay_num);     
  CST816_SCL_Set();
  delay_us(delay_num);                  
  CST816_SCL_Clr(); 
}

//等待IIC应答信号
unsigned char CST816_IIC_Wait_ACK(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  unsigned char t = 0;

	CST816_SDA_IN();
	CST816_SDA_Set();
	delay_us(delay_num); 
	CST816_SCL_Set();
	delay_us(delay_num); 
	while(CST816_SDA_Get())
	{
		t++;
		if(t>250)
		{
			CST816_IIC_Stop();
			return 1;
		}
	}
  CST816_SCL_Clr();              
  return 0;	
}


//IIC发送一字节数据
void CST816_IIC_SendByte(unsigned char byte)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	unsigned char  BitCnt;
	CST816_SDA_OUT();
	CST816_SCL_Clr();
	for(BitCnt=0;BitCnt<8;BitCnt++)//要传送的数据长度为8位
	{
		if(byte&0x80) CST816_SDA_Set();//判断发送位
		else CST816_SDA_Clr(); 
		byte<<=1;
		delay_us(delay_num); 
		CST816_SCL_Set();
		delay_us(delay_num);
		CST816_SCL_Clr();
		delay_us(delay_num);
	}
}

//IIC接收一字节数据
unsigned char CST816_IIC_RecvByte(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  unsigned char retc;
  unsigned char BitCnt;
  retc=0; 
  CST816_SDA_IN();//置数据线为输入方式                
  for(BitCnt=0;BitCnt<8;BitCnt++)
  {        
		CST816_SCL_Clr();
		delay_us(delay_num);
		CST816_SCL_Set();//置时钟线为高使数据线上数据有效                
		retc=retc<<1;
		if(CST816_SDA_Get()) retc++;//读数据位,接收的数据位放入retc中 
		delay_us(delay_num);
  }
  return(retc);
}

//IIC写入指定寄存器数据
void CST816_IIC_WriteREG(unsigned char reg,unsigned char date)
{
	CST816_IIC_Start();
	CST816_IIC_SendByte(0x2A);
	CST816_IIC_Wait_ACK();
	CST816_IIC_SendByte(reg);
	CST816_IIC_Wait_ACK();
	CST816_IIC_SendByte(date);
	CST816_IIC_Wait_ACK();
	CST816_IIC_Stop();
	HAL_Delay(10);
}

//IIC读取指定寄存器数据
unsigned char CST816_IIC_ReadREG(unsigned char reg)
{
	unsigned char date;
	CST816_IIC_Start();
	CST816_IIC_SendByte(0x2A);
	CST816_IIC_Wait_ACK();
	CST816_IIC_SendByte(reg);
	CST816_IIC_Wait_ACK();
	CST816_IIC_Start();
//	delay_us(4);
	CST816_IIC_SendByte(0x2B);
	CST816_IIC_Wait_ACK();
	date=CST816_IIC_RecvByte();
	CST816_IIC_ACK();
	CST816_IIC_Stop();
//	delay_us(5);
	return date;
}

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

void CST816_Init(void)
{
    //我自己不需要做任何操作,由于习惯就写了Init函数。
    //可根据自己需求进行修改
}
unsigned char CST816_Get_ChipID()
{
	return CST816_IIC_ReadREG(ChipID);    //读取芯片ID
}


void CST816_Get_XY()
{

    //这个函数非常值得注意,为什么我没有使用上面提到的直接读取指定寄存器的函数,
    //因为这个CST816芯片的原因,当读取过XY坐标四个寄存器之中的任意一个之后,其他寄存器会被清空,得到的数据不准确。
    //因此必须连续读取,这样也可以学习下IIC总线的读取逻辑嘛对不对。

	unsigned char temp[4];
	unsigned int x,y;
	
	CST816_IIC_Start();
	CST816_IIC_SendByte(0x2A);
	CST816_IIC_Wait_ACK();
	CST816_IIC_SendByte(0x03);
	CST816_IIC_Wait_ACK();
	CST816_IIC_Start();
//	delay_us(4);
	CST816_IIC_SendByte(0x2B);
	CST816_IIC_Wait_ACK();
	temp[0]=CST816_IIC_RecvByte();
	CST816_IIC_ACK();
	temp[1]=CST816_IIC_RecvByte();
	CST816_IIC_ACK();
	temp[2]=CST816_IIC_RecvByte();
	CST816_IIC_ACK();
	temp[3]=CST816_IIC_RecvByte();
	CST816_IIC_ACK();
	CST816_IIC_Stop();
	
	x=(unsigned int)((temp[0]&0x0F)<<8)|temp[1];//(temp[0]&0X0F)<<4|
	y=(unsigned int)((temp[2]&0x0F)<<8)|temp[3];//(temp[2]&0X0F)<<4|
	if(x<240&&y<280)
	{
		CST816_Instance.X_Pos	=	x;
		CST816_Instance.Y_Pos	=	y;
	}
}



unsigned char CST816_Get_Sta()
{
	unsigned char sta;
	
	CST816_IIC_Start();
	CST816_IIC_SendByte(0x2A);
	CST816_IIC_Wait_ACK();
	CST816_IIC_SendByte(0x01);
	CST816_IIC_Wait_ACK();
	CST816_IIC_Start();
//	delay_us(4);
	CST816_IIC_SendByte(0x2B);
	CST816_IIC_Wait_ACK();
	CST816_IIC_RecvByte();
	CST816_IIC_ACK();
	sta=CST816_IIC_RecvByte();
	CST816_IIC_ACK();
	CST816_IIC_Stop();
	if(sta!=255&sta!=0)return 1;
	else return 0;     
}

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

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

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

unsigned char CST816_Get_Gesture(void);

 文章来源地址https://www.toymoban.com/news/detail-553366.html

到了这里,关于CST816S触摸驱动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • K_A35_017 基于STM32等单片机驱动TTP229矩阵触摸传感器 串口与OLED0.96双显示

    其他资料目录 直戳跳转 单片机型号 测试条件 模块名称 代码功能 STC89C52RC 晶振11.0592M TTP229矩阵触摸模块 STC89C52RC驱动TTP229矩阵触摸模块 串口与OLED0.96双显示 STM32F103C8T6 晶振8M/系统时钟72M TTP229矩阵触摸模块 STM32F103C8T6驱动TTP229矩阵触摸模块 串口与OLED0.96双显示 TTP229矩阵触摸传

    2024年02月02日
    浏览(39)
  • 单片机与触摸屏的通信实现方法

    单片机与触摸屏的通信是在嵌入式系统中常见的任务之一。通过合适的通信协议和接口,我们可以实现单片机与触摸屏之间的数据传输和交互。下面将详细介绍一种常用的实现方法,并提供相应的源代码示例。 硬件连接 首先,我们需要将触摸屏与单片机正确地连接起来。触

    2024年03月12日
    浏览(42)
  • 51单片机外设系列:LCD1602 的详细编程

    前言,LCD1602是一个比较常用的单片机显示外设,下面我们从它的显示原理,来分析用51单片机编程的思路。另外结尾还提供了完成的程序代码参考。 一、LCD1602的外观、结构和基本参数 引脚功能解析: 第1引脚:GND为电源地脚。 第2引脚:VCC接5V电源正极。 第3引脚:VL为液晶显

    2024年02月05日
    浏览(38)
  • 基于串口通信技术——让数码管显示的数据发送给电脑,电脑控制单片机外设——15单片机

    目录 1.使用的单片机为IAPI15F2K61S2 2.使用的外设 3.各个外设的作用 1.数码管功能  2.LED灯 3.蜂鸣器与继电器 4.按键 5.串口通信 4.利用发送单个字符函数 发送字符型的数字值,为一个变量+\\\'0\\\',发送为字符型数字。 4.初始化 5.程序 1.main 2.iic.h 3.onewire.c 1.LED灯,继电器与蜂鸣器。 2.数

    2024年02月10日
    浏览(44)
  • 【GD32】从0开始学GD32单片机(9)—— SPI外设详解+主机从机发送和接收例程

    SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种 高速的,全双工,同步的 通信总线。 SPI总共需要4根线来实现通信, NSS:片选线,用于选择需要通信的从机;CLK:同步时钟线,用于提供同步时钟信号;MISO:主机读从机写线;MOSI:主机写从机读线 。 GD32F103系列的

    2023年04月08日
    浏览(38)
  • 单片机开发教程5——51单片机驱动TFT彩屏

    TFT.zip 开发资料中的例程有些瑕疵,上面是整理后的例程,修改了一些参数,也添加了不少函数,函数都有对应的注释,只要花心思去看一应该是能看懂怎么用的。此外,这个例程也可以作为你们工程的模板,往上面添加一些函数、完善一下内容,差不多就能做出一个作品了

    2023年04月23日
    浏览(40)
  • 单片机】51单片机,TLC2543,驱动程序,读取adc

    TLC2543 是一款 12 位精密模数转换器 (ADC)。 1~9、11、12——AIN0~AIN10为模拟输入端; 15——CS 为片选端; 17——DIN 为串行数据输入端;(控制字输入端,用于选择转换及输出数据格式) 16——DOUT为A/D转换结果的三态串行输出端;(A/D转换结果的输出端。) 19——EOC为转换结束端

    2024年02月14日
    浏览(49)
  • 【单片机】51单片机,TLC2543,驱动程序,读取adc

    TLC2543 是一款 12 位精密模数转换器 (ADC)。 1~9、11、12——AIN0~AIN10为模拟输入端; 15——CS 为片选端; 17——DIN 为串行数据输入端;(控制字输入端,用于选择转换及输出数据格式) 16——DOUT为A/D转换结果的三态串行输出端;(A/D转换结果的输出端。) 19——EOC为转换结束端

    2024年02月14日
    浏览(40)
  • 【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

    I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。 I2C总线是一个真正的多主机总线,如果两个或多个主机同时初始化数据传输,可以通过冲突检测和仲裁防止数据破坏,每个连接到总线上的器件都有

    2024年02月02日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包