STM32F1嵌入式入门指南:从选型到外设实战

1. 为什么STM32F1至今仍是嵌入式入门的首选

如果你在电子类论坛或者技术群里待过一段时间,一定会发现一个现象:每隔几周就有人问“2025年了,学单片机还值得从STM32F1开始吗?”底下的回复往往分成两派,一派说F1太老了该直接上F4或者国产替代,另一派则坚持F1是永远的经典。我自己的看法很明确:对于第一次接触ARM Cortex-M架构的人来说,STM32F1依然是最稳妥的起点,没有之一。

原因不复杂。F1系列基于Cortex-M3内核,主频通常跑在72MHz,外设资源够用但不冗余,参考手册和技术文档的积累量在所有MCU里几乎是最厚的。你遇到的绝大多数问题,早在十几年前就有人在论坛上问过并且得到了解答。这种“问题覆盖率”对新手来说极其重要——它意味着你踩的每一个坑,几乎都能找到现成的排查思路,而不是对着一片空白自己摸索。

另一个容易被忽略的点是成本。一块F103C8T6的最小系统板,也就是大家常说的“蓝板”或者“最小系统板”,价格长期稳定在很低的水平,配套的ST-Link调试器同样便宜。这意味着你可以同时买好几块,一块做实验,一块烧坏了也不心疼。相比之下,直接上手F4或者H7系列,光是开发板成本就翻了好几倍,而你能学到的核心概念——GPIO、中断、定时器、串口、SPI、I2C、ADC——在F1上一样都不少。

当然,我不是说F1适合所有场景。如果你要做浮点运算密集的信号处理,或者需要以太网、USB高速、大容量RAM,那F1确实力不从心。但作为理解MCU工作原理、掌握寄存器操作逻辑、建立嵌入式开发思维的载体,F1的性价比无可替代。这篇文章我会从实际使用的角度,把F1系列的核心要点、常见坑位、以及从零搭建一个可用工程的全过程讲清楚,适合刚入门的朋友,也适合想回头梳理基础的老手。

2. 先把F1系列的产品线理清楚,别选错型号

2.1 从F103到F107:后缀数字到底代表什么

STM32F1系列并不是一个单一型号,而是一个包含多个子系列的产品家族。很多新手在选型时看到“STM32F103C8T6”“STM32F103RCT6”“STM32F107VCT6”这些型号就懵了,其实拆开看逻辑很清晰。

以STM32F103C8T6为例,拆解规则是这样的:STM32是家族名,F代表基础型系列,103是子系列编号,C代表引脚数(C=48脚,R=64脚,V=100脚,Z=144脚),8代表Flash容量(6=32KB,8=64KB,B=128KB,C=256KB,D=384KB,E=512KB),T代表封装(T=LQFP,H=BGA,U=QFN),6代表温度范围(6=-40到85度,7=-40到105度)。

F1系列内部主要分几条线:F103是主力通用型,外设最均衡,资料最多;F101是精简版,少了USB和CAN,适合纯控制场景;F102和F105/107增加了USB OTG和以太网,其中F107带以太网MAC,适合需要联网的场合;F100是低端型,主频和Flash都缩水。对于绝大多数入门和中等复杂度的项目,F103系列足够覆盖。

2.2 选型时最容易忽略的三个参数

第一个是RAM大小。很多人只看Flash,觉得64KB Flash够用了,结果写代码时发现RAM只有20KB,稍微开几个缓冲区就爆了。F103C8T6的RAM是20KB,F103RCT6是48KB,F103ZET6是64KB。如果你打算跑RTOS或者做大量数据缓存,RAM比Flash更值得关注。

第二个是定时器数量。F103C8T6有3个通用定时器加1个高级定时器,而F103RC以上有4个通用定时器加2个高级定时器。如果你要做多路PWM输出或者输入捕获,定时器数量直接决定你能不能完成任务。

第三个是封装与焊接难度。LQFP封装引脚间距是0.5mm,手工焊接需要一定的技巧;QFN封装底部有散热焊盘,手工焊接难度更大。如果你是自己做板子,建议优先选LQFP封装,实在不行就买现成的核心板。

