STM32F407_多点电容触摸(GT911)驱动

目录标题

  • 前言
  • 1、简单介绍
  • 2、触摸芯片与主机的硬件连接
  • 3、内部寄存器
    • 3.1、控制寄存器(0X8040)
    • 3.2、配置寄存器组(0X8047~0X8100)
    • 3.3、状态寄存器(0x814E)
    • 3.4、坐标寄存器(0x8150-0x8177)
  • 4、初始化流程
    • 4.1、IIC地址选择
    • 4.2、更新GT911寄存器配置
  • 5、触摸点坐标值读取
  • 6、提示
  • 7、代码部分
    • 7.1、gt911.h
    • 7.2、GT911.c

前言

做毕设用到了电容触摸屏,移植了几天内才整好。在网上找到的好多例程都是电容屏、电阻屏都融合到一起去了,对于新手来说,不是太好理解,所以我来分享一下我的认识、例程和学习过程中遇到的问题以及要注意的点。

1、简单介绍

GT911、GT928、GT9147都属于GT9系列非单层多点触控芯片,他们支持的触控点数不同(GT928支持10个点、GT911支持5个点)、驱动和感应通道也可能不同。可是他们的寄存器和IIC通讯时序是相同的,也就是说驱动程序是兼容的。
所以如果是使用的GT9147也可以看看这个文档,整理下思路。

2、触摸芯片与主机的硬件连接

接口介绍
VCC电源
GND
SCL与GT911进行IIC通信的时钟线
SDA与GT911进行IIC通信的数据线
INT当发生触摸时,GT911的INT脚会输出上升/下降沿(内部寄存器可以配置),主机就可以通过外部中断处理去读取触点信息。
RST复位引脚,拉低100us以上,即可复位。正常工作时,应该保持拉高

3、内部寄存器

GT911上电初始化情况,是由其内部FLASH中的若干个寄存器来决定的,我们下面对其中比较重要的进行讲解。

3.1、控制寄存器(0X8040)

通过往里面写入不同的8bit数据。可以使其完成不同的任务。
在这里插入图片描述
如图示,一般的操作是在复位时,先往0X8040里面写2,对其进行软复位,然后判断是否需要对其配置寄存器进行更新,若需要更新,则写入新版本的配置参数(这部分配合着后面来看才能看懂),然后在往0X8040里面写0,结束软复位,后面就能正常读取触摸坐标了。
总结一下:

  • 要更新配置:(一般来说,买到的屏幕商家都已经预先写进去了,不需要更新)
    • 1、往0X8040写2(开始软复位)
    • 2、往0X8047~0X8100写入新的配置寄存器参数
    • 3、往0X8040写0(结束软复位)
    • 4、后面正常读触点坐标
  • 不更新配置:
    • 1、往0X8040写2(开始软复位)
    • 2、往0X8040写0(结束软复位)
    • 3、后面正常读触点坐标

3.2、配置寄存器组(0X8047~0X8100)

在这里插入图片描述
在这里插入图片描述

如上图示,这里共有186个寄存器,用于配置GT9147的各个参数,这些参数对于不同的屏幕也都各有不同。一般买回来的里面呢都自带的有(也就是说,原来就是好用的,不需要再自己进行操作了)

如果你要是不小心把原来的覆盖掉了,就只能再重新写一次了(我在调试过程中就是这样,把其它型号的配置参数写进去了,要命的是我还没有正确的了,最后还是从我同学的一块同款屏幕上将这186个寄存器的值都读出来,又重新写入到我的屏幕的GT911中,才弄好了)

在这样的情况下,你就需要对这些寄存器的一些特性,做些更深入的了解了。

  • 0x8047——这个寄存器中,保存的是当前配置参数的版本号,你新写入配置参数的版本号,必须要比它大或者在相等的情况下,其他参数有变化,否则不会生效。
  • 0x80FF——这里需要写入的是从0x8047到0x80FE之间184个数据和的补码,否则那你写入的配置也不会生效。
  • 0x8100——用于控制是否将配置保存在GT911的FLASH中,写0,则不保存配置,写1则保存配置。

