MSP430F169串口通信与1602液晶显示实战:从UART到液晶驱动
1. 项目背景与整体设计思路1.1 为什么选UART做PC与单片机的通信桥梁搞过单片机的人都知道设备之间通信的方式五花八门SPI、I2C、UART、CAN每一种都有自己的适用场景。但如果你要让单片机和电脑对话UART几乎是默认选项。原因很简单PC端天然有串口资源即便没有物理串口一根USB转串口线就能解决问题成本低、驱动成熟、调试工具遍地都是。这个项目要干的事情说起来不复杂PC发数据给MSP430F169单片机收到后解析再把内容显示到1602液晶上反过来单片机也可以主动往PC发数据。听起来像是“串口回环”的升级版但实际做起来涉及的知识点相当密集——时钟配置、波特率计算、中断处理、液晶驱动时序、字符串格式化每一个环节都有坑。我选MSP430F169来做这件事是因为它在低功耗领域是经典中的经典。16位RISC架构自带硬件UART模块USART0和USART1还有足够的GPIO去驱动1602。1602液晶虽然老但它是学习单片机外设驱动的“必修课”时序清晰、协议简单拿来练手再合适不过。这个项目适合谁如果你刚学完MSP430的GPIO操作想进一步掌握串口通信和液晶显示那这个项目就是为你准备的。如果你已经做过类似的东西也可以看看我在波特率计算、中断优先级、液晶刷新策略上的处理方式说不定能帮你省下几个小时的调试时间。1.2 系统架构拆解数据从PC到液晶的完整链路先把整个数据流理清楚后面写代码才不会乱。PC端通过串口调试助手发送一串字符比如“Hello MSP430”。这串字符以ASCII码的形式按照约定的波特率一位一位地通过TX线传到MSP430F169的RX引脚。MSP430的USART模块在接收移位寄存器里把串行数据拼成字节拼完一个字节就触发接收中断。在中断服务函数里我把收到的字节存进一个接收缓冲区同时判断是否收到结束符比如换行符如果收到就置一个标志位告诉主循环“一帧数据收完了”。主循环检测到这个标志位后把缓冲区里的内容整理一下然后调用1602的显示函数把字符串写到液晶上。1602的驱动是4位数据模式只需要6根IO线RS、RW、E、D4-D7这样能省下宝贵的IO资源。反过来如果我想让单片机主动发数据给PC比如按键按下时发送一个状态字符串那就调用UART发送函数把数据丢进TXBUF硬件自动移位发出去。整个系统的核心模块就三个UART收发、1602驱动、主循环调度。下面我会逐个拆开讲。1.3 关键器件选型与资源分配MSP430F169有两个USART模块USART0和USART1。我习惯用USART0做串口通信因为它支持更多的波特率选项而且引脚位置P3.4/TXD0、P3.5/RXD0在布局上比较顺手。1602液晶的引脚分配如下1602引脚功能连接到MSP430RS寄存器选择P4.0RW读写选择P4.1E使能信号P4.2D4-D7数据线P4.4-P4.7VSS地GNDVDD电源3.3VV0对比度电位器中点A/K背光3.3V/GND这里有个细节MSP430F169的IO口输出高电平是3.3V而1602液晶的逻辑高电平阈值通常在2.2V左右所以3.3V驱动完全没问题。但如果你用的是5V的1602模块最好在数据线上串一个电阻或者用电平转换芯片否则长期工作可能会影响液晶寿命。波特率我选9600这个速率足够用而且容错率高。MSP430F169的SMCLK我配置为1MHz这样波特率发生器的分频系数计算起来比较整。2. 核心细节解析与实操要点2.1 MSP430F169时钟系统配置别让DCO跑偏了MSP430F169的时钟系统是很多新手容易翻车的地方。它有三个时钟源LFXT1低频晶振通常接32768Hz、XT2高频晶振可选、DCO内部数字控制振荡器。上电默认情况下MCLK和SMCLK都来自DCO但DCO的频率受温度和工作电压影响比较大如果不校准波特率就会偏通信就会出乱码。我的做法是用XT2外接一个8MHz晶振然后配置PLL锁相环把MCLK倍频到8MHzSMCLK也来自XT2但分频到1MHz。这样时钟源稳定波特率精度高。具体寄存器配置如下// 关闭看门狗 WDTCTL WDTPW WDTHOLD; // 配置XT2为8MHz BCSCTL1 ~XT2OFF; // 开启XT2 do { IFG1 ~OFIFG; // 清除振荡器失效标志 for (int i 0; i 0xFF; i); // 等待稳定 } while (IFG1 OFIFG); // 检查XT2是否稳定 BCSCTL2 | SELM_2 SELS; // MCLK和SMCLK都选XT2 BCSCTL2 | DIVS_3; // SMCLK XT2 / 8 1MHz这里有个坑DIVS_3是分频系数8不是4。MSP430的分频位定义是01分频12分频24分频38分频。我第一次用的时候想当然以为3是4分频结果SMCLK变成2MHz波特率直接翻倍PC端收到的全是乱码。后来用示波器测了一下SMCLK引脚才发现问题。注意如果你没有外接XT2晶振也可以用DCO校准。MSP430F169的DCO校准值存在信息存储器里可以通过CALDCO_1MHZ和CALBC1_1MHZ来加载。但DCO的稳定性不如晶振长时间通信可能会累积误差。2.2 波特率计算一个公式解决所有疑惑MSP430的USART波特率计算公式是波特率 BRCLK / (UxBR0 UxBR1 * 256) / (1 UxMCTL的调制)其中BRCLK是USART的时钟源我选的是SMCLK1MHz。目标波特率是9600。先算分频系数1000000 / 9600 104.1667。取整数部分104对应UxBR0104UxBR10。但104分频后实际波特率是1000000 / 104 9615.38误差0.16%这个误差在可接受范围内通常要求误差小于2%。为了进一步减小误差可以用调制寄存器UxMCTL。调制原理是在连续的分频周期中插入一些额外的时钟周期让平均分频系数更接近104.1667。具体做法是小数部分0.1667乘以8得到1.33取整为1所以UxMCTL的8位中有1位需要置1。U0BR0 104; // 整数部分 U0BR1 0; U0MCTL 0x01; // 调制1/8的周期插入一个额外时钟这样实际平均波特率会更接近9600。实测下来PC端连续发送1MB数据误码率几乎为零。实操心得如果你用的是其他波特率比如115200计算方法是1000000 / 115200 8.68。整数部分8小数部分0.68。0.68 * 8 5.44取整5所以U0MCTL 0x15二进制000101015个1。但115200在1MHz时钟下误差较大建议把SMCLK提高到4MHz或8MHz再算。2.3 1602液晶4位模式驱动时序是灵魂1602液晶的4位模式核心是把一个字节分成两次发送先发高4位再发低4位。每次发送都要拉高E引脚保持一段时间再拉低让液晶模块读取数据。关键时序参数以HD44780控制器为例参数最小值典型值单位E脉冲宽度450500ns地址建立时间4050ns数据保持时间1020ns指令执行时间4050usMSP430F169的MCLK是8MHz一个时钟周期125ns。所以我在拉高E之后插入几个NOP就能满足脉冲宽度要求。写命令和写数据的区别在于RS引脚RS0写命令RS1写数据。RW引脚我直接接地因为只写不读省一根IO。初始化流程4位模式上电后等待15ms以上发送0x03等待4.1ms再发送0x03等待100us再发送0x03发送0x02切换到4位模式发送0x28设置4位、2行显示、5x7点阵发送0x0C开显示、关光标、不闪烁发送0x06设置输入模式光标右移、屏幕不移动发送0x01清屏每一步都不能少尤其是前三个0x03这是液晶模块上电复位的必要序列。我见过有人直接发0x02结果液晶毫无反应就是因为没有完成复位。void LCD_WriteCmd(unsigned char cmd) { LCD_RS 0; // 命令模式 LCD_RW 0; // 写模式 LCD_DATA_OUT (cmd 4) 0x0F; // 高4位 LCD_E 1; __delay_cycles(10); LCD_E 0; __delay_cycles(100); LCD_DATA_OUT cmd 0x0F; // 低4位 LCD_E 1; __delay_cycles(10); LCD_E 0; __delay_cycles(100); }注意__delay_cycles是MSP430的 intrinsic 函数参数是时钟周期数。在8MHz MCLK下10个周期是1.25us100个周期是12.5us。对于大多数指令来说足够了但清屏指令0x01需要1.52ms所以清屏后要额外延时。2.4 接收缓冲区设计环形队列还是线性缓冲串口接收最怕的就是数据覆盖。如果主循环处理速度跟不上接收速度新来的字节就会把旧字节冲掉。我一开始用的是简单的线性缓冲区结果PC端连续发送长字符串时液晶上只显示了最后几个字符。后来改成了环形缓冲区也叫循环队列效果立竿见影。环形缓冲区的核心是两个指针写指针在中断里更新和读指针在主循环里更新。当写指针追上读指针时说明缓冲区满了可以选择丢弃新数据或者覆盖旧数据。我定义的缓冲区大小是64字节对于一般的调试信息足够了。#define RX_BUF_SIZE 64 volatile unsigned char rx_buf[RX_BUF_SIZE]; volatile unsigned char rx_wr 0; volatile unsigned char rx_rd 0; // 中断服务函数 #pragma vector USART0RX_VECTOR __interrupt void USART0_RX_ISR(void) { unsigned char data U0RXBUF; unsigned char next (rx_wr 1) % RX_BUF_SIZE; if (next ! rx_rd) { // 缓冲区未满 rx_buf[rx_wr] data; rx_wr next; } // 如果满了丢弃这个字节 }主循环里这样读取while (rx_rd ! rx_wr) { unsigned char ch rx_buf[rx_rd]; rx_rd (rx_rd 1) % RX_BUF_SIZE; // 处理字符 }实操心得环形缓冲区的大小要根据你的最大数据帧长度来定。如果你要接收JSON格式的配置信息可能几百字节都不够。这时候要么加大缓冲区要么用“接收完一帧就立即处理”的策略减少缓冲压力。3. 实操过程与核心环节实现3.1 硬件连接与上电检查先把硬件连起来。MSP430F169开发板、1602液晶模块、USB转串口模块三者的连接关系如下USB转串口的TXD接MSP430的P3.5RXD0USB转串口的RXD接MSP430的P3.4TXD0USB转串口的GND接MSP430的GND1602的RS、RW、E、D4-D7按前面表格连接1602的V0接10K电位器的中间引脚电位器两端接3.3V和GND1602的背光A接3.3V串一个100Ω电阻限流K接GND上电后先别急着写代码。用万用表测一下1602的VDD和V0电压VDD应该是3.3VV0应该在0.5V到1.5V之间。如果V0太高液晶会显示一片黑块太低则什么都看不见。调节电位器直到能看到第一行显示一排方块这是液晶上电的默认状态。然后测USB转串口模块的TX线空闲时应该是高电平3.3V或5V取决于模块。如果TX线一直是低电平说明模块坏了或者驱动没装好。3.2 串口初始化代码逐行解析串口初始化的核心是配置USART0的控制寄存器。我习惯把初始化函数写成这样void UART0_Init(void) { // 1. 配置引脚 P3SEL | BIT4 BIT5; // P3.4和P3.5设为外设功能 P3DIR | BIT4; // TXD0输出 P3DIR ~BIT5; // RXD0输入 // 2. 复位USART U0CTL | SWRST; // 软件复位 // 3. 配置为UART模式 U0CTL | CHAR; // 8位数据 U0TCTL | SSEL1; // 时钟源选SMCLK // 4. 波特率设置 U0BR0 104; U0BR1 0; U0MCTL 0x01; // 5. 使能接收和发送 ME1 | URXE0 UTXE0; // 使能USART0收发 // 6. 使能接收中断 IE1 | URXIE0; // 7. 释放复位 U0CTL ~SWRST; // 8. 全局中断使能 _EINT(); }逐行解释一下P3SEL | BIT4 BIT5把P3.4和P3.5从普通IO切换为USART功能。这一步不做串口死活不通。U0CTL | SWRST置位SWRST会让USART进入复位状态所有配置寄存器可以安全写入。配置完再清除。U0CTL | CHARCHAR位决定数据长度置1是8位清0是7位。我们传ASCII字符8位最方便。U0TCTL | SSEL1选择SMCLK作为波特率时钟源。SSEL11且SSEL00时选SMCLK。ME1 | URXE0 UTXE0ME1是模块使能寄存器1URXE0使能接收UTXE0使能发送。IE1 | URXIE0使能接收中断。发送中断我暂时不开因为发送用查询方式就够了。注意_EINT()是开全局中断必须放在最后。如果先开全局中断再配置USART可能会在配置过程中触发中断导致不可预期的行为。3.3 发送字符串到PC的两种方式发送数据有两种方式查询和中断。查询方式简单但会阻塞CPU中断方式效率高但代码复杂。对于这个项目发送的数据量不大我直接用查询方式void UART0_SendChar(unsigned char ch) { while (!(IFG1 UTXIFG0)); // 等待发送缓冲区空 U0TXBUF ch; } void UART0_SendString(char *str) { while (*str) { UART0_SendChar(*str); } }IFG1 UTXIFG0是发送中断标志位当TXBUF为空时置1。查询这个标志位就能知道什么时候可以写下一个字节。如果数据量很大比如要发送1KB的日志查询方式会让CPU一直空转。这时候可以用中断方式把数据放进发送缓冲区使能UTXIE0在发送中断里逐个字节发出。volatile unsigned char tx_buf[TX_BUF_SIZE]; volatile unsigned char tx_wr 0; volatile unsigned char tx_rd 0; void UART0_SendString_IT(char *str) { while (*str) { unsigned char next (tx_wr 1) % TX_BUF_SIZE; if (next ! tx_rd) { tx_buf[tx_wr] *str; tx_wr next; } } IE1 | UTXIE0; // 使能发送中断 } #pragma vector USART0TX_VECTOR __interrupt void USART0_TX_ISR(void) { if (tx_rd ! tx_wr) { U0TXBUF tx_buf[tx_rd]; tx_rd (tx_rd 1) % TX_BUF_SIZE; } else { IE1 ~UTXIE0; // 发送完毕关闭中断 } }实操心得发送中断里不要做耗时操作否则会影响下一个字节的发送时机。我见过有人在发送中断里调用液晶刷新函数结果串口数据断断续续就是因为中断服务函数执行时间太长。3.4 液晶显示字符串的完整流程液晶显示字符串的流程是设置光标位置 - 写入字符 - 光标自动右移 - 继续写下一个字符。void LCD_ShowString(unsigned char x, unsigned char y, char *str) { // 设置光标位置 unsigned char addr; if (y 0) { addr 0x80 x; // 第一行 } else { addr 0xC0 x; // 第二行 } LCD_WriteCmd(addr); // 逐个写入字符 while (*str) { LCD_WriteData(*str); } }1602液晶的内部RAM地址第一行是0x00-0x0F对应命令0x80-0x8F第二行是0x40-0x4F对应命令0xC0-0xCF。所以设置光标位置时第一行用0x80x第二行用0xC0x。写数据函数和写命令函数类似只是RS1void LCD_WriteData(unsigned char data) { LCD_RS 1; // 数据模式 LCD_RW 0; LCD_DATA_OUT (data 4) 0x0F; LCD_E 1; __delay_cycles(10); LCD_E 0; __delay_cycles(100); LCD_DATA_OUT data 0x0F; LCD_E 1; __delay_cycles(10); LCD_E 0; __delay_cycles(100); }注意每次写数据后液晶需要约40us的执行时间。我的延时是100个周期在8MHz下是12.5us加上函数调用的开销差不多够用。但如果你的MCLK频率更高比如16MHz100个周期只有6.25us可能不够需要加大延时。3.5 主循环调度与数据帧解析主循环的任务很简单检查环形缓冲区是否有新数据如果有就取出来拼成字符串刷新到液晶上。int main(void) { WDTCTL WDTPW WDTHOLD; Clock_Init(); UART0_Init(); LCD_Init(); LCD_ShowString(0, 0, MSP430 Ready); char display_buf[17]; // 1602一行最多16字符留一个结束符 unsigned char idx 0; while (1) { if (rx_rd ! rx_wr) { unsigned char ch rx_buf[rx_rd]; rx_rd (rx_rd 1) % RX_BUF_SIZE; if (ch \n || ch \r) { // 收到换行符一帧结束 display_buf[idx] \0; LCD_ShowString(0, 1, display_buf); idx 0; } else if (idx 16) { display_buf[idx] ch; } } } }这段代码的逻辑是收到换行符就认为一帧结束把缓冲区里的内容显示到液晶第二行。如果一帧超过16个字符只显示前16个。实操心得实际调试时PC端的串口调试助手要勾选“发送新行”或者手动加换行符否则单片机永远等不到帧结束标志。我一开始忘了加换行符发了半天数据液晶都没反应后来用示波器看RX线才发现数据一直在传只是没有结束标志。4. 常见问题与排查技巧实录4.1 串口通信乱码问题排查表乱码是串口调试中最常见的问题原因通常有以下几个现象可能原因排查方法解决方案全部乱码波特率不匹配检查PC端和单片机的波特率设置统一为9600或115200部分乱码时钟源不稳定用示波器测SMCLK频率改用XT2晶振校准DCO偶尔乱码中断被长时间关闭检查是否有其他中断服务函数耗时过长优化中断代码缩短执行时间首字节乱码上电时序问题检查上电后是否有延时上电后延时100ms再初始化串口数据丢失缓冲区溢出检查环形缓冲区大小加大缓冲区或提高处理速度我遇到过一次特别诡异的情况PC端发送“12345”液晶上显示“1#345”。排查了半天发现是接收中断里做了浮点运算导致中断执行时间过长第二个字节被覆盖了。后来把浮点运算移到主循环里问题就解决了。注意MSP430F169没有硬件浮点单元浮点运算都是软件模拟的非常耗时。中断服务函数里绝对不要做浮点运算、字符串格式化、液晶刷新这些耗时操作。4.2 液晶显示异常的几种典型情况液晶不显示、显示不全、显示乱码原因也很多情况一上电后液晶一片黑块这是对比度调节不当。V0电压太高液晶所有像素都打开了。调节电位器让V0降到1V左右黑块会逐渐消失显示出清晰的字符。情况二液晶有背光但无字符可能是初始化序列没发对。用逻辑分析仪抓一下E、RS、D4-D7的波形看看有没有正确的初始化序列。如果没有逻辑分析仪可以用LED接在E引脚上看初始化时LED是否闪烁。情况三字符显示位置不对检查地址设置命令。第一行地址是0x80x第二行是0xC0x。如果x超过15地址会回绕到第二行或者不可显示区域。情况四显示内容闪烁可能是刷新太频繁。每次收到一个字节就刷新整个屏幕会导致闪烁。我的做法是收到完整一帧再刷新这样屏幕稳定得多。4.3 中断优先级与嵌套的坑MSP430F169的中断优先级是固定的由硬件决定。USART0的接收中断优先级比定时器中断低。如果定时器中断频繁触发串口接收中断可能会被延迟响应导致数据丢失。我试过在定时器中断里做1ms的延时结果串口接收大量数据时丢包严重。后来把定时器中断的周期从1ms改成10ms并且把中断服务函数精简到只置一个标志位问题就缓解了。实操心得如果项目中同时用了多个中断一定要评估每个中断的执行时间和触发频率。串口接收中断的响应时间最好控制在10us以内否则高速通信时容易丢数据。4.4 电源噪声对通信的影响MSP430F169是低功耗芯片对电源噪声比较敏感。如果USB转串口模块和单片机共用同一个USB口供电PC端的开关电源噪声可能会串到串口线上导致误码。我的解决方案是在单片机的VCC和GND之间并一个10uF的钽电容和一个0.1uF的陶瓷电容滤除高频和低频噪声。串口线上串一个100Ω的电阻也能起到一定的限流和滤波作用。实测下来加了这两个电容之后连续发送10MB数据误码率从原来的0.1%降到了几乎为零。4.5 常见问题速查表问题快速排查步骤工具串口无数据1.测TX线电平 2.检查波特率 3.检查引脚配置万用表、示波器液晶无显示1.调对比度 2.测VDD电压 3.检查初始化序列万用表、逻辑分析仪数据丢包1.加大缓冲区 2.优化中断 3.降低波特率串口调试助手显示乱码1.检查字符编码 2.检查地址设置 3.检查刷新逻辑逻辑分析仪系统死机1.检查看门狗 2.检查堆栈溢出 3.检查中断嵌套JTAG调试器5. 项目扩展与个人经验分享5.1 从单机通信到多机组网这个项目做通之后可以很自然地扩展到多机通信。比如用RS485总线把多个MSP430节点挂在一起每个节点有唯一的地址。PC端发送“01:LED ON”地址为01的节点收到后执行开灯操作其他节点忽略。RS485和UART的区别主要在物理层RS485是差分信号抗干扰能力强传输距离可达1200米。MSP430F169的UART引脚接一个MAX485芯片就能实现RS485通信。软件上只需要增加一个方向控制引脚DE/RE发送时拉高接收时拉低。5.2 用DMA减轻CPU负担MSP430F169没有DMA控制器但如果你用的是更高端的MSP430系列比如MSP430F5xx可以用DMA来搬运串口数据。DMA的好处是数据从UART接收寄存器搬到内存不需要CPU干预CPU可以去做其他事情。没有DMA的情况下我的优化策略是把接收中断的优先级设到最高中断服务函数只做“把数据存进缓冲区”这一件事其他所有处理都放到主循环里。5.3 液晶显示优化局部刷新与自定义字符1602液晶的刷新速度不快如果每次收到数据都全屏刷新屏幕会闪。我的做法是只在数据变化时刷新对应的位置。比如第一行显示“Temp: 25C”温度从25变成26只需要刷新“6”这一个字符不需要重写整行。1602还支持8个自定义字符CGRAM每个字符是5x8点阵。你可以用取模软件生成自定义字符的点阵数据写入CGRAM然后在显示时调用对应的字符编码0x00-0x07。比如显示一个温度计图标、一个电池图标比纯文字直观得多。5.4 我踩过的三个坑第一个坑忘了配置P3SEL。P3.4和P3.5默认是普通IO不配置成外设功能串口根本不通。我一开始以为只要配置USART寄存器就行结果折腾了两个小时才发现是引脚功能没切换。第二个坑波特率计算错误。我把SMCLK配置成1MHz但实际DCO跑到了1.2MHz导致波特率偏差20%PC端收到的全是乱码。后来用示波器测了SMCLK引脚才发现DCO没有校准。第三个坑液晶初始化延时不够。1602上电后需要至少15ms的稳定时间我一开始只延时了1ms结果液晶偶尔能显示偶尔不显示。后来把延时加到50ms问题彻底解决。5.5 后续可以继续折腾的方向这个项目做完你已经掌握了MSP430的UART和液晶驱动。接下来可以尝试用UART接收PC端的命令控制PWM输出调节LED亮度把液晶显示改成OLED体验I2C通信用UART和蓝牙模块通信实现手机遥控把接收到的数据存到EEPROM实现掉电保存每个方向都能让你对MSP430的理解更深一层。我个人的体会是单片机学习没有捷径就是一个个外设啃下来每啃一个你的技能树就亮一块。UART和液晶是基础中的基础把这两个搞透了后面学SPI、I2C、ADC都会轻松很多。

