如何在Arduino中通过SPI读取MAX35101的16位寄存器?
MAX35101 TDC芯片0xB8寄存器读取返回0xFF问题排查
问题描述
读取MAX35101的0xB8寄存器(默认值应为0x1311)时,返回值始终为0xFF,读写操作返回布尔值1,需排查代码逻辑问题。
完整代码
#define SS 10 // D14 = MCP23S08 GPIO SPI select pin #define SCLK 13 // D18 SPI SCLK #define MISO 12 // D19 SPI MISO #define MOSI 11 // D23 SPI MOSI #define RESET 0X04 // #include <SPI.h> bool MAX35101_Send_Opcode(char opcode); bool MAX35101_Write_Register(char address, uint16_t DatatoWrite); void MAX35101_Read_Register(char address, uint16_t* results); void setup() { Serial.begin(115200); SPI.begin(); pinMode(SS, OUTPUT); digitalWrite(SS, HIGH); } bool MAX35101_Send_Opcode(char Opcode) { bool success; SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); digitalWrite(SS, LOW); success = SPI.transfer(Opcode); Serial.println(success); digitalWrite(SS, HIGH); SPI.endTransaction(); } bool MAX35101_Write_Register(char address, uint16_t DatatoWrite)// one word register only, Modulates CS# line, Sends address, reads data { bool success; SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); digitalWrite(SS, LOW); //Modulate CS# success |= SPI.transfer(address); //Transmit the 8 bits over the SPI Bus //OPcode address success |= SPI.transfer((char) (DatatoWrite >> 8)); //Transmit the 8 bits over the SPI Bus // MSB success |= SPI.transfer((char) (DatatoWrite & 0x00FF)); //Transmit the 8 bits over the / Bus //LSB digitalWrite(SS, HIGH); SPI.endTransaction(); //Modulate CS# //Serial.println('The write status is ' + success + '.'); Serial.println(success); } void MAX35101_Read_Register(char address, uint16_t* results)//Read one word register only, Modulates CS# line, Sends address, reads data { uint16_t success; uint16_t success_data; address |= 0x80; //Read Opcodes Always have MSB of Opcode (address) Set SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); digitalWrite(SS, LOW); delayMicroseconds(1); success = SPI.transfer(address); //Transmit the 8 bits over the SPI Bus success |= SPI.transfer(results); digitalWrite(SS, HIGH); SPI.endTransaction(); Serial.println(success); //Serial.println(results); } unsigned long readRegister(uint8_t registerAddress) //Function for READING a selected register { int registerValueR; registerAddress |= 0x80; SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); digitalWrite(SS, LOW); delayMicroseconds(1); SPI.transfer(registerAddress); SPI.transfer(0x00); delayMicroseconds(1); registerValueR = SPI.transfer(0xFF); delayMicroseconds(1); digitalWrite(SS, HIGH); SPI.endTransaction(); Serial.println(registerValueR); } void loop() { //uint16_t readData = 0; delay(5000); //MAX35101_Write_Register(0x38, 1311); readRegister(0xB8); delay(60*60*1000); }
已尝试方案
- 单独读取1字节
- 通过或运算合并两个变量读取2字节
- 观察到串口打印的是读取寄存器时发送的虚拟字节值
代码问题分析与修复
核心问题(readRegister函数)
当前调用的readRegister函数存在严重时序错误,无法正确读取16位寄存器:
- 读取位数不足:0xB8是16位寄存器,函数仅读取了1字节。
- SPI时序错误:SPI为全双工通信,读寄存器需在发送地址后,连续发送两个dummy字节以接收寄存器的MSB和LSB;当前代码的字节发送/接收顺序完全不符合MAX35101的SPI协议。
- 返回类型冗余:寄存器为16位,无需使用
unsigned long类型。
修复后的readRegister函数
unsigned int readRegister(uint8_t registerAddress) { uint16_t registerValue = 0; registerAddress |= 0x80; // 设置读操作标志位(最高位为1) SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); digitalWrite(SS, LOW); delayMicroseconds(1); // 发送寄存器地址,忽略返回的dummy数据 SPI.transfer(registerAddress); // 接收MSB并左移8位 registerValue = (uint16_t)SPI.transfer(0x00) << 8; // 接收LSB并合并到结果 registerValue |= SPI.transfer(0x00); delayMicroseconds(1); digitalWrite(SS, HIGH); SPI.endTransaction(); Serial.print("寄存器0x"); Serial.print(registerAddress & 0x7F, HEX); Serial.print("读取值:0x"); Serial.println(registerValue, HEX); return registerValue; }
其他函数问题修复
- MAX35101_Send_Opcode:MAX35101无需单独发送Opcode,读写操作通过地址+数据完成,该函数无意义,可删除。
- MAX35101_Write_Register:错误地将SPI传输返回的字节作为成功标志,实际MAX35101写操作无应答字节,应修正为:
void MAX35101_Write_Register(char address, uint16_t DatatoWrite) { address &= 0x7F; // 写操作地址最高位为0 SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); digitalWrite(SS, LOW); SPI.transfer(address); // 发送寄存器地址 SPI.transfer((char)(DatatoWrite >> 8)); // 发送MSB SPI.transfer((char)(DatatoWrite & 0x00FF)); // 发送LSB digitalWrite(SS, HIGH); SPI.endTransaction(); }
- MAX35101_Read_Register:错误地传递指针给
SPI.transfer,应修正为:
void MAX35101_Read_Register(char address, uint16_t* results) { address |= 0x80; // 设置读操作标志位 SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1)); digitalWrite(SS, LOW); delayMicroseconds(1); SPI.transfer(address); // 发送地址 *results = (uint16_t)SPI.transfer(0x00) << 8; // 读取MSB *results |= SPI.transfer(0x00); // 读取LSB digitalWrite(SS, HIGH); SPI.endTransaction(); Serial.print("寄存器0x"); Serial.print(address & 0x7F, HEX); Serial.print("读取值:0x"); Serial.println(*results, HEX); }
额外硬件检查建议
- 确认SS引脚正确连接到MAX35101的CS#引脚
- 检查SPI总线(SCLK、MOSI、MISO)的接线对应关系
- 初始化RESET引脚:拉低至少10μs再拉高,完成芯片复位
void setup() { Serial.begin(115200); SPI.begin(); pinMode(SS, OUTPUT); digitalWrite(SS, HIGH); // 复位芯片 pinMode(RESET, OUTPUT); digitalWrite(RESET, LOW); delayMicroseconds(10); digitalWrite(RESET, HIGH); delay(100); }
内容的提问来源于stack exchange,提问作者Veeramani
相关产品推荐
相关产品推荐

