Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32L476 HAL_SPI_TransmitReceive
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Димон Безпарольный
Отладил на програмном SPI общение с памятью SPI. Решил попробовать HAL.

Код
unsigned int VF016_SPI_RW(unsigned char Tx)    //
{    Tx = 0x55;                                //
    uint8_t Rx;
    HAL_SPI_TransmitReceive(&hspi1, &Rx, &Tx, 1, 0x1000);
    return (unsigned int)Rx;
}


В итоге на MOSI выдается постоянный 0, SCK выдает исправно 8 тактов. Интерфейс 8-битный.

Настройки HAL:

Код
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  HAL_SPI_Init(&hspi1);
Lagman
В вызове функции HAL_SPI_TransmitReceive порядок аргументов Tx и Rx перепутан поэтому передается Rx в котором 0. sm.gif
Димон Безпарольный
И правда Ваша. Второй случай когда HAL заработал почти сразу. Спасибо.
Allregia
Цитата(Димон Безпарольный @ Jun 12 2016, 19:10) *
И правда Ваша. Второй случай когда HAL заработал почти сразу. Спасибо.


SPI через HAL да, работает сразу, но мееедлееееннннооооо........

Особенно, с софтовым CS!

Если делать:
Код
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi1, (u8 *)&d, (u8 *)&d1,1,100);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);


то на F103 при 36Мгц это происходит 12 микросекунд при частоте SPI 4.5Mhz и 16-битной передаче.
Причем, после установки 0 на CS, проходит куча времени, потом корткая пачка импульсов, потом опять длиная пауpа переl снятием CS.

Если же сделать так:
Код
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
  hspi1.Instance->DR = d;
    while(__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_RXNE) == RESET);
    d = hspi1.Instance->DR;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);


то время передачи(от \_ до _/ на CS) уменьшается вдвое!

(да, можно конечно и управление CS заменить на прямое, вместо вызова халовской функции, но это практически ничего по скорости не дает, как ит замена HAL_SPI_GET_FLAG на прямое чтение флага. А вот замена hspi1.Instance->DR на SPI1->DR экономит еще микросекунду!)
AlanDrakes
Тогда уж что мешает сделать ещё оптимизацию?
Код
GPIOx->BSRR = GPIO_BSRR_BR0 // Допустим, 0-й пин - это /CS
SPIx->DR = DataToTransmit
while (!(SPIx->SR & SPI_SR_TXE)); // Ждём, пока буфер отправки не опустеет
while (SPIx->SR & SPI_SR_BSY); // Ждём окончания передачи
GPIOx->BSRR = GPIO_BSRR_BS0 // Поднимаем пин.

И... Ой, а где же собственно, HAL?

По поводу моего кода - явный костыль с парой флагов. Но если убрать один из них - слишком рано снимается /CS. Передаю по 8 бит, вероятно причина именно в этом. В данном случае не принимаю ответа от устройства.
Димон Безпарольный
Цитата(AlanDrakes @ Jun 19 2016, 13:30) *
Тогда уж что мешает сделать ещё оптимизацию?
Код
GPIOx->BSRR = GPIO_BSRR_BR0 // Допустим, 0-й пин - это /CS
SPIx->DR = DataToTransmit
while (!(SPIx->SR & SPI_SR_TXE)); // Ждём, пока буфер отправки не опустеет
while (SPIx->SR & SPI_SR_BSY); // Ждём окончания передачи
GPIOx->BSRR = GPIO_BSRR_BS0 // Поднимаем пин.

И... Ой, а где же собственно, HAL?

По поводу моего кода - явный костыль с парой флагов. Но если убрать один из них - слишком рано снимается /CS. Передаю по 8 бит, вероятно причина именно в этом. В данном случае не принимаю ответа от устройства.

Вот это как раз и был мой вариант. Прелести (у меня ) начались именно на 8 битах. 9-бит - все нормально передается через DMA. У меня дисплей Нокиа 1100 так работает. Но когда я прицепил память 25016 (8 бит передачи), пошла упаковка. Чтоб ее в качель... И на 8 бит у меня передается... 16 циклов. Плюнул пока разбираться, так на Хале и оставил. На Хале почему -то 8 циклов.
Genadi Zawidowski
Цитата
пошла упаковка. Чтоб ее в качель... И на 8 бит у меня передается... 16 циклов

Для отказа от упаковки при передаче запись данных должна идти в 8-битный регистр периферии. Ну написал же...
Димон Безпарольный
Цитата(Genadi Zawidowski @ Jun 19 2016, 22:21) *
Для отказа от упаковки при передаче запись данных должна идти в 8-битный регистр периферии. Ну написал же...

Что - то я недопонял. Т.е. SPIx->DR. А какие еще варианты есть при работе с SPI? Этот регистр 16-битный...
Alechek
Цитата(Димон Безпарольный @ Jun 20 2016, 00:40) *
Что - то я недопонял. Т.е. SPIx->DR. А какие еще варианты есть при работе с SPI? Этот регистр 16-битный...

Такие, что запись по данному адресу должна быть 8-битной.
Т.е. *(uint8_t*)(&SPIx->DR) = char
Genadi Zawidowski
*(volatile uint8_t*)(&SPIx->DR) = value_for_send

это при ручной передаче. При DMA поставьте 8 бит источник и 8 бит приемник для простоты.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.