型号FlashRAM引脚定时器串口SPII2CADC通道
F103C8T664KB20KB48432210
F103RCT6256KB48KB64853216
F103ZET6512KB64KB144853221
F107VCT6256KB64KB100853216

这张表建议保存下来,选型时对照着看,能省去很多翻手册的时间。

3. 搭建开发环境的几个关键决策

3.1 IDE选型:Keil、IAR还是STM32CubeIDE

这个问题在社区里争论了很多年,我的建议是根据你的目标来定。如果你追求极致的轻量和成熟的生态,Keil MDK是首选。它的编译器优化做得好,生成的代码体积小,调试器支持完善,而且网上绝大多数F1的例程都是Keil工程,直接拿来就能用。缺点是正版授权费用不低,不过对于学习用途,社区版的功能已经足够。

STM32CubeIDE是ST官方推出的免费方案,基于Eclipse,集成了CubeMX配置工具,可以图形化配置引脚和外设,自动生成初始化代码。对于新手来说,这个工具能大幅降低入门门槛——你不需要手动查手册算寄存器值,点几下鼠标就能把时钟树配好。但它的代码生成风格比较“重”,生成的工程文件多,编译速度也比Keil慢一些。

IAR的优势在于编译效率和调试体验,但授权费用更高,社区版有代码大小限制。我个人的习惯是:学习和快速验证用CubeIDE,正式项目用Keil。两者之间可以互相导入工程,切换成本不高。

3.2 调试器:ST-Link还是J-Link

ST-Link是ST官方的调试器,价格便宜,和CubeIDE、Keil都能无缝配合。市面上常见的“ST-Link V2”山寨版价格极低,功能上对于F1系列完全够用。J-Link性能更强,支持更多芯片型号,但价格也更高。对于F1开发,ST-Link完全够用,没必要上J-Link。

需要注意的是,ST-Link的固件版本会影响兼容性。如果你买的是山寨版,可能会遇到“无法识别设备”或者“下载失败”的问题。解决办法是用ST官方的升级工具更新固件,或者换一个USB口试试。另外,SWD接口只需要四根线:VCC、GND、SWDIO、SWCLK,接线越短越好,超过20厘米就容易出现通信不稳定的情况。

3.3 时钟配置:为什么你的串口总是乱码

时钟配置是F1开发中最容易出错的地方之一。F103的外部晶振通常是8MHz,经过PLL倍频到72MHz作为系统时钟。但很多人忽略了APB1和APB2的分频系数——APB1最大只能到36MHz,APB2可以到72MHz。如果你把APB1的时钟配成72MHz,定时器和串口的时钟就会出错,导致波特率不对、串口输出乱码。

在CubeMX里配置时钟树时,注意看每个总线的时钟频率是否在允许范围内。串口1挂在APB2上,串口2和3挂在APB1上,计算波特率时要根据对应的总线时钟来算。如果你用标准库手动配置,记得在SystemInit之后检查一下RCC_GetClocksFreq的返回值,确认各总线时钟符合预期。

4. GPIO与中断:从点灯到按键响应的完整链路

4.1 GPIO的八种模式,什么时候用哪一种

F1的GPIO有八种工作模式,新手最容易混淆的是推挽输出、开漏输出、上拉输入、浮空输入这四种。我用一个简单的类比来解释:推挽输出就像两个人推拉一扇门,一个负责推一个负责拉,能主动输出高电平和低电平;开漏输出只有一个人负责拉,高电平需要外部上拉电阻来实现,适合I2C这种需要线与逻辑的总线。

上拉输入和浮空输入的区别在于内部有没有接上拉电阻。按键检测通常用上拉输入,按键另一端接GND,按下时读到低电平,松开时内部上拉保证读到高电平。如果用的是浮空输入,按键松开时引脚电平不确定,读到的值可能是随机的。

