您好!
在 DSP F28335和 ADS1256之间通过 SPI 进行通信时、我需要一些帮助来解决一些问题。 ADS1256未响应任何命令、每当我读取寄存器或数据时、MISO 始终返回 FF。 我怀疑发送到 ADC 的命令未被识别、因此没有响应。 Data Ready 连接到 GPIO、上电时、数据就绪信号的周期为33us、即大约2.4us 高电平、然后大约30.6us 低电平、
F28335 SPI SCLK 设置为1.25MHz、在上升沿发送数据、在下降沿接收数据、无相位延迟、空闲低电平。
我已附上显示 SCLK、CS 和 MOSI 的波形。 SCLK、CS 和 MOSI 之间的时序符合如下所示的时序规格。 并且连续的 MOSI 字节也满足时序要求。 MISO 未显示、但在测试中、它始终保持高电平。

下图显示了写入单个字节时的情况。 蓝线-- CS,黄线-- SCLK,紫线-- MOSI。

下图显示了写入多个字节时的情况。 绿线-- CS,紫线-- SCLK,蓝线-- MOSI

我还附上了配置代码。 这是 ADC 设置。
// adc_spi.c
#include "adc_spi.h"
#include "DSP28x_Project.h"
#include "spi.h"
enum
{
REG_STATUS = 0x0000, // x1H
REG_MUX = 0x0100, // 01H
REG_ADCON = 0x0200, // 20H
REG_DRATE = 0x0300, // F0H
REG_IO = 0x0400, // E0H
REG_OFC0 = 0x0500, // xxH
REG_OFC1 = 0x0600, // xxH
REG_OFC2 = 0x0700, // xxH
REG_FSC0 = 0x0800, // xxH
REG_FSC1 = 0x0900, // xxH
REG_FSC2 = 0x0A00, // xxH
};
// Command Table
enum
{
CMD_WAKEUP = 0x0000, // Completes SYNC and Exits Standby Mode 0000 0000 (00h)
CMD_RDATA = 0x0100, // Read Data 0000 0001 (01h)
CMD_RDATAC = 0x0300, // Read Data Continuously 0000 0011 (03h)
CMD_SDATAC = 0x0F00, // Stop Read Data Continuously 0000 1111 (0Fh)
CMD_RREG = 0x1000, // Read from REG rrr 0001 rrrr (1xh)
CMD_WREG = 0x5000, // Write to REG rrr 0101 rrrr (5xh)
CMD_SELFCAL = 0xF000, // Offset and Gain Self-Calibration 1111 0000 (F0h)
CMD_SELFOCAL= 0xF100, // Offset Self-Calibration 1111 0001 (F1h)
CMD_SELFGCAL= 0xF200, // Gain Self-Calibration 1111 0010 (F2h)
CMD_SYSOCAL = 0xF300, // System Offset Calibration 1111 0011 (F3h)
CMD_SYSGCAL = 0xF400, // System Gain Calibration 1111 0100 (F4h)
CMD_SYNC = 0xFC00, // Synchronize the A/D Conversion 1111 1100 (FCh)
CMD_STANDBY = 0xFD00, // Begin Standby Mode 1111 1101 (FDh)
CMD_RESET = 0xFE00, // Reset to Power-Up Values 1111 1110 (FEh)
//CMD_WAKEUP = 0xFF, // Completes SYNC and Exits Standby Mode (FFh)
};
static void bsp_DelayMS(Uint16 nms);
static void bsp_DelayUS(Uint16 nus);
static void ADS1256_WaitDRDY(void);
static void ADS1256_ResetHard(void);
static void ADS1256_DelaySCLK(void);
static void ADS1256_DelayDATA(void);
static void ADS1256_DelayCS(void);
static void ADS1256_DelaySYNC(void);
static void ADS1256_WriteCmd(Uint16 _cmd);
//static void ADS1256_WriteReg(Uint16 _RegID, Uint16 _RegValue);
//static Uint16 ADS1256_ReadReg(Uint16 _RegID);
static Uint32 ADS1256_ReadData(void);
static void ADS1256_SetChannal(Uint16 _ch);
//static void ADS1256_StopScan(void);
ADS1256_VAR_T g_tADS1256;
static const Uint16 s_tabDataRate[ADS1256_DRATE_MAX] =
{
0xF000, // 30K SPS
0xE000, // 15K
0xD000, // 7.5K
0xC000, // 3750
0xB000, // 2000
0xA100, // 1000
0x9200, // 500
0x8200, // 100
0x7200, // 60
0x6300, // 50
0x5300, // 30
0x4300, // 25
0x3300, // 15
0x2300, // 10
0x1300, // 5
0x0300 // 2.5
};
void bsp_DelayUS(Uint16 nus)
{
DELAY_US(nus);
}
void ADS1256_Init(){
EALLOW;
// CS
GpioCtrlRegs.GPAMUX1.bit.GPIO6=0; // GPIO
GpioCtrlRegs.GPAPUD.bit.GPIO6=0; // Enable internal pullup
GpioCtrlRegs.GPADIR.bit.GPIO6=1; // Output
//RST
GpioCtrlRegs.GPAMUX1.bit.GPIO7=0; // GPIO
GpioCtrlRegs.GPAPUD.bit.GPIO7=0; // Enable internal pullup
GpioCtrlRegs.GPADIR.bit.GPIO7=1; // Output
//SYNC
GpioCtrlRegs.GPAMUX1.bit.GPIO8=0; // GPIO
GpioCtrlRegs.GPAPUD.bit.GPIO8=0; // Enable internal pullup
GpioCtrlRegs.GPADIR.bit.GPIO8=1; // Output
//DATA READY
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock
GpioCtrlRegs.GPAMUX1.bit.GPIO9=0; // GPIO
GpioCtrlRegs.GPAPUD.bit.GPIO9=1; // Disable internal pullup
GpioCtrlRegs.GPADIR.bit.GPIO9=0; // Input
GpioCtrlRegs.GPAQSEL1.bit.GPIO9= 0;
GpioDataRegs.GPASET.bit.GPIO6=1; // Set value
GpioDataRegs.GPASET.bit.GPIO7=1; // Set value
GpioDataRegs.GPASET.bit.GPIO8=1; // Set value
EDIS;
};
// t11 -> min 1/7.68M * 4 = 0.52 us Delay for final SCLK falling edge to first
// rising edge of next command, WREG, RREG, RDATA
// RESET and SYNC must be low for at least 0.52 us to be effective
static void ADS1256_DelaySCLK(void)
{
bsp_DelayUS(1);
}
// t11 -> min 1/7.68M * 24 = 3.12 us Delay for final SCLK falling edge to first
// rising edge of next command, RDATAC, SYNC
static void ADS1256_DelaySYNC(void)
{
bsp_DelayUS(5);
}
// t8 -> min 1/7.68M * 8 = 1.04 us Delay for final SCLK falling edge to first
// CS goes high
static void ADS1256_DelayCS(void)
{
bsp_DelayUS(3);
}
// t6 -> min 50 * 0.13uS = 6.5uS
// Delay from last SCLK edge for DIN to first SCLK rising edge for
// DOUT: RDATA, RDATAC,RREG Commands
static void ADS1256_DelayDATA(void)
{
bsp_DelayUS(10);
}
// SCLK period 37.5 M / 60 = 625K
// 1/625k = 1.6 us
// Data ready time
static void ADS1256_WaitDRDY(void)
{
Uint32 i;
for (i = 0; i < 40000000; i++)
{
if (DRDY_IS_LOW())
{
break;
}
}
}
// Write register
void ADS1256_WriteReg(Uint16 _RegID, Uint16 _RegValue)
{
ADS1256_WaitDRDY();
spi_xmit(CMD_WREG | _RegID);
DELAY_US(10);
ADS1256_WaitDRDY();
spi_xmit(0x0000);
DELAY_US(10);
ADS1256_WaitDRDY();
spi_xmit(_RegValue);
}
// Send command
static void ADS1256_WriteCmd(Uint16 _cmd)
{
DELAY_US(10);
spi_xmit(_cmd);
DELAY_US(10);
}
void ADS1256_CfgADC(ADS1256_GAIN_E _gain, ADS1256_DRATE_E _drate)
{
g_tADS1256.Gain = _gain;
g_tADS1256.DataRate = _drate;
ADS1256_StopScan();
ADS1256_ResetHard();
ADS1256_WriteCmd(CMD_RESET);
DELAY_US(60);
ADS1256_WriteCmd(CMD_SDATAC);
DELAY_US(60);
{
Uint16 buf[4];
buf[0] = (((0 << 3) | (1 << 2) | (0 << 1))<<8);
// write 00000100, MSB, auto-calibration, buffer disable
buf[1] = 0x0800;
// output mux 00001000
buf[2] = (((0 << 5) | (0 << 3) | (_gain << 0))<<8);
// no clock out, sensor detect off, gain 1
buf[3] = s_tabDataRate[_drate];
//ADS1256_DelaySCLK();
DELAY_US(20);
spi_xmit(CMD_WREG | 0);
DELAY_US(20);
spi_xmit(0x0303);
DELAY_US(20);
spi_xmit(buf[0]);
DELAY_US(20);
spi_xmit(buf[1]);
DELAY_US(20);
spi_xmit(buf[2]);
DELAY_US(20);
spi_xmit(buf[3]);
DELAY_US(20);
}
DELAY_US(50);
ADS1256_WriteCmd(CMD_SYNC);
DELAY_US(20);
ADS1256_WriteCmd(CMD_WAKEUP);
DELAY_US(800);
}
static void ADS1256_ResetHard(void)
{
RST(0);
DELAY_US(10);
RST(1);
SYNC(0);
bsp_DelayUS(2);
DELAY_US(10);
SYNC(1);
DELAY_US(800);
ADS1256_WaitDRDY(); /* Ready time 630us */
}
Uint16 ADS1256_ReadReg(Uint16 _RegID)
{
Uint16 read;
read = 0;
ADS1256_WaitDRDY();
DELAY_US(20);
spi_xmit(CMD_RREG | _RegID);
DELAY_US(20);
spi_xmit(0x0000);
DELAY_US(20);
spi_xmit(0xEEEE);
read = SpiaRegs.SPIRXBUF;
DELAY_US(10);
return read;
}
Uint16 ADS1256_ReadChipID(void)
{
Uint16 id;
id = ADS1256_ReadReg(REG_STATUS);
return (id >> 4);
}
这是 SPI 设置。
#include "spi.h"
#include "SCI.h"
#include "adc.h"
//SPI send out data
void spi_xmit(Uint16 a){
SpiaRegs.SPISTS.bit.INT_FLAG = 1;
SpiaRegs.SPITXBUF = a;
while(!SpiaRegs.SPISTS.bit.INT_FLAG){}
//DELAY_US(20);
}
void spi_init(){
// Initialize spigpio:16--SIMO, 17--SOMI, 18--CLK, 19--STEA
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; //Enable pull-up on GPIO16 (SPISIMOA)
GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; //Enable pull-up on GPIO17 (SPISOMIA)
GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; //Enable pull-up on GPIO18 (SPICLKA)
GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; //Enable pull-up on GPIO19 (SPISTEA)
//
// Set qualification for selected pins to asynch only
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.
//
GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)
//
// Configure SPI-A pins using GPIO regs
// This specifies which of the possible GPIO pins will be SPI
// functional pins.
// Comment out other unwanted lines.
//
GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA
EDIS;
SpiaRegs.SPICCR.all = 0x0008; // Reset SPI, send out on rising edge, receive on falling edge, 8 bit
SpiaRegs.SPICTL.all = 0x0006; //no phase delay master mode
SpiaRegs.SPIBRR = 0x001D; // SPICLK(SPICLK 37.5M/(29+1))
SpiaRegs.SPIPRI.bit.FREE = 1; // Free run
//SPI FIFO
SpiaRegs.SPIFFTX.all = 0xE040; //enable SPI TX interrupt
SpiaRegs.SPICCR.all= 0x0088; // Renable SPI
}
interrupt void spi_rx_isr(void){
SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 1; //Clear inerrupt
PieCtrlRegs.PIEACK.bit.ACK6 = 1; //
}
interrupt void spi_tx_isr(void){
SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1; // Clear interrupt
PieCtrlRegs.PIEACK.bit.ACK6 = 1; //
}
期待您的帮助。
谢谢
乍得





