Microchip PIC24FJ SPI写入正常但读取始终为0的问题求助
PIC24FJ256GA702与AD5724RBREZ SPI通信:写入正常但读取控制寄存器始终返回0
问题现象
- PIC24FJ256GA702通过SPI与AD5724RBREZ四通道DAC通信,写入功能正常,但读取控制寄存器时始终返回0。
- 示波器显示PIC引脚波形符合预期(时钟为蓝色,DAC输出到PIC的数据为黄色),波形非全0,与4通道及内部基准使能的状态匹配(波形振铃疑似长接地导致,实际芯片间距约25mm)。
- 已排除输入引脚为模拟引脚的可能:已正确配置为数字输入;将该引脚连接到Timer1计数器,读取DAC时计数器能正常计数,说明PPS配置有效、引脚无损坏、输入信号清晰。
- 推测问题出在代码或SPI模块解码时序,但时钟周期内数据稳定,无法定位。
- 查阅论坛资料,多数同类问题源于模拟功能启用,但本次并非此情况。
相关代码
初始化函数
void AOUT_init(void) { //assume PPS is unlocked (it is on reset) - see note below //setup SPI1 itself SPI1CON1L = 0x0160; //TX work read 0 //SPI1CON1L = 0x0060; //TX not work //SPI1CON1L = 0x0120; //TX work, read 0 //SPI1CON1L = 0x0020; //not tried SPI1CON1H = 0x3000; SPI1CON2L = 0x0017; //word length (17 hex = 24 bits) //BRG SPI1BRGL = 0x0000; //default = no divisor //PPS - assume unlocked at this point ANSBbits.ANSB13 = 0; TRISBbits.TRISB13 = TRIS_INPUT; //########################################################################## RPINR20bits.SDI1R = 13; //set SDI1 data input to PIC to RB13 //########################################################################## TRISBbits.TRISB15 = TRIS_OUTPUT; RPOR7bits.RP15R = 8; //RB15 to SDI1 clock out from PIC TRISBbits.TRISB14 = TRIS_OUTPUT; RPOR7bits.RP14R = 7; //RB14 to SDI1 data out from PIC //AD5724R has additional lines - not all used in practice //setup and set initial level here //AOUT-/LDAC TRISBbits.TRISB6 = TRIS_OUTPUT; LATBbits.LATB6 = 1; //AOUT-/SYNC TRISBbits.TRISB7 = TRIS_OUTPUT; LATBbits.LATB7 = 1; //AOUT-/CLR TRISBbits.TRISB12 = TRIS_OUTPUT; LATBbits.LATB12 = 1; //turn SPI on SPI1CON1Lbits.SPIEN = 1; SPI1CON1Lbits.MSTEN = 1; //included in definition above //now setup the AD chip //output range set AOUT_TX(0x0C00,0x0100); //all channels to 10V //control AOUT_TX(0x1900,0x0500); //power control - enable DACs AOUT_TX(0x1000,0x1F00); }
通信控制函数
static void AOUT_Comms(bool bSync, bool bLDAC, bool bClr) { //AOUT-/LDAC LATBbits.LATB6 = bLDAC; //AOUT-/SYNC LATBbits.LATB7 = bSync; //AOUT-/CLR LATBbits.LATB12 = bClr; }
写入函数(功能正常)
void AOUT_TX(uint16_t dataH, uint16_t dataL) { //AOUT uses 24 bit data //this routine handles /SYNC line //relies on AD chip having much faster response than chip cycle time //AD chip limits at about 38MHz so much quicker than PIC. AOUT_Comms(0,1,1); SPI1BUFL = dataL; SPI1BUFH = dataH; while(SPI1STATLbits.SPIBUSY) //wait until sent { ; } AOUT_Comms(1,1,1); // }
读取函数
void AOUT_read_control(uint16_t ReadH, uint16_t ReadL) { uint16_t temp; //to read, transmit the register to be read, then transmit a dummy command "NOP" to clock the data out. //send register AOUT_TX(0x9000,0x0000); //read out- this is similar to write but reads the received buffer at the end. //clear buffer while (SPI1STATLbits.SPIRBF) { temp = SPI1BUFL; temp = SPI1BUFH; } AOUT_Comms(0,1,1); SPI1BUFL = 0; SPI1BUFH = 0x1800; //nop operation via control register while(SPI1STATLbits.SPIBUSY) //wait until sent { ; } while (!SPI1STATLbits.SPIRBF) { ; //hold until something received } ReadH = SPI1BUFH; ReadL = SPI1BUFL; //these read zero AOUT_Comms(1,1,1); // //dummy so can check counter also connected to same pin temp = TMR1; temp = TMR1; }
更新信息
- 将接收数据直接输出到显示器,结果均为0000;
- 用逻辑分析仪检测PIC引脚,读写解码均正确(通道1/MOSI写入0x180000,通道2/MISO读取0x00001F)。
请求帮助
- 提供排查方向;
- 分享可用的SPI读取代码以验证现有代码是否存在问题。
内容的提问来源于stack exchange,提问作者REPuzzle
相关产品推荐
相关产品推荐

