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,一经查实,立即删除!

相关文章

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;…

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

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

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;包括燃气轮机、燃气锅炉、余热…

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…

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…

拜占庭将军问题相关问题

1、拜占庭将军问题基本描述 问题 当我们讨论区块链共识时&#xff0c;为什么会讨论拜占庭将军问题&#xff1f; 区块链网络的本质是一个分布式系统&#xff0c;在存在恶意节点的情况下&#xff0c;希望 整个系统当中的善良节点能够对于重要的信息达成一致&#xff0c;这个机…

2024年3月18日 十二生肖 今日运势

小运播报&#xff1a;2024年3月18日&#xff0c;星期一&#xff0c;农历二月初九 &#xff08;甲辰年丁卯月辛巳日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;牛、鸡、猴 需要注意&#xff1a;鼠、虎、猪 喜神方位&#xff1a;西南方 财神方位&#xff1a;…

分数相加减(C语言)

一、流程图&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int fenmu 2;int result 1;int fuhao 1;//执行循环&#xff1b;while (fenmu < 100){//运算&#xff1b;fuhao (-1…

mvnd 安装和配置

mvnd 是 maven 的增强工具&#xff0c;在执行速度方面优于 maven 下载安装&#xff1a; https://github.com/apache/maven-mvnd/releases/ 根据不同的系统下载不同的安装包 配置环境变量 Path 新增 mvnd 安装路径下的 bin 目录 E:\maven-mvnd-1.0-m8-m39-windows-amd64\b…

HCIA——30奈奎斯特定理、香农定理

学习目标&#xff1a; 计算机网络 1.掌握计算机网络的基本概念、基本原理和基本方法。 2.掌握计算机网络的体系结构和典型网络协议&#xff0c;了解典型网络设备的组成和特点&#xff0c;理解典型网络设备的工作原理。 3.能够运用计算机网络的基本概念、基本原理和基本方法进行…

MySQL语法分类 DQL(4)聚合函数

为了更好的学习这里给出基本表数据用于查询操作 create table student (id int, name varchar(20), age int, sex varchar(5),address varchar(100),math int,english int );insert into student (id,name,age,sex,address,math,english) values (1,马云,55,男,杭州,66,78),…

图解Transformer——注意力计算原理

文章目录 1、输入序列怎样传入注意力模块 2、进入注意力模块的矩阵的每一行&#xff0c;都是源序列中的一个词 3、每一行&#xff0c;都会经过一系列可学习的变换操作 4、如何得到注意力分数 5、Query、Key、Value的作用 6、点积&#xff1a;衡量向量之间的相似度 7、Transform…

在webapp中手动发布一个应用

部署应用前&#xff0c;我们需要下载Tomcat。 下载官网: Apache Tomcat - Welcome! 1、下载 第一步 : 找到Download目录下的Tomcat8 第二步:选择下载第一个zip链接 2、下载完成后&#xff0c;解压并打开Tomcat文件 3、找到并点击webapp文件 创建一个文件夹 在创建的文件中…

浅谈C/C++的常量const、指针和引用问题

今天我们来探讨C/C中const、指针和引用的相关问题。这些概念是编程中的重要组成部分&#xff0c;它们的正确使用对于代码的可读性和可维护性至关重要。通过深入了解const的不可变性、指针的灵活性以及引用的简洁性&#xff0c;我们能够更好地掌握编程的精髓&#xff0c;并写出更…

产品推荐 - 基于FPGA XC7K325T+DSP TMS320C6678的双目交汇视觉图像处理平台

一、产品概述 TES601是一款基于FPGA与DSP协同处理架构的双目交汇视觉图像处理系统平台&#xff0c;该平台采用1片TI的KeyStone系列多核浮点/定点DSP TMS320C6678作为核心处理单元&#xff0c;来完成视觉图像处理算法&#xff0c;采用1片Xilinx的Kintex-7系列FPGA XC7K325T作为视…