Как исправить Chip Select Timing для SPI на STM32F3? - PullRequest
2 голосов
/ 08 апреля 2019

Я работаю над проектом с STM32F303RE, который требует полнодуплексного SPI, и я использую библиотеку HAL, предоставленную STM. Хотя все линии работают с точки зрения SCK, MOSI и MISO, я заметил, что линия выбора микросхемы снижается намного дольше, чем необходимо, и, похоже, срабатывает около 20 кГц, в отличие от 2 МГц SPI. Это проблема, так как ведомое устройство, которое я использую, запускает с линии CS, и во время нескольких вызовов SPI данные становятся поврежденными. Как я могу исправить время?

В настоящее время я использую ручной GPIO, который просто устанавливает низкий / высокий уровень до и после вызова SPI. Из чтения в режиме онлайн кажется, что вывод CS является источником проблем для довольно многих людей, поскольку есть также возможность использовать аппаратный сигнал NSS, хотя люди рекомендуют против этого, поскольку он не работает должным образом.

// Set SS pin low to activate
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);

// Read Temp
if(HAL_SPI_TransmitReceive(&hspi2, (uint8_t*)&master_buffer_tx[4], (uint8_t*)&master_buffer_rx[4], 1, 1000)!=HAL_OK){
      Error_Handler();
}

// Check finished
while(HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY){
}

// Set SS pin high to deactivate
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);

HAL_Delay(10);

Я бы ожидал, что уровень CS снизится примерно на половину цикла до SCK и аналогично после. Вот возможные идеи, которые у меня были: вызывает ли проблема строка «Проверка завершена»? Это могут быть мои настройки часов? Должен ли используемый мной вывод GPIO быть таким же, как там, где будет NSS? Должен ли я использовать аппаратный NSS? Нужно ли использовать прерывания и DMA?

Извините, если что-то из этого кажется наивным, так как я все еще работаю над пониманием микроконтроллера. Спасибо!

Время CS и SCK

1 Ответ

1 голос
/ 19 мая 2019

Я думаю, что могу объяснить задержку между активацией CS и передачей SPI: если вы посмотрите внутрь HAL_SPI_TransmitReceive(), вы увидите, что на самом деле для настройки и запуска фактической передачи SPI требуется много операций.В зависимости от конфигурации часов это может занять несколько микросекунд (см. Также этот вопрос ).

Я немного озадачен задержкой после передачи SPI, пока CS не будет отменен.Код HAL должен требовать гораздо меньше операций для завершения передачи по сравнению с подготовкой передачи.Код «Проверка завершен» также не должен иметь много циклов, поскольку он фактически проверяет только программный флаг (даже не аппаратный регистр).Однако в вызове нет необходимости, поскольку HAL_SPI_TransmitReceive() является функцией блокировки, которая возвращается только после завершения передачи SPI.

Что касается вашей проблемы, я хотел бы порекомендовать использовать аппаратную функцию NSS.Но, подумав, это подтверждает CS, как только модуль SPI включен.Кажется, что ST HAL не отключает модуль SPI после каждой передачи, так что это не будет работать, как предполагалось.

Я думаю, что вам необходимо проанализировать, что происходит внутри HAL между фактической передачей SPI и отменой утверждения CS.Это не похоже на нормальное поведение.Нет необходимости использовать прерывания или DMA для улучшения поведения CS.Эти функции загружаются с процессора, но требуют более сложного кода, который может не улучшить задержку CS.

...