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

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

|
Короче,чтобы начать плностью с нуля, пошел взял новую плату Дискавери, девственную, вскрыл упаковку подключил только ноги 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 );
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Apr 24 2013, 03:41
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
а где варианта SSM =1, SSI = 0? вроде как инструкция об этом говорит. SSM = 1, SSI - задает состояние NSS, или нет? еще вот такая приписка Когда NSS разрешено работать в качестве выхода (SSM = 0, SSOE = 1), эта конфигурация используется только в режиме Master. Когда ведущее устройство начинает соединение, NSS переводится в состояние низкого уровня, и поддерживается в этом состоянии до момента деактивации модуля SPI. и остается теперь потихоньку добавлять периферию прошлого проекта и смотреть какой модуль убъет СПИ
|
|
|
|
|
Apr 24 2013, 04:13
|

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

|
Цитата(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) если хотите можете проверить.
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Apr 24 2013, 05:05
|

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

|
Я не пойму немного, разве целью установки SSOE=1 не является автоматическое управление пином NSS? т.е.сделать так, чтобы этот пин сам подтягивался на 0 во время транзакции и возвращался на 1 когда транзакция закончена? как можно достичь такoго поведения? И еще, вы говорите SSOE=1 и управляй пином NSS через GPIO.. но ведь пин PB12 (NSS) настроен как Alternate Function... ? (тестовыйпроект выложен в этом посте если что: http://electronix.ru/forum/index.php?showt...&p=1157091)
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Apr 24 2013, 07:45
|

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

|
Цитата(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; так более красиво как то (не нужно циклы вставлять..)
Сообщение отредактировал IgorKossak - Apr 24 2013, 08:44
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Apr 24 2013, 11:44
|
Местный
  
Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126

|
Всё это, конечно... очень интересно... "А был ли мальчик?"(С) А глюк то... где??? Неужто самоликвидировался???
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|