输出速度的设置也有讲究。速度越高,功耗和电磁干扰越大。对于LED控制这种低速场景,设置成2MHz就够了;对于SPI时钟这种高速信号,才需要设置成50MHz。很多人习惯性地把所有引脚都设成最高速度,这在低功耗场景下是不必要的浪费。

4.2 外部中断的配置陷阱

按键中断是学F1时绕不开的练习,但这里有几个坑值得提前说。第一,中断线是复用的。PA0和PB0共用EXTI0中断线,如果你同时开了PA0和PB0的中断,触发时会分不清是哪个引脚。解决办法是在中断服务函数里读取引脚状态来判断,或者干脆避免同时使用相同编号的引脚。

第二,按键抖动必须处理。机械按键按下和松开时会产生几毫秒的抖动,如果不做消抖,一次按下可能触发多次中断。硬件消抖是在按键两端并联一个0.1uF电容,软件消抖是在中断里延时10ms后再次确认电平。我通常推荐软件消抖,因为硬件电容会增加成本,而且调试时不容易观察。

第三,中断优先级要规划好。F1的中断优先级分抢占优先级和响应优先级,数值越小优先级越高。如果多个中断同时触发,抢占优先级高的先执行;如果抢占优先级相同,响应优先级高的先执行。规划原则是:实时性要求高的中断给高抢占优先级,执行时间长的中断给低抢占优先级,避免在中断里做耗时操作阻塞其他中断。

4.3 一个完整的按键控制LED的代码框架

下面是一个基于标准库的按键中断控制LED的代码框架,关键部分我加了注释:

// 按键初始化:PA0上拉输入,下降沿触发 void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); // 将PA0映射到EXTI0 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); // 配置NVIC NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } // 中断服务函数 void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) != RESET) { // 软件消抖:延时后再次确认 delay_ms(10); if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) { GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13))); } EXTI_ClearITPendingBit(EXTI_Line0); // 必须清除标志位 } }

这段代码里最容易忘记的是清除中断标志位。如果不调用EXTI_ClearITPendingBit,中断会反复触发,程序看起来就像卡死了一样。另外,GPIO_EXTILineConfig这个函数容易被忽略,它的作用是把GPIO引脚和中断线关联起来,不调用的话中断永远不会触发。

5. 定时器:F1最强大也最容易被低估的外设

5.1 基本定时、PWM输出、输入捕获的底层逻辑

F1的定时器分为高级定时器(TIM1、TIM8)、通用定时器(TIM2到TIM5)和基本定时器(TIM6、TIM7)。高级定时器支持互补输出和死区插入,适合电机控制;通用定时器功能最全,适合大多数场景;基本定时器只能计数,适合做简单的延时。

定时器的核心是一个计数器,它根据时钟源向上或向下计数,计到设定值时产生事件。PWM输出的原理是:计数器不断计数,同时比较计数器和比较寄存器的值,当计数值小于比较值时输出高电平,大于时输出低电平。改变比较值就能改变占空比,改变自动重装载值就能改变频率。

输入捕获的原理正好相反:当引脚上检测到边沿信号时,把当前计数器的值锁存到捕获寄存器里。通过两次捕获的值之差,就能算出信号的周期或脉宽。超声波测距模块就是典型的输入捕获应用——发送触发信号后,捕获回波引脚的高电平持续时间,乘以声速就能算出距离。

5.2 PWM频率与占空比的参数计算

假设系统时钟72MHz,APB1预分频后定时器时钟为72MHz(注意APB1分频系数不为1时,定时器时钟会倍频)。要产生1kHz的PWM,计算过程如下:

  • 定时器时钟 = 72MHz
  • 目标频率 = 1kHz
  • 自动重装载值 + 1 = 72MHz / 1kHz = 72000
  • 取自动重装载值为7199,预分频系数为0

如果要产生50Hz的舵机控制信号,计算过程是:

  • 72MHz / 50Hz = 1440000
  • 预分频系数设为71,则定时器时钟变为1MHz
  • 自动重装载值 = 1MHz / 50Hz - 1 = 19999

舵机的占空比对应角度:0.5ms对应0度,1.5ms对应90度,2.5ms对应180度。在1MHz时钟下,0.5ms对应500个计数,所以比较值设为500就是0度,1500就是90度,2500就是180度。

注意:高级定时器的PWM输出需要额外使能TIM_CtrlPWMOutputs,否则引脚不会有输出。这个坑我见过很多人踩,配置了半天发现没波形,最后发现是少了这一句。

5.3 定时器中断的频率规划

定时器中断常用于周期性任务,比如每1ms读取一次传感器、每10ms刷新一次显示。规划中断频率时要考虑两个因素:任务的实际需求和CPU的负担。中断太频繁会占用大量CPU时间,中断太慢又会影响响应速度。

我的经验是:控制类任务用1kHz到10kHz,显示刷新用50Hz到100Hz,传感器采集根据传感器手册来定。在中断服务函数里只做最紧急的事情,比如置标志位、存数据,把耗时的处理放到主循环里。这样能保证中断响应及时,又不会阻塞其他中断。

6. 串口通信:从乱码到稳定收发的排查路径

6.1 串口乱码的五个常见原因

串口是调试阶段最重要的工具,但也是问题最多的外设。乱码的第一大原因是波特率不匹配,发送方和接收方必须用相同的波特率,而且实际波特率和设定值的误差不能超过2%。F1的串口波特率由APB时钟和USARTDIV寄存器决定,如果APB时钟配置错误,波特率就会偏。

第二个原因是时钟源问题。如果你用的是外部晶振,但晶振没有起振,系统会切换到内部RC振荡器,频率偏差较大,导致波特率不准。检查方法是测量PA8引脚有没有时钟输出,或者在代码里读取RCC的时钟源状态。

第三个原因是电平不匹配。F1的串口是TTL电平(0到3.3V),如果直接连RS232设备(正负12V),不仅收不到数据,还可能烧坏引脚。必须经过电平转换芯片。

第四个原因是接线错误。TX要接对方的RX,RX要接对方的TX,很多人第一次接线时容易接成TX对TX。另外GND必须共地,不共地的话电平没有参考点,数据也是乱的。

第五个原因是中断优先级冲突。如果串口接收中断被其他高优先级中断频繁打断,接收缓冲区可能溢出,导致数据丢失或错位。解决办法是给串口中断合理的优先级,或者用DMA接收。

6.2 用DMA加空闲中断实现不定长数据接收

传统的串口接收方式是每收到一个字节进一次中断,把数据存到缓冲区。这种方式在低波特率下没问题,但在高波特率下会频繁打断CPU。更好的方案是DMA加空闲中断:DMA负责把串口数据搬到内存,空闲中断在总线空闲时触发,告诉你一帧数据接收完毕。

配置步骤是这样的:先初始化DMA通道,设置外设地址为串口数据寄存器,内存地址为接收缓冲区,传输方向为外设到内存。然后使能串口的DMA接收请求和空闲中断。在空闲中断服务函数里,计算DMA剩余传输数量,算出实际接收到的字节数,然后重新配置DMA准备下一次接收。

这个方案的好处是CPU几乎不参与数据搬运,只在帧结束时处理一次中断。对于需要接收大量数据的场景,比如GPS模块、无线模块,这个方案能显著降低CPU负载。

6.3 printf重定向的两种实现方式

调试时经常需要用printf输出信息,但标准库的printf默认输出到控制台,在单片机上需要重定向到串口。第一种方式是重写fputc函数,在函数里把字符发送到串口。这种方式简单直接,但需要勾选Keil的“Use MicroLIB”选项,否则会卡在while(USART_GetFlagStatus(...) == RESET)里出不来。

第二种方式是用__io_putchar或者自定义输出函数,不依赖标准库的缓冲机制。这种方式更可控,但需要自己实现格式化输出的逻辑。我通常用第一种方式,因为够简单,而且MicroLIB的体积也小。

// 重定向fputc到串口1 int fputc(int ch, FILE *f) { while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_SendData(USART1, (uint8_t)ch); return ch; }