3.3、状态寄存器(0x814E)

寄存器bit7bit6bit5 bit4bit3 bit2 bit1 bit0
0x814Ebuffer状态large detectReserved有效触点个数

我们只看此寄存器的最高位和低四位即可。
最高位表示的Buffer状态,若有数据(有触摸),则Buffer为1‘
低四位表示有效出点的个数,0~5,0表示此时没有触摸。5表示此时有5点触摸
(我们上面提到过gt911最多同时支持五个触控点数)

3.4、坐标寄存器(0x8150-0x8177)

在这里插入图片描述
在这里插入图片描述
如上图所示,我们可以将其分为5组,其分别用来表示5个触点坐标
下面以触点1的坐标数据寄存器为例做具体讲解:

寄存器bit7~0寄存器bit7~0
0x8150触点1X坐标低8位0x8151触点1X坐标高8位
0x8152触点1Y坐标低8位0x8153触点1Y坐标高8位
0x8154触点1触摸尺寸低8位0x8155触点1触摸尺寸高8位

一般只用到触点的x,y坐标,所以只需要读取0X8150-0X8153的数据,组合即可得到触点坐标。其它四组分别是:0X8158、0X8160、0X8168和0X8170等开头的的16个寄存器组成,分别针对触点2~5的坐标。同样GT911也支持寄存器地址自增,我们只需要发送寄存器组的首地址,然后连续读取即可,GT9147会自动地址自增,从而提高读取速度。

4、初始化流程

4.1、IIC地址选择

GT911作为从设备,其地址有两种选择:

7bit地址8bit写地址8bit读地址
0x5D0xBA0xBB
0x140x280x29

其配置方法如下:

  • 将地址配置为0x28/0x29

    • 1、将RST引脚设置为上拉推挽输出模式,将INT引脚设置为上拉输入模式
    • 2、将RST拉低,延时大于1ms
    • 3、将RST拉高,延时大于5ms
    • 4、将INT配置为悬浮输入态,RST维持拉高输出
      在这里插入图片描述
  • 将地址配置为0xBA/0xBB

    • 1、将RST和INT引脚配置为输出模式并拉低
    • 2、延时1ms
    • 3、将RST拉高,延时大于5ms
    • 4、将INT配置为悬浮输入态,RST维持拉高输出
      在这里插入图片描述
      注意:因为我使用的是查询扫描模式,所以没有配置INT引脚的外部中断模式,如果需要,这里也需要配置。

4.2、更新GT911寄存器配置

就像上面3.2说的,如果刚买回来的触摸屏幕,里面应该是本身就有适配此屏幕的参数配置的,这一条就可以省略直接进行下面的4.3,去读取触摸点坐标值。
注:这点尤为关键,因为你非常容易写进去错误的寄存器配置导致原来的配置被覆盖掉,你还不知道原来的配置参数是多少。
如果你真的需要更新它。

  • 1、向命令寄存器(0x8040)写入2,开始软复位
  • 2、把配置参数数组(那186个参数)写入寄存器(0x8047-0x8100).
    • 1)、 0x8047——这个寄存器中,保存的是当前配置参数的版本号,你新写入配置参数的版本号,必须要比它大或者在相等的情况下,其他参数有变化,否则不会生效。
    • 2)、0x80FF——这里需要写入的是从0x8047到0x80FE之间184个数据和的补码,否则那你写入的配置也不会生效。
    • 3)、0x8100——用于控制是否将配置保存在GT911的FLASH中,写0,则不保存配置,写1则保存配置。
  • 3、往向命令寄存器(0x8040)写入0,结束软复位

5、触摸点坐标值读取

当有触摸发生时,GT911会有3个提示:

  • 1、INT会输出上升沿或下降沿信号。(由寄存器配置参数决定)
  • 2、状态寄存器0x814E的最高位(buffer状态位)的值变为1,表示数据已准备好。
  • 3、状态寄存器0x814E的低4位的值会变为触摸点个数,提示有多少个点被按下。

注意:读完坐标后,要把0x814E寄存器清为0,表示坐标点已读。否则GT911会一直输出INT信号,不继续检测触摸。

