Перейти к содержанию

Stm32 Spi


Zhuebok

Рекомендуемые сообщения

Работаю без SPL и на данный момент с ней работать не хочу (тут, что было бы лучше писать не надо - все бессмысленно).

Собрался подключить по SPI другое устройство (ENC28J60), но тут возникла незадача: SPI Работать отказывается. Во время отладки посмотрел состояние регистра SPI1_CR1, и, как оказалось, бит SPE не выставлен, как, впрочем и MSTR.

Вот что выдает GDB по этому поводу (SPI1_CR1):

x/2tb 0x40013000
0x40013000: 00000010 00000001

младший и старший байты регистра.

Код инициализации следующий:

void SetSPI (void)
{
// разрешаем тактирование порта A
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

// настраиваем пины 4, 5, 6, 7 как выходы альтернативной функции
GPIOA->MODER &= ~(GPIO_MODER_MODER4 | GPIO_MODER_MODER5 | GPIO_MODER_MODER6 | GPIO_MODER_MODER7);
GPIOA->MODER |= GPIO_MODER_MODER4_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1;

// настройка скорости работы
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR4_1 | GPIO_OSPEEDER_OSPEEDR5_1 | GPIO_OSPEEDER_OSPEEDR6_1 | GPIO_OSPEEDER_OSPEEDR7_1;

// настройка альтернативных функций
// сначала сбрасываем, затем устанавливаем другие значения
// AF0 - для всех регистров gpio - SPI1
GPIOA->AFR[0] = 0;

// разрешаем тактирование SPI
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;

// включаем модуль SPI1.
// максимальная скорость передачи - 24МБод
// делаем ведущим
// полярность - отрицательная.
SPI1->CR1 = SPI_CR1_CPOL | SPI_CR1_MSTR | SPI_CR1_SSI;

// размер отправляемых и принимаемых данных по SPI равен 8 бит
SPI1->CR2 = SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;

// далее включаем SPI
SPI1->CR1 |= SPI_CR1_SPE;
}

Вообще та ли последовательность инициализации, или что-то надо менять. Может где ошибка закралась?

Изменено пользователем Zhuebok
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Кстати, отмечу следующее: несколько раз перепрыгивал на начало программы, и, соответственно, инициализация SPI каждый раз повторялась, получилось так. что каждый второй раз (через раз) флаг SPE был выставлен, в другие разы - сброшен. Что-то тут нечисто.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Понятное дело, что нечисто. Найдите готовый пример без использования библиотек, и сравните.

Потенциально возможные проблемы:

1) Тактирование шины, где SPI подключен (маловероятно и наивно)

2) Неправильное конфигурирование порта

3) Неправильная обработка прерывания (если контроллер сам "перепрыгивал" на начало программы - тут непонятно, кто перепрыгивал :))

4) Недопонимание работы самого модуля. Может датащит внимательнее прочитать, вдруг поможет (мне помогало иногда)

Но готовый пример обычно быстрее проясняет проблемы.

Сам я на STM32 почти ничего не делал, поверхностно ознакомился.... Но раз никто поопытнее не отвечает.... :) Кстати, какой STM то у Вас?

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Тот. что на дисвакери стоит - STM32F051R8T6.

На одном ресурсе посоветовали проверять состояние флага MODF регистра SPI1_SR. Прочитал в даташите, что эта штуковина отвечает за фэйлы в настройке, ладно. сбрасываю его по рекомендации из даташита, но тут ситуация такая: устанавливаю бит SPE - бит MSTR сбрасывается, устанавливаю бит MSTR - бит SPE сбрасывается.

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

Тактирование модуля включил с самого начала.

Блин, вот я краб :) Оказывается проглядел бит SSOE, который SPI1_CR2 расположен, а он отвечает за возможность выбора устройства в качестве мастера в многомастерной (или как ее) конфигурации. Его только поставить и все завелось. Вот тетеря

Изменено пользователем Zhuebok
Ссылка на комментарий
Поделиться на другие сайты

Кстати, раз уж тред открыт, наверно задам еще один вопрос, но на этот раз уже про ENC28J60.

Как я понял, размерность одного слова при передаче сообщения - 8 бит (то есть код операции (3 бита) + адрес регистра (при необходимости, но 5 бит обязательно) или последующие данные по 8 бит). Но хотел бы узнать вот что. Делаю так:

  1. Отправляю первым словом код операции с указанием регистра (в моем случае чтение регистра).
  2. Так как режим дуплексный, отправляю вторым байтом 0x00 для того, чтобы с MISO считать данные.

Вопрос вот в чем: когда я отправляю второе слово - ENC28J60 также его считывает или делает его игнорирование (?), поскольку заметил такую вещь, что данные с не изменявшегося регистра приходят разные каждый раз (и циклически повторяются, судя по моим наблюдениям). Видел на какой-то из временных диаграмм, что на одной из шин было написано Don't carry (не волнуюсь. буквально). Если он его считывает, то каким образом в таком случае поступить?

Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

Добрый день!

Есть макетная плата stm32discovery с МК stm32f100rb. На нем 2 spi. Хочу проверить их работу, spi1 настраиваю как мастер, spi2 как слэйв.

Код инициализации:

void SPI1_MasterInit()
{
SPI1->CR1 = 0; // сброс
SPI1->CR2 = 0; // сброс

SPI1->CR1 |= 0<<SPI_CR1_BR_0; // baudrate - clk/2
SPI1->CR1 |= SPI_CR1_CPHA;	 // по второму фронту
SPI1->CR1 &= ~SPI_CR1_CPOL;	 // CK to 0 when idle
SPI1->CR1 |= SPI_CR1_DFF;		 // формат слова - 16 бит
SPI1->CR1 &= ~SPI_CR1_LSBFIRST; // младший бит передается первым
SPI1->CR1 |= SPI_CR1_MSTR;	 // master
SPI1->CR2 |= SPI_CR2_SSOE;	 // NSS используется как выход
SPI1->CR1 |= SPI_CR1_SPE; // SPI enable
}

void SPI2_SlaveInit()
{
SPI2->CR1 = 0; // сброс
SPI2->CR2 = 0; // сброс

SPI2->CR1 |= 0<<SPI_CR1_BR_0; // baudrate - clk/2
SPI2->CR1 |= SPI_CR1_CPHA; // по второму фронту
SPI2->CR1 &= ~SPI_CR1_CPOL; // CK to 0 when idle
SPI2->CR1 |= SPI_CR1_DFF; // формат слова - 16 бит
SPI2->CR1 &= ~SPI_CR1_LSBFIRST; // младший бит передается первым
SPI2->CR1 &= ~SPI_CR1_MSTR; // slave

SPI2->CR2 |= SPI_CR2_RXNEIE; // разрешение прерывания по Rx not empty

NVIC_EnableIRQ(SPI2_IRQn); // разрешение прерывания
SPI2->CR1 |= SPI_CR1_SPE; // SPI enable
}

Для теста я передаю десять 16битных слов. В такой конфигурации работает всё корректно. Если сбросить МК и заново запустить отладку, то данные так же принимаются корректно. Однако, если я конфигурирую модули (spi1,spi2) так, что бы клок находился в единице, когда передачи данных нет (бит CPOL=1), то работать всё начинает через раз. То есть запускаю на отладку - приходит мусор, сбрасываю МК, запускаю второй раз на отладку - приходит мусор, уже другой, сбрасываю третий раз - приходит то, что и должно, сбрасываю снова и запускаю - получаю мусор, который приходил в самый первый раз. Таким образом данные принимаются правильно каждый третий раз. С чем это может быть связано?

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Для теста я передаю десять 16битных слов. В такой конфигурации работает всё корректно. Если сбросить МК и заново запустить отладку, то данные так же принимаются корректно. Однако, если я конфигурирую модули (spi1,spi2) так, что бы клок находился в единице, когда передачи данных нет (бит CPOL=1), то работать всё начинает через раз. То есть запускаю на отладку - приходит мусор, сбрасываю МК, запускаю второй раз на отладку - приходит мусор, уже другой, сбрасываю третий раз - приходит то, что и должно, сбрасываю снова и запускаю - получаю мусор, который приходил в самый первый раз. Таким образом данные принимаются правильно каждый третий раз. С чем это может быть связано?

Сколько байт данных отсылаешь и сколько принимаешь?

Ссылка на комментарий
Поделиться на другие сайты

  • 5 месяцев спустя...

Доброго времени всем!

У меня тут вопрос помогите кто может по поводу spi.

перерыл кучу статей , смотрел видео уроки по этому интерфейсу , говорят что эспэай эта сдвиговый регистр но, сдвиговым регистром хорошо знаком но его ни как не могу понять . во всех статьях одно и тоже , будто друг у друга переписывают . принцип передачи и приема данных кто то может сказать как лично он понимает а не с тех фото и дублированных статей рассказать ? Спасибо !

Ссылка на комментарий
Поделиться на другие сайты

ну как, два сдвиговых регистра просто сцеплены - выход одного со входом другого и всё. А сдвиги производятся от тактовых импульсов на соответствующей линии. В итоге данные (зависит от разрядности регистра) как бы перетекают через линию из одного рега в другой.

Мастер (ведущий) - это то устройство, которое генерирует тактовые импульсы по сути определяя скорость передачи. Короче дирижёр. Слейв (ведомый) - только реакция на тактовые импульсы. Мастер обычно один, а слейвов от одного и больше. Короче оркестр.

Подключать можно слейвы паралелльно к мастеру - все шины общие. В этом случае от мастера к каждому слейву отдельно должно идти по проводу выбора. Мастер должен сначала выбрать кого то одного, и потом начинать передачу. Невыбранные не будут реагировать никак.

Можно включать последовательно: мастер -> слейв 1 -> слейв 2 -> и т.п.н.н. (и так пока не надоест) В этом случае биты будут кочевать по всей цепи и надо будет передать из мастера столько информации - чтобы заполнить всю цепь. Плюс данного подхода - не нужны управляющие проводники для каждого слейва, минус - нет индивидуального воздействия - т.е. придётся полный массив информации для всех элементов передавать.

Выход крайнего (или единственного)слейва можно обратно в мастера воткнуть.

Это в общих чертах. На деле в различных устройствах может отсутствовать часть описаного выше или механизм реакции на передачу несколько отличается. Обычно все тонкости описаны в датащите микросхемы. Но суть та же - тактирование и поочередное пробегание данных.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...