Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32: Свое тактирование SPI
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
xmailer
Подскажите пож-та, пытаюсь тактировать SPI по своему алгоритму:
1. настроил на таймере Output Compare на 1 секунду и режимом Toggle on match, на выходе получаю секундный меандр
2. соединил выход таймера с пином тактирования SPI, по идее теперь SPI должен сдвигать свой регистр с частотой в 1 секунду
3. пытаюсь передать 1 бит 01010100 в SPI и жду на выходе мигание светодиодом 3 раза с задержкой 1 секунда
----- проблема -------
1. диод мигает не с секундной задержкой, о несколько дольше.
2. передача повторяется циклично, т.е. передачей одного байта дело не заканчивается, он снова и снова передается, или просто зависает на MISO

Иллюстрация настроек и работы
gerber
Цитата(xmailer @ Oct 24 2016, 00:01) *
----- проблема -------
1. диод мигает не с секундной задержкой, о несколько дольше.

Светодиод будет (должен) мигать с периодом 4 секунды, 2 секунды светится, 2 секунды нет, так 3 раза. Затем пауза будет дольше, так как нулей в младших битах больше.
xmailer
Цитата(gerber @ Oct 25 2016, 16:17) *
Светодиод будет (должен) мигать с периодом 4 секунды, 2 секунды светится, 2 секунды нет, так 3 раза. Затем пауза будет дольше, так как нулей в младших битах больше.

Спасибо! Понял, принял, согласен.
Скажите, HAL_SPI_Transmit после успешной передачи должен очищает SPI->DR? у меня сейчас передаваемое значение зависает в SPI.
На другом форуме ребята говорили, что на некоторых камнях HAL_SPI_Transmit работает не корректно, рекомендовали пользоваться HAL_SPI_TransmitReceive.
Что нужно чтобы передать по SPI значение один раз?


gerber
Цитата(xmailer @ Oct 25 2016, 16:08) *
Скажите, HAL_SPI_Transmit после успешной передачи должен очищает SPI->DR? у меня сейчас передаваемое значение зависает в SPI.

Смотря что понимать под "очисткой" ...
Это не участок памяти, а функциональный регистр периферии, поэтому его поведение отличается от обычной памяти.
То, что вы в него записываете - прыгает в сдвиговый регистр и начинает передаваться на линию MOSI, при этом одновременно, такт за тактом, другим сдвиговым регистром, считывается значение с линии MISO. После того, как этот цикл завершен - считанное значение можно считать в том же самом регистре SPI->DR.
Перед записью в SPI->DR нужно убедиться, что он пуст, но НЕ в том смысле, что там ноль, а в том смысле, что предыдущая запись ушла в сдвиговый регистр. Для этого служит регистр статуса SPI->SR (бит TXE, Tx Empty).
Точно также - перед чтением нужно убедиться, что там что-то есть, то есть тактовый цикл на шине (8 или 16 тактов, как настроите) завершен. Для этого смотрим в тот же SPI->SR (бит RXNE, RX Not Empty).
Цитата(xmailer @ Oct 25 2016, 16:08) *
Что нужно чтобы передать по SPI значение один раз?

Убедиться, что передающий буфер пуст и записать в него один раз значение.
toweroff
Кстати, не факт, что там тот же самый регистр. Их может быть два - в один можно только записывать, из другого - только читать. А адрес - да, тот же самый

Цитата(gerber @ Oct 25 2016, 17:34) *
считанное значение можно считать в том же самом регистре SPI->DR.

xmailer
Парни, вижу что вы на форуме с опытом, просветите по созвучной с SPI темой (чтобы не плодить тем) - DMA в Periph и HAL, а именно не нашел в HAL аналога атрибуту DMA_InitStructure.DMA_Memory0BaseAddr, т.е. собственно DMA_Memory0BaseAddr задает ссылку на memory переменную и после разрешения DMA и SPI осуществляется передача (в примере ниже цикличная) данных из переменной в SPI->DR.
В HAL такой конкретной линковки с переменной нет, я правильно понимаю, что функцию линковки можно считать HAL_SPI_Transmit_DMA(&hspiX, (uint8_t *)&buffer, sizeof(buffer))?
Или дайте наводку на аналог DMA_PeripheralBaseAddr в HAL.
Спасибо.

в Periph:
Код
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.с = (uint_t)&buffer;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
...
пуск передачи
DMA_Cmd(DMA2_StreamX,ENABLE);
SPI_Cmd(SPIX, ENABLE);


в HAL:
Код
...
hdma_spiX_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spiX_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spiX_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spiX_tx.Init.Mode = DMA_CIRCULAR;
...
HAL_DMA_Init(&hdma_spi1_tx);
// линк
__HAL_LINKDMA(hspi,hdmatx,hdma_spiX_tx);
...
пуск передачи
__HAL_DMA_ENABLE(&hdma_spiX_tx);
__HAL_SPI_ENABLE(&hspiX);

RuSTA
На счет первого поста автора, как мне думается дело не в DR регистре SPI, а все таки в том что тактирование продолжается, попробуйте в таймер отключить после передачи 8 бит. И еще, впервые встречаю такую реализацию SPI, что в дальнейшем вы с ним хотите делать?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.