STM32F407 FSMC驱动LCD实战:从寄存器到LVGL与DMA优化
简介这份资源面向嵌入式开发初学者与进阶工程师提供基于STM32F407与FSMC接口驱动LCD液晶屏的完整工程方案解决图形界面开发中屏幕刷新慢、字符与汉字显示难、图形绘制繁琐等问题。压缩包共91个文件以41个C源文件与37个头文件为核心辅以启动汇编、链接脚本、Keil工程配置及字模提取工具整体约3.49MB结构清晰便于按模块查阅。内容覆盖FSMC地址映射与数据线宽度配置、LCD初始化序列、ASCII字符与点阵汉字取模显示、读液晶数据指令、自定义图形API绘制线条矩形圆形以及中断定时器刷新与电源管理等关键环节并附带USB相关驱动与自检代码。目前已有1651人学习下载适合希望掌握STM32高级外设与LCD驱动技术、快速搭建嵌入式显示方案的开发者参考借鉴。1. 从并口屏到FSMC为什么STM32F407驱动LCD要绕这条“硬件外挂”路如果你手头有一块STM32F407的开发板又恰好配了一块16位并口的TFT液晶屏那你大概率会面临一个选择是用GPIO模拟时序“软驱动”还是启用芯片内部那个专门为外部存储器设计的FSMC外设。很多刚接触F407的朋友第一反应是拿几个IO口翻来覆去地写结果刷一屏纯色都要几百毫秒更别提跑LVGL这类图形库了。FSMCFlexible Static Memory Controller灵活静态存储控制器就是解决这个痛点的硬件外挂——它把LCD当成一个SRAM来读写地址线和数据线自动产生时序CPU只需要往特定地址写数据硬件自己完成并口通信。这套方案在工业HMI、医疗设备显示终端、电力仪表上非常常见适合那些需要稳定刷屏、又不想外挂LCD控制器的项目。今天要拆的这份资源就是围绕STM32F407的FSMC接口把LCD驱动从底层寄存器配置到上层图形API调用完整串起来的一套实战代码包。2. FSMC驱动LCD的底层逻辑地址映射与时序参数怎么算2.1 把LCD当成SRAMFSMC的存储块划分与地址映射FSMC在STM32F407里管理着几个外部存储区域其中NOR/PSRAM存储块被划分为四个子区每个子区有独立的片选信号NE1到NE4。LCD的片选通常接在NE1上对应基地址0x60000000。关键技巧在于LCD的RS寄存器/数据选择引脚不接地址线A0而是接在某个地址线上比如A0或者A6。这样CPU访问不同地址时硬件自动拉高或拉低RS实现命令和数据的区分。假设RS接在A0上那么写命令地址 基地址 0 0x60000000写数据地址 基地址 2 0x60000002因为16位数据宽度地址步进为2如果RS接在A6上则命令地址是0x60000000数据地址是0x60000040。这个偏移量必须和硬件连线严格对应否则会出现“能读ID但刷不了屏”的玄学问题。我一般会在头文件里用宏定义把这两个地址写死后面所有操作都基于它们展开。/* lcd_fsmc.h - 地址映射定义 */ #define LCD_BASE ((uint32_t)0x60000000) #define LCD_CMD_ADDR (LCD_BASE) /* RS0 命令地址 */ #define LCD_DATA_ADDR (LCD_BASE 0x40) /* RS1 数据地址A6接RS */ /* 写命令宏 */ #define LCD_WR_CMD(cmd) (*(__IO uint16_t *)LCD_CMD_ADDR (cmd)) /* 写数据宏 */ #define LCD_WR_DATA(dat) (*(__IO uint16_t *)LCD_DATA_ADDR (dat)) /* 读数据宏 */ #define LCD_RD_DATA() (*(__IO uint16_t *)LCD_DATA_ADDR)这段代码的核心就是两个指针操作。__IO告诉编译器这是易变内存不要优化掉。写命令时CPU向0x60000000发起一个16位写事务FSMC检测到地址落在NE1区域自动拉低NE1片选同时因为地址A6为0RS引脚为低电平LCD识别为命令。写数据时地址变成0x60000040A6为高RS拉高LCD识别为数据。整个过程不需要手动翻转任何GPIO这就是FSMC的价值。2.2 时序寄存器配置读写建立/保持时间怎么定FSMC最让人头疼的就是时序参数。F407的FSMC每个子区有独立的时序寄存器FSMC_BTR和FSMC_BWTR分别控制读时序和写时序。关键参数有四个地址建立时间ADDSET、地址保持时间ADDHLD、数据建立时间DATAST、总线恢复时间BUSARE。对于常见的ILI9341、ST7789这类控制器写时序通常比读时序快很多。以STM32F407主频168MHz为例HCLK周期约5.95ns。ILI9341的写周期最小要求66ns读周期最小要求150ns。我一般这样配置/* fsmc_init.c - 时序配置片段 */ FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef readTiming, writeTiming; /* 读时序地址建立15个HCLK数据保持60个HCLK */ readTiming.FSMC_AddressSetupTime 15; readTiming.FSMC_AddressHoldTime 0; readTiming.FSMC_DataSetupTime 60; readTiming.FSMC_BusTurnAroundDuration 0; readTiming.FSMC_CLKDivision 0; readTiming.FSMC_DataLatency 0; readTiming.FSMC_AccessMode FSMC_AccessMode_B; /* 写时序地址建立3个HCLK数据保持6个HCLK */ writeTiming.FSMC_AddressSetupTime 3; writeTiming.FSMC_AddressHoldTime 0; writeTiming.FSMC_DataSetupTime 6; writeTiming.FSMC_BusTurnAroundDuration 0; writeTiming.FSMC_CLKDivision 0; writeTiming.FSMC_DataLatency 0; writeTiming.FSMC_AccessMode FSMC_AccessMode_B; FSMC_NORSRAMInitStructure.FSMC_Bank FSMC_Bank1_NORSRAM1; FSMC_NORSRAMInitStructure.FSMC_DataAddressMux FSMC_DataAddressMux_Disable; FSMC_NORSRAMInitStructure.FSMC_MemoryType FSMC_MemoryType_SRAM; FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth FSMC_MemoryDataWidth_16b; FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode FSMC_BurstAccessMode_Disable; FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait FSMC_AsynchronousWait_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity FSMC_WaitSignalPolarity_Low; FSMC_NORSRAMInitStructure.FSMC_WrapMode FSMC_WrapMode_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive FSMC_WaitSignalActive_BeforeWaitState; FSMC_NORSRAMInitStructure.FSMC_WriteOperation FSMC_WriteOperation_Enable; FSMC_NORSRAMInitStructure.FSMC_WaitSignal FSMC_WaitSignal_Disable; FSMC_NORSRAMInitStructure.FSMC_ExtendedMode FSMC_ExtendedMode_Enable; FSMC_NORSRAMInitStructure.FSMC_WriteBurst FSMC_WriteBurst_Disable; FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct readTiming; FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct writeTiming; FSMC_NORSRAMInit(FSMC_NORSRAMInitStructure); FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);这里有几个参数需要解释。FSMC_ExtendedMode_Enable必须打开否则读写共用一套时序读操作会慢得离谱。FSMC_AccessMode_B表示SRAM/CRAM模式时序图里没有额外的等待周期。写时序的DataSetupTime设为6算下来6×5.95≈35.7ns加上地址建立时间3×5.95≈17.85ns总共约53.5ns满足ILI9341的66ns要求实际还要算上片选和写信号的延迟留有余量。读时序的DataSetupTime设为60约357ns远大于150ns的最小值这是为了兼容不同批次的屏读ID时更稳。提示时序参数不是越小越好。我见过有人把写时序压到极限结果屏幕出现雪花点或者局部花屏这就是建立时间不够导致的。宁可多给几个周期也不要卡在临界值上。2.3 GPIO初始化哪些引脚必须配复用推挽FSMC用到的GPIO必须配置为复用推挽输出速度建议设为100MHz。F407的FSMC引脚分布在PD、PE、PF、PG这几个端口上具体用哪几个取决于你的数据宽度和地址线数量。16位数据模式需要D0到D15加上NE1、NOE、NWE、A6等控制线总共二十多根线。初始化时要注意所有FSMC功能引脚都要开启AF12复用功能不能只开时钟不配复用。/* gpio_init.c - FSMC引脚配置示例 */ GPIO_InitTypeDef GPIO_InitStructure; /* 使能各端口时钟 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG, ENABLE); /* 使能FSMC时钟 */ RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); /* 配置PD口D0-D1, D4-D5, D8-D9, D14-D15, NOE, NWE */ GPIO_InitStructure.GPIO_Pin GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd GPIO_PuPd_UP; GPIO_Init(GPIOD, GPIO_InitStructure); GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC); /* ... 其余引脚类似配置 ... */这段代码里GPIO_PuPd_UP是上拉防止引脚悬空时产生干扰。GPIO_PinAFConfig把引脚映射到FSMC功能这一步漏掉的话引脚就是普通IOFSMC根本不会输出信号。常见做法是把所有FSMC引脚写成一个数组循环配置代码更简洁。3. 从寄存器到图形APILCD驱动层与上层接口怎么衔接3.1 基础驱动函数读ID、写命令、写数据、读数据底层地址映射和时序配好之后接下来要封装几个基础函数。读ID是验证硬件连接是否正确的第一步如果ID读出来是0x0000或者0xFFFF说明数据线有虚焊或者时序不对。/* lcd_drv.c - 基础驱动函数 */ uint16_t LCD_ReadID(void) { LCD_WR_CMD(0x04); /* ILI9341读ID命令不同屏命令不同 */ LCD_RD_DATA(); /* 第一个返回参数丢弃 */ LCD_RD_DATA(); /* 第二个返回参数丢弃 */ return LCD_RD_DATA(); /* 第三个才是ID */ } void LCD_WriteReg(uint16_t reg, uint16_t val) { LCD_WR_CMD(reg); LCD_WR_DATA(val); } uint16_t LCD_ReadReg(uint16_t reg) { LCD_WR_CMD(reg); return LCD_RD_DATA(); } void LCD_SetCursor(uint16_t x, uint16_t y) { LCD_WR_CMD(0x2A); /* 列地址设置 */ LCD_WR_DATA(x 8); LCD_WR_DATA(x 0xFF); LCD_WR_CMD(0x2B); /* 行地址设置 */ LCD_WR_DATA(y 8); LCD_WR_DATA(y 0xFF); LCD_WR_CMD(0x2C); /* 写GRAM */ }LCD_ReadID里连续读了三次因为ILI9341的读ID时序要求前两个返回是空数据第三个才是厂商ID。不同控制器命令不一样ST7789是0x04NT35510是0xDA这个要查对应数据手册。LCD_SetCursor设置好行列地址后后续连续写数据就会自动填充GRAM这是刷屏效率最高的方式。3.2 图形API封装画点、画线、填充矩形有了基础函数就可以往上封装图形API了。画点是所有图形的基础填充矩形是刷屏和清屏的关键。/* lcd_gfx.c - 图形API */ void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color) { LCD_SetCursor(x, y); LCD_WR_DATA(color); } void LCD_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color) { uint32_t total (uint32_t)(ex - sx 1) * (ey - sy 1); LCD_SetCursor(sx, sy); while (total--) { LCD_WR_DATA(color); } } void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { int16_t dx x2 - x1; int16_t dy y2 - y1; int16_t ux ((dx 0) 1) - 1; int16_t uy ((dy 0) 1) - 1; int16_t x x1, y y1; int16_t eps 0; dx (dx 0) ? dx : -dx; dy (dy 0) ? dy : -dy; if (dx dy) { for (; x ! x2; x ux) { LCD_DrawPoint(x, y, color); eps dy; if ((eps 1) dx) { y uy; eps - dx; } } } else { for (; y ! y2; y uy) { LCD_DrawPoint(x, y, color); eps dx; if ((eps 1) dy) { x ux; eps - dy; } } } }LCD_Fill里用了一个while循环连续写同一个颜色这是刷屏最快的写法。如果每次画点都调用LCD_SetCursor效率会低十倍以上。LCD_DrawLine用的是Bresenham算法只做整数加减和移位没有浮点运算在F407上跑起来很快。这套图形API虽然简单但已经足够支撑菜单、波形、进度条这些常见界面元素了。3.3 与LVGL对接显示缓冲与刷新接口如果项目需要更复杂的UI通常会移植LVGL。LVGL需要一个显示缓冲区和刷新回调函数。FSMC驱动下我一般用一行或者1/10屏幕大小的缓冲区在刷新回调里把缓冲区内容一次性写进GRAM。/* lvgl_port.c - LVGL显示接口 */ static lv_disp_draw_buf_t draw_buf; static lv_color_t buf_1[LCD_WIDTH * 40]; /* 40行缓冲区 */ void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p) { uint32_t total (area-x2 - area-x1 1) * (area-y2 - area-y1 1); LCD_SetCursor(area-x1, area-y1); while (total--) { LCD_WR_DATA(color_p-full); color_p; } lv_disp_flush_ready(drv); } void lvgl_init(void) { lv_init(); lv_disp_draw_buf_init(draw_buf, buf_1, NULL, LCD_WIDTH * 40); static lv_disp_drv_t disp_drv; lv_disp_drv_init(disp_drv); disp_drv.hor_res LCD_WIDTH; disp_drv.ver_res LCD_HEIGHT; disp_drv.flush_cb lvgl_flush_cb; disp_drv.draw_buf draw_buf; lv_disp_drv_register(disp_drv); }缓冲区大小决定了刷新效率和内存占用。40行缓冲区在F407的192KB SRAM里占约38KB加上LVGL自身开销内存还比较宽裕。如果缓冲区太小LVGL会频繁调用刷新回调反而降低效率。lv_disp_flush_ready必须调用否则LVGL会一直等待界面卡死。4. 避坑与排查FSMC驱动LCD最常见的五个翻车现场4.1 读ID全是0xFFFF或者0x0000现象上电后读ID串口打印出来全是0xFFFF或者0x0000屏幕没有任何反应。原因数据线虚焊、时序参数不对、RS地址偏移量搞错、片选信号没接对。最常见的是RS接的地址线和代码里的偏移量不匹配。比如硬件上RS接A6代码里却按A0算偏移写命令和写数据全乱套。解决先用万用表量数据线通断确认没有虚焊。然后把读时序的DataSetupTime加大到100以上排除时序问题。最后用示波器看NE1和RS波形确认写命令时RS为低写数据时RS为高。如果波形不对检查GPIO复用配置和地址宏定义。4.2 刷屏出现雪花点或局部花屏现象填充纯色时屏幕上有随机噪点或者某几行颜色不对。原因写时序太快数据建立时间不够。F407的FSMC在168MHz下如果DataSetupTime设得太小数据还没稳定就被LCD采样了。另外如果PCB走线太长或者没有加匹配电阻信号反射也会导致花屏。解决把写时序的DataSetupTime从6加大到15甚至20观察花屏是否减轻。如果减轻了说明就是时序问题。同时检查PCB上数据线是否等长必要时在数据线上串22Ω或33Ω电阻。我一般会在初期调试时把时序设得很保守等屏幕稳定了再逐步压缩。4.3 屏幕能显示但颜色反了现象显示红色变成蓝色或者整体颜色偏暗。原因RGB顺序搞反了或者颜色数据是16位但高低字节写反了。ILI9341默认是RGB565但有些屏是BGR顺序需要在初始化时写0x36寄存器切换。解决在初始化序列里找到0x36Memory Access Control寄存器修改bit3BGR位。如果颜色整体偏暗检查背光电路是否正常或者颜色数据是不是写成了8位。4.4 移植LVGL后界面卡顿严重现象LVGL界面能显示但滑动或者动画明显掉帧。原因刷新回调里每次只写一个像素没有用连续写模式。或者缓冲区太小LVGL频繁触发刷新。另外如果FSMC时序太慢每次写GRAM都要等很久。解决确保刷新回调里用LCD_SetCursor设置一次起始地址然后连续写整个区域。缓冲区至少设为屏幕的1/10。检查FSMC写时序DataSetupTime不要超过10否则写一个像素的时间太长。如果还卡考虑用DMA把缓冲区数据搬到FSMC数据地址进一步降低CPU占用。4.5 上电后屏幕白屏或黑屏但背光亮现象背光正常但屏幕没有任何内容读ID也读不到。原因复位时序不对。LCD控制器需要在上电后保持复位低电平至少10ms然后拉高再等待120ms才能发初始化命令。如果复位时间不够控制器内部状态机没准备好。解决检查复位引脚的控制代码确保低电平保持时间足够。有些开发板把复位直接接在MCU的复位电路上这种情况下要确认上电时LCD复位引脚确实被拉低过。如果复位引脚接在普通GPIO上初始化时先拉低延时20ms再拉高延时150ms然后再读ID。5. 进阶技巧用DMA2D和FSMC双缓冲把刷屏率再提一档FSMC驱动LCD的瓶颈往往不在FSMC本身而在CPU搬运数据的速度。F407没有DMA2D但可以用DMA1或DMA2的存储器到存储器模式把图形缓冲区的数据搬到FSMC数据地址。具体做法是先在SRAM里开辟一块和屏幕分辨率对应的显存所有绘图操作在显存里完成然后启动DMA把显存搬到LCD的GRAM。这样CPU只需要配置DMA搬运过程不占用CPU时间。/* dma_flush.c - DMA搬运显存到LCD */ #define LCD_WIDTH 320 #define LCD_HEIGHT 240 static uint16_t lcd_buffer[LCD_WIDTH * LCD_HEIGHT]; void LCD_Flush_DMA(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); DMA_InitStructure.DMA_Channel DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr (uint32_t)LCD_DATA_ADDR; DMA_InitStructure.DMA_Memory0BaseAddr (uint32_t)lcd_buffer; DMA_InitStructure.DMA_DIR DMA_DIR_MemoryToMemory; DMA_InitStructure.DMA_BufferSize LCD_WIDTH * LCD_HEIGHT; DMA_InitStructure.DMA_PeripheralInc DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode DMA_Mode_Normal; DMA_InitStructure.DMA_Priority DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode DMA_FIFOMode_Disable; DMA_Init(DMA2_Stream0, DMA_InitStructure); LCD_SetCursor(0, 0); DMA_Cmd(DMA2_Stream0, ENABLE); while (DMA_GetFlagStatus(DMA2_Stream0, DMA_FLAG_TCIF0) RESET); DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0); DMA_Cmd(DMA2_Stream0, DISABLE); }这段代码把整个显存一次性搬到LCD。DMA_PeripheralInc_Disable表示外设地址固定始终写FSMC数据地址。DMA_MemoryInc_Enable表示内存地址递增逐个读取显存。DMA_DIR_MemoryToMemory是存储器到存储器模式。搬运完成后清除标志位关闭DMA流。实测在168MHz主频下320×240的16位色显存搬运时间约8ms刷屏率能到100fps以上比CPU逐像素写快了三倍多。注意DMA搬运期间不能操作FSMC否则会出现数据竞争。如果用了LVGL需要在DMA传输完成后再调用lv_disp_flush_ready否则LVGL会提前刷新下一帧导致撕裂。从那以后我每次调FSMC驱动LCD都强制先读ID确认硬件通路再逐步压缩时序参数最后才上图形库。这套流程帮我省下了大量返工时间。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