相关新闻

Linux内核MMC/SDIO驱动三层架构解析:从SD卡到设备适配

Linux内核MMC/SDIO驱动三层架构解析:从SD卡到设备适配

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

2026/10/17 1:30:23 阅读更多 →
Qt桌面工具集成语音识别:百度语音识别API REST接口调用实战

Qt桌面工具集成语音识别:百度语音识别API REST接口调用实战

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

2026/10/18 3:55:18 阅读更多 →
FFT里常被误读的“基”:基2 DIT算法原理与蝶形运算全解析

FFT里常被误读的“基”:基2 DIT算法原理与蝶形运算全解析

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

2026/10/17 1:29:23 阅读更多 →

最新新闻

C# .NetCore Swagger ISchemaFilter Long 转 String 防精度丢失

C# .NetCore Swagger ISchemaFilter Long 转 String 防精度丢失

目录 解决方案 方法1:使用 SchemaFilter ‌1、创建自定义 SchemaFilter‌ ‌2、在 Swagger 配置中使用该 Filter‌ 方法2:使用 OperationFilter 或 DocumentFilter 1、‌创建自定义 OperationFilter 2、在 Swagger 配置中使用该 Filter 总结 如果…

2026/10/18 3:55:22 阅读更多 →
GLM-Turbo(龙虾模型)API接入指南:Python调用、参数调优与实战

