STM32软硬件SPI驱动MAX31865实现PT100高精度测温与Shell交互
1. PT100测温与MAX31865模块基础PT100铂电阻作为工业测温的常青树其原理就像体温计里的水银柱——温度变化时电阻值会线性改变。但要把这微小的电阻变化0.385Ω/℃转换成精确温度读数MAX31865就像个专业翻译官把电阻信号翻译成数字信号。实测下来这个芯片在-200℃~850℃范围内能实现±0.5℃的精度比普通DS18B20强不少。硬件连接其实比想象中简单模块的典型接线就像搭积木VIN接3.3V注意别超3.6VGND接地SCK/CS/MOSI/MISO对应STM32的SPI引脚RTD和RTD-接PT100的两根线注意2/3/4线制区别我推荐直接用现成模块自己画PCB容易在参考电阻精度和走线抗干扰上踩坑。有个细节要注意模块上的RREF参考电阻通常430Ω决定了量程换成400Ω能提升低温段分辨率。2. 软件模拟SPI的实战实现当硬件SPI被占用或需要快速验证时软件模拟SPI就像瑞士军刀——灵活但效率低。我用STM32F103实测模拟SPI的时钟最快只能到500kHz左右而硬件SPI轻松上8MHz。初始化GPIO是关键第一步void MAX31865_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 配置CS/SCK/SDI为推挽输出 GPIO_InitStructure.GPIO_Pin GPIO_Pin_12 | GPIO_Pin_9 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_Init(GPIOC, GPIO_InitStructure); // 配置SDO/DRDY为上拉输入 GPIO_InitStructure.GPIO_Pin GPIO_Pin_10 | GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; GPIO_Init(GPIOC, GPIO_InitStructure); MAX31865_CS_SET; // 初始置高CS }读写时序要注意的坑写操作时先发地址字节最高位置1再发数据字节读操作时先发地址字节最高位清0再读数据每个字节传输都要从高位开始MSB first时钟上升沿采样数据温度换算有个技巧直接套用Callendar-Van Dusen公式计算正温度负温度段用多项式拟合更高效float MAX31865_GetTemp(void) { uint16_t data (MAX31865_Read(0x01) 8) | MAX31865_Read(0x02); data 1; // 丢弃错误标志位 float Rt (float)data / 32768.0 * RREF; // 正温度计算 float temp (-3.9083e-3 sqrt(9.304e-6 1.6e-5 * (Rt/100 - 1))) / (2 * -5.775e-7); if(temp 0) return temp; // 负温度拟合 return -242.02 2.2228*Rt 2.5859e-3*Rt*Rt - 4.8260e-6*Rt*Rt*Rt; }3. 硬件SPI的高效驱动硬件SPI就像开了高速公路配置时这几个参数最容易出错SPI_InitTypeDef SPI_InitStructure; SPI_InitStructure.SPI_Direction SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode SPI_Mode_Master; SPI_InitStructure.SPI_DataSize SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL SPI_CPOL_High; // MAX31865要求CPOL1 SPI_InitStructure.SPI_CPHA SPI_CPHA_2Edge; // 第2边沿采样 SPI_InitStructure.SPI_NSS SPI_NSS_Soft; // 软件控制CS SPI_InitStructure.SPI_BaudRatePrescaler SPI_BaudRatePrescaler_8; // 9MHz72MHz SPI_Init(SPI1, SPI_InitStructure);硬件SPI的读写函数要处理超时避免死等uint8_t SPI_WriteByte(uint8_t data) { uint32_t timeout 100000; while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) timeout--); SPI_I2S_SendData(SPI1, data); timeout 100000; while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) timeout--); return SPI_I2S_ReceiveData(SPI1); }实测对比数据指标软件SPI硬件SPI最大时钟频率500kHz8MHzCPU占用率85%5%代码体积1.2KB0.8KB抗干扰能力较弱强4. Shell交互的实用技巧给测温系统加上Shell就像装了个控制台调试时不用反复烧录。我用串口实现基础命令temp立即读取当前温度config [bias] [filter]配置偏置电压和滤波器fault读取故障状态实现框架建议用状态机解析void Shell_Process(void) { if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)) { char ch USART_ReceiveData(USART1); if(ch \r) { if(strcmp(cmd_buf, temp) 0) { float temp MAX31865_GetTemp(); printf(Current temp: %.2fC\r\n, temp); } memset(cmd_buf, 0, sizeof(cmd_buf)); cmd_idx 0; } else { cmd_buf[cmd_idx] ch; } } }提升Shell体验的三个技巧添加Tab键命令补全实现命令历史记录上下键调取加入ANSI转义序列实现彩色输出我在实际项目中发现用硬件SPIShell组合后调试效率提升至少3倍。特别是批量测试时直接通过串口命令自动化采集数据不用再连接调试器。