提示:如果重定向后没有输出,先检查串口初始化是否正确,再检查MicroLIB是否勾选,最后检查波特率和接线。这三个地方排查完,基本能解决90%的问题。

7. 那些手册上不会写的实操经验

7.1 电源与复位电路的细节

F1的供电范围是2.0V到3.6V,典型值是3.3V。VDDA和VSSA是模拟部分的供电,即使你不用ADC,也建议接上滤波电容,否则可能影响其他外设的稳定性。VBAT是备份电池供电,如果你不需要RTC和备份寄存器,可以直接接VDD。

复位电路通常是一个10k电阻上拉到VDD,加一个100nF电容到GND。有些开发板省掉了这个电容,短期用没问题,但在电磁环境复杂的场合可能出现随机复位。NRST引脚内部有上拉电阻,但阻值较大,外部再加一个10k上拉会更可靠。

BOOT0和BOOT1的配置决定启动模式。BOOT0=0时从Flash启动,这是正常运行的模式;BOOT0=1、BOOT1=0时从系统存储器启动,用于串口下载程序;BOOT0=1、BOOT1=1时从RAM启动,用于调试。很多人在下载程序后忘记把BOOT0拨回0,结果程序不运行,还以为芯片坏了。

7.2 下载失败与芯片锁死的处理

下载失败最常见的原因是SWD引脚被复用。如果你在代码里把PA13和PA14配置成了普通GPIO,SWD接口就失效了,下次下载时连不上芯片。解决办法是在初始化代码里先延时几秒再配置这两个引脚,给自己留出下载的时间窗口。或者用“Connect under Reset”模式,在复位期间连接芯片。

如果芯片被读保护锁死,需要用ST-Link Utility或者STM32CubeProgrammer执行全片擦除。全片擦除会清除读保护标志,但也会清掉所有Flash内容。操作时注意选择“Erase Chip”而不是“Erase Sectors”,后者可能无法解除读保护。

还有一种情况是芯片进入低功耗模式后无法唤醒。如果代码里调用了PWR_EnterSTOPMode或者PWR_EnterSTANDBYMode,而没有正确的唤醒源,芯片会一直休眠。解决办法是检查唤醒源配置,或者用复位引脚强制复位。

7.3 代码优化与Flash占用的平衡

F1的Flash容量有限,C8T6只有64KB,写多了就装不下。开启编译器优化能显著减小代码体积,Keil里可以选Level 1或者Level 2。但优化等级太高可能引入难以排查的问题,比如变量被优化掉、延时函数被优化没。我的建议是调试阶段用Level 0,发布阶段用Level 1,在体积和可调试性之间取平衡。

常量数据放到Flash里而不是RAM里,用const关键字修饰。字符串常量、查找表、字体数据这些不修改的数据,都应该加const。如果数据量特别大,还可以用__attribute__((section(".rodata")))指定段。

浮点运算尽量用整数代替。F1没有硬件浮点单元,浮点运算靠软件模拟,速度慢且占空间。比如计算电压值时,可以用毫伏为单位做整数运算,最后显示时再插入小数点。这样能省下不少Flash空间,运行速度也更快。

8. 从F1出发的进阶路线

F1学透之后,下一步往哪走取决于你的方向。如果做物联网终端,可以转向F4或者L4系列,前者性能更强,后者低功耗更优;如果做电机控制,可以看G4或者F3系列,它们有更丰富的高级定时器和运算放大器;如果做GUI显示,可以看F7或者H7系列,它们有更大的RAM和LCD接口。

但不管往哪走,F1上建立的基础不会浪费。GPIO的操作逻辑、中断的优先级机制、定时器的计数原理、串口的通信协议,这些在所有Cortex-M芯片上都是相通的。你换芯片时主要适应的是新的外设库和配置工具,底层的思维方式不需要推倒重来。

我自己的习惯是每学一个新外设,就在F1上写一个最小可运行示例,把配置过程、关键寄存器、常见问题都记录下来。这些笔记后来成了我排查问题的第一手资料,比翻手册快得多。F1的生态足够成熟,你遇到的每一个问题几乎都有现成的答案,关键是你要知道去哪里找、怎么验证。

