0

我正在使用 LPC1788 微控制器,我正在尝试使用 SPI 从 UFDC-1(通用频率数字转换器)发送和接收数据。我能够通过 MOSI 很好地向它传输数据(我已经用示波器确认了这一点),但是每当我发送诸如“获取精度”之类的指令时,我的数据缓冲区中唯一的数据就是数据或指令我刚发。“环回”未启用。

这是我的代码:

SSP_CFG_Type sspConfig;
SSP_DATA_SETUP_Type sspData;
LPC_SSP_TypeDef *SSPx = NULL;

UFDC_RESULT_T result_SSP0_FX1, result_SSP0_FX2;
UFDC_RESULT_T result_SSP1_FX1, result_SSP1_FX2;
UFDC_RESULT_T *result, *resultFX1, *resultFX2 = NULL;

uint8_t resultSign;
uint64_t resultInt, resultFract;

uint8_t SSP0resultFX1sign, SSP0resultFX2sign;
uint8_t SSP1resultFX1sign, SSP1resultFX2sign;

uint64_t SSP0resultFX1int, SSP0resultFX2int;
uint64_t SSP1resultFX1int, SSP1resultFX2int;

uint64_t SSP0resultFX1fract, SSP0resultFX2fract;
uint64_t SSP1resultFX1fract, SSP1resultFX2fract;

uint16_t getAccInstr = 0x01FF;
uint16_t setAccInstr = 0x020A;
uint16_t checkStatusInstr = 0x03FF;
uint16_t setMeasureModeInstr1 = 0x0600;
uint16_t setMeasureModeInstr2 = 0x060E;
uint16_t getBCDResultInstr = 0x07FF;
uint8_t startMeasureInstr = 0x09;

uint32_t measureInstr;

uint8_t txData[2];
uint8_t rxData[2];

uint16_t data;

sspConfig.CPHA = SSP_CPHA_FIRST;
sspConfig.CPOL = SSP_CPOL_HI;
sspConfig.ClockRate = 100000;
sspConfig.Databit = SSP_DATABIT_16;
sspConfig.Mode = SSP_MASTER_MODE;
sspConfig.FrameFormat = SSP_FRAME_SPI;

sspData.tx_data = txData;
sspData.rx_data = rxData;
sspData.length = 2;

printf("Initialising SSP0 and SSP1...\n\n");

PINSEL_ConfigPin(0, 15, 2); // SSP0_SCK
PINSEL_ConfigPin(0, 16, 2); // SSP0_SSEL
PINSEL_ConfigPin(0, 17, 2); // SSP0_MISO
PINSEL_ConfigPin(0, 18, 2); // SSP0_MOSI
PINSEL_ConfigPin(0, 6, 2); // SSP1_SCK
PINSEL_ConfigPin(0, 7, 2); // SSP1_SSEL
PINSEL_ConfigPin(0, 8, 2); // SSP1_MISO
PINSEL_ConfigPin(0, 9, 2); // SSP1_MOSI

PINSEL_SetFilter(0, 7, DISABLE);
PINSEL_SetFilter(0, 8, DISABLE);
PINSEL_SetFilter(0, 9, DISABLE);

SSP_Init(LPC_SSP0, &sspConfig);
SSP_Init(LPC_SSP1, &sspConfig);
SSP_Cmd(LPC_SSP0, ENABLE);
SSP_Cmd(LPC_SSP1, ENABLE);

printf("Reading UDFC frequency values...\n\n");
for(int i=0; i < 2; i++)
{
  if(i == 0)
  {
    SSPx = LPC_SSP0;
    resultFX1 = &result_SSP0_FX1;
    resultFX2 = &result_SSP0_FX2;
  }
  else
  {
    SSPx = LPC_SSP1;
    resultFX1 = &result_SSP1_FX1;
    resultFX2 = &result_SSP1_FX2;
  }

  // Set UFDC accuracy to 1%.
  SSP_SendData(SSPx, setAccInstr);
  while(SSPx->SR & SSP_SR_BSY);

  // Check accuracy.
  while(1)
  {
    printf("Sending data...\n");
    SSP_SendData(SSPx, getAccInstr);

    while(SSPx->SR & SSP_SR_BSY);

    // Wait to receive back data.
    while(SSPx->SR & SSP_SR_RNE)
    {
      printf("Received data here: 0x%x\n", SSP_ReceiveData(SSPx));
    }

    //data = SSP_ReceiveData(SSPx);
    //printf("Accuracy check 1: %i\n", data >> 8);
    //printf("Accuracy check 2: %i\n", data & 0xFF);
  }

编辑:是发送“设置精度”指令(0x020A)后我所有 SPI 线的捕获。预计 MISO 中的数据在这里毫无意义。如果需要,我可以为其他指令生成捕获。

从上到下:

  • 味噌
  • 莫西
  • 党卫军
  • 时钟

编辑 2: 具体来说,我要做的是使用指令 0x020A 设置 UFDC-1 的精度。最后一部分(“0A”)是准确度数。在那之后,我有一个while循环,我试图读回那个准确性。“获取准确度”指令是 0x01FF,其中“FF”是为了读回准确度号而发送的一个虚拟字节。因此,当我发送“0x01FF”时,我希望在从 UFDC-1 发回的数据中某处读回“0A”。

编辑 3:是我第一次向 UFDC-1 发送“获取精度”指令时捕获的 SPI 线。蓝线(从上数第二个)是 MOSI,它肯定给出了正确的命令 (0x01FF)。如果这工作正常,UFDC-1 应该通过 MISO 回复“0A”(0b00001010),这是准确度数,在 MOSI 传输“FF”的同时。相反,当时我收到了“1A”,我不相信“A”实际上来自 UFDC-1,而只是来自我之前发送的“设置精度”指令 (0x020A)。这是因为我在 while 循环中有“获取准确性”指令,而我正在读回的稳态值是“0x7F00”

这是我的输出的样子:

Initialising SSP0 and SSP1...

Reading UDFC frequency values...

Sending data...
Received data here: 0xff00
Received data here: 0xa1a
Sending data...
Received data here: 0xff00
Sending data...
Received data here: 0x7f00
Sending data...
Received data here: 0x7f00
Sending data...
Received data here: 0x7f00
Sending data...
Received data here: 0x7f00
Sending data...
Received data here: 0x7f00
Sending data...

编辑:原来问题出在 CPOL 和 CPHA 位上。它们都从 0 更改为 1。这似乎让 SPI 控制器与 UFDC 正确交互。

剩下的一个问题是 MISO 上的随机数据的 SPI 时钟。例如,我有一个 while 循环,我希望只返回“0xedff”。我得到的是:

Data : 0xedff
Data : 0xffff
Data : 0xff01
Data : 0xffff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
Data : 0xedff
4

1 回答 1

0

LPC17xx 中的 SSP 具有用于发送和接收的 FIFO。这意味着您必须匹配您的SSP_SendData()andSSP_ReceiveData()调用,或者清空 FIFO。在接收数据时,您还必须发送一个虚拟值- 通常0x000xFF用作虚拟值。

该库执行此操作SSP_ReadWrite(),您可以在其中使用。

更简单的版本如下所示:

uint16_t spi_write_read( LPC_SSP_TypeDef* SSPx, uint16_t outgoing )
{
    uint16_t incoming;

    while( !( SSPx->SR & (1 << SSP_SR_TNF ) ) ) { ; }
    SSPx->DR = outgoing;
    while( !( SSPSR & ( 1 << SSP_SR_RNE ) ) ) { ; }
    incoming = SSPx->DR;

    return incoming;
}

此函数可用作代码SSP_SendData()SSP_ReceiveData()代码中的替代品。

最后说明:您可能不需要硬件芯片选择,因为这可以取消选择命令和响应字之间的从机。阅读相应的数据表,在许多情况下这是不允许的。

于 2013-07-22T13:09:30.617 回答