This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] ADS1298:通过SPI与设备通信时出现问题

Guru**** 2487425 points
Other Parts Discussed in Thread: ADS1298

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/631106/ads1298-issues-communicating-with-the-device-via-spi

部件号:ADS1298
线程中讨论的其他部件:TMS320F2.8377万S

您好,

我正在尝试使用TMS320F2.8377万S与ADS1298建立联系。 我正在使用200MHz的SYSCLK和200kbps的SPI波特率。

我可以通过检查ID建立一次通信

不过,我现在得到的结果却是完全不同的。

我不知道为什么它不再起作用。

这是我的通电顺序

GPIO_setDirectionMode (ADC_CLKSEL,GPIO_DIR_MODE_OUT);
 GPIO设置方向模式(ADC_RESET,GPIO DIR_MODE_OUT);
 GPIO_setDirectionMode (ADC_PDWN,GPIO_DIR_MODE_OUT);
 GPIO_setDirectionMode (ADC_DRDY,GPIO_DIR_MODE_In);
 GPIO_setDirectionMode (ADC_START,GPIO_DIR_MODE_OUT);
 GPIO_setPinConfig (GPIO _87_GPIO87);
 GPIO _setPinConfig (GPIO_69_GPIO69);
 GPIO_setPinConfig (GPIO _66_GPIO66);
 GPIO_setPinConfig (GPIO _86_GPIO86);
 GPIO_setPinConfig (GPIO _65_GPIO65);

 GPIO写入引脚(ADC_START,0);
 GPIO_writePin (ADC_PDWN,0);
 GPIO写入引脚(ADC_RESET,0);
 DELAY毫秒(140);

 GPIO写入引脚(ADC_CLKSEL,1);
 DELAY _Us (10);
 GPIO写入引脚(ADC_PDWN,1);
 GPIO写入引脚(ADC_RESET,1);
 DELAY毫秒(140);
 GPIO写入引脚(ADC_RESET,0);
 DELAY _Us (10);
 GPIO写入引脚(ADC_RESET,1);
 // SENDSDATAC命令

这是我的上述数字代码

   而(1){
 GPIO写入引脚(61,1);
 delay_ms(10);
 GPIO写入引脚(61,0);
   DELAY _Us (100);
   SPI_writeDataNonBlocking(SPIA_base,((SDATAC)<<8));
   UINT16_t dummy = SPI_readDataBlockingNonFIFO (SPIA_BASE);
   DELAY _Us (5);
   SPI_writeDataNonBlocking (SPIA_BASE,((0x20)<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 DELAY _Us (5);
 SPI_writeDataNonBlocking(SPIA_base,((0x00)<<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 DELAY _Us (5);
 SPI_writeDataNonBlocking(SPIA_base,((0x00)<<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 DELAY _Us (100);
   };

*****************

如有必要,我可以提供电路图副本。 如果您有任何建议,请告诉我。 我当前的目标是通过检查ID与ADC建立联系,以便根据需要对ADC进行编程。

*****************

下面提供了我的整个代码的副本

//**********************************************
//包含的文件
//**********************************************
#include "driverlib.h"
包含"device.h"

//**********************************************
//定义
//**********************************************
// UC引脚到ADC引脚
#define ADC_CLKSEL 87
#define ADC_RESET 69
#define ADC_PDWN 66
#define ADC_DRDY 86
#define ADC_START 65
// ADC寄存器地址
#define ID   0x00
#define config1  0x01
#define CONFIIG2  0x02
#define CONFIG3  0x03
#Define LoFF  0x04
#define CH1SET  0x05
#define CH2SET  0x06
#define CH3SET  0x07
#define CH4SET  0x08
#define CH5SET  0x09
#define CH6SET  0x0A
#define CH7SET  0x0B
#define CH8SET  0x0C
#define RLDSENSP 0x0D
#define RLDSENSN 0x0E
#define LOFFSENSP 0x0F
#define LOFFSENSN 0x10
#define LOFFFLIP 0X11
#define LOFFSTATP 0x12
#define LOFFSTATN 0x13
#定义GPIO  0x14
#定义PACE  0x15
#define resp  0x16
#define CONFIIG4  0x17
#define WCT1  0X18
#define WCT2  0x19
//ADC SPI命令
#define wakeup  0x02
#定义待机  0x04
#define reset  0x06
#define start  0x08
#define stop  0x0A
#define RDATAC  0x10
#define SDATAC  0x11
#define RDATA  0x12
//通用UC统计信息
#define CPU_clock 1亿
#define per时钟 2500万

//**********************************************
//变量
//**********************************************
UINT16_t ADC_INIT_ADDR[]={CONFIIG3,CONFIIG2,LOFF,CH1SET, CH2SET,CH3SET,CH4SET,CH5SET,CH6SET, CH7SET,CH8SET,
       RLDSENSP,RLDSENSN,LOFFSENSP,LOFFSENSN,LOFFFLIP, Pace,RESP,CONFIIG4};
UINT16_t ADC_INIT_DATA[]={0xCC,0xC6,0x00,0x00,0x10, 0x10,0x10,0x10,0x10,0x10, 0x10,0x10,
       0x03,0x01,0x00,0x00,0x00, 0x00,0x29,0x00};
UINT16_t ADC_ID[]={0x11,0x20,0x00,0x00};

//**********************************************
//函数原型
//**********************************************
void SPI_init(void);
void SPI_TX_STRING();
UINT16_t SPI_RX_STRING();
void SPI_TX_Byte();
UINT16_t SPI_RX_BYTE();
void SPI_TX_CMD();
void adc_power _init();
void delay_us();
void delay_ms();

//**********************************************
//主菜单
//**********************************************
Void主(void)

 //初始化设备时钟和外围设备
   device_init();
    /* 修改系统时钟
    * Device.h -> device_setclock_CFG
    *  sysctl_imULT (40)
    *  sysctl_fmULT_0
    *  sysctl_SYSDIV (4)
    *   -> 100 MHz
    * Device.c ->线路88
    *  sysctl_LSPCLK_prescale_4
    *   -> 25 MHz
    */
   //禁用引脚锁并启用内部上拉。
   DEVICE_INITGPIO ();
   //初始化饼图和清除饼图寄存器。 禁用CPU中断。
   interrup_initModule();
   //使用指向外壳中断的指针初始化PIE矢量表
   //服务例程(ISR)。
   interrupT_initVectorTable();
   //启用全局中断(INTM)和实时中断(DBGM)
   EINT;
   ERTM;

   //设置SPI,手动控制/CS-pin61
   SPI_init();

   //开始ADC的通电例程,需要手动控制/CS-pin61
   ADC_POWER_INIT();

//   SPI_TX_CMD (SDATAC);
//   SPI_TX_STRING (ADC_INIT_ADDR,ADC_INIT_DATA,sizeof (ADC_INIT_ADDR));
//   SPI_TX_CMD (RDATAC);
//   SPI_TX_CMD (启动);

   uINT16_t文档;
   而(1){
 GPIO写入引脚(61,1);
 delay_ms(10);
 GPIO写入引脚(61,0);
   DELAY _Us (100);
   SPI_writeDataNonBlocking(SPIA_base,((SDATAC)<<8));
   UINT16_t dummy = SPI_readDataBlockingNonFIFO (SPIA_BASE);
   DELAY _Us (5);
   SPI_writeDataNonBlocking (SPIA_BASE,((0x20)<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 DELAY _Us (5);
 SPI_writeDataNonBlocking(SPIA_base,((0x00)<<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 DELAY _Us (5);
 SPI_writeDataNonBlocking(SPIA_base,((0x00)<<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 DELAY _Us (100);
   };
//   同时(1)
//   {
//    SPI_TX_CMD (SDATAC);
//    delay_us (10);
//    SPI_RX_BYTE (0);
//    delay_us (10);
////  SPI_TX_Byte (ADC_INIT_ADDR[0],ADC_INIT_DATA[0]);
////  SPI_RX_BYTE (ADC_INIT_ADDR[0]);
////  SPI_TX_CMD (RDATAC);
////  SPI_TX_CMD (启动);
//   }

 IF (GPIO _readPin (47)=0)
 {
  GPIO写入引脚(61,1);
 }
   同时(1);
}

//**********************************************
//函数声明
//**********************************************

//
//在FIFO模式下配置SPI A的功能。
//
void spi_init()

   //
   //必须在配置SPI之前将其置入重置
   //
   SPI_DisableModule (SPIA_base);

   //GPIO MUX配置
 GPIO _setDirectionMode (58,GPIO _DIR_MODE_OUT);  // SPI-A-SIMO (引脚58)设置为输出
 GPIO _setDirectionMode (59,GPIO _DIR_MODE_In); // SPI-A-SOMI (引脚59)设置为输出
 GPIO _setDirectionMode (61,GPIO _DIR_MODE_OUT);  // SPI-A-CS (引脚61)设置为输出
 GPIO _setDirectionMode (60,GPIO _DIR_MODE_OUT);  // SPI-A-CLK (引脚60)设置为输出
 GPIO _setPinConfig (GPIO_58_SPISIMOA);           // PIN58多路复用配置设置为SPI-A-SIMO
 GPIO _setPinConfig (GPIO_59_SPISOMIA);   // PIN59多路复用配置设置为SPI-A-SOMI
 GPIO_setPinConfig (GPIO _61_GPIO61);             // PIN61多路复用配置设置为SPI-A-CS
 GPIO _setPinConfig (GPIO_60_SPICLKA);            // PIN60多路复用配置设置为SPI-A-CLK

   //
   // SPI配置。 使用1MHz SPICLK和16位字大小。
   //
   SPI_setConfig(SPIA_base, DEVICE_LSPCLK_FREQ, SPI_PROT_POL1PHA0,
                 SPI_MODE_MASTER,20万,8);
   SPI_enableLoopback (SPIA_base);
   SPI_setEmulation Mode(SPIA_base, SPI_emulation_stop_after transmit);

   //
   //配置完成。 启用模块。
   //
   SPI_enableModule (SPIA_base);
   GPIO写入引脚(61,1);
   delay_ms(10);
   GPIO写入引脚(61,0);
}

void spI_tx_string(uint16_t *addr, uint16_t *data,uint16_t size)

 INT I = 0;
 用于(i=0;i<大小;i++)
 {
  SPI_TX_Byte (addr[i],data[i]);
 }
}

uINT16_t SPI_RX_STRING(uint16_t *addr, uint16_t size)

 INT I = 0;
 用于(i=0;i<大小;i++)
 {
  SPI_RX_BYTE (addr[I]);
 }
}

void SPI_TX_Byte(uint16_t addr, uint16_t byte)

 GPIO写入引脚(61,0);
 DELAY _Us (1);
 SPI_writeDataNonBlocking(SPIA_base,((0x40 | addr)<8));
 UINT16_t dummy = SPI_readDataBlockingNonFIFO (SPIA_BASE);
 SPI_writeDataNonBlocking (SPIA_BASE,(0x00<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 SPI_writeDataNonBlocking (SPIA_BASE,(字节<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 DELAY _Us (1);
 GPIO写入引脚(61,1);
}

UINT16_t SPI_RX_BYTE (uint16_t addr)

 GPIO写入引脚(61,0);
 DELAY _Us (1);
 SPI_writeDataNonBlocking(SPIA_base,((0x20 | addr)<8));
 UINT16_t dummy = SPI_readDataBlockingNonFIFO (SPIA_BASE);
 SPI_writeDataNonBlocking (SPIA_BASE,(0x00<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 SPI_writeDataNonBlocking (SPIA_BASE,(0x00<8));
 虚拟= SPI_readDataBlockingNonFIFO (SPIA_base);
 DELAY _Us (1);
 GPIO写入引脚(61,1);
}

空SPI_TX_CMD (uint16_t CMD)

 GPIO写入引脚(61,0);
 DELAY _Us (1);
 SPI_writeDataNonBlocking (SPIA_BASE,(CMD<<8));
 UINT16_t dummy = SPI_readDataBlockingNonFIFO (SPIA_BASE);
 DELAY _Us (1);
 GPIO写入引脚(61,1);
}

void adc_POWER_init()

 GPIO_setDirectionMode (ADC_CLKSEL,GPIO_DIR_MODE_OUT);
 GPIO设置方向模式(ADC_RESET,GPIO DIR_MODE_OUT);
 GPIO_setDirectionMode (ADC_PDWN,GPIO_DIR_MODE_OUT);
 GPIO_setDirectionMode (ADC_DRDY,GPIO_DIR_MODE_In);
 GPIO_setDirectionMode (ADC_START,GPIO_DIR_MODE_OUT);
 GPIO_setPinConfig (GPIO _87_GPIO87);
 GPIO _setPinConfig (GPIO_69_GPIO69);
 GPIO_setPinConfig (GPIO _66_GPIO66);
 GPIO_setPinConfig (GPIO _86_GPIO86);
 GPIO_setPinConfig (GPIO _65_GPIO65);

 GPIO写入引脚(ADC_START,0);
 GPIO_writePin (ADC_PDWN,0);
 GPIO写入引脚(ADC_RESET,0);
 DELAY毫秒(140);

 GPIO写入引脚(ADC_CLKSEL,1);
 DELAY _Us (10);
 GPIO写入引脚(ADC_PDWN,1);
 GPIO写入引脚(ADC_RESET,1);
 DELAY毫秒(140);
 GPIO写入引脚(ADC_RESET,0);
 DELAY _Us (10);
 GPIO写入引脚(ADC_RESET,1);
 // SENDSDATAC命令
}

void delay_us(uint16_t delay)

 易失性UINT32_t刻度;
 易失性UINT32_t持续时间= CPU_CLOCK/100万*延迟;
 对于(ticks=0;ticks<=持续时间;ticks++);
}

void delay_ms (uint16_t延迟)

 易失性UINT32_t刻度;
 易失性UINT32_t持续时间= CPU_CLOCK/1000*DELAY;
 对于(ticks=0;ticks<=持续时间;ticks++);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是我当前电路的Altium原理图

    希望这有助于调试过程。

    注意DAD CH是指我作为LSA使用的勤勉模拟发现板。

    注:我目前没有TMS320F2.8377万的原理图文件,因此UC针脚是指该微控制器的针脚编号。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Seth:

    感谢您的帖子。

    您是否使用了正确的SPI模式? ADS1298使用SPI模式1,即CPOL =0,CPHA =1。 在您的逻辑分析器捕获中,SCLK似乎处于高怠速状态,并随着下降边缘而领先。 我们希望SCLK低怠速。 然后使用上升边缘移动数据,下降边缘随后锁定数据。 请尝试一下,并告诉我这是否可以解决您的问题。

    https://www.totalphase.com/support/article_attachments/200063856/spi-modes.png

    此致,

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,

    我很抱歉花了这么长时间才对这一问题作出回应。 我不得不将注意力转移到该项目的其他方面,以满足最后期限。
    我已实施了上面建议的更改,但它未修复我的错误。 实际上,它导致系统完全停止工作。 在我当前的修复程序下,这种情况仍然存在/不存在。

    此致,
    Seth
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,

    我终于找到了解决方案。 基本上,我只是需要使时钟的下降边缘出现在数据位的中间。

    基本上,示波器阻抗的电容元件导致下降边缘延迟,以便ADC可以记录数据。 我通过在SCLK和接地之间添加一个电容器来确认这一点。 最后,我在SPI控制寄存器中进行了简单的下降边缘修改。