Ruslan
26.05.2017
12:02:49
Serg
26.05.2017
12:07:02
STM32F2xx_StdPeriph_Lib_V1.1.0/Project/STM32F2xx_StdPeriph_Examples/SPI/SPI_TwoBoards/DataExchangeInterrupt/
Нет двунаправленности, там один только передает, другой только принимает:
void SPIx_IRQHANDLER(void)
{
#ifdef SPI_SLAVE
if (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_RXNE) == SET)
RxBuffer[Rx_Idx++] = SPI_I2S_ReceiveData(SPIx);
#endif
#ifdef SPI_MASTER
if (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_TXE) == SET)
{
if (CmdStatus == 0x00)
{
SPI_I2S_SendData(SPIx, CmdTransmitted);
CmdStatus = 0x01;
}
else
{
if (Tx_Idx < GetVar_NbrOfData())
{
SPI_I2S_SendData(SPIx, TxBuffer[Tx_Idx++]);
}
else
{
SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_TXE, DISABLE);
}
}
}
#endif /* SPI_SLAVE */
}
Дмитрий
26.05.2017
12:09:24
void SendData (uint8_t * data, size_t size)
{
for(size_t i = 0; i < size; i++)
{
SPI_I2S_SendData(FLASH_SPI, data[i]);
while( SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_TXE) != SET );
while( SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_RXNE) != SET );
SPI_I2S_ReceiveData(FLASH_SPI); // Считать данные в холостую
}
}
void ReceiveData (uint8_t * data, size_t size)
{
for(size_t i = 0; i < size; i++)
{
SPI_I2S_SendData(FLASH_SPI, 0x55); // Отправить данные в холостую
while( SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_TXE) != SET );
while( SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_RXNE) != SET );
data[i] = SPI_I2S_ReceiveData(FLASH_SPI);
}
}
Google
Serg
26.05.2017
12:10:00
где тут прерывания используются?
Konstantin
26.05.2017
12:10:02
Ruslan
26.05.2017
12:14:36
обычно эта экономия выходит геморроем
Дмитрий
26.05.2017
12:19:16
Danil
26.05.2017
13:45:18
Когда до реализации I2C без блокировки на прерываниях и очередью на отправку и приём дойдете, позовёте, ок?
metaclass
26.05.2017
13:46:15
а на stm32 с ней что-то сложное?
Danil
26.05.2017
13:48:20
А найти его реализацию не получилось, в итоге нужно еще будет, что то вроде менеджера сообщений
С I2c на прерываниях вообще как-то тихо, только с блокировкой, а такое на марс не отправишь
metaclass
26.05.2017
13:52:52
я для avr такое делал, всякие htu21 и bme280 опрашивать
надо будет на stm32 попробовать повторить
Danil
26.05.2017
13:54:34
Google
Danil
26.05.2017
13:55:57
Ruslan
26.05.2017
14:09:52
Danil
26.05.2017
14:25:27
стандартные страдания получение данных по запросу через SPI детектед.
Стандартное решение #1: дополнительный провод от слейва к мастеру для сигнала готовности данных.
Стандартное решение #2: опрос слейва после таймааута гарантированной готовности данных.
Стандартное решение #3: Поллинг слейва на предмет готовности данных.
Стандартный вариант #4: Использование другого интерфейса - I2C, UART etc.
SPI - это боль для двунаправленного обмена. Например SD карты в режиме SPI да и SDIO только поллингом
Danil
26.05.2017
14:27:13
Danil
26.05.2017
14:28:52
i2c на стм32ф1 серии имеет косяки для передачи 1 и 2 байт. все посылки что длиннее 2х байт аппаратно работают на ура. в ф0, ф3 и ф4 всё уже пофиксено и работает нормально
на ф1 с учетом особенностей тоже работает I2C вполне надежно - например часы, епром и датчик температуры на одной шине пашут и не тупят вполне
вообще на любых камнях нормально делать проверку на зависание и2ц по таймауту и ресетить шину ногодрыгом как описано в стандарте
т. к. зависают не только МК но и периферия вполне даже регулярно
Serg
26.05.2017
15:35:26
Danil
26.05.2017
15:37:15
Serg
26.05.2017
15:37:36
Danil
26.05.2017
15:38:02
Serg
26.05.2017
15:39:30
Danil
26.05.2017
15:39:58
Может я гоню
Serg
26.05.2017
15:41:49
Я правильно понимаю что после SPI_I2S_SendData сразу надо принять байт - SPI_I2S_ReceiveData(SPIx), или сработает прерывание SPI_I2S_IT_RXNE ?
Danil
26.05.2017
15:43:16
Сработает прерывание, в котором забираешь данные
Danil
26.05.2017
15:43:52
проблема с SPI в том, что нельзя спросить слейв и получить ответ просто так. SPI всегда одновременно передаёт и получает данные
Danil
26.05.2017
15:43:54
По моему в нете были примеры-с рабочим спиаем
Google
Danil
26.05.2017
15:44:18
т. е. в момент передачи запроса от мастера слейв уже должен отдавать что-то
СПИ в стм32 такой же простой как и в атмеге
просто больше фишечек, которые часто не нужны. аппаратный CRC, кстати, очень годная штука
Danil
26.05.2017
15:46:12
А мастер разве запрашивает данные? Он-же только включаем доступ-к устройству
Danil
26.05.2017
15:46:29
в СПИ есть один мастер- все остальные слейвы.
слейв спи устройство вообще ничего не может само
Danil
26.05.2017
15:47:54
А да мы клоком данные требуем,
Danil
26.05.2017
15:48:16
SPI хорош для потоковой передачи данных на высокой скорости
но адресация только отдельными линиями CS
мультимастер на СПИ почти нереалезуем без корявых костылей
Danil
26.05.2017
15:50:27
Ну вообщем тот вариант, с прерываниями должен был-работать нормально
Только там данные либо забрал либо отправил и только в след прерывании остальное
Опять не так выразился, прощу прощения, вы все говорите верно
С точки зрения программиста нужно только ждать когда выставится флаг принятых данных
Правильно?
Danil
26.05.2017
15:56:40
в каждый момент времени СПИ работает либо мастером либо слейвом. Прерывания вызываются соответствующие. У мастера ТХЕ - передача окончена, буфер пуст. у слейва RXC (или как то так) - прием окончен, байт в буфере
есть ещё прерывания по ошибке CRC если используется аппаратный
Google
Danil
26.05.2017
15:58:37
есть прерывание что буфер полон, но у стм32 есть шэдоу буфер. т. е. можно писать следующий байт пока предыдущий еще передаётся и читать прошлый пока принимается новый
Danil
26.05.2017
15:58:57
Serg
26.05.2017
15:59:44
Мне одновременно и не надо, надо запрос - ответ
Danil
26.05.2017
16:00:07
Serg
26.05.2017
16:00:24
не на прерываниях у меня и так есть, работает
Danil
26.05.2017
16:01:07
Тебе может и не нужно, а мне любопытно стало
Danil
26.05.2017
16:02:55
всегда, когда передаётся байт, в приемный буфер считывается байт с линии. его можно считать, но не обязательно вроде - но я точно не помню уже
Danil
26.05.2017
16:02:58
Danil
26.05.2017
16:03:17
в режиме слейва не обязательно грузить байт на отправку мастеру
Danil
26.05.2017
16:03:23
Danil
26.05.2017
16:04:34
в примерах от стм все есть - поллинг, прерывания и ДМА
Danil
26.05.2017
16:04:59
Serg
26.05.2017
16:05:51
получается в момент отправки надо после отправки каждого байта также принимать байт и игнорировать его, пока весь пакет запроса не отправится?
Danil
26.05.2017
16:06:29
Danil
26.05.2017
16:07:33
поллинг это опрос флага в бесконечном цикле
Danil
26.05.2017
16:07:49
Danil
26.05.2017
16:07:54
самый тупой вариант, но всегда рабочий
Danil
26.05.2017
16:08:19
Google
Danil
26.05.2017
16:09:52
вот не факт. часто прерыввния разрешены только ОС. А все пользовательские процессы работают через её АПИ/ХАЛ и там тупление в цикле в ожидании флага вообще нормальная практика
Danil
26.05.2017
16:09:58
Serg
26.05.2017
16:10:27
Danil
26.05.2017
16:11:01
разделение ресурсов и процессорного времени и есть основная задача РТОСа
Danil
26.05.2017
16:11:08
Serg
26.05.2017
16:11:59
Данила с Данилом, я запутался в вас :)
Danil
26.05.2017
16:12:14
То есть вместо цикла ожидания вы прямо говорите мк, позовешь, когда будешь готов продолжить
Давайте разберемся, что у вас есть и что хотите
Ифдеф убираем, на пару с ендифом
Cmdstatus и его тело
Хоть телеграмм на комп ставь :/
Serg
26.05.2017
16:20:38
вот это не работает,отправляет какую то ересь:
void SPI1_IRQHandler()
{
if (SPI_I2S_GetITStatus(SPI1, SPI_IT_RXNE) == SET)
{
uint8_t x = (uint8_t)SPI_I2S_ReceiveData(SPI1);
fifo_put(&_rxFifo, x));
}
if (SPI_I2S_GetITStatus(SPI1, SPI_IT_TXE) == SET)
{
if (!fifo_empty(&_txFifo))
{
uint8_t x = fifo_get(&_txFifo);
SPI_SendData(SPI1, x);
}
else
SPI_I2S_ITConfig(SPI1, SPI_IT_TXE, DISABLE);
}
}
стою отладчиков, на SPI_SendData(SPI1, x)
передается правильная последовательность из пяти байт - 0x47 0x01 0x00 0x10 0x83
Danil
26.05.2017
16:22:44
ну нормально всё вроде, только нахуя сразу писать код и мастера и слэйва?
Danil
26.05.2017
16:23:22
Serg
26.05.2017
16:23:40
так это мастер отсылает запрос слейву и должен получить от него ответ
так, передается от STM32 правильная последовательность
Danil
26.05.2017
16:24:30