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.
您好!
我只是 SPI 协议的初学者、我尝试使用 CCS IDE 和 EK-TM4C129-EXL 板对 TM4C 控制器进行编程、以连接 ADS1220 ADC。 我已经在回路中测试了 SPI 接口、现在正在进行、下面列出了我用于 SPI 和与 ADC 通信的配置、ADC 不会进行寄存器回读、我请求您提供一些帮助以解决问题。
谢谢你
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SPI 配置
INTERRUPT_FLAG = 0xFF;//初始设置标志
#if defined (target_IS_TM4C129_RA0)||\
已定义(TARGET_IS_TM4C129_RA1)||\
已定义(TARGET_IS_TM4C129_RA2)
#endif
ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480)、120000000);//将时钟设置为以120MHz 直接从晶体运行。
SysCtlPeripheralEnable (SYSCTL_Periph_SSI0);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
GPIOPinConfigure (GPIO_PA2_SSI0CLK);
GPIOPinConfigure (GPIO_PA3_SSI0FSS);
GPIOPinConfigure (GPIO_PA4_SSI0XDAT0);
GPIOPinConfigure (GPIO_PA5_SSI0XDAT1);
GPIOPinTypeGPIOInput (GPIO_Porta_base、GPIO_PIN_6);//中断
GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
GPIO_PIN_2);
#if defined (target_IS_TM4C129_RA0)||\
已定义(TARGET_IS_TM4C129_RA1)||\
已定义(TARGET_IS_TM4C129_RA2)
SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_MODE_1、
SSI_MODE_MASTER、1000000、8);
其他
SSIConfigSetExpClk (SSI0_BASE、SysCtlClockGet ()、SSI_FRF_MOTO_MOTO_MODE_1、
SSI_MODE_MASTER、1000000、8);
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ADC 配置
SSIEnable (SSI0_BASE);
SSIDataPut (SSI0_BASE、ADC_Reset);//重置 ADC
delay_ms (1);//确定延迟
pui32DataTx[0]= 0x43;// WREG 命令写入寄存器
pui32DataTx[1]= 0x01;// Register0数据值
pui32DataTx[2]= 0xD4;// Register1数据值
pui32DataTx[3]= 0x00;// Register2数据值
pui32DataTx[4]= 0x00;// Register3数据值
for (ui32Index = 0;ui32Index < 5;ui32Index++)
{
SSIDataPut (SSI0_BASE、pui32DataTx[ui32Index]);
}
while (SSIBusy (SSI0_BASE))
{
}
delay_ms (1);
SSIDataPut (SSI0_BASE、0x23);//读取寄存器
while (SSIBusy (SSI0_BASE))
{
}
for (ui32Index = 0;ui32Index < 4;ui32Index++)
{
SSIDataGet (SSI0_BASE、&pui32DataRx[ui32Index]);
pui32DataRx[ui32Index]&= 0x00FF;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
您好、Kurian、
最好始终通过观察示波器或逻辑分析仪上的通信来验证通信是否正确。 一个注意事项与 SPI 外设的数据长度有关。 如果您使用 SPI 外设的 SS 部分、SS 将仅在通信缓冲区的长度内保持低电平。 这可以是8位、16位或32位。 对于 ADS1220、CS (SS)必须在整个通信事务期间保持低电平。 通常最好通过 GPIO 控制手动控制 SS。 您可以通过开头所述的方法之一进行验证。
此致、
Bob B
您好、Kurian、
我真的看不到您的代码会有什么问题。 您是否已验证1ms 延迟实际上是1ms? 如果在发送 RESET 命令和 WREG 命令之间没有足够的时间、则可以忽略第二条命令。 您应该用示波器验证发出命令之间的时间间隔。
您的示波器照片仅显示一个信号。 查看传输的数据和 SCLK 以验证通信是否正确会更有帮助。 尤其是用于寄存器写入的 MOSI 和 SCLK。 您似乎有一个4通道示波器、因此我建议您使用 ADS1220 CS、DOUT、DIN 和 SCLK 进行拍摄。
此致、
Bob B
尊敬的 Bob:
非常感谢、
问题在于在没有时钟的情况下接收数据、因此提供了虚拟时钟来读取寄存器。 我将向某些人分享我的经验、提供有用的信息;请找到工作代码和探测信号。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SSIDataPutNonBlocking (SSI0_BASE、ADC_Reset); //重置 ADC
delay_ms (1); // ms 延迟
pui32DataTx[0]= 0x43; // WREG 命令写入寄存器
pui32DataTx[1]= 0x01; // Register0数据值
pui32DataTx[2]= 0xD4; // Register1数据值
pui32DataTx[3]= 0x00; // Register2数据值
pui32DataTx[4]= 0x00; // Register3数据值
pui32DataTx[5] = READ_ADCregister;
pui32DataTx[6] = Start_Conversion;(Pui32DataTx[6]=启动转换;)
pui32DataTx[7] = 0x00; //虚拟
pui32DataTx[8] = 0x00; //虚拟
pui32DataTx[9] = 0x00; //虚拟
pui32DataTx[10]= 0x00; //虚拟
for (ui32Index = 0;ui32Index < NUM_SSI_DATA;ui32Index++)
{
SSIDataPutNonBlocking (SSI0_BASE、pui32DataTx[ui32Index]);
SSIDataGet (SSI0_BASE、&pui32DataRx[ui32Index]);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
您好、Kurian、
很高兴您取得了进展、现在可以从 ADS1220读取数据。 简而言之、当希望从器件读取数据时、主器件必须发出 SCLK。 为了使 SPI 外设 从从器件读取数据、时钟通过写入 TX 缓冲器来启动。 这是一个 NOP (或一些不会被解释为通常为0x00或0xFF 的命令的值)、主器件可以通过传输来启动时钟。
运行顺序很重要。 如果写入后未清除 RX 缓冲 区、则 RX 缓冲区中可能存在垃圾数据。 从从从器件读取数据时、必须确保正在读取所需的数据、而不是先前的数据。 如果在 将 NOP 写入 TX 缓冲区之前未清除 RX 缓冲区、则下一次读取的 RX 缓冲区可能是旧数据。 因此、当从器件读取数据时、应清除 RX 缓冲区、然后 写入 TX 缓冲区。 在 读取前等待有效数据被完全写入 RX 缓冲区。 这通常通过轮询缓冲器标志来完成。
另一 项考虑涉及 为 防止超支而传输的数据块。 顺序 C 代码 的执行速度实际上可能比您所意识到的要快。 在大多数情况下、处理器的运行速度比外设时钟快得多、因此、即使您使用 FIFO 作为发送和接收缓冲区、也需要非常小心、以免丢失发送或接收的数据。 同样、可以通过监视发送和接收标志来完成此操作。
此致、
Bob B