最后说一个我踩过的坑:不要一上来就追求“完美架构”。我见过很多新手在点灯阶段就开始设计分层架构、写驱动框架,结果灯还没亮,人已经放弃了。正确的做法是先让功能跑起来,再逐步重构。F1的调试工具足够强大,你可以随时暂停、查看寄存器、修改变量,这种即时反馈是学习嵌入式最宝贵的东西。把每个外设都亲手调通一遍,比看十遍视频教程都管用。

相关新闻

IGBT驱动隔离电源模块互通评估:QA03与DQ1-24D1509S替代验证指南

IGBT驱动隔离电源模块互通评估:QA03与DQ1-24D1509S替代验证指南

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

2026/10/21 1:04:48 阅读更多 →
LM4040AIM3-3.0+T并联电压基准选型、电阻计算与实测避坑指南

LM4040AIM3-3.0+T并联电压基准选型、电阻计算与实测避坑指南

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

2026/10/21 1:04:48 阅读更多 →
Multisim电容充电仿真:参数设置、波形验证与报错排查全攻略

Multisim电容充电仿真:参数设置、波形验证与报错排查全攻略

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

2026/10/21 1:04:48 阅读更多 →

最新新闻

点了「应用」却没生效?dsh-purge 提示词注入机制与规则集切换实用指南

点了「应用」却没生效?dsh-purge 提示词注入机制与规则集切换实用指南

点了「应用」却没生效?dsh-purge 提示词注入机制与规则集切换实用指南 【免费下载链接】dsh-purge DeepSeek Harness 破甲:让所有模型都能破甲,不同模型可换不同提示词;默认提示词面向国模「小码酱」。Jailbreak for every model — swap pr…

2026/10/21 1:42:28 阅读更多 →
AUTOSAR CanTp深度解析:从核心机制到配置调试实战

AUTOSAR CanTp深度解析:从核心机制到配置调试实战

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

2026/10/21 1:42:28 阅读更多 →
如何用Thingino为IP摄像头刷开源固件-Ingenic摄像头固件刷写与RTSP接入教程

如何用Thingino为IP摄像头刷开源固件-Ingenic摄像头固件刷写与RTSP接入教程

如何用Thingino为IP摄像头刷开源固件-Ingenic摄像头固件刷写与RTSP接入教程 【免费下载链接】thingino-firmware Open-source firmware for Ingenic SoC IP cameras 项目地址: https://gitcode.com/GitHub_Trending/th/thingino-firmware 原厂固件功能封闭、私有协议不通…

2026/10/21 1:42:28 阅读更多 →
Linux root 密码遗忘怎么办?rd.break 救援模式重置全流程

Linux root 密码遗忘怎么办?rd.break 救援模式重置全流程

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

2026/10/21 1:42:28 阅读更多 →
用 Java 5 行代码跑通 Neptune 图查询:Gremlin 与 SPARQL 怎么选

用 Java 5 行代码跑通 Neptune 图查询:Gremlin 与 SPARQL 怎么选

用 Java 5 行代码跑通 Neptune 图查询:Gremlin 与 SPARQL 怎么选 【免费下载链接】aws-sdk-java-v2 The official AWS SDK for Java - Version 2 项目地址: https://gitcode.com/GitHub_Trending/aw/aws-sdk-java-v2 电商知识图谱里,给定一个用户…

2026/10/21 1:42:28 阅读更多 →
如何快速获取 A 股通达信行情数据?mootdx 完整指南

如何快速获取 A 股通达信行情数据?mootdx 完整指南

如何快速获取 A 股通达信行情数据?mootdx 完整指南 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx mootdx 是一个纯 Python 编写的通达信数据获取封装库:它把通达信的在线行…

2026/10/21 1:41:28 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起:用户到底在追求什么“封号重开”这四个字,放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流,背后是大量的时间和精力成本。正常情况下,没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”,而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时,就意识到:单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →