#arm #embedded #stm32 #stm32f3
#arm #встроенный #stm32 #stm32f3
Вопрос:
Я работаю с платой STM32F3DISCOVERY и пытаюсь немного глубже погрузиться в абстракции HAL. Я создал простую версию функции, которая передает данные по SPI, к сожалению, она не работает (по крайней мере, ЦАП, на который я ее отправляю, не меняет состояние), и я не уверен, чего мне там не хватает. Возможно, в коде инициализации также есть что-то, что не работает с моей простой версией. Я был бы рад любым рекомендациям или ссылкам, которые я мог бы проверить. Спасибо!
#include <stm32f3xx_hal.h>
#define PINS_SPI GPIO_PIN_5 | GPIO_PIN_7
#define GPIO_PORT GPIOA
/* This is the simplest function I could come up with to do the transfer but I'm clearly missing something here */
uint8_t SPI_SendReceive(SPI_HandleTypeDef *hspi, uint8_t data) {
/* Loop while DR register in not empty */
while ((hspi->Instance->SR amp; SPI_FLAG_TXE) == RESET) {
}
/* Send data through the SPI1 peripheral */
hspi->Instance->DR = data;
/* Wait to receive data */
while ((hspi->Instance->SR amp; SPI_FLAG_RXNE) == RESET) {
}
return hspi->Instance->DR;
}
int main() {
HAL_Init();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
static SPI_HandleTypeDef spi = {.Instance = SPI1};
spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
spi.Init.Direction = SPI_DIRECTION_2LINES;
spi.Init.CLKPhase = SPI_PHASE_1EDGE;
spi.Init.CLKPolarity = SPI_POLARITY_LOW;
spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spi.Init.DataSize = SPI_DATASIZE_8BIT;
spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
spi.Init.NSS = SPI_NSS_HARD_OUTPUT;
spi.Init.TIMode = SPI_TIMODE_DISABLE;
spi.Init.Mode = SPI_MODE_MASTER;
HAL_SPI_Init(amp;spi);
__HAL_SPI_ENABLE(amp;spi);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = PINS_SPI;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, amp;GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOA, amp;GPIO_InitStruct);
/* TI 8564 DAC Settings */
uint8_t cmd1 = 0b00010000;
/* DAC output value (16-bit) */
uint16_t cmd23 = 0;
uint8_t cmd2 = cmd23 >> 8;
uint8_t cmd3 = cmd23 amp; 0xff;
uint8_t command[3] = {cmd1, cmd2, cmd3};
while (true) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
/* This does not work :( */
SPI_SendReceive(amp;spi, command[0]);
SPI_SendReceive(amp;spi, command[1]);
SPI_SendReceive(amp;spi, command[2]);
/* This works! When commenting in the lines above and commenting this out */
/* HAL_SPI_Transmit(amp;spi, command, 3, HAL_MAX_DELAY); */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(1000);
}
}
Комментарии:
1. Если
HAL_SPI_Transmit
работает, периферийное устройство инициализировано правильно, я бы проверил, чтоHAL_SPI_Transmit
делает, и различия сSPI_SendReceive
2. Вы не говорите, что именно не работает… Также вы передаете данные по SPI. Но к чему? Другая плата? Периферийное устройство?
3. Спасибо вам обоим за ваши комментарии! Я пытаюсь поговорить с ЦАП TI 8564 . Извините, что не разъяснил это. Прямо сейчас единственное, что я могу оценить, это изменение напряжения в ЦАП. Однако я попытаюсь получить доступ к логическому анализатору, а затем предоставить дополнительную информацию! Пока спасибо! @Jose Я проверил
HAL_SPI_Transmit
функцию, и она выполняет ужасно много вещей, которые могут быть обязательными, а могут и не быть. Я немного повозился с этим, пытаясь прокомментировать вещи, которые, как я думал, могут не понадобиться в моем случае, но в конце концов сдался : (4. Да, HAL довольно сложный, потому что он пытается поддерживать все возможные конфигурации и варианты использования. Однако в этом «ужасно большом количестве вещей» есть некоторые, которые являются обязательными… В частности, вы должны установить количество байтов, которые будут отправлены / получены, и запускать / останавливать SPI при каждой передаче. Справочное руководство по STM32 описывает, что вам нужно сделать.
5. Спасибо, @GuillaumePetitjean, я проверю справочное руководство и поищу, как только у меня появятся лучшие средства для отладки, а не просто обратная связь о включении / выключении!
Ответ №1:
Проверьте содержимое HAL_SPI_Init. Скорее всего, эта функция вызывает другую функцию, которая должна выполнять низкоуровневую инициализацию, и вы несете ответственность за предоставление этой функции самостоятельно. Чтобы сделать это более сложным, для этой предполагаемой второй функции уже определен «фиктивный» слабый псевдоним, поэтому набор инструментов не возвращает никакой ошибки, а просто создает код, неспособный что-либо сделать.