Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F407 Проблемы с SPI
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
BlackOps
Цитата(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 проблему тоже не решало.
ViKo
Я так и не увидел ответа, что SPI не работал из-за того, что тактовая частота на модуль SPI подавалась непосредственно перед его использованием.
Golikov A.
Цитата(ViKo @ Apr 23 2013, 08:11) *
Я так и не увидел ответа, что SPI не работал из-за того, что тактовая частота на модуль SPI подавалась непосредственно перед его использованием.


потому что это не так.

перед отправкой байта пробовали втыкать посылку по уарт явно больше 2 тактов шины
после отправки ставили while(1) на случай если бит TXE ставиться с задержкой.
пробовали ждать ТХЕ до отправки он в 1 и ситуация таже.

нужна достаточно долгая пауза перед стартом, непонятно почему. Я ставлю на то что либо какие то клоки стабилизируются (не понятно почему тогда УАРТ работает), или что-то заряжается... вообщем ситуация странная о чем мы все и говорим...



Genadi Zawidowski
Если вход NSS перед началом передачи где-то около "0", то и не передаст. Если успел зарядиться - то прокатывает. Я "ставлю" на это.
BlackOps
Цитата(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...


Genadi Zawidowski
Нет желания подтянуть к "1" вывод NSS? ИЛи поиграться отключением его от вывода процессора?
HHIMERA
Детский сад... гадание пальцем на манной каше... biggrin.gif
Да не так это всё делается... по хорошему...
Выкладывается проект со всеми настройками, по самому минимуму и без всяких излишеств... типа УАРТ и прочей хрени... когда ещё глюк "имеет место быть"...
ViKo
Цитата(HHIMERA @ Apr 23 2013, 12:37) *
Выкладывается проект со всеми настройками, по самому минимуму и без всяких излишеств...

+1.
Имею Дискавери F4, Кейл. Могу проверить. И осциллограф - Agilent. sm.gif
Tolyaha
Цитата(ViKo @ Apr 23 2013, 12:41) *
Имею Дискавери F4, Кейл. Могу проверить. И осциллограф - Agilent. sm.gif

Вобщем, щас загрузил кусочек ТС к себе на плату (скопировал и вставил с первого поста) с STM405, все работает
Не выложена инициализация портов.
Так что, гдето в другом месте лажа.
Прошу прощения не первый, а с настройкой SPI
HHIMERA
Цитата(Tolyaha @ Apr 23 2013, 13:11) *
Не выложена инициализация портов.

Ага... и в итоге окажется, что ноги настроены open-drain и Low Speed... laughing.gif
Genadi Zawidowski
Цитата
Детский сад... гадание пальцем на манной каше...

А что ещё делать с неполной информацией?
Golikov A.
написать что типа в мануале все верно, а все дураки...

кстати про ноги хорошая идея, они настроены на правильную частоту работы то?
НСС - сам не должен прыгать , в режиме когда SSM в 1, SSI им управляет, вы задаете значение SSI, а NSS реагирует, вроде как...
BlackOps
Короче,чтобы начать плностью с нуля, пошел взял новую плату Дискавери, девственную, вскрыл упаковку подключил только ноги PB13,PB14 к осциллографу.

Переписал новый проект, выкинул все, оставил только SPI2 работающий на:
PB12 - NSS
PB13 - SCK
PB14 - MISO (не использую в тесте)
PB15 - MOSI

Проект прикреплен к сообщению.

Загружаю простой код.. и работает сразу... Не нужно теперь очень долгую задержку ставить.
Новый тестовый проект скопирован из старого, только часть SPI2 и все.

Значит в старом проекте проблема усугублялась тем чтоподключены и другие устройства к порту были (PWM - просто вывод напины,I2C1 - подключены 2 сенсора)
Я не думаю хотя что в старой плате дискавери был дефект, т.к. тогда не рабтало бы вообще. Сорее всего проблемабыла с включением нескольких периферий на одном порту сразу, другого ничего не может быть.


Вот что я отработал в новом проекте:

1) SSM=0,SSI=0
Включил, естессвтенно не сработало

2) SSM=0,SSI=0, Подтянул 1 к выводу NSS (PB12) как посоветовали.
Сработало, сразу после включения вижу байт на осциллографе

3) SSM=1,SSI=1, ничего не подтянуто к NSS
Сработало тоже, сразу после включения вижу байт на осциллографе


