Я работаю с микроконтроллером LPC1788, и я пытаюсь отправлять и получать данные с UFDC-1 (универсальный преобразователь частоты-в-цифровой) с использованием SPI. Я могу передавать данные через MOSI на это отлично (я подтвердил это с помощью осциллографа), но всякий раз, когда я отправляю инструкцию типа «получить точность», единственными данными, которые у меня есть в буфере данных, являются данные или инструкции Я только что отправил. «Loop back» не включен.LPC1788: Общение с UFDC-1 с использованием SPI
Это код, у меня есть:
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);
}
Edit: Here является захват всех моих линий SPI после отправки "установить точность" инструкцию (0x020A). Ожидается, что данные в MISO будут бессмысленными. Я могу произвести захват для других инструкций, если это необходимо.
Сверху вниз:
- MISO
- MOSI
- SS
- SCLK
Edit 2: В частности, то, что я пытаюсь сделать, это установить точность UFDC-1 с инструкцией 0x020A. Последняя часть этого («0A») - это номер точности. После этого у меня есть цикл while, где я пытаюсь прочитать эту точность. Инструкция «получить точность» - 0x01FF, где «FF» - это фиктивный байт, отправленный для чтения номера точности. Поэтому, когда я отправляю «0x01FF», я ожидаю, что вернусь «0A» где-нибудь в данных, которые я получаю обратно от UFDC-1.
Редактировать 3: Here - это захват линий SPI, поскольку я впервые отправляю инструкцию «получить точность» в UFDC-1. Синяя линия (вторая сверху) - MOSI, и она, безусловно, дает правильную команду (0x01FF). Если это работает правильно, UFDC-1 должен отвечать через MISO с «0A» (0b00001010), который является номером точности, в то же время, когда MOSI передает «FF». Вместо этого я получаю сообщение «1A» в то время, и я не считаю, что «A» на самом деле происходит из UFDC-1, но только из инструкции «set precision» (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...
Edit: Оказывается, проблема была с 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
Я не совсем понимаю ваш вопрос. Но я предполагаю, что вы ожидаете полученные данные в буфере, но не получаете его. Вы посмотрели на сигнал SPI в таблице данных UFDC-1? Я не знаю, как линия выбора микросхемы обрабатывается вашей функцией. Большинство интегральных микросхем SPI требуют от ведущего устройства сохранить выбранный чип для ответа на команду. – Thanushan
«Но я предполагаю, что вы ожидаете полученные данные в буфере, но не получаете его». Ага. Я уточню вопрос с разъяснением. «Большинство интегральных микросхем SPI требуют, чтобы ведущий держал выбранный чип для ответа на команду« Мой микроконтроллер, похоже, обрабатывает это автоматически, основываясь на захватах, которые я получил от осциллографа. Выбор подчиненного устройства, кажется, удерживается до тех пор, пока не будет отправлена вся команда. – Tagc
Получаете ли вы ответ от UFDC-1, глядя с объемом? Я думаю, что линия выбора чипа обрабатывается SSP_SendData() и SSP_ReceiveData. Но UFDC-1, возможно, захочет поддерживать низкую линию до тех пор, пока ответ не будет отправлен, т. Е. Не будет тянуть его высоко после записи инструкции, а затем потянуть его на низком уровне для получения данных (только угадать). – Thanushan