|
STM32F407 Проблемы с SPI, Не отсылается байт сразу после проверки бита ТХЕ в регистре SR |
|
|
|
Apr 21 2013, 05:50
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
Вот код: Код while ( ( (SPI2 -> SR) & 0x2 ) == RESET) { //wait until TXE bit is 1 } SPI2 -> DR = d0; когда этот код исполняется на чипе, или в дебаггере без брейкпоинтов то на осциллографе я только вижу SCK поднятый а MOSI на нуле. Но когда я исполняю этот код по очереди линию за линией в дебаггере, или же ставлю брейк поинт в дебаггере между циклом while и строчкой с записью в DR, а затем достигнув брейкпоинта опятй продолжаю исполнять код, то на осциллографе вижу переключение SCK и отсылку битов d0. в чем может быть проблема? Мне например кажется что SPI2 -> DR = d0; который сразу следует после цикла не дает возможности SPI контроллеру быстро среагировать и послать бит, а исполняя код строка за строкой все работает. но ведь с другой стороны, я же циклом проверяю бит ТХЕ!? и если я вышел с цикла то буфер свободен и должен бит нормально отослатся? (я пробовал тоже самое циклом проверять и бит BSY, тоже самое) есть идеи?
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
 |
Ответов
(45 - 59)
|
Apr 22 2013, 11:06
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
У меня хорошо работает такая инициализация: CODE void __inline init_SPI2(void) { SPI2->CR1 = (0 << SPI_CR1_SPE) | (0 << SPI_CR1_DFF) | (1 << SPI_CR1_SSM) | (1 << SPI_CR1_SSI) | (1 << SPI_CR1_MSTR) | (0 << SPI_CR1_BR);
SPI2->CR2 = (0 << SPI_CR2_RXNEIE) | (0 << SPI_CR2_TXDMAEN) | (1 << SPI_CR2_SSOE);
SPI2->CR1 = (1 << SPI_CR1_SPE) | (0 << SPI_CR1_DFF) | (1 << SPI_CR1_SSM) | (1 << SPI_CR1_SSI) | (1 << SPI_CR1_MSTR) | (0 << SPI_CR1_BR); } И такая отправка/прием Код BYTE sd_send_byte(const BYTE data) { BYTE spib; while((SPI2->SR & (1 << SPI_SR_TXE)) == 0); SPI2->DR = data; while((SPI2->SR & (1 << SPI_SR_RXNE)) == 0); spib = SPI2->DR; return spib; } Правда, битики я объявляю номером, а не маской...
Сообщение отредактировал IgorKossak - Apr 22 2013, 11:18
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Apr 22 2013, 12:28
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Я свои SPI в STM32F207 инициализировал так. Тактирование, естественно, задавал раньше, вместе с остальными устройствами. И больше не трогал. CODE /* SPI1 -- связь с SFM M25PE40 8-bit, MSB first, SPEn, Fpclk2 / 4 (15 MHz), Master, CPOL=0, CPHA=0 */ SPI1->CR1 = SPI_CR1_CPHA * 0 | // Clock Phase SPI_CR1_CPOL * 0 | // Clock Polarity SPI_CR1_MSTR * 1 | // Master Selection SPI_CR1_BR_0 * 1 | // Baud Rate Control - fpclk2 / 4 = 15 MHz SPI_CR1_BR_1 * 0 | // SPI_CR1_BR_2 * 0 | // SPI_CR1_SPE * 1 | // SPI Enable SPI_CR1_LSBFIRST * 0 | // Frame Format SPI_CR1_SSI * 1 | // Internal slave select SPI_CR1_SSM * 1 | // Software slave management SPI_CR1_RXONLY * 0 | // Receive only SPI_CR1_DFF * 0 | // Data Frame Format SPI_CR1_CRCNEXT * 0 | // Transmit CRC next SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable SPI1->CR2 = SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable SPI_CR2_SSOE * 0 | // SS Output Enable SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode SPI_CR2_ERRIE * 0 | // Error Interrupt Enable SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable // SPI1->CR1 |= SPI_CR1_MSTR | SPI_CR1_SPE; // Разрешить, Мастер /* SPI2 -- конфигурирование EP3C5 CONF_N (NSS) переключается программно */ SPI2->CR1 = SPI_CR1_CPHA * 0 | // Clock Phase SPI_CR1_CPOL * 0 | // Clock Polarity SPI_CR1_MSTR * 1 | // Master Selection SPI_CR1_BR_0 * 0 | // Baud Rate Control - fpclk1 / 2 = 15 MHz SPI_CR1_BR_1 * 0 | // SPI_CR1_BR_2 * 0 | // SPI_CR1_SPE * 1 | // SPI Enable (раньше включалось позже!) SPI_CR1_LSBFIRST * 1 | // Frame Format SPI_CR1_SSI * 1 | // Internal slave select (раньше задавалось!) SPI_CR1_SSM * 1 | // Software slave management SPI_CR1_RXONLY * 0 | // Receive only SPI_CR1_DFF * 0 | // Data Frame Format - 8 bit SPI_CR1_CRCNEXT * 0 | // Transmit CRC next SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable SPI2->CR2 = SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable SPI_CR2_SSOE * 0 | // SS Output Enable (все равно используется GPIO?) SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode SPI_CR2_ERRIE * 0 | // Error Interrupt Enable SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable // SPI2->CR1 |= SPI_CR1_SPE;
/* SPI3 -- регистр управления аналоговыми узлами 8-bit, MSB first, SPEn, Fpclk1 / 2 (15MHz), Master, CPOL=0, CPHA=0 74HC595 SCK - Pos, AD5314 SCK - Neg (изменить CPOL) */ SPI3->CR1 = SPI_CR1_CPHA * 0 | // Clock Phase SPI_CR1_CPOL * 0 | // Clock Polarity HC595 SPI_CR1_MSTR * 1 | // Master Selection SPI_CR1_BR_0 * 0 | // Baud Rate Control - fpclk1 / 2 = 15 MHz SPI_CR1_BR_1 * 0 | // SPI_CR1_BR_2 * 0 | // SPI_CR1_SPE * 1 | // SPI Enable SPI_CR1_LSBFIRST * 0 | // Frame Format SPI_CR1_SSI * 1 | // Internal slave select SPI_CR1_SSM * 1 | // Software slave management SPI_CR1_RXONLY * 0 | // Receive only SPI_CR1_DFF * 0 | // Data Frame Format (8 bit) SPI_CR1_CRCNEXT * 0 | // Transmit CRC next SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable SPI3->CR2 = SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable SPI_CR2_SSOE * 0 | // SS Output Enable SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode SPI_CR2_ERRIE * 0 | // Error Interrupt Enable SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable
|
|
|
|
|
Apr 22 2013, 21:04
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
Цитата(Golikov A. @ Apr 22 2013, 19:56)  в нем утверждается что если поставить SSM, чтобы устройство было мастером необходимо поставить и SSI, это будет двигать уровень NSS, тоже говорит и реф мануал... так это и я говорил вот в этом посте, ссылаясь на даташит: http://electronix.ru/forum/index.php?showt...t&p=1156434Цитата(Golikov A. @ Apr 22 2013, 20:28)  не понятно почему пауза перед записью в регистр помогала решить проблему... может все таки что-то схемное... да нет там ничего сложного в схеме, цепляю выводи к осциллографу и все. А плата стандартная дискавери. Golikov A. за линк спасибо, пройдусь по нему тоже. Genadi Zawidowski: использование только SSM без SSI проблему тоже не решало.
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Apr 23 2013, 04:26
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата(ViKo @ Apr 23 2013, 08:11)  Я так и не увидел ответа, что SPI не работал из-за того, что тактовая частота на модуль SPI подавалась непосредственно перед его использованием. потому что это не так. перед отправкой байта пробовали втыкать посылку по уарт явно больше 2 тактов шины после отправки ставили while(1) на случай если бит TXE ставиться с задержкой. пробовали ждать ТХЕ до отправки он в 1 и ситуация таже. нужна достаточно долгая пауза перед стартом, непонятно почему. Я ставлю на то что либо какие то клоки стабилизируются (не понятно почему тогда УАРТ работает), или что-то заряжается... вообщем ситуация странная о чем мы все и говорим...
|
|
|
|
|
Apr 23 2013, 07:41
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
Цитата(Golikov A. @ Apr 23 2013, 08:26)  нужна достаточно долгая пауза перед стартом, непонятно почему. Я ставлю на то что либо какие то клоки стабилизируются (не понятно почему тогда УАРТ работает), в этом посте: http://electronix.ru/forum/index.php?showt...t&p=1156458я как раз таки хотел сказать в пункте 1), что отправка байта с УАРТ тоже не сработала! пришлось поставить непрерывный цикл, и ждать команды от того же уарта (приема от него байта команды) который прерывает цикл, а дальше код исполняет ту процедуру с отправкой байта в СПИ. Цитата(Genadi Zawidowski @ Apr 23 2013, 10:16)  Если вход NSS перед началом передачи где-то около "0", то и не передаст. Если успел зарядиться - то прокатывает. Я "ставлю" на это. Я не думаю что это так, потомучто я сделал такой тест: Подключил к осциллографу не только SCK/MOSI, но еще и NSS. И включил передачю байта разумеется в режиме в котором у меня работает нормально, т.е. байт я вижу на осциллографе.. а вот НСС всегда нулевой! Даже не дернулся во время передачи! (хотя байт сам передался как надо я ето вижу на дисплее осциллографа) хотя это странно у меня же и SSM и SSI поставлены как 1...
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Apr 23 2013, 09:37
|
Местный
  
Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126

|
Детский сад... гадание пальцем на манной каше... Да не так это всё делается... по хорошему... Выкладывается проект со всеми настройками, по самому минимуму и без всяких излишеств... типа УАРТ и прочей хрени... когда ещё глюк "имеет место быть"...
|
|
|
|
|
Apr 23 2013, 10:11
|
Частый гость
 
Группа: Свой
Сообщений: 116
Регистрация: 2-03-07
Из: Украина
Пользователь №: 25 826

|
Цитата(ViKo @ Apr 23 2013, 12:41)  Имею Дискавери F4, Кейл. Могу проверить. И осциллограф - Agilent.  Вобщем, щас загрузил кусочек ТС к себе на плату (скопировал и вставил с первого поста) с STM405, все работает Не выложена инициализация портов. Так что, гдето в другом месте лажа. Прошу прощения не первый, а с настройкой SPI
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|