读取方法:

  • 1、使用INT中断,当发生触摸时,会进入外部中断处理程序,在中断服务中,可以去读取0x8114E中的低四位获取触摸点数,然后再去读去相应寄存器,获取触点坐标,读完后将0x814E寄存器清零。
  • 2、轮询读取0x814E寄存器值,若最高位为1,则通过低四位获取触摸点数,然后去读相应触摸点数的坐标值,读完后将0x814E清零。若最高位为0,则退出,等待下次监测。

6、提示

  • 因为GT911的触摸检测频率小于100HZ,所以我们采用轮询读取时,读取频率设的小于100HZ即可。

7、代码部分

7.1、gt911.h

#ifndef __GT911_H
#define __GT911_H	
#include "sys.h"	#include "ctiic.h"
#include "Serial.h"
#include "DWT_Delay.h" 
#include "string.h" #include "lcd_init.h"
#define TP_PRES_DOWN 0x80  //触屏被按下	  
#define TP_CATH_PRES 0x40  //有按键按下了 
#define CT_MAX_TOUCH  5    //电容屏支持的点数,固定为5点//触摸屏控制器
typedef struct
{uint16_t x[CT_MAX_TOUCH]; 		//当前坐标uint16_t y[CT_MAX_TOUCH];		//电容屏有最多5组坐标,电阻屏则用x[0],y[0]代表:此次扫描时,触屏的坐标,用//x[4],y[4]存储第一次按下时的坐标. uint8_t  sta;					//笔的状态 //b7:按下1/松开0; //b6:0,没有按键按下;1,有按键按下. //b5:保留//b4~b0:电容触摸屏按下的点数(0,表示未按下,1表示按下)
}_m_tp_dev;extern _m_tp_dev tp_dev;	 	//触屏控制器在touch.c里面定义
//IO操作函数	 
#define GT_RST    		PBout(9)	//GT911复位引脚
#define GT_INT    		PBin(8)		//GT911中断引脚	//I2C读写命令	
#define GT_CMD_WR 		0X28     	//写命令
#define GT_CMD_RD 		0X29		//读命令//GT911 部分寄存器定义 
#define GT_CTRL_REG 	0X8040   	//GT911控制寄存器
#define GT_CFGS_REG 	0X8047   	//GT911配置起始地址寄存器
#define GT_CHECK_REG 	0X80FF   	//GT911校验和寄存器
#define GT_PID_REG 		0X8140   	//GT911产品ID寄存器#define GT_GSTID_REG 	0X814E   	//GT911当前检测到的触摸情况
#define GT_TP1_REG 		0X8150  	//第一个触摸点数据地址
#define GT_TP2_REG 		0X8158		//第二个触摸点数据地址
#define GT_TP3_REG 		0X8160		//第三个触摸点数据地址
#define GT_TP4_REG 		0X8168		//第四个触摸点数据地址
#define GT_TP5_REG 		0X8170		//第五个触摸点数据地址  void GT911_Send_Cfg(uint8_t mode);                           /*更新GT911配置参数*/
uint8_t GT911_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len); /*向GT911写入一次数据*/
void GT911_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len);    /*从GT911读出一次数据*/
uint8_t GT911_Init(void);                                    /*初始化GT911触摸屏*/
uint8_t GT911_Scan(uint8_t mode);                            /*扫描触摸屏(采用查询方式)*/
#endif

7.2、GT911.c

#include "gt911.h"_m_tp_dev tp_dev;				/*五个触摸点的数据寄存器起始地址*/
const uint16_t GT911_TPX_TBL[5]={GT_TP1_REG,GT_TP2_REG,GT_TP3_REG,GT_TP4_REG,GT_TP5_REG};//GT911配置参数表--适用于耀元鸿2.8寸IPS屏幕。不同尺寸屏幕配置参数会有区别
const uint8_t GT911_CFG_TBL[]=
{ 
0x61,0xf0,0x00,0x40,0x01,0x05,0x35,0x00,0x02,0x08,
0x1e,0x08,0x50,0x3c,0x0f,0x05,0x00,0x00,0x00,0x00,
0x50,0x00,0x00,0x18,0x1a,0x1e,0x14,0x87,0x27,0x0a,
0x4b,0x4d,0xd3,0x07,0x00,0x00,0x00,0x02,0x32,0x1c,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x00,0x2a,0x32,0x64,0x94,0xd5,0x02,0x07,0x00,0x00,0x04,
0xa5,0x35,0x00,0x91,0x3d,0x00,0x80,0x46,0x00,0x70,
0x51,0x00,0x63,0x5d,0x00,0x63,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x14,0x12,0x10,0x0e,0x0c,0x0a,0x08,0x06,
0x04,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x24,0x22,0x21,0x20,0x1f,0x1e,0x1d,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
};  /*
* 函数名称: GT911_Send_Cfg
* 功能描述: 更新GT911配置参数
* 传入参数: mode:0,参数不保存到flash
*                1:参数保存到flash
*   返回值: 0,成功;1,失败.
*/
void GT911_Send_Cfg(uint8_t mode)
{uint8_t buf[2];uint8_t i=0;buf[0]=0;buf[1]=mode;	//是否写入到GT911 FLASH?  即是否掉电保存for(i=0;i<sizeof(GT911_CFG_TBL);i++)buf[0]+=GT911_CFG_TBL[i];//计算校验和buf[0]=(~buf[0])+1;GT911_WR_Reg(GT_CFGS_REG,(uint8_t*)GT911_CFG_TBL,sizeof(GT911_CFG_TBL));//发送寄存器配置GT911_WR_Reg(GT_CHECK_REG,buf,2);//写入校验和,和配置更新标记
} /*
* 函数名称: GT911_WR_Reg
* 功能描述: 向GT911写入一次数据
* 传入参数: reg:起始寄存器地址
*           buf:数据缓缓存区
*           len:写数据长度	
*   返回值: 0,成功;1,失败.
*/
uint8_t GT911_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{uint8_t i;uint8_t ret=0;CT_IIC_Start();	CT_IIC_Send_Byte(GT_CMD_WR);   	//发送写命令 	 CT_IIC_Wait_Ack();CT_IIC_Send_Byte(reg>>8);   	//发送高8位地址CT_IIC_Wait_Ack(); 	 										  		   CT_IIC_Send_Byte(reg&0XFF);   	//发送低8位地址CT_IIC_Wait_Ack();  for(i=0;i<len;i++){	   CT_IIC_Send_Byte(buf[i]);  	//发数据ret=CT_IIC_Wait_Ack();if(ret)break;  }CT_IIC_Stop();					//产生一个停止条件	    return ret; 
}/*
* 函数名称: GT911_RD_Reg
* 功能描述: 从GT911读出一次数据
* 传入参数: reg:起始寄存器地址
*           buf:数据缓缓存区
*           len:读数据长度	
*   返回值: 无
*/
void GT911_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{uint8_t i; CT_IIC_Start();	CT_IIC_Send_Byte(GT_CMD_WR);   //发送写命令 	 CT_IIC_Wait_Ack();CT_IIC_Send_Byte(reg>>8);   	//发送高8位地址CT_IIC_Wait_Ack(); 	 										  		   CT_IIC_Send_Byte(reg&0XFF);   	//发送低8位地址CT_IIC_Wait_Ack();  CT_IIC_Start();  	 	   CT_IIC_Send_Byte(GT_CMD_RD);   //发送读命令		   CT_IIC_Wait_Ack();	   for(i=0;i<len;i++){	   buf[i]=CT_IIC_Read_Byte(i==(len-1)?0:1); //发数据	  } CT_IIC_Stop();//产生一个停止条件    
} /*
* 函数名称: GT911_Init
* 功能描述: 初始化GT911触摸屏
* 传入参数: 无
*   返回值: 0,初始化成功;1,初始化失败
*/uint8_t GT911_Init(void)
{//	uint8_t zancun[190]; /*测试使用*/
//	uint8_t i;
//	uint8_t z;uint8_t temp[5]; GPIO_InitTypeDef  GPIO_InitStructure;	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB,C时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;//PB1设置为上拉输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//PC13设置为推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出模式GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化	CT_IIC_Init();      	//初始化电容屏的I2C总线  GT_RST=0;				//复位DWT_DelayMS(1);GT_RST=1;				//释放复位		    DWT_DelayMS(5); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化	DWT_DelayMS(10);  GT911_RD_Reg(GT_PID_REG,temp,4);//读取产品IDtemp[4]=0;printf("CTP ID:%s\r\n",temp);	//打印IDif(strcmp((char*)temp,"911")==0)//ID==9147{temp[0]=0X02;			GT911_WR_Reg(GT_CTRL_REG,temp,1);//软复位GT911GT911_RD_Reg(GT_CFGS_REG,temp,1);//读取GT_CFGS_REG寄存器/*可用来读取GT911本地0x8047-0x80FE的寄存器参数*/
/*GT911_RD_Reg(GT_CFGS_REG,(uint8_t *)zancun,186);		 //读取出配置寄存器值for(i=0;i<186;i++){if(i<185){z+=zancun[i];}if(i==185){printf("校验值1:%x\r\n",z);}printf("%x,",zancun[i]);                   //打印出配置寄存器值}
*/if(temp[0]<0X62)//默认版本比较低,需要更新flash配置{printf("Default Ver:%x\r\n",temp[0]);
//			GT911_Send_Cfg(1);//更新并保存配置}DWT_DelayMS(10);temp[0]=0X00;	 GT911_WR_Reg(GT_CTRL_REG,temp,1);//结束复位   return 0;} return 0;
}/*
* 函数名称: GT911_Scan
* 功能描述: 扫描触摸屏(采用查询方式)
* 传入参数: mode:0,正常扫描.
* 传出参数: 无
*   返回值: 当前触屏状态.0,触屏无触摸;1,触屏有触摸
*/
uint8_t GT911_Scan(uint8_t mode)
{uint8_t buf[4]; /*触屏坐标信息存储缓冲区*/uint8_t i=0;uint8_t res=0;  /*返回触摸状态*/uint8_t temp;   uint8_t tempsta;  /*保存当前触摸状态*/static uint8_t t=0;//控制查询间隔,从而降低CPU占用率   t++;if((t%10)==0||t<10)//空闲时,每进入10次CTP_Scan函数才检测1次,从而节省CPU使用率{GT911_RD_Reg(GT_GSTID_REG,&mode,1);	//读取触摸点的状态  temp=0;GT911_WR_Reg(GT_GSTID_REG,&temp,1);//清标志 			if((mode&0XF)&&((mode&0XF)<6)) {temp=0XFF<<(mode&0XF);		//将点的个数转换为1的位数,匹配tp_dev.sta定义 tempsta=tp_dev.sta;			//保存当前的tp_dev.sta值tp_dev.sta=(~temp)|TP_PRES_DOWN|TP_CATH_PRES; tp_dev.x[4]=tp_dev.x[0];	//保存触点0的数据tp_dev.y[4]=tp_dev.y[0];for(i=0;i<5;i++){if(tp_dev.sta&(1<<i))	//触摸有效?{GT911_RD_Reg(GT911_TPX_TBL[i],buf,4);	//读取XY坐标值  tp_dev.y[i]=240-(((uint16_t)buf[1]<<8)+buf[0]);tp_dev.x[i]=((uint16_t)buf[3]<<8)+buf[2];printf("x[%d]:%d,y[%d]:%d\r\n",i,tp_dev.x[i],i,tp_dev.y[i]);}			} res=1;if(tp_dev.x[0]>LCD_W||tp_dev.y[0]>LCD_H)//非法数据(坐标超出了){ if((mode&0XF)>1)		//有其他点有数据,则复第二个触点的数据到第一个触点.{tp_dev.x[0]=tp_dev.x[1];tp_dev.y[0]=tp_dev.y[1];t=0;				//触发一次,则会最少连续监测10次,从而提高命中率}else					//非法数据,则忽略此次数据(还原原来的)  {tp_dev.x[0]=tp_dev.x[4];tp_dev.y[0]=tp_dev.y[4];mode=0X80;		tp_dev.sta=tempsta;	//恢复tp_dev.sta}}else t=0;					//触发一次,则会最少连续监测10次,从而提高命中率}}if((mode&0X8F)==0X80)//无触摸点按下{ if(tp_dev.sta&TP_PRES_DOWN)	//之前是被按下的{tp_dev.sta&=~(1<<7);	//标记按键松开}tp_dev.x[0]=0xffff;tp_dev.y[0]=0xffff;tp_dev.sta&=0XE0;	//清除点有效标记	} 	if(t>240)t=10;//重新从10开始计数return res;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/751421.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FTP服务器的工作原理

1.1、概述 FTP服务器是网络中提供文件存储和访问服务的服务器&#xff0c;无论是个人还是企业&#xff0c;都可以搭建FTP服务器&#xff0c;用来上传数据、下载数据和共享文件。FTP采用C/S&#xff08;客户端/服务器&#xff09;架构&#xff0c;用户只要通过FTP客户端程序连接…

html--简历

文章目录 html html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"maximum-scale1.0,minimum-scale1.0,user-scalable0,widthdevice-width,initial-scale1.0&qu…

字母异位词分组【每日一题】

可以通过案例找到规律&#xff0c;每个词排序完后是同一个&#xff0c;所以通过hasmap存储排序过的值做key&#xff0c;值是存储单词集合。 package HasTable;import java.util.*;class Solution {static List<List<String>> groupAnagrams(String[] strs) {Map&l…

jupyter notebook 突然莫名奇妙的白屏

jupyter notebook 突然莫名奇妙的白屏 事件背景&#xff1a; 最近在折腾openai&#xff0c;哎&#xff0c;一言难尽&#xff0c;使用的是conda管理python版本的切换&#xff0c;使用jupyter notebook来运行python程序&#xff0c;其实PyCharm也行&#xff0c;但是&#xff0c;…

JAVA构造方法的作用

JAVA构造方法主要有以下作用&#xff1a; 1. 初始化对象的状态&#xff1a;构造方法用于创建对象时&#xff0c;可以初始化对象的实例变量和其他属性&#xff0c;为对象的状态赋初值。 2. 调用父类构造方法&#xff1a;构造方法还可以用来调用父类的构造方法&#xff0c;通过su…

uView Code 验证码输入框

考虑到用户实际发送验证码的场景&#xff0c;可能是一个按钮&#xff0c;也可能是一段文字&#xff0c;提示语各有不同&#xff0c;所以本组件 不提供界面显示&#xff0c;只提供提示语&#xff0c;由用户将提示语嵌入到具体的场景 #平台差异说明 App&#xff08;vue&#xf…

lqb省赛日志[11/37] -[dfs]

一只小蒟蒻备考蓝桥杯的日志 文章目录 笔记刷题心得小结 笔记 最近对二维数组[][]&#xff0c;xy的区分好混乱啊。。。 刷题 P1101 单词方阵P2404 自然数的拆分问题P1596 [USACO10OCT] Lake Counting SP1162 填涂颜色 心得 莫名其妙就爆0了&#xff0c;但是样例对&#x…

【递归搜索回溯专栏】专题二:二叉树中的深搜----二叉树剪枝

本专栏内容为&#xff1a;递归&#xff0c;搜索与回溯算法专栏。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;递归搜索回溯专栏 &#x1f69a;代码仓库&#xff1a;小小unicorn的代…

git |常用命令

git 命令 非常常用 主流的仓库管理服务器&#xff0c;svn 和git 接下来&#xff0c;介绍git 操作&#xff08;自用 先讲一个简单的demo 流程 环境&#xff1a;centos、git #先创建一个本地 git 文件夹 mkdir test && cd ./test #写一个README.md #echo “# 张不大 的de…

MySQL调优:explain详解

MySQL的EXPLAIN命令用于获取SQL查询的执行计划&#xff08;Execution Plan&#xff09;&#xff0c;它揭示了MySQL服务器如何执行给定的SELECT语句&#xff0c;包括如何连接表、使用索引以及MySQL优化器选择的查询路径等重要信息。这对于分析查询性能、找出潜在的瓶颈并优化SQL…

redis发布订阅与stream类型

发布订阅 redis发布订阅(pub/sub)是一种消息通信模式&#xff1b;发送者(pub)发送消息&#xff0c;订阅者(sub)接收消息。redis客户端可以订阅任意数量的频道。 基础命令&#xff1a; 语法 redis publish命令基本语法如下&#xff1a; redis 127.0.0.1:6379> PUBLISH ch…

Matlab|考虑可再生能源消纳的电热综合能源系统日前经济调度模型

目录 1 主要内容 模型示意图 目标函数 程序亮点 2 部分程序 3 程序结果 4 下载链接 1 主要内容 本程序参考文献《考虑可再生能源消纳的建筑综合能源系统日前经济调度模型》模型&#xff0c;建立了电热综合能源系统优化调度模型&#xff0c;包括燃气轮机、燃气锅炉、余热…

Arduino RP2040 + SSD1306 I2C OLED +LittleFS存储GBK字库实现中文显示

Arduino RP2040 + SSD1306 I2C OLED +LittleFS存储GBK字库实现中文显示 📌LittleFS插件安装,可以参考《Arduino RP2040 LittleFS的使用介绍》🎈相关内容《Arduino esp8266 软件I2C SSD1306 +LittleFS存储GBK字库实现中文显示》🔖基于Earle F. Philhower, III的核心固件开…

如何针对机械表进行识别读数

识别机械表的读数通常涉及到图像处理和模式识别技术。以下是一个简单的例子&#xff0c;使用Python和OpenCV库来识别机械表的读数。这个例子假设表盘是静止的&#xff0c;并且有一个清晰的背景。 首先&#xff0c;你需要安装OpenCV库&#xff08;如果你还没有安装的话&#xff…

Python基础(七)之数值类型集合

Python基础&#xff08;七&#xff09;之数值类型集合 1、简介 集合&#xff0c;英文set。 集合&#xff08;set&#xff09;是由一个或多个元素组成&#xff0c;是一个无序且不可重复的序列。 集合&#xff08;set&#xff09;只存储不可变的数据类型&#xff0c;如Number、…

修改yolov9的模型打印不出来Gflops的解决办法

正在修改yolov9的模块&#xff0c;发现修改后的模型没有GFlops这个参数 解决办法&#xff1a; 找到utils/torch_utils.py这个文件&#xff0c;有一个model_info函数 然后将其中的stride改为固定的640就可以打印了。 stride max(int(model.stride.max()), 32) if hasattr(mo…

请求头content-type的类型有什么?

"Content-Type" 是 HTTP 请求头中的一个字段&#xff0c;用于指示发送给接收方的实体正文的媒体类型。常见的 "Content-Type" 类型包括但不限于以下几种&#xff1a; application/json&#xff1a; 用于指示请求或响应中的实体正文是 JSON 格式的数据。 ap…

telnet命令使用

window启用telnet telnet命令连接服务端 启动netty服务端后&#xff0c;使用如下cmd命令连接服务端&#xff0c;按enter&#xff0c;将连接到netty服务端 再按CTRL ]&#xff0c;进入命令交互界面 输入 help&#xff0c;查看命令介绍 发送消息&#xff0c;再断开连接&…

Linux:系统初始化,内核优化,性能优化(2)

优化ssh协议 Linux&#xff1a;ssh配置_ssh配置文件-CSDN博客https://blog.csdn.net/w14768855/article/details/131520745?ops_request_misc%257B%2522request%255Fid%2522%253A%2522171068202516800197044705%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fb…

js基础语法大全(时间戳,uuid,字符串转json)

目录 一、获取时间戳二、获取uuid三、字符串转json格式 一、获取时间戳 var times Math.round(new Date().getTime()/1000).toString(); //获取 10位 时间戳 console.log(times);二、获取uuid function guid() {return xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replace(/[xy]…