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.

[参考译文] CCS/TMS320F28377S:使用 SPI 进行通信时出现问题+变量和寄存器信息之间存在奇数差异

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/627126/ccs-tms320f28377s-issue-communicating-with-spi-odd-discrepency-between-variable-and-register-information

器件型号:TMS320F28377S
主题中讨论的其他器件: ADS1298

工具/软件:Code Composer Studio

我正在尝试使用 SPIA 在 TMS320F28377和 ADS1298之间建立连接。 我目前正在独立测试 TMS、以确保它通过重复传输0x24实现我所期望的通信。 为此,我创建了函数 init_spi(),以确保将我需要的 GPIO 引脚设置为输出,将引脚多路复用器设置为所需的 SPI,并启用外设时钟。 在执行此操作时、我可以确认/CS 工作正常、时钟也工作正常。 但是、数据不会在环路上传输。 相反、我只接收0 (我通过勤奋的模拟发现板查看此情况)。 我检查了寄存器状态、发现 INTFLAG 和 BUFFULL 被保持在高电平。 我想这会导致数据锁存。 因此、我设置了一个 while 条件、等待该位清零。 当我运行代码时、我意识到它没有触发我的暂停条件。 然后、我注意到:

变量和寄存器具有不同的值。 几分钟后、我决定验证寄存器的地址(我右键单击 BUFFULL 并选择"查看地址处的存储器")、结果如下:

请注意、这里的地址与我的变量的地址不同。 我已经添加了代码和项目窗口的副本、以帮助您确定发生这种情况的原因。 请提供任何帮助。

附录:

(二

这是我到目前为止拥有的代码:

/********

 *包括
 (二 /
#include "F28x_Project.h"
#include "sysctl.h"
#include "spi.h"
#include "cputimer.h"
#include "gpio.h"
#include "pin_map.h"

/********
 *定义
 (二 /
#define CPU_CLK    200000000
#define SPI_Clk     30000000
#define SPI_bps          500

/********
 *函数-原型
 (二 /
void init_spi();

/********
 *主函数
 (二 /
int main()

//   EALLOW;
//   CPUTimer_selectClockSource (CPUSYS_base、CPUTIME_CLOCK SOURCE_SYS、CPUTIME_CLOCK_PRER_1);
//   EDIS;
   /*设置时钟
    * CLKSRCCTL1、2、3
    * CPUSYSREGS
    *
    *

   init_spi();
//   GPIO_setDirectionMode (123、GPIO_DIR_MODE_OUT);
//   GPIO_writePin (123、1U);
 while (1)
 {
    SPI_writeDataNonBlocking (SPIA_BASE、0x24);
    while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG = 1);
    NOP;
    NOP;
    NOP;
    NOP;
 }

/********
 *函数-声明
 (二 /
空 init_spi()

   //GPIO MUX 配置
   GPIO_setDirectionMode (58、GPIO_DIR_MODE_OUT);  // SPI-A-SIMO (引脚58)设置为输出
   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_61_SPISTEA);            // PIN61多路复用器配置设置为 SPI-A-CS
   GPIO_setPinConfig (GPIO_60_SPICLKA);            // PIN60多路复用器配置设置为 SPI-A-CLK

   //sysctl_resetPeripheral (sysctl_Periph_CLK_SPIA);
   SYSCTL_enablePeripheral (SYSCTL_Periph_CLK_SPIA);
   SPI_setConfig (SPIA_BASE、SPI_Clk、SPI_PROT_POL0PHA0、SPI_MODE_MASTER、SPI_bps、 8);
   //SPI_setConfig (SPIA_BASE、100000000、SPI_PROT_POL0PHA0、SPI_MODE_MASTER、50000、16);
   SPI_enableModule (SPIA_BASE);

以下是我的项目窗口的屏幕截图:

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

    您的整个 main()代码是这样吗? 如果是、您似乎没有将 CPU 时钟配置为以200MHz 运行(请查看任何 driverlib 示例中的 Device_init()函数以了解预期结果)。 此外、SPI 的输入时钟(即 SPI_Clk 时钟)是低速外设时钟、默认情况下以200MHz 的/4运行。 我认为这不一定会导致传输失败、但 SPI 输出时钟不是您所期望的。

    我发现的另一个问题是 SPI_writeDataNonBlocking ()。 当在 SPI_setConfig()中选择的字符大小小于16时,此函数要求数据在数据参数中左对齐。 因此、这意味着您应该具有 SPI_writeDataNonBlocking (SPIA_BASE、(0x24 << 8))。

    尝试清除上述问题并查看是否仍然无法发送。

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

    您好!

    因此、我最终控制了 SPI 和系统时钟。 非常感谢您在这方面的帮助。 但是、我现在遇到了 ADC 本身的问题。 2017年10月27日、我首次与 ADS1298建立通信:

    但是、当我现在做同样的事情时、它不起作用

    我所做的唯一更改是创建函数 SPI_TX_BYTE、SPI_RX_BYTE、SPI_TX_STRING 和 SPI_RX_STRING。

    我认为 SPI 或 ADC_POWER_INIT 例程没有任何问题、但可以随意检查。 如有必要、我可以提供我的接线方案图。 感谢您提供的任何帮助。

    我的代码如下所示。

    //*********
    //包含的文件
    //*********
    #include "driverlib.h"
    #include "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 CONFIG2  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
    #define GPIO  0x14
    #define PACE  0X15
    #define RESP  0x16
    #define CONFIG4  0x17
    #define WCT1  0X18
    #define WCT2  0x19
    //ADC SPI 命令
    #define WAKEUP  0x02
    #define STANDBY  0x04
    #define RESET  0x06
    #define START  0x08
    #define STOP  0x0A
    #define RDATAC  0x10
    #define SDATAC  0x11
    #define RDATA  0x12
    //通用 UC 统计数据
    #define CPU_CLOCK 100000000
    define PER_CLOCK 25000000

    //*********
    //变量
    //*********
    uint16_t ADC_INIT_ADDR[]={CONFIG3、CONFIG1、CONFIG2、LOFF、CH1SET、 CH2SET、CH3SET、CH4SET、CH5SET、CH6SET、 CH7SET、CH8SET、
           RLDSENSP、RLDSENSN、LOFFSENSP、LOFFSENSN、LOFFFLIP、 Pace、RESP、CONFIG4};
    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 main (void)

     //初始化设备时钟和外设
       device_init();
        /* 修改系统时钟
        * Device.h -> DEVICE_setClock_CFG
        *  SYSCTL_IMULT (40)
        *  SYSCTL_FMULT_0
        *  SYSCTL_SYSDIV (4)
        *   -> 100MHz
        * Device.c ->第88行
        *  SYSCTL_LSPCLK_PRESCALE_4
        *   -> 25MHz
        *
       //禁用引脚锁定并启用内部上拉。
       DEVICE_initGPIO();
       //初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
       interrupt_initModule();
       //使用指向 shell 中断的指针初始化 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 DOUT;

    //指定一个将 ADC 持续置于 SDATAC 模式时,  

    //并检查 ADC 的 ID。 这可确保 SPI 正常工作。
       while (1){
     GPIO_writePin (61、1);
     delay_ms (10);
     GPIO_writePin (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);
       };
    //   while (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_writePin (61、1);
     }
       while (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 (pin59)设置为输出
     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、200000、8);
       SPI_enableLoopback (SPIA_BASE);
       SPI_setEmulationMode (SPIA_BASE、SPI_emulation_stop_after_transmit);

       //
       //配置完成。 启用模块。
       //
       SPI_enableModule (SPIA_BASE);
       GPIO_writePin (61、1);
       delay_ms (10);
       GPIO_writePin (61、0);

    void SPI_TX_string (uint16_t *地址、uint16_t *数据、uint16_t 大小)

     int i = 0;
     for (i=0;<size;i++))
     {
      SPI_TX_BYTE (addr[i]、data[i]);
     }

    uint16_t SPI_RX_string (uint16_t *地址、uint16_t 大小)

     int i = 0;
     for (i=0;<size;i++))
     {
      SPI_RX_BYTE (addr[i]);
     }

    void SPI_TX_BYTE (uint16_t addr、uint16_t byte)

     GPIO_writePin (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、(BYTE<8));
     虚拟= SPI_readDataBlockingNonFIFO (SPIA_BASE);
     DELAY_us (1);
     GPIO_writePin (61、1);

    uint16_t SPI_RX_BYTE (uint16_t addr)

     GPIO_writePin (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_writePin (61、1);

    void SPI_TX_CMD (uint16_t CMD)

     GPIO_writePin (61、0);
     DELAY_us (1);
     SPI_writeDataNonBlocking (SPIA_BASE、(CMD<8));
     uint16_t dummy = SPI_readDataBlockingNonFIFO (SPIA_BASE);
     DELAY_us (1);
     GPIO_writePin (61、1);

    void adc_power_init ()

     GPIO_setDirectionMode (ADC_CLKSEL、GPIO_DIR_MODE_OUT);
     GPIO_setDirectionMode (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_writePin (ADC_START、0);
     GPIO_writePin (ADC_PDWN、0);
     GPIO_writePin (ADC_RESET、0);
     delay_ms (140);

     GPIO_writePin (ADC_CLKSEL、1);
     delay_us (10);
     GPIO_writePin (ADC_PDWN、1);
     GPIO_writePin (ADC_RESET、1);
     delay_ms (140);
     GPIO_writePin (ADC_RESET、0);
     delay_us (10);
     GPIO_writePin (ADC_RESET、1);
     // SENDSDATAC 命令

    void delay_us (uint16_t delay)

     volatile uint32_t tick;
     易失性 uint32_t 持续时间= cpu_clock/1000000*延迟;
     for (ticks = 0;tick <=持续时间;ticks ++);

    void delay_ms (uint16_t delay)

     volatile uint32_t tick;
     易失性 uint32_t 持续时间= cpu_clock/1000*延迟;
     for (ticks = 0;tick <=持续时间;ticks ++);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的代码看起来很好。 我没有看到任何明显的问题、从您的波形捕获中可以看到、在这两种情况下、C2000似乎以相同的方式发送其命令。

    我以前从未使用过 ADS1298。 您是否需要检查代码中某个位置的 DRDY 输入?

    我建议您在精密数据转换器论坛上发帖、但我看到您已经完成了。 希望他们能够发现问题。

    惠特尼