GD32F303RCT6硬件SPI配置MT6701磁编码器的保姆级教程(附SPI分频计算与避坑点)

张开发
2026/4/19 6:36:11 15 分钟阅读

分享文章

GD32F303RCT6硬件SPI配置MT6701磁编码器的保姆级教程(附SPI分频计算与避坑点)
GD32F303RCT6硬件SPI配置MT6701磁编码器的保姆级教程附SPI分频计算与避坑点磁编码器在电机控制、机器人关节定位等场景中扮演着关键角色。相比传统的光学编码器MT6701这类磁编码器具有抗污染、体积小、寿命长等优势。本文将手把手教你如何用GD32F303RCT6的硬件SPI接口与MT6701建立可靠通信重点解决分频计算、GPIO复用配置等实际问题。1. 硬件连接与引脚配置GD32F303RCT6的SPI0外设默认复用PA4-PA7引脚。MT6701作为从设备只需要接收时钟信号(SCK)和发送数据(MISO)因此硬件连接非常简单PA4(SPI0_NSS)→ MT6701片选(CS)PA5(SPI0_SCK)→ MT6701时钟输入(SCK)PA6(SPI0_MISO)→ MT6701数据输出(MISO)PA7(SPI0_MOSI)→ 悬空仅读取数据时不使用注意虽然MT6701不需要MOSI线但GD32的硬件SPI在全双工模式下要求MOSI引脚必须正确配置否则可能导致通信异常。引脚初始化代码示例// 使能GPIOA和SPI0时钟 rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_SPI0); // 配置SPI引脚 gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7); // SCK, MOSI gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6); // MISO gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4); // NSS(CS)2. SPI时钟分频计算详解GD32F303RCT6的APB2总线时钟为120MHz而MT6701要求SCK周期64ns即频率15.6MHz。分频系数计算过程如下确定传感器最大时钟频率f_max 1 / 64ns ≈ 15.625MHz计算可用分频系数GD32的SPI分频选项为2、4、8、16、32、64、128、256分频。选择满足120MHz / N ≤ 15.625MHz的最小N值120/815MHz 15.625MHz ✔️120/167.5MHz 虽然更安全但会降低通信速率实际时钟参数验证理论周期1/15MHz ≈ 66.67ns满足64ns要求且保留约4%的余量关键代码配置spi_init_struct.prescale SPI_PSC_8; // 8分频3. SPI模式与参数配置MT6701需要特定的SPI通信模式以下是关键参数解析参数配置值说明传输模式全双工虽然只读数据但硬件SPI需要全双工模式数据帧格式8位MT6701数据以8位为单位传输时钟极性/相位CPOL0, CPHA1空闲时SCK低电平第二个边沿采样NSS模式软件控制手动控制PA4引脚电平字节序MSB优先MT6701协议规定高位先传输初始化函数完整实现void SPI_Init(void) { spi_parameter_struct spi_init_struct; // 时钟与GPIO初始化(见前文) spi_init_struct.trans_mode SPI_TRANSMODE_FULLDUPLEX; spi_init_struct.device_mode SPI_MASTER; spi_init_struct.frame_size SPI_FRAMESIZE_8BIT; spi_init_struct.clock_polarity_phase SPI_CK_PL_LOW_PH_2EDGE; spi_init_struct.nss SPI_NSS_SOFT; spi_init_struct.prescale SPI_PSC_8; spi_init_struct.endian SPI_ENDIAN_MSB; spi_init(SPI0, spi_init_struct); spi_enable(SPI0); }4. 数据读取与处理实战MT6701通过SPI接口输出14位原始角度数据需要三次8位读取操作片选控制宏定义#define CS_L gpio_bit_reset(GPIOA, GPIO_PIN_4) #define CS_H gpio_bit_set(GPIOA, GPIO_PIN_4)基础读写函数uint8_t SPIx_ReadWriteByte(uint8_t txdata) { while(RESET spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)); spi_i2s_data_transmit(SPI0, txdata); while(RESET spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)); return spi_i2s_data_receive(SPI0); }原始数据读取uint32_t ReadRaw(void) { uint8_t tmp0, tmp1, tmp2; CS_L; tmp0 SPIx_ReadWriteByte(0xFF); // 虚拟写入 tmp1 SPIx_ReadWriteByte(0xFF); tmp2 SPIx_ReadWriteByte(0xFF); CS_H; return ((tmp0 16) | (tmp1 8) | tmp2) 10; // 提取14位有效数据 }角度值转换float MT6701GetAngle(void) { uint32_t raw ReadRaw(); return (raw / 16384.0f) * (2 * 3.1415926f); // 转换为弧度值 }5. 常见问题与调试技巧问题1读取数据全为0xFF或0x00检查硬件连接确保SCK、MISO、CS线连接正确验证SPI模式CPOL/CPHA必须与传感器要求一致测量SCK信号用示波器确认频率和波形是否符合预期问题2数据不稳定有跳变降低SPI时钟频率尝试如改用16分频检查电源质量磁编码器对电源噪声敏感缩短信号线长度或增加上拉电阻问题3NSS信号异常软件NSS模式下确保CS信号在传输前后有足够稳定时间硬件NSS模式需额外配置SPI_CTL1寄存器调试建议先用逻辑分析仪捕获SPI波形单独测试SPI接口发送已知模式数据逐步增加功能模块验证

更多文章