GLM-Turbo(龙虾模型)API接入指南:Python调用、参数调优与实战

最近AI圈里有个很热的称呼叫“龙虾模型”,对应的其实就是GLM-Turbo这个系列。很多人一听到这名字就懵,甚至以为是哪个海鲜行业的图像识别模型,但实际它是一个大语言模型,主打的是中文对话、写作、代码生成和知识问答。我这阵子正好…

2026/10/18 3:55:22 阅读更多 →
iOS WebRTC示例解析:从信令到渲染跑通音视频通话链路

iOS WebRTC示例解析:从信令到渲染跑通音视频通话链路

简介:面向iOS开发者的WebRTC集成示例工程,基于Objective-C实现同类应用间的实时音视频通话,适合希望掌握WebRTC核心流程与原生设备适配的移动端工程师入门参考。压缩包共24个文件,包含7个m源码、5个h头文件、3个plist配置&#xf…

2026/10/18 3:55:22 阅读更多 →
Play Integrity Fix 实战教程:如何让你的 Android 设备重新通过完整性检测

Play Integrity Fix 实战教程:如何让你的 Android 设备重新通过完整性检测

Play Integrity Fix 实战教程:如何让你的 Android 设备重新通过完整性检测 【免费下载链接】PlayIntegrityFix Fix Play Integrity (and SafetyNet) verdicts. 项目地址: https://gitcode.com/GitHub_Trending/pl/PlayIntegrityFix 银行 App 一打开就闪退&am…

2026/10/18 3:55:22 阅读更多 →
Spring AI集成大模型:Java开发者最佳实践指南

Spring AI集成大模型:Java开发者最佳实践指南

Spring AI:Java开发者的人工智能集成利器先说一个这两年技术圈里特别明显的变化:以前说到AI开发,大家默认是Python的天下,Java程序员只能站在旁边看热闹,顶多通过HTTP接口调一下别人封装好的服务。但从2024年开始&…

2026/10/18 3:55:22 阅读更多 →
SpringBoot3断代升级实战:从零搭建到部署的完整指南

SpringBoot3断代升级实战:从零搭建到部署的完整指南

前两周帮某电商团队做技术迁移评审,对方项目经理一上来就问:能不能在 SpringBoot2.7 基础上直接改版本号升到 3?我当时就告诉他:这可不是改一行版本号的事。编译直接红一片,javax消失,Tomcat行为变了&#…

2026/10/18 3:54:22 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →