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 全体のデータは無意味であると予想されます。必要に応じて、他の命令のキャプチャを作成できます。

上から下まで:

  • 味噌
  • モシ
  • SS
  • SCLK

編集 2: 具体的には、UFDC-1 の精度を命令 0x020A で設定することです。その最後の部分 (「0A」) は精度の数値です。その後、その精度を読み取ろうとする while ループがあります。「精度を取得」命令は 0x01FF で、「FF」は精度数値を読み取るために送信されるダミー バイトです。したがって、「0x01FF」を送信すると、UFDC-1 から返されたデータのどこかで「0A」が読み取られると予想されます。

編集 3:これは、「精度を取得する」命令を初めて UFDC-1 に送信したときの SPI ラインのキャプチャです青い線 (上から 2 番目) は MOSI であり、間違いなく正しいコマンド (0x01FF) を示しています。これが正常に機能していた場合、UFDC-1 は、MOSI が「FF」を送信するのと同時に、精度の数値である「0A」(0b00001010) で MISO を介して応答するはずです。代わりに、その時点で「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 と適切に対話できるようになります。

残っている 1 つの問題は、SPI が MISO でランダム データをクロックすることです。たとえば、"0xedff" 以外は返されないと予想される while ループがあります。代わりに得られるものは次のとおりです。

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 を空にする必要があります。また、データを受信するときにダミー値を送信する必要があります-通常、0x00または0xFFダミーとして使用されます。

ライブラリはこれを行い、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 に答える