реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
Димон Безпарольн...
сообщение Jun 12 2016, 17:11
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Отладил на програмном 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);


Сообщение отредактировал Димон Безпарольный - Jun 12 2016, 17:14
Go to the top of the page
 
+Quote Post
Lagman
сообщение Jun 12 2016, 17:59
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



В вызове функции HAL_SPI_TransmitReceive порядок аргументов Tx и Rx перепутан поэтому передается Rx в котором 0. sm.gif
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Jun 12 2016, 18:10
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



И правда Ваша. Второй случай когда HAL заработал почти сразу. Спасибо.

Сообщение отредактировал Димон Безпарольный - Jun 12 2016, 18:28
Go to the top of the page
 
+Quote Post
Allregia
сообщение Jun 19 2016, 09:55
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Цитата(Димон Безпарольный @ 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 экономит еще микросекунду!)
Go to the top of the page
 
+Quote Post
AlanDrakes
сообщение Jun 19 2016, 10:30
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 101
Регистрация: 2-05-15
Из: Россия, Омск
Пользователь №: 86 474



Тогда уж что мешает сделать ещё оптимизацию?
Код
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, 10:34
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Jun 19 2016, 15:23
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(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 циклов.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jun 19 2016, 19:21
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
пошла упаковка. Чтоб ее в качель... И на 8 бит у меня передается... 16 циклов

Для отказа от упаковки при передаче запись данных должна идти в 8-битный регистр периферии. Ну написал же...
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Jun 19 2016, 19:40
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



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

Что - то я недопонял. Т.е. SPIx->DR. А какие еще варианты есть при работе с SPI? Этот регистр 16-битный...
Go to the top of the page
 
+Quote Post
Alechek
сообщение Jun 20 2016, 14:10
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



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

Такие, что запись по данному адресу должна быть 8-битной.
Т.е. *(uint8_t*)(&SPIx->DR) = char
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jun 20 2016, 20:52
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



*(volatile uint8_t*)(&SPIx->DR) = value_for_send

это при ручной передаче. При DMA поставьте 8 бит источник и 8 бит приемник для простоты.

Сообщение отредактировал Genadi Zawidowski - Jun 20 2016, 20:56
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 11:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01451 секунд с 7
ELECTRONIX ©2004-2016