Прикрепленный проект содержит конфигурацию №3


Теперь у меня вопрос по конфигурации №3: Почему после и во время того как я увидел свой байт на осциллографе NSS (PB12) ни разу не поднялся на уровень "1"?
Ведь у меня же стоит SSM=1,SSI=1... Почему NSS не равен "1" на ножке PB12?
Проверяю тестером и осциллографом, он всегда 0
Пробовал включать SSOE в регистре СR2 всеравно пин NSS всегда 0





Да, я вижу вы говорили про настройки ног, вот как настроены они был для порта B в старом проекте:
(К данному прикрепленному тестовому проекту отношения не имеет!!, NSS и MISO были закомментированы позже)

CODE
//=============================================================================
// GPIOB configuration
//=============================================================================

// enable GPIOB clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;

// Alternate Function
GPIOB->MODER = 0; // clear moder register
GPIOB->MODER |=
(
//GPIO_MODER_MODER12_1 | // Alternate Function, SPI2 NSS
GPIO_MODER_MODER13_1 | // Alternate Function, SPI2 SCK
//GPIO_MODER_MODER14_1 | // Alternate Function, SPI2 MISO
GPIO_MODER_MODER15_1 | // Alternate Function, SPI2 MOSI

GPIO_MODER_MODER9_1 | // Alternate Function, I2C1, SDA
GPIO_MODER_MODER8_1 | // Alternate Function, I2C1, SCL

GPIO_MODER_MODER4_1 | // AF, PWM_OUT1, TIM3_CH1
GPIO_MODER_MODER5_1 | // AF, PWM_OUT2, TIM3_CH2
GPIO_MODER_MODER0_1 | // AF, PWM_OUT3, TIM3_CH3
GPIO_MODER_MODER1_1 | // AF, PWM_OUT4, TIM3_CH4
GPIO_MODER_MODER6_1 | // AF, PWM_IN5, TIM4_CH1
GPIO_MODER_MODER7_1 // AF, PWM_IN6, TIM4_CH2
);

// Output type
GPIOB->OTYPER = 0; // clear otype register
GPIOB->OTYPER |= // push-pull if 0
(
GPIO_OTYPER_OT_8 | // Open-Drain, I2C1, SCL
GPIO_OTYPER_OT_9 // OPen-Drain, I2C1, SDA
);

// Speed type
GPIOB->OSPEEDR = 0; // clear ospeedr register
GPIOB->OSPEEDR |=
(
//GPIO_OSPEEDER_OSPEEDR12_1 | // SPI2 NSS 50MH
GPIO_OSPEEDER_OSPEEDR13_1 | // SPI2 SCK, 50MHz
//GPIO_OSPEEDER_OSPEEDR14_1 | // SPI2 MISO 50MH
GPIO_OSPEEDER_OSPEEDR15_1 | // SPI2 MOSI 50MH

GPIO_OSPEEDER_OSPEEDR4_1 | // PWM_OUT1, TIM3_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR5_1 | // PWM_OUT2, TIM3_CH2, 50MHz
GPIO_OSPEEDER_OSPEEDR0_1 | // PWM_OUT3, TIM3_CH3, 50MHz
GPIO_OSPEEDER_OSPEEDR1_1 | // PWM_OUT4, TIM3_CH4, 50MHz
GPIO_OSPEEDER_OSPEEDR6_1 | // PWM_IN5, TIM4_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR7_1 // PWM_IN6, TIM4_CH2, 50MHz
);

// Push/Pull
GPIOB->PUPDR = 0; // clear pupdr register
GPIOB->PUPDR |=
(
GPIO_PUPDR_PUPDR8_0 | // Pull-Up, I2C1, SCL
GPIO_PUPDR_PUPDR9_0 | // Pull-Up, I2C1, SDA
GPIO_PUPDR_PUPDR4_0 | // Pull-Up, PWM_OUT1, TIM3_CH1
GPIO_PUPDR_PUPDR5_0 | // Pull-Up, PWM_OUT2, TIM3_CH2
GPIO_PUPDR_PUPDR0_0 | // Pull-Up, PWM_OUT3, TIM3_CH3
GPIO_PUPDR_PUPDR1_0 | // Pull-Up, PWM_OUT4, TIM3_CH4
GPIO_PUPDR_PUPDR6_0 | // Pull-Up, PWM_IN5, TIM4_CH1
GPIO_PUPDR_PUPDR7_0 // Pull-Up, PWM_IN6, TIM4_CH2
);


// Alternate Function pins
GPIOB->AFR[1] = 0; // clear AFR_H register
GPIOB->AFR[1] |=
(
(4 << ((8 - 8) << 2)) | // I2C1 SCL, AF4
(4 << ((9 - 8) << 2)) | // I2C1 SDA, AF4

//(5 << ((12 - 8) << 2)) | // SPI2 NSS, AF5
(5 << ((13 - 8) << 2)) | // SPI2 SCK, AF5
//(5 << ((14 - 8) << 2)) | // SPI2 MISO, AF5
(5 << ((15 - 8) << 2)) // SPI2 MOSI, AF5

);

GPIOB->AFR[0] = 0; // clear AFR_L register
GPIOB->AFR[0] |=
(
(2 << ((4 - 0) << 2)) | // PWM_OUT1, TIM3_CH1, AF2
(2 << ((5 - 0) << 2)) | // PWM_OUT2, TIM3_CH2, AF2
(2 << ((0 - 0) << 2)) | // PWM_OUT3, TIM3_CH3, AF2
(2 << ((1 - 0) << 2)) | // PWM_OUT4, TIM3_CH4, AF2
(2 << ((6 - 0) << 2)) | // TIM4_CH1, AF2
(2 << ((7 - 0) << 2)) // TIM4_CH2, AF2
);
Golikov A.
а где варианта
SSM =1, SSI = 0?

вроде как инструкция об этом говорит. SSM = 1, SSI - задает состояние NSS, или нет?

еще вот такая приписка

Когда NSS разрешено работать в качестве выхода (SSM = 0, SSOE = 1), эта конфигурация используется только в режиме Master. Когда ведущее устройство начинает соединение, NSS переводится в состояние низкого уровня, и поддерживается в этом состоянии до момента деактивации модуля SPI.


и остается теперь потихоньку добавлять периферию прошлого проекта и смотреть какой модуль убъет СПИsm.gif
BlackOps
Цитата(Golikov A. @ Apr 24 2013, 08:41) *
Когда NSS разрешено работать в качестве выхода (SSM = 0, SSOE = 1), эта конфигурация используется только в режиме Master. Когда ведущее устройство начинает соединение, NSS переводится в состояние низкого уровня, и поддерживается в этом состоянии до момента деактивации модуля SPI.

Попробовал этот вариант тоже. Тогда байт не передается, мне нужно вручную проводом подтянуть NSS к "1" чтобы заработало (ну и тогда естесственно NSS никогда на ноль естесственно не подтягивается стоит как 1 всегда, даже когда выключаю модуль)


Цитата(Golikov A. @ Apr 24 2013, 08:41) *
а где варианта
SSM =1, SSI = 0?

Тогда вообще не работает.

Простенькй проект прикрепил (работающий: SSM=1,SSI=1,SSOE=0) если хотите можете проверить.
adnega
Цитата(BlackOps @ Apr 24 2013, 08:13) *
Простенькй проект прикрепил (работающий: SSM=1,SSI=1,SSOE=0) если хотите можете проверить.

А зачем SSOE=0?
BlackOps
затем что с ним не работает как надо!
SSM = 0, SSOE = 1
"Попробовал этот вариант тоже. Тогда байт не передается, мне нужно вручную проводом подтянуть NSS к "1" чтобы заработало (ну и тогда естесственно NSS никогда на ноль естесственно не подтягивается стоит как 1 всегда, даже когда выключаю модуль)"
adnega
Цитата(BlackOps @ Apr 24 2013, 08:51) *
затем что с ним не работает как надо!

А вариант: SSM=1, SSI=1, SSOE=1, NSS управляется через GPIO чем-то не устраивает?
BlackOps
Я не пойму немного, разве целью установки SSOE=1 не является автоматическое управление пином NSS?
т.е.сделать так, чтобы этот пин сам подтягивался на 0 во время транзакции и возвращался на 1 когда транзакция закончена?
как можно достичь такoго поведения?


И еще, вы говорите SSOE=1 и управляй пином NSS через GPIO.. но ведь пин PB12 (NSS) настроен как Alternate Function... ?


(тестовыйпроект выложен в этом посте если что: http://electronix.ru/forum/index.php?showt...&p=1157091)
Golikov A.
SSM=1, SSI = 0 - тут пин NSS в 1 вроде должен быть, передавать нельзя до момента SSI = 1, который как раз пин NSS переведет в 0. Я вроде так понял мануал...
adnega
Цитата(BlackOps @ Apr 24 2013, 09:05) *
И еще, вы говорите SSOE=1 и управляй пином NSS через GPIO.. но ведь пин PB12 (NSS) настроен как Alternate Function... ?

Никто не мешает изменить его на OUT_PP.
Вообще разные бывают случаи и управлять NSS "автоматом" можно только в простейших из них.
Например, при инициализации SD карт по SPI вначале нужно передать 0xFF 74 раза при NSS=1.
BlackOps
Цитата(adnega @ Apr 24 2013, 11:22) *
Никто не мешает изменить его на OUT_PP.
Вообще разные бывают случаи и управлять NSS "автоматом" можно только в простейших из них.
Например, при инициализации SD карт по SPI вначале нужно передать 0xFF 74 раза при NSS=1.


Ну вобщем сейчас я поменял NSS на General Purpose Pin, и захотел чтобы этот пин был 0 во время транзакции и 1 когда нет транзакции.
решил установить его в начале 1, затем перед транзакцией на 0, потом проверить биты TXE и BSY а затем опять выставить в 1.

Проблема была в том, что TXE и BSY видимо выставляются почти сразу после того как сдвиговый регистр загружен, и если после этого выставлять пин на 1 то получается слишком рано, чуть ли не у начала реальной транзакции ( а не в конце).

поетому поставил небольшой цикл for, чтобы отрегулировать задержку.

короче, сейчас работает вобщемто так как я хочу, но ставить задержку на GPIO SS пин чтобы подогнать его так чтобы он был 0 только во время транзакции это просто уродство какоето, неужели просто нету более красивого или эффективного решения?

для справки, мне надо чтобы этот SS (NSS) пин вел себя как сигнал LE вот на этой диаграмме:
http://i.imgur.com/EV9flrf.jpg

вот еще такое решение, проверка RXNE, чтение DR затем проверка BSY, затем уже поднять вручную пин на 1

CODE
GPIOB->ODR |= GPIO_ODR_ODR_12;

//////////////// SPI2 Communication Routine ///////////////////////////////////
while ( ( (SPI2 -> SR) & SPI_SR_TXE ) == RESET)
{
// wait until TXE bit is 1
}
GPIOB->ODR &= !GPIO_ODR_ODR_12;

SPI2 -> DR = d0;


while ( //( ( (SPI2 -> SR) & SPI_SR_TXE ) == RESET) &&
(( (SPI2 -> SR) & SPI_SR_RXNE ) == RESET) )
{

}

dd = SPI2->DR;


while ( //( ( (SPI2 -> SR) & SPI_SR_TXE ) == RESET) &&
(( (SPI2 -> SR) & SPI_SR_BSY ) == SET) )
{

}


GPIOB->ODR |= GPIO_ODR_ODR_12;


так более красиво как то (не нужно циклы вставлять..)
HHIMERA
Всё это, конечно... очень интересно... rolleyes.gif
"А был ли мальчик?"(С)
А глюк то... где??? Неужто самоликвидировался???
Genadi Zawidowski
Цитата
поетому поставил небольшой цикл for, чтобы отрегулировать задержку

Смотрим мой кусочек кода и копируем оттуда ожидание ПРИЁМА - после этого точно байт/слово передался. с задержками это опять магия потребуется.
Golikov A.
Цитата(HHIMERA @ Apr 24 2013, 15:44) *
Всё это, конечно... очень интересно... rolleyes.gif
"А был ли мальчик?"(С)
А глюк то... где??? Неужто самоликвидировался???


если коротко ТС взял другую плату дискавери, и залил туда проект с одним лишь СПИ, без прочей периферии, и глюк пропал.

Предложение по одному добавлять остальную периферию и найти какой модуль рушит СПИ одобрения не встретило. Потому до конца не ясно что же является причиной плата или остальная периферия.
BlackOps
Пишу с опозданием надобыло кое какие проекты сдавать и платы делать.

Во первых я не заявлял что нашел глюк, тема четко говорит "проблемы с СПИ", а проблемы могут быть по разым причинам, в том числе и по причине моей ошибки.

Сделал вот что:

1) После того как убедился что на новой голой плате проект СПИ заработал, я переписал старый проект по новому, и прогнал его тоже на новой плате - Заработало.

2) Старую платуполностью отсоеденил от всего что было соеденено, прогнал тот же епределанный проект - Заработало.

3) Начал присоеденять по очереди остальную перферию - Заработало с присоединенной всей периферией (Uart,PWM,I2C)

4) После того как СПИ проект с подсоединенной но не активизированной программно периферией заработал, я ее начал по очереди активизировать, в итоге проект был доведен до "оригиального" состояния, и тоже заработал

под "заработал" я имею ввиду что сразу при включении не надо долго ждать и я вижу свои байты на осциллографе.


Единственное что я заметил в результате всего этого это задержка SCK на примерно 1500нс когда все нижеприведенные функции не заккоментированны.
Когда закомментированны две последние функции включения i2c и usart3 то задержка подтянутого SCK не более 400нс
Когда закомментирован только usart3 то задержка SCk перед его переключением и посылкой байта 900нс
Когда все нижеприведенные функции включены (не закомментированны) то задержка SCK перед его переключением и посылкой байта 1500нс

При этом: Если включить всеэти функции (не комментировать их) и включить цикл задержки длинной после включения платы, а потом подать через тот же Usart3 команду на посылку байта по SPI, то байт отсылается сразу и SCK не задерживается (сразу начинает пиерелючатся)

Вот моя последовательность включения программно периферии:
Код
config_gpio_all(); // configure all GPIOs
config_pwm_io(); // configure Input and Output PWM channels
config_spi_all(); // config all peripherals using SPI
config_i2c_all(); // config all peripherals using I2C
config_usart3(); // configure USART3


А вот код каждой функции:
CODE

uint32_t config_gpio_all(void)
{

//=============================================================================
// GPIOB configuration
//=============================================================================

// enable GPIOB clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;

// Alternate Function
GPIOB->MODER = 0; // clear moder register
GPIOB->MODER |=
(
GPIO_MODER_MODER12_1 | // Alternate Function, SPI2 NSS
GPIO_MODER_MODER13_1 | // Alternate Function, SPI2 SCK
GPIO_MODER_MODER14_1 | // Alternate Function, SPI2 MISO
GPIO_MODER_MODER15_1 | // Alternate Function, SPI2 MOSI

GPIO_MODER_MODER9_1 | // Alternate Function, I2C1, SDA
GPIO_MODER_MODER8_1 | // Alternate Function, I2C1, SCL

GPIO_MODER_MODER4_1 | // AF, PWM_OUT1, TIM3_CH1
GPIO_MODER_MODER5_1 | // AF, PWM_OUT2, TIM3_CH2
GPIO_MODER_MODER0_1 | // AF, PWM_OUT3, TIM3_CH3
GPIO_MODER_MODER1_1 | // AF, PWM_OUT4, TIM3_CH4
GPIO_MODER_MODER6_1 | // AF, PWM_IN5, TIM4_CH1
GPIO_MODER_MODER7_1 // AF, PWM_IN6, TIM4_CH2
);

// Output type
GPIOB->OTYPER = 0; // clear otype register
GPIOB->OTYPER |= // push-pull if 0
(
GPIO_OTYPER_OT_8 | // Open-Drain, I2C1, SCL
GPIO_OTYPER_OT_9 // OPen-Drain, I2C1, SDA
);

// Speed type
GPIOB->OSPEEDR = 0; // clear ospeedr register
GPIOB->OSPEEDR |=
(
GPIO_OSPEEDER_OSPEEDR12_1 | // SPI2 NSS 50MH
GPIO_OSPEEDER_OSPEEDR13_1 | // SPI2 SCK, 50MHz
GPIO_OSPEEDER_OSPEEDR14_1 | // SPI2 MISO 50MH
GPIO_OSPEEDER_OSPEEDR15_1 | // SPI2 MOSI 50MH

GPIO_OSPEEDER_OSPEEDR4_1 | // PWM_OUT1, TIM3_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR5_1 | // PWM_OUT2, TIM3_CH2, 50MHz
GPIO_OSPEEDER_OSPEEDR0_1 | // PWM_OUT3, TIM3_CH3, 50MHz
GPIO_OSPEEDER_OSPEEDR1_1 | // PWM_OUT4, TIM3_CH4, 50MHz
GPIO_OSPEEDER_OSPEEDR6_1 | // PWM_IN5, TIM4_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR7_1 // PWM_IN6, TIM4_CH2, 50MHz
);

// Push/Pull
GPIOB->PUPDR = 0; // clear pupdr register
GPIOB->PUPDR |=
(
GPIO_PUPDR_PUPDR8_0 | // Pull-Up, I2C1, SCL
GPIO_PUPDR_PUPDR9_0 | // Pull-Up, I2C1, SDA
GPIO_PUPDR_PUPDR4_0 | // Pull-Up, PWM_OUT1, TIM3_CH1
GPIO_PUPDR_PUPDR5_0 | // Pull-Up, PWM_OUT2, TIM3_CH2
GPIO_PUPDR_PUPDR0_0 | // Pull-Up, PWM_OUT3, TIM3_CH3
GPIO_PUPDR_PUPDR1_0 | // Pull-Up, PWM_OUT4, TIM3_CH4
GPIO_PUPDR_PUPDR6_0 | // Pull-Up, PWM_IN5, TIM4_CH1
GPIO_PUPDR_PUPDR7_0 // Pull-Up, PWM_IN6, TIM4_CH2
);


// Alternate Function pins
GPIOB->AFR[1] = 0; // clear AFR_H register
GPIOB->AFR[1] |=
(
(4 << ((8 - 8) << 2)) | // I2C1 SCL, AF4
(4 << ((9 - 8) << 2)) | // I2C1 SDA, AF4

(5 << ((12 - 8) << 2)) | // SPI2 NSS, AF5
(5 << ((13 - 8) << 2)) | // SPI2 SCK, AF5
(5 << ((14 - 8) << 2)) | // SPI2 MISO, AF5
(5 << ((15 - 8) << 2)) // SPI2 MOSI, AF5

);

GPIOB->AFR[0] = 0; // clear AFR_L register
GPIOB->AFR[0] |=
(
(2 << ((4 - 0) << 2)) | // PWM_OUT1, TIM3_CH1, AF2
(2 << ((5 - 0) << 2)) | // PWM_OUT2, TIM3_CH2, AF2
(2 << ((0 - 0) << 2)) | // PWM_OUT3, TIM3_CH3, AF2
(2 << ((1 - 0) << 2)) | // PWM_OUT4, TIM3_CH4, AF2
(2 << ((6 - 0) << 2)) | // TIM4_CH1, AF2
(2 << ((7 - 0) << 2)) // TIM4_CH2, AF2
);







//=============================================================================
// GPIOD configuration
//=============================================================================
// enable GPIOD clock
((RCC_TypeDef *)(RCC_BASE))->AHB1ENR |= RCC_AHB1ENR_GPIODEN;


// Alternate Function
((GPIO_TypeDef *)(GPIOD_BASE))->MODER |=
(GPIO_MODER_MODER9_1 | // Alternate Function, USART3_RX
GPIO_MODER_MODER8_1 ); // Alternate Function, USART3_TX

// Output type
((GPIO_TypeDef *)(GPIOD_BASE))->OTYPER |= 0;// push-pull if 0
//(GPIO_OTYPER_OT_8 | // Open-Drain, I2C1, SCL
//GPIO_OTYPER_OT_9); // OPen-Drain, I2C1, SDA



// Speed type
((GPIO_TypeDef *)(GPIOD))->OSPEEDR |=
(GPIO_OSPEEDER_OSPEEDR8_1 | // USART3 TX 50 MHz
GPIO_OSPEEDER_OSPEEDR9_1); // USART3 RX 50 MHz


// Push/Pull for USART3
((GPIO_TypeDef *)(GPIOD_BASE))->PUPDR |=
(
GPIO_PUPDR_PUPDR8_0 | // Pull-Up, USART3 TX
GPIO_PUPDR_PUPDR9_0 // Pull-Up, USART3 RX
);


((GPIO_TypeDef *)(GPIOD_BASE))->AFR[1] |= (
(7 << ((8 - 8) << 2)) | // USART3 TX, AF7
(7 << ((9 - 8) << 2)) ); // USART3 RX, AF7







return 0;
}


CODE

uint32_t config_pwm_io(void)
{
//=============================================================================
// set up PWM Output on TIM3 channels
//=============================================================================

// enable TIM3 clock
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;


// set the prescaler for 2MHz clock count
// fpclk = 42MHz, TIM3_clk = 2*fpclk = 84MHz
// CK_CNT = TIM3_clk / (PSC + 1)
// PSC = TIM3_clk / CK_CNT - 1
TIM3->PSC = 41; // 84MHz/2MHz - 1 = 41

// set the Auto Reload Register
// Needed period = (1/CK_CNT) * ARR
TIM3->ARR = 30000; // PWM_period = 15ms / (1/2MHz)

// clear CR2
TIM3->CR2 = 0;


TIM3->CCR1 = 3000; // 10% duty cycle, for CH1
TIM3->CCR2 = 3000; // 10% duty cycle, for CH2
TIM3->CCR3 = 3000; // 10% duty cycle, for CH3
TIM3->CCR4 = 3000; // 10% duty cycle, for CH4

// set output compare mode 1.
TIM3->CCMR1 |=
TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | // CH1
TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // CH2

TIM3->CCMR2 |=
TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | // CH3
TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1; // CH4


// enable Output compare
TIM3->CCER |= TIM_CCER_CC1E; //CH1
TIM3->CCER |= TIM_CCER_CC2E; //CH2
TIM3->CCER |= TIM_CCER_CC3E; //CH3
TIM3->CCER |= TIM_CCER_CC4E; //CH4

// enable TIM3
TIM3->CR1 |= TIM_CR1_CEN;


return 0;
}


CODE

uint32_t config_spi_all(void)
{

//=============================================================================
// SPI1 Related configuration
//=============================================================================
// enable SPI2 clock
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;


// configure SPI2
SPI2 -> CR1 |= (SPI_CR1_SPE | SPI_CR1_CPOL |
SPI_CR1_CPHA | SPI_CR1_MSTR |
SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI);


//SPI2->CR2 |= (SPI_CR2_SSOE);



return 0;
}



CODE

uint32_t config_i2c_all(void)
{

//=============================================================================
// I2C1 Related configuration
//=============================================================================
// enable I2C1 clock
((RCC_TypeDef *) (RCC_BASE))->APB1ENR |= RCC_APB1ENR_I2C1EN;





// 1) configure I2C_CR2
I2C1 -> CR2 |= (I2C_CR2_FREQ_5 | I2C_CR2_FREQ_3 |
I2C_CR2_FREQ_1); // APB1 clock is 42MHz

// 2) Configure Clock Control Register, I2C_CCR
// For 100KHz, APB1clk=42MHz, T_high = T_low = (1/42MHz)*210 = 5us
// For Fast mode, T_high = 9*(1/42MHz)*CCR = 0.8us,
// T_low = 16*(1/42MHz)*CCR = 1.5us,
// CCR = 4, F/S = 1, DUTY = 1, I2C_CCR = 0xc004
I2C1 -> CCR = 0xc004; // 0xd2, d210 for 100KHz,

// 3) Configure I2C_TRISE, Rise Time register
I2C1 -> TRISE = 0x2b; // 0x2b, d42 (42 + 1)

// 4) enable I2C1 peripheral
I2C1 -> CR1 |= (I2C_CR1_PE);


return 0;
}




CODE

uint32_t config_usart3(void)
{

//=============================================================================
// USART3 Related configuration
//=============================================================================
// enable I2C1 clock
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;


// 1) Setting UE, amd M bits
USART3-> CR1 |= 0x2000; // UE = 1

// 2) Programming number of stop bits if needed


// 3) Enable DMA if needed


// 4) set the Baud Rate
// BAUD = fck / ( 8 * (2 - OVER8) * USARTDIV )
// fck = 42MHz,
// OVER8 = 0
// Choose BAUD = 115200
// then: USARTDIV = fck / ( 8 * (2 -OVER8) * BAUD = 22.75
// BRR = (22 << 4) | ( 0.75 * 16) = 364,
// or: BRR = fck / BAUD = 42MHz / 115200 = 364
USART3->BRR = 364;


// enable transmitter
USART3->CR1 |= USART_CR1_TE;

// enable receiver
USART3->CR1 |= USART_CR1_RE;

return 0;
}



Короче вывод такой что если сразу после включения всей периферии в приведенном коде посылать байт по SPI то буден задержкав 1500нс, но байт по любому отсылается.


p.s. задача поднятия пина SS после передачи байта тоже решена программным путем. Никакие эксперименты с битами SSOE SSI SSM ни следование мануалу не привело к тому чтобыstm32 сам поднимал пин SS вверх после успешной отправки байта. (как я уже написал...после отправки читаю прием а потом уже BSY и вручную поднимаю его сам)
(почти тоже самое что в теме приведенной Viko)

а так вобщем работает все.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.