STM32CubeMX学习笔记17--- FSMC
1.1 TFTLCD简介
TFT-LCD(thin film transistor-liquid crystal display)即薄膜晶体管液晶显示器。液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),每个像素都可以通过点脉冲直接控制,因而每个节点都相对独立,并可以连续控制,不仅提高了显示屏的反应速度,同时可以精确控制显示色阶,所以TFT液晶的色彩更真,因此TFT-LCD也被叫做真彩液晶显示器 常用的TFT液晶屏接口有8位、9位、16位、18位,这里的位数表示的是彩屏数据线的数量。常用的通信模式有6800模式和8080模式,本例程使用8080并口模式(简称80并口),8080接口有5条基本的控制线和多条数据线(8/9/16/18位),它们的功能如下表:
8080接口模式的时序如下图所示:
- 在WR跳变为低电平后,液晶屏开始读取总线上面的数据
- 在RD跳变为低电平后,液晶屏开始放置数据到总线上面
本例程使用3.0寸的TFT-LCD模块,驱动芯片为R61509VN,分辨率240*400,接口为16位的80并口,自带触摸功能,该模块原理图如下所示:
该模块的80并口有如下信号线
信号线 | 作用 |
---|---|
CS | TFTLCD片选信号 |
WR | 向TFTLCD写入数据 |
RD | 从TFTLCD读取数据 |
RS | 命令/数据选择(0:读写命令,1:读写数据) |
DB[15:0] | 16位双向数据线 |
RST | TFTLCD复位 |
任何LCD的使用流程都可以简单的用以下流程图来表示,其中硬复位和初始化序列只需要执行一次即可。画点流程:设置坐标 --> 写GRAM指令 --> 写入颜色数据,然后在LCD上就可以看到对应的点显示写入的颜色了;读点流程:设置坐标 --> 读GRAM指令 --> 读取颜色数据,这样就可以获取到对应点的颜色数据了
以上是最简单也是最常用的操作,有了这些操作一般就可以正常使用TFTLCD了。设置TFT液晶显示通常需要以下几个步骤:
- 设置STM32F1与TFTLCD模块箱连接的IO口,将与TFTLCD模块相连的IO口进行初始化,以便驱动LCD,这里使用的是STM32F1的FSMC
- 初始化TFTLCD模块(写入一系列设置值),本例程中LCD模块的复位引脚是接在STM32F1的复位上,所以直接按下开发板复位键即可;然后就是初始化序列,即向LCD控制器写入一系列的设置值(比如RGB格式、LCD显示方向、伽马校准等),这部分代码一般LCD厂商会提供。初始化之后LCD才可以正常使用
- 通过函数将字符和数字显示到TFTLCD模块上,画点流程只是一个点的处理,因此需要设计一个函数来多次使用这个步骤以实现字符和数字的显示
1.2 FSMC简介
FSMC(Flexible Static Memory Controller即灵活的静态存储控制器)是STM32系列采用的一种新型存储器扩展技术,能够连接同步、异步存储器和16位PC存储卡,STM32通过FSMC可以与SRAM、ROM、PSRAM、NOR Flash和NAND Flash等存储器的引脚直接相连。STM32F1的FSMC内部框图如下图示:
- 时钟输入:FSMC的时钟来自时钟控制器HCLK
- AHB接口:CPU和其他AHB总线主设备可通过该AHB从设备接口访问外部静态存储器
- 外部设备:FSMC将外部设备分为2类,NOR/PSRAM设备和NAND/PC卡设备。它们共用地址数据总线等信号,但具有不同的CS以区分不同的设备
本例程中使用的是FSMC的NOR/PSRAM存储器控制器部分,即把TFTLCD当成SRAM设备使用。NOR/PSRAM存储器控制器的接口信号功能如下图示:
从上图中可以看出外部SRAM的控制一般有:A0 ~ A25、D0 ~ D15、NWE、NOE、NE[x],如果支持字节控制还有UB/LB信号。而TFTLCD的信号线包括:RS、DB0 ~ DB15、WR、RD、CS、RST等。由此可见它们的操作接口信号完全类似,唯一不同就是TFTLCD有RS信号没有地址信号
TFTLCD通过RS信号来决定传送的数据是数据还是命令,可以理解为一个地址信号。比如我们把 RS 接在A0上面,当FSMC控制器写地址0的时候,会使得A0变为0,对TFTLCD来说就是写命令;而FSMC写地址1的时候,A0将会变为1,对TFTLCD来说就是写数据了。这样就把数据和命令区分开了,其实就是对应SRAM操作的两个连续地址。 当然RS也可以接在其他地址线上,本例程中RS是连接在 A10 上面的
下面介绍一下FSMC的外部设备地址映射,从FSMC的角度外部存储器被划分为4个固定大小的存储区域(Bank),每个存储区域的大小为256MB,共1GB空间,详见下图:
Bank1可连接多达4个NOR Flash或PSRAM存储器器件,此存储区域被划分为4个NOR/PSRAM区域,带4个专用片选信号;Bank2和Bank3用于连接NAND Flash器件;Bank4用于连接PC卡设备;对于每个存储区域,所要使用的存储器类型有用户在配置寄存器中定义。FSMC各Bank配置寄存器如下图示:
这里使用的是Bank1,Bank1又被分为4个区,每个区管理64MB空间,每个区都有独立的寄存器对所连接的存储器进行配置。Bank1的256MB空间由28根地址线(HADDR[27:0])寻址,HADDR是内部AHB地址总线,其中HADDR[25:0]来自外部存储器地址FSMC_A[25:0],HADDR[27:26]用于对4个区寻址:
本例程使用的是Bank1的第4区,即起始地址为0x6C000000,这里需要特别注意HADDR[25:0],HADDR[25:0]包含外部存储器地址,由于HADDR为字节地址,而存储器按字寻址,所以根据存储器数据宽度不同,实际向存储器发送的地址也有所不同,如下图示:
不论外部接8位/16位宽设备,FSMC_A[0]始终接在外部设备地址A[0]。本例程中TFTLCD使用的是16位数据宽度,所以HADDR[0]并没有用到,只有HADDR[25:1]是有效的,对应关系变为:HADDR[25:1] --> FSMC_A[24:0],相当于右移了一位。比如地址0x7E对应的二进制是01111110,此时FSMC_A6是0而不是1,因为要右移一位。另外HADDR[27:26]是不需要我们干预的。
FSMC的NOR Flash控制器支持同步和异步突发两种访问方式,选用不同的时序模型时,需要设置不同的时序参数:
- 同步突发访问方式:需要设置CLKDIV(分频系数)、DATLAT(获得第一个数据所需要的等待延迟)
- 异步突发访问方式:需要设置DATAST(数据建立时间)、ADDSET(地址建立时间)、ADDHLD(地址保持时间)
在实际扩展时根据选用存储器的特征确定时序模型,从而确定个时间参数与存储器读写周期参数指标之间的计算关系;利用该计算关系和存储芯片数据手册中给定的参数指标,可计算出FSMC所需要的各时间参数,从而对时间参数寄存器进行合理的配置
这里使用异步模式A(ModeA)方式来控制TFTLCD,模式A的读操作时序图如下所示:
模式A的写操作时序图如下所示:
2. 硬件设计
LED2指示灯用来提示系统运行状态,TFTLCD的ID通过串口1打印输出
- LED2指示灯
- USART1
- FSMC
- TFTLCD模块
3、 STM32CubeMX设置
- RCC设置外接HSE,时钟设置为72M
- PE5设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
- USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位
FSMC参数配置
(1)、选择FSMC,选中Bank1,片选为NE4(即Bank1的第4区),存储器类型选为LCD Interface,LCD寄存器选择(RS)设置为A10,数据宽度设为16位
在 Connectivity 中选择 FSMC 设置,并在 NOR Flash/PSRAM/SRAM/ROM/LCD 1 中选择 NE1 Chip Select 片选选择原理图中的片选引脚NE1【选择Bank1的第一区,是根据原理图的映射管脚进行选择的,这里选择不同区对应的引脚是不同的】
FSMC_NE 是用于控制存储器芯片的片选控制信号线,STM32 具有 FSMC_NE1/2/3/4 号引脚,不同的引脚对应 STM32 内部不同的地址区域。例如,当 STM32 访问 0x68000000-0x6BFFFFFF 地址空间时,FSMC_NE3 引脚会自动设置为低电平,由于它一般连接到外部存储器的片选引脚且低电平有效,所以外部存储器的片选被使能,而访问 0x60000000-
0x63FFFFFF 地址时,FSMC_NE1 会输出低电平。当使用不同的 FSMC_NE 引脚连接外部存储器时,STM32 访问外部存储的地址不一样,从而达到控制多个外部存储器芯片的目的。
- Memory type(设置要控制的存储器类型): 选择
LCD Interface
LCD接口 - LCD Register Select(RS引脚): 选择
A16
,RS脚也就是命令/数据选择位,同样是根据原理图得知这里应该选择A10
Data(设置要控制的存储器的数据宽度): 选择 16 bits
很明显从原理图看出有16个数据引脚,这里选择16bits就好
(2)、在配置菜单中,使能存储器写,根据LCD驱动芯片的数据参数设置地址建立时间、数据保存时间、总线周转阶段持续时间(设置为0),模式设置为A
NOR/PSRAM control:
- Write operation(设置是否写使能): 选择
Enabled
,禁止写使能的话 FSMC 只能从存储器中读取数据,不能写入。 - Extended mode(设置是否使用扩展模式): 选择
Enabled
,在非扩展模式下,对存储器读写的时序都只使用 FSMC_BCR 寄存器中的配;在扩展模式下,对存储器的读写时序可以分开配置,读时序使用 FSMC_BCR 寄存器,写时序使用 FSMC_BWTR 寄存器的配置。
FSMC读时序配置
这里引入一个基本概念:
HCLK周期:
按STM32F103的默认配置,HCLK的时钟频率为72MHz,即一个 THCLK 为 1/72us=0.0138us=13.8us。
NOR/PSRAM timing(FSMC读时序配置):
- Address setup time in HCLK clock cycles(地址建立时间): 填
0
- Data setup time in HCLK clock cycles(数据建立时间): 填
26
根据ILI9341时序配置FSMC读时序
NEx片选后,NOE要保持一段时间的高电平,这个时间就是
ADDSET地址建立时间
(通过寄存器FMC_BTRx可配置)。
之后NOE变为低电平,读使能。低电平保持的时间由DATAST数据建立时间
(通过寄存器FMC_BTRx可配置)决定。
tast:
tast 表示地址建立时间,最小为0ns
由时序图可以知道,FSMC在ADDSET周期之后,进入DATAST周期之后将会进行数据采样。所以我们设置(ADDSET)HCLK的时间要大于等于tast地址建立时间。
(ADDSET)HCLK >= 0ns,(0)·13.8 = 0ns,所以ADDSET可以设置为0就可保证满足最小tast地址建立时间
trdlfm:
trdlfm 表示读取数据低电平的时间,最小为355ns
ILI9341时序图没有给出ILI9341操作数据线传输被读取的数据时的相关信息,,我们最好做到满足其读取数据低电平的最小时间。
当然不做到也行,影响不大,只要在FSMC在DATAST的这个周期的数据采样中获取所有的要访问的数据就行。(DATAST)HCLK >355ns,(26) * 13.8 = 358.8ns>355ns,
所以DATAST设置为26。
- Bus turn around time in HCLK clock cycles(总线转换周期): 填
0
,仅适用于总线复用模式的NOR Flash操作,所以这里设0。 - Access mode(存储器访问模式): 选
A
,LCD控制器使用 Mode A ,该模式用来控制SRAM/PSRAM且OE会翻转。控制异步 NOR FLASH 时使用 B 模式。
FSMC写时序配置
NOR/PSRAM timing for write accesses(FSMC写时序配置):
- Extended address setup time(地址建立时间): 填
0
- Extended data setup time(数据建立时间): 填
1
根据ILI9341时序配置FSMC写时序
NEx片选后,NWE要保持一段时间的高电平,这个时间就是
ADDSET地址建立时间
(通过寄存器FMC_BTRx可配置)。
之后NWE变为低电平,写使能。低电平保持的时间由DATAST数据建立时间
(通过寄存器FMC_BTRx可配置)决定。
tast:
tast 表示地址建立时间,最小为0ns
由时序图可以知道,FSMC在ADDSET周期之后,进入DATAST周期之后将会进行数据采样。
所以我们设置(ADDSET)HCLK的时间要大于等于tast地址建立时间。
(ADDSET)HCLK >= 0ns,(0)·13.8 = 0ns,所以ADDSET可以设置为0就可保证满足最小tast地址建立时间。
tdst、tdht:
tdst:数据设置时间最小是10ns,在这个周期内WRX线处于低电平。
tdht:数据保持时间,与 twrh写控制高电平的最小时间相同,是10ns,在这个周期内WRX线处于高电平。观察时序图,我们设置 tdst数据设置时间 为1HCLK(13.8>10)就能满足数据设置最小时间的要求,我们不需要考虑tdht数据保持时间(看上面模式B时序图,NWE变成高电平后,会持续1HCLK=13.8ns,默认满足tdht了)。
故我们只需考虑数据建立周期 DATAST 要大于10ns就行。
(DATAST)HCLK > 10ns,13.8>10 ,故DATAST 至少设置为1
- Extended bus turn around time(总线转换周期): 填
0
- Extended access mode(存储器访问模式): 选
A
(3)、设置背光和复位引脚
根据原理图,复位脚已经跟单片机的复位脚连接在一起了,因此只需要设置背光引脚BL_EN就行了。
将PB0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为低电平,重命名为BL_EN。
(4)、输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码
4、 MDK-ARM编程
- 在fsmc.c文件下可以看到FSMC的初始化函数
void MX_FSMC_Init(void){FSMC_NORSRAM_TimingTypeDef Timing = {0};FSMC_NORSRAM_TimingTypeDef ExtTiming = {0};hsram1.Instance = FSMC_NORSRAM_DEVICE;hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;/* hsram1.Init */hsram1.Init.NSBank = FSMC_NORSRAM_BANK4;hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE;hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;/* Timing */Timing.AddressSetupTime = 0x01; //地址建立时间(ADDSET)为2个HCLK,即2/72M = 27.8nsTiming.AddressHoldTime = 15; //默认值,地址保持时间(ADDHLD)模式A未用到Timing.DataSetupTime = 0x0f; //数据建立时间(DATST)为16个HCLK,即16/72M = 222.2nsTiming.BusTurnAroundDuration = 0x00; //总线恢复时间Timing.CLKDivision = 16; //默认值(时钟分频),同步突发访问方式才需要设置此值Timing.DataLatency = 17; //默认值(数据保持时间),同步突发访问方式才需要设置此值Timing.AccessMode = FSMC_ACCESS_MODE_A;/* ExtTiming */ExtTiming.AddressSetupTime = 0x0f;//地址建立时间(ADDSET)为16个HCLK,即16/72M = 222.2nsExtTiming.AddressHoldTime = 15; //默认值,地址保持时间(ADDHLD)模式A未用到ExtTiming.DataSetupTime = 0x05; //数据建立时间(DATST)为6个HCLK,即6/72M = 83.3nsExtTiming.BusTurnAroundDuration = 0x00; //总线恢复时间ExtTiming.CLKDivision = 16; //默认值(时钟分频),同步突发访问方式才需要设置此值ExtTiming.DataLatency = 17; //默认值(数据保持时间),同步突发访问方式才需要设置此值ExtTiming.AccessMode = FSMC_ACCESS_MODE_A;if (HAL_SRAM_Init(&hsram1, &Timing, &ExtTiming) != HAL_OK){Error_Handler( );}__HAL_AFIO_FSMCNADV_DISCONNECTED();
}
- 创建TFTLCD驱动文件tftlcd.c 和相关头文件tftlcd.h 本例程使用FSMC存储器1的第4区驱动LCD,TFTLCD的RS接在FSMC_A10上,CS接在FSMC_NE4上,并且是16位数据总线,可以在tftlcd.h里定义如下LCD操作结构体:
//TFTLCD操作结构体
typedef struct{uint16_t LCD_CMD;uint16_t LCD_DATA;
}TFTLCD_TypeDef;
//HADDR[27,26]=11,A10作为数据命令区分线
//设置时STM32内部会右移以为对齐
#define TFTLCD_BASE ((uint32_t)(0x6C000000 | 0x000007FE))
#define TFTLCD ((TFTLCD_TypeDef *) TFTLCD_BASE)
//0x6C000000是Bank1.sector4的起始地址;0x000007FE是A10的偏移量
//0x7FE即11111111110,16位数据宽度时地址需要右移一位对齐
//因此实际对应到引脚时A10:A0=01111111111,此时A10是0
//如果16位地址再加1,则A10:A0=10000000000,此时A10是1
//有了以上定义,LCD写命令/数据极为方便
TFTLCD->LCD_CMD = CMD; //写命令
TFTLCD->LCD_DATA = DATA; //写数据
//读的时候反过来操作即可
CMD = TFTLCD->LCD_CMD //读LCD寄存器
DATA = TFTLCD->LCD_DATA //读LCD数据
tftlcd.h中另一个重要结构体:管理LCD重要参数
//LCD重要参数集
typedef struct{ uint16_t width; //LCD宽度uint16_t height; //LCD高度uint16_t id; //LCD IDuint8_t dir; //LCD显示方向
}_tftlcd_data;
extern _tftlcd_data tftlcd_data; //管理LCD重要参数
几个简单但是很重要的函数:
#define TFTLCD_R61509VN //本例程的TFTLCD屏驱动类型为R61509VN
//写寄存器函数,cmd:寄存器地址
void LCD_WriteCmd(uint16_t cmd){TFTLCD->LCD_CMD=(cmd>>8)<<1;TFTLCD->LCD_CMD=(cmd&0xff)<<1; //写入要写的寄存器序号
}
//写LCD数据,data:要写入的值
void LCD_WriteData(uint16_t data){TFTLCD->LCD_DATA=(data>>8)<<1;TFTLCD->LCD_DATA=(data&0xff)<<1;
}
//写寄存器,cmd:寄存器地址;data:要写入的数据
void LCD_WriteCmdData(uint16_t cmd,uint16_t data){LCD_WriteCmd(cmd);LCD_WriteData(data);
}
//读LCD数据,返回读到的值
uint16_t LCD_ReadData(void){ uint16_t ram; ram=(TFTLCD->LCD_DATA)>>1;ram=ram<<8;ram|=(TFTLCD->LCD_DATA)>>1; return ram;
}
链接: 百度网盘 请输入提取码 提取码:tvil
链接: https://pan.baidu.com/s/1Zb8qI-yZ795eyjGyXpgocQ?pwd=fnro 提取码:fnro
void LCD_Display_Dir(uint8_t dir); //设置LCD显示方向
void LCD_Set_Window(uint16_t sx,uint16_t sy,uint16_t width,uint16_t height); //设置窗口
void LCD_Clear(uint16_t Color); //清屏
void LCD_Fill(uint16_t xState,uint16_t yState,uint16_t xEnd,uint16_t yEnd,uint16_t color); //在指定区域内填充颜色
void LCD_DrawPoint(uint16_t x,uint16_t y); //画点
void LCD_DrawFRONT_COLOR(uint16_t x,uint16_t y,uint16_t color); //指定颜色画点
uint16_t LCD_ReadPoint(uint16_t x,uint16_t y); //读取某点的颜色
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); //画线
void LCD_DrawLine_Color(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color); //指定颜色画线
void LCD_DrowSign(uint16_t x, uint16_t y, uint16_t color); //画十字标记
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); //画矩形
void LCD_Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r); //指定位置画指定大小的圆
void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint8_t size,uint8_t mode); //在指定位置显示一个字符
void LCD_ShowNum(uint16_t x,uint16_t y,uint32_t num,uint8_t len,uint8_t size); //显示数字,不显示高位的0
void LCD_ShowxNum(uint16_t x,uint16_t y,uint32_t num,uint8_t len,uint8_t size,uint8_t mode); //显示数字,显示高位的0
void LCD_ShowString(uint16_t x,uint16_t y,uint16_t width,uint16_t height,uint8_t size,uint8_t *p); //显示字符串
void LCD_ShowFontHZ(uint16_t x, uint16_t y, uint8_t *cn); //显示汉字
void LCD_ShowPicture(uint16_t x, uint16_t y, uint16_t wide, uint16_t high,uint8_t *pic); //显示图片
- 在main.c文件下编写TFTLCD测试代码
int main(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_FSMC_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */TFTLCD_Init(); FRONT_COLOR=BLACK;LCD_ShowString(10,10,240,400,12,(uint8_t*)"TFTLCD Testing...!");FRONT_COLOR=RED;LCD_ShowString(10,30,240,400,16,(uint8_t*)"TFTLCD Testing...!");FRONT_COLOR=GREEN;LCD_ShowString(10,50,240,400,24,(uint8_t*)"TFTLCD Testing...!"); /* USER CODE END 2 */while (1){HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);HAL_Delay(200);}
}
5. 下载验证
STM32CubeMX生成的代码默认优化级别为Level 3,在此优化级别下编译无误下载到开发板后,可以看到D1指示灯不断闪烁,但是LCD屏不能被点亮;将优化级别调整到Level 0编译下载后,LCD屏能够被点亮
KEIL5中C/C++优化等级介绍: -O0:最少的优化,可以最大程度上配合产生代码调试信息,可以在任何代码行打断点,特别是死代码处。 -O1:有限的优化,去除无用的inline和无用的static函数、死代码消除等,在影响到调试信息的地方均不进行优化。在适当的代码体积和充分的调试之间平衡,代码编写阶段最常用的优化等级。 -O2:高度优化,调试信息不友好,有可能会修改代码和函数调用执行流程,自动对函数进行内联等。 -O3:最大程度优化,产生极少量的调试信息。会进行更多代码优化,例如循环展开,更激进的函数内联等。
编译无误下载到开发板后,可以看到D1指示灯不断闪烁,LCD屏显示相应的文字,串口打印出LCD的ID信息
6、参考文献
STM32CubeMX学习笔记(38)——FSMC接口使用(TFT-LCD屏显示)_cubemx配置lcd时复位引脚-CSDN博客
STM32CubeMX系列 | TFTLCD显示 - 知乎 (zhihu.com)
相关文章:

STM32CubeMX学习笔记17--- FSMC
1.1 TFTLCD简介 TFT-LCD(thin film transistor-liquid crystal display)即薄膜晶体管液晶显示器。液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),每个像素都可以通过点脉冲直接控制,因而每个节点都…...
【MogDB】实战MogDB数据库适配Halo博客系统1.6版本(基于springframework+hibernate+HikariPool)
前言 前一篇文章说了MogDB适配Halo,【MogDB】将流行的博客系统Halo后端的数据库设置为MogDB,但是适配的是2.x版本,由于2.x版本已经引入了对postgresql的支持,而MogDB对于postgresql有很好的兼容性,因此适配起来很简单。但是由于halo2.x的版本…...

Python与FPGA——局部二值化
文章目录 前言一、局部二值化二、Python局部二值化三、FPGA局部二值化总结 前言 局部二值化较全局二值化难,我们将在此实现Python与FPGA的局部二值化处理。 一、局部二值化 局部二值化就是使用一个窗口,在图像上进行扫描,每扫出9个像素求平均…...

shell文本处理工具-shell三剑客1
shell脚本常用基础命令2 shell脚本常用基础命令 shell脚本常用基础命令2一、grep用法二、sed用法2.1p参数 (显示)n参数(只显示处理过的行) 文本处理三剑客:grep sed awk 一、grep用法 grep -E egrep (扩展搜索正文表…...

函数的传入参数-传参定义
基于函数的定义语法: def 函数名(传入参数)函数体return 返回值 可以有如下函数定义: def add(x,y):return xyprint(f"{x} {y}的结果是:{result}") 实现了,每次计算的是xy,而非…...

主流接口测试框架对比,究竟哪个更好用
公司计划系统的开展接口自动化测试,需要我这边调研一下主流的接口测试框架给后端测试(主要测试接口)的同事介绍一下每个框架的特定和使用方式。后端同事根据他们接口的特点提出一下需求,看哪个框架更适合我们。 需求 1、接口编写…...
常用python模板
1.简单脚本模板 def main():#代码逻辑if __name__"__main__":main() 2.类定义模板 Class Myclass:def __init__(self,parameter):self.parameterparameterdef my_method(self):#方法逻辑 3.函数定义模板 def my_function(parameter):#代码逻辑return result 4.…...
53. 最大子数组和(力扣LeetCode)
文章目录 53. 最大子数组和题目描述暴力(运行超时)贪心 53. 最大子数组和 题目描述 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组是数组…...
如何远程SSH连接在家的服务器主机
当您需要通过SSH远程连接到家里的服务器主机时,以下是更详细的实施步骤: 1. 确保服务器主机已开启SSH服务 安装SSH服务:首先,确保您的服务器主机上安装了SSH服务。根据您的操作系统,您可以使用相应的包管理器来安装。…...

【亲测有效】解决三月八号ChatGPT 发消息无响应!
背景 今天忽然发现 ChatGPT 无法发送消息,能查看历史对话,但是无法发送消息。 可能的原因 出现这个问题的各位,应该都是点击登录后顶部弹窗邀请 [加入多语言 alapha 测试] 了,并且语言选择了中文,抓包看到 ab.chatg…...

vue结合vue-electron创建应用程序
这里写自定义目录标题 安装electron第一种方式:vue init electron-vue第二种方式:vue add electron-builder 启动electron调试功能:background操作和使用1、覆盖窗口的菜单上下文、右键菜单2、监听关闭事件、阻止默认行为3、创建悬浮窗口4、窗…...

【C++】STL(二) string容器
一、string基本概念 1、本质 string是C风格的字符串,而string本质上是一个类 string和char * 区别: char * 是一个指针 string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。 2、特点 1、stri…...

PyCM:Python中的混淆矩阵库
PyCM:Python中的混淆矩阵库 在机器学习和数据科学领域,评估模型的性能是至关重要的。混淆矩阵是一种常用的评估工具,用于可视化和量化分类模型的预测结果。PyCM是一个开源的Python库,提供了丰富的功能来计算和分析混淆矩阵。本文将…...

Day22:安全开发-PHP应用留言板功能超全局变量数据库操作第三方插件引用
目录 开发环境 数据导入-mysql架构&库表列 数据库操作-mysqli函数&增删改查 数据接收输出-html混编&超全局变量 第三方插件引用-js传参&函数对象调用 完整源码 思维导图 PHP知识点: 功能:新闻列表,会员中心࿰…...
IOS面试题object-c 61-70
61. 阐述isKindOfClass、isMemberOfClass、selector作用分别是什么?isKindOfClass:作用是某个对象属于某个类型或者继承自某类型。 isMemberOfClass:某个对象确切属于某个类型。 selector:通过方法名,获取在内存中的函…...
Git指令reset的参数soft、mixed与hard三者之间的区别
主要内容 reset默认不写参数,与使用mixed参数含义一样 为了描述简洁,使用下图说明: #mermaid-svg-LtChquRXlEV1j6og {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-LtChquRXlEV1j…...
RGMII 接口调试
目录 硬件检查 软件检查 调试步骤 硬件检查 硬件工程师检查原理图和PCB,核查RGMII线路连接是否正确,PHY的 TX连接对端 RX,PHY的RX连接对端TX,原理图上以引脚序号引脚名 引脚类型(输入还是输出)逐一核查RGMII接口各个网络&#…...

Ubuntu 24.04 抢先体验换国内源 清华源 阿里源 中科大源 163源
Update 240307:Ubuntu 24.04 LTS 进入功能冻结期 预计4月25日正式发布。 Ubuntu22.04换源 Ubuntu 24.04重要升级daily版本下载换源步骤 (阿里源)清华源中科大源网易163源 Ubuntu 24.04 LTS,代号 「Noble Numbat」,即将与我们见面! Canonica…...
软件设计模式:模板方法模式
1. 简介 模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。这样,可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 2. 使用条件 模板方法模式适用于以下情况: 算法…...

【算法】Hash存储——开放寻址法
模拟散列表 维护一个集合,支持如下几种操作: I x,插入一个整数 x; Q x,询问整数 x是否在集合中出现过; 现在要进行 N次操作,对于每个询问操作输出对应的结果。 输入格式 第一行包含整数 N&am…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...