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

 
 
 
Reply to this topicStart new topic
> Про SPI STM32F405
Vladimir_T
сообщение Jun 30 2014, 17:24
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 517
Регистрация: 7-02-06
Пользователь №: 14 073



Уважаемые коллеги, посмотрите на этот код. Yужно обеспечить обмен по SPI (STM32F405 - Slave) между двумя МК. Поддержка обмена по прерываниям от SPI. Идея в том, чтобы к моменту прихода данных в приемник SPI, в передатчике уже есть ответ. Так все и работает, т.е. первым делом разрешается прерывание от флага TXE и в буфер передатчика передается первый байт ответа, затем прием и буфер приемника опустошается и вновь заполняется следующим байтом ответа. Но надежность этого кода низкая: почему-то при входе в прерывание иногда оба флага установлены и TXE, и RXNE. А ведь эти флаги должны, по моим убеждениям, работать в противофазе.
Если кто разбирался, подскажите.
CODE
/*****************************************************************************
SPI_Configuration ();
******************************************************************************/
void SPI2_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;

Config_SPI2_Pin ();
RCC_APB1PeriphResetCmd (RCC_APB1Periph_SPI2, DISABLE);
RCC_APB1PeriphClockCmd (RCC_APB1Periph_SPI2, ENABLE);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //Config SPI Protocol
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; //
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);
SPI_CalculateCRC(SPI2, DISABLE);
SPI_SSOutputCmd(SPI2, ENABLE);

Cnt_Tx = Cnt_Rx =0;
SPI_Protocol_Out.DD = AED_Answer_Prepare (Cmd_Power_ON);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);

} // SPI2_Configuration()

/*****************************************************************************
SPI1_IRQHandler ();
******************************************************************************/
__irq void SPI2_IRQHandler(void)
{
if (SPI2->SR & SPI_I2S_FLAG_TXE)
{
SPI2->DR = SPI_Protocol_Out.D08 [Cnt_Tx];

if (++Cnt_Tx == Cnt_Pack) Cnt_Tx = 0; // Clear Cnt
}

if (SPI2->SR & SPI_I2S_FLAG_RXNE)
{
SPI_Protocol_In.D08 [Cnt_Rx] = SPI2->DR;

if (++Cnt_Rx == Cnt_Pack)
{

if (CRC_16((u8 *)SPI_Protocol_In.D08, Cnt_Pack-2) == SPI_Protocol_In.DD.CRC16) pCtrl-> Link_SPI = True;
Cnt_Rx =0;
}
}

} // __irq SPI2_IRQHandler()


Сообщение отредактировал IgorKossak - Jul 1 2014, 07:49
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jul 1 2014, 09:53
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



У меня то же не вышло работать с обоими флагами. Использую только флаг приема, поскольку он то же выставляется после передачи байта.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 1 2014, 14:52
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



TXE, - передающий буфер пустой (TX empty)
RXNE, - приемный буфер не пустой (RX not empty)

ИМХО эти флаги должны выставляться одновременно.

Вы пихаете что-то в ТХ, и стираете RХ, как только TX уйдет, RX наполниться и оба флага должны появиться...

Есть возможно малюсенькая задержка между появлением RX и уходом данных из ТХ в которую вы иногда попадали...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 1 2014, 15:33
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Golikov A. @ Jul 1 2014, 17:52) *
Есть, возможно, малюсенькая задержка между появлением RX и уходом данных из ТХ
Задержка в половину бита. RXNE по идее должен выставляться на половину бита раньше - нога RX опрашивается в середине бита.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 1 2014, 16:29
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Golikov A. @ Jul 1 2014, 18:52) *
TXE, - передающий буфер пустой (TX empty)
RXNE, - приемный буфер не пустой (RX not empty)

ИМХО эти флаги должны выставляться одновременно.

Вы пихаете что-то в ТХ, и стираете RХ, как только TX уйдет, RX наполниться и оба флага должны появиться...

Есть возможно малюсенькая задержка между появлением RX и уходом данных из ТХ в которую вы иногда попадали...

Советую повнимательнее почитать документацию.
В начальный момент, когда нет передаваемых данных выставлен TXE.
Записываем в DR данные, TXE сбрасывается и через такт устанавливается, т.к. данные из буферного регистра копируются в передатчик и буферный регистр снова свободен. При этом RXNE установится только после приема первого байта причем в момент защелкивания последнего бита. Для побайтовой передачи считаю этот момент существенным. При непрерывной передаче RXNE появляется на один такт раньше, чем TXE. Картинки есть в UM.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 1 2014, 18:42
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а если как освободился TXE в передатчик подать байт?, при этом SPI slave, то после передачи первого байта если мастер не просит следующий, сколько флагов будет стоять?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 1 2014, 23:08
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Мастер в SPI не просит байты, он только выдаёт клоки. Сколько послал клоков, столько и будет передано байт.
Думаю проблемы у ТС в том, что он не учитывает, что при так написанной передаче как у него, в первом
SPI-кадре будет записано в DR на одно слово больше, чем принято. А в дальнейших SPI-кадрах, первым
будет передаваться слово, записанное в прошлом SPI-кадре. И всегда будет сдвиг на одно лишнее слово.

PS: Совет как всегда один - ТС, читай мануал!!!
Go to the top of the page
 
+Quote Post
Vladimir_T
сообщение Jul 2 2014, 16:57
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 517
Регистрация: 7-02-06
Пользователь №: 14 073



Цитата(jcxz @ Jul 2 2014, 03:08) *
Думаю проблемы у ТС в том, что он не учитывает, что при так написанной передаче как у него, в первом
SPI-кадре будет записано в DR на одно слово больше, чем принято. А в дальнейших SPI-кадрах, первым
будет передаваться слово, записанное в прошлом SPI-кадре. И всегда будет сдвиг на одно лишнее слово.


Я учитываю эти закономерности. Вот выдержка из RM0090.
The transmit sequence begins when the slave device receives the clock signal and the most
significant bit of the data on its MOSI pin. The remaining bits (the 7 bits in 8-bit data frame
format, and the 15 bits in 16-bit data frame format) are loaded into the shift-register. The
TXE flag in the SPI_SR register is set on the transfer of data from the Tx Buffer to the shift
register and an interrupt is generated if the TXEIE bit in the SPI_CR2 register is set.

Но прерывание от TXE формируется сразу, как только его разрешаю и таким образом в DR заносится первое слово текущего кадра. Когда завершен прием текущего кадра, то основная программа в DR записывает начало следующего кадра. Вроде все логично. Примерчик, что в начале поста, работает, но иногда появляется рассогласавание: количество переданных слов больше принятых.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 3 2014, 02:03
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Возможно у вас баг в той, части исходников что за пределами ISR. Например - в согласовании ISR и обработчика принятых байтов или источника байтов для передачи.
Go to the top of the page
 
+Quote Post
dac
сообщение Jul 3 2014, 02:41
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 600
Регистрация: 27-05-05
Пользователь №: 5 482



QUOTE (Vladimir_T @ Jul 2 2014, 22:57) *
но иногда появляется рассогласавание: количество переданных слов больше принятых.
а вы часом не в отладчике смотрите? а то там есть мелкая грабля - если отладчик считал данные с регистра раньше программы, флаг сбрасывается
Go to the top of the page
 
+Quote Post

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

 


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


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