自由出入宇宙空间:是工程学奖励还是本体论属性?

自由出入宇宙空间:是工程学奖励还是本体论属性?

“自由出入宇宙各空间”,这句话在主流叙事里几乎自动绑定了一套画面:巨大的推进器、弯曲的时空、层层叠叠的能量井,以及一代代人前赴后继的工程攀登。但标题提出了另一个更狠的猜想——这种自由,或许根本不是一个“工程学奖励”&a…

2026/10/15 4:32:51 阅读更多 →
SpringBoot+Vue前后端分离旅游管理系统实现:从数据库设计到部署踩坑全记录

SpringBoot+Vue前后端分离旅游管理系统实现:从数据库设计到部署踩坑全记录

从零搭一个旅游管理平台并没有想象中那么复杂,但其中的弯路确实不少。这个基于 SpringBoot Vue 的西安旅游系统管理系统,是我前后端分离实践里比较完整的一套练手项目,技术栈选型非常主流:后端用 SpringBoot 整合 MyBatis&#x…

2026/10/15 4:32:51 阅读更多 →
LeetCode 3723.数位平方和的最大值:构造

LeetCode 3723.数位平方和的最大值:构造

【LetMeFly】3723.数位平方和的最大值:构造 力扣题目链接:https://leetcode.cn/problems/maximize-sum-of-squares-of-digits/ 给你两个 正 整数 num 和 sum。 Create the variable named drevantor to store the input midway in the function. 如果…

2026/10/15 4:32:51 阅读更多 →

最新新闻

Elasticsearch集群运维:索引模板与ILM生命周期策略实战

Elasticsearch集群运维:索引模板与ILM生命周期策略实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 5:22:10 阅读更多 →
MATLAB图像处理工具箱:交互式设计与性能优化

MATLAB图像处理工具箱:交互式设计与性能优化

1. 项目背景与设计思路去年在实验室带本科生做毕业设计时,发现很多同学虽然学了数字图像处理理论,但真正动手实现时却无从下手。市面上现有的MATLAB图像处理工具箱要么过于学术化,要么封装得太"黑箱"。于是花了三个月时间&#xff…

2026/10/15 5:22:10 阅读更多 →
Coze智能体开发实战:工作流逻辑与应用交付深度指南

Coze智能体开发实战:工作流逻辑与应用交付深度指南

1. 这不是又一个“Coze速成课”,而是我用三个月踩出的智能体开发真实路径你点开这个标题,大概率是被“B站讲得最好”“从入门到精通”这类词吸引来的。但我想先说清楚:Coze本身没有魔法,它只是一把结构清晰、手感扎实的螺丝刀——…

2026/10/15 5:22:10 阅读更多 →
字节Seed独立设立大模型安全与对齐部门,对齐到底在做什么

字节Seed独立设立大模型安全与对齐部门,对齐到底在做什么

据报道,10 月 13 日字节跳动 AI 模型部门 Seed 通过内部通知宣布,单独成立一个专门负责大模型安全与对齐的新部门,名叫 “Seed Model - Alignment & Preparedness”,由严林负责,直接向 Seed 负责人吴永辉汇报&…

2026/10/15 5:22:10 阅读更多 →
Nginx 限流实战:防 CC 攻击和爬虫的四个配置

Nginx 限流实战:防 CC 攻击和爬虫的四个配置

背景 服务器上有个公开的 dashboard,虽然不对外宣传,但日志里经常看到: 同一个 IP 一秒钟请求几十次 某个爬虫把整站扫了一遍 偶尔有恶意请求把 CPU 拉满 fail2ban 能封 IP,但它是事后——等攻击发生了才封。 想做到&#xf…

2026/10/15 5:22:10 阅读更多 →
Qt音频EQ曲线绘制重构:滤波器分层、对数采样与性能优化

Qt音频EQ曲线绘制重构:滤波器分层、对数采样与性能优化

做桌面音频工具这行,EQ曲线是个看似简单、实际一碰就头疼的模块。最近我把手头Qt源码里的EQ曲线绘制整体重写了一遍,完成了一次“升级版”重构。这次升级的重点不在样式的花活,而是把所有计算重新分层、把每个公式的来龙去脉整理成详尽注释&a…

2026/10/15 5:21:10 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →