Я работаю с микроконтроллером LPC1788, и я пытаюсь отправлять и получать данные от UFDC-1 (универсальный преобразователь частоты в цифровой) с помощью SPI. Я могу передавать данные через 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);
}
Изменить: Здесь представлены все мои строки SPI после отправки инструкции «установить точность» (0x020A). Ожидается, что данные по MISO будут здесь бессмысленными. При необходимости я могу сделать снимки для других инструкций.
Сверху донизу:
- MISO
- MOSI
- SS
- SCLK
Изменить 2: В частности, я пытаюсь установить точность UFDC-1 с помощью инструкции 0x020A. Последняя часть («0A») - это показатель точности. После этого у меня есть цикл while, в котором я пытаюсь восстановить эту точность. Команда "получить точность" - это 0x01FF, где "FF" - фиктивный байт, посланный для того, чтобы считать число точности. Поэтому, когда я отправляю «0x01FF», я ожидаю, что где-то в данных, которые я получаю от UFDC-1, снова прочитал «0A».
Изменить 3: Вот захват строк SPI, когда я отправляю команду "получить точность" в UFDC-1 в первый раз. Синяя линия (вторая сверху) - это MOSI, и она определенно дает правильную команду (0x01FF). Если это работает правильно, UFDC-1 должен отвечать через MISO с помощью «0A» (0b00001010), которое является числом точности, в то же время, когда MOSI передает «FF». Вместо этого я получаю обратно "1A", и я не верю, что "A" на самом деле исходит от UFDC-1, а только от инструкции "установить точность" (0x020A), которую я отправил ранее. Это потому, что у меня есть инструкция «получить точность», выполняемую в цикле while, и постоянное значение, которое я читаю, - «0x7F00» - ничего общего с числом точности UFDC-1.
Вот как выглядит мой результат:
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.
Остается одна проблема: SPI синхронизирует случайные данные на MISO. Например, у меня есть цикл 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