Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F103
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
MySOL
Здравствуйте друзья! Нужна помощь в поимке особо опасной ошибки, скрывающейся в глубинах моего кода. Пытаюсь настроить SPI в режиме мастера и передать простой код. При отладке в KEIL'е все регистры встают на место, а вот при попытке записать данные в SPI1-DR ничего не происходит: регистр как был пустой, так и остался. Пытался брать примеры из интернета - тоже не отсылается ничего. Спасибо! P.S. хотелось бы реализовать всё без std_periph
CODE
#include "stm32f10x.h"
void InitAll(void);

void InitAll(void)
{
//Clock source
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;

//Initial GPIO
//SPI1_NSS alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF12;
GPIOB->CRH |=GPIO_CRH_CNF12_1;

GPIOB->CRH &=~GPIO_CRH_MODE12;
GPIOB->CRH |=GPIO_CRH_MODE12_1 | GPIO_CRH_MODE12_0;

//SPI1_SCK alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF13;
GPIOB->CRH |=GPIO_CRH_CNF13_1;

GPIOB->CRH &=~GPIO_CRH_MODE13;
GPIOB->CRH |=GPIO_CRH_MODE13_1 | GPIO_CRH_MODE13_0;

//SPI1_MISO input with pull-up/down
GPIOB->CRH &=~GPIO_CRH_CNF14;

GPIOB->CRH |=GPIO_CRH_CNF14_1;

GPIOB->CRH &=~GPIO_CRH_MODE14;

//SPI1_MOSI alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF15;
GPIOB->CRH |=GPIO_CRH_CNF15_1;

GPIOB->CRH &=~GPIO_CRH_MODE15;
GPIOB->CRH |=GPIO_CRH_MODE15_1 | GPIO_CRH_MODE15_0;

//SPI1_INIT
SPI1->CR1 |=SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE;

}

int __main(void)
{
InitAll();
while(1)
{
SPI1->DR =0xFF;
}
}
adnega
Так нельзя!
Нужно записывать в DR только когда передатчик пуст. Проверяйте флаг перед записью.
MySOL
Цитата(adnega @ Apr 13 2014, 10:10) *
Так нельзя!
Нужно записывать в DR только когда передатчик пуст. Проверяйте флаг перед записью.

Изменил код, всё равно не работает
CODE
#include "stm32f10x.h"
void InitAll(void);

void InitAll(void)
{
//Clock source
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;

//Initial GPIO
//SPI1_NSS alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF12;
GPIOB->CRH |=GPIO_CRH_CNF12_1;

GPIOB->CRH &=~GPIO_CRH_MODE12;
GPIOB->CRH |=GPIO_CRH_MODE12_1 | GPIO_CRH_MODE12_0;

//SPI1_SCK alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF13;
GPIOB->CRH |=GPIO_CRH_CNF13_1;

GPIOB->CRH &=~GPIO_CRH_MODE13;
GPIOB->CRH |=GPIO_CRH_MODE13_1 | GPIO_CRH_MODE13_0;

//SPI1_MISO input with pull-up/down
GPIOB->CRH &=~GPIO_CRH_CNF14;

GPIOB->CRH |=GPIO_CRH_CNF14_1;

GPIOB->CRH &=~GPIO_CRH_MODE14;

//SPI1_MOSI alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF15;
GPIOB->CRH |=GPIO_CRH_CNF15_1;

GPIOB->CRH &=~GPIO_CRH_MODE15;
GPIOB->CRH |=GPIO_CRH_MODE15_1 | GPIO_CRH_MODE15_0;

//SPI1_INIT
SPI1->CR1 |=SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE;

}

int __main(void)
{
InitAll();

while(1)
{
SPI1->DR =0xF0;
while(SPI1->SR & SPI_SR_BSY);
}
}

тут ещё вот что интересно. На осциллографе все ноги молчат замертво, нет ни SCK ни MISO. SS тоже 0
Сергей Борщ
Цитата(MySOL @ Apr 13 2014, 09:29) *
Изменил код, всё равно не работает
Не вижу включения тактирования SPI
MySOL
Цитата(Сергей Борщ @ Apr 13 2014, 10:54) *
Не вижу включения тактирования SPI

Исправил. Реакции нет. Как при программной отладке, так и на осциллографе
CODE
#include "stm32f10x.h"
void InitAll(void);

void InitAll(void)
{
//Clock source
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;

//Initial GPIO
//SPI1_NSS alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF12;
GPIOB->CRH |=GPIO_CRH_CNF12_1;

GPIOB->CRH &=~GPIO_CRH_MODE12;
GPIOB->CRH |=GPIO_CRH_MODE12_1 | GPIO_CRH_MODE12_0;

//SPI1_SCK alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF13;
GPIOB->CRH |=GPIO_CRH_CNF13_1;

GPIOB->CRH &=~GPIO_CRH_MODE13;
GPIOB->CRH |=GPIO_CRH_MODE13_1 | GPIO_CRH_MODE13_0;

//SPI1_MISO input with pull-up/down
GPIOB->CRH &=~GPIO_CRH_CNF14;

GPIOB->CRH |=GPIO_CRH_CNF14_1;

GPIOB->CRH &=~GPIO_CRH_MODE14;

//SPI1_MOSI alternate output push-pull
GPIOB->CRH &=~GPIO_CRH_CNF15;
GPIOB->CRH |=GPIO_CRH_CNF15_1;

GPIOB->CRH &=~GPIO_CRH_MODE15;
GPIOB->CRH |=GPIO_CRH_MODE15_1 | GPIO_CRH_MODE15_0;

//SPI1_INIT
SPI1->CR1 |=SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE;

}

int __main(void)
{
InitAll();

while(1)
{
SPI1->DR =0xF0;
while(SPI1->SR & SPI_SR_BSY);
}
}
adnega
Неужели SPI1 ремапится на эти ноги (PB12-PB15)?
Ккой именно контроллер (полная маркировка)?
MySOL
Цитата(adnega @ Apr 13 2014, 14:22) *
Неужели SPI1 ремапится на эти ноги (PB12-PB15)?
Ккой именно контроллер (полная маркировка)?

STM32F103C8T6
adnega
Смотрим Таблицу 56 RM0008.
Для SPI1.
При ремап = 0 ноги PA4-PA7
при ремап = 1 ноги PA15, PB3-PB5

У Вас скорее всего SPI2.
MySOL
Цитата(adnega @ Apr 13 2014, 14:41) *
Смотрим Таблицу 56 RM0008.
Для SPI1.
При ремап = 0 ноги PA4-PA7
при ремап = 1 ноги PA15, PB3-PB5

У Вас скорее всего SPI2.

Вы оказались правы. Я даже не подумал об этом. Пользуюсь отладочной платой Pinboard и бездумно доверился шелкографии на плате. Надо было сразу проверить. Спасибо! Но теперь возникла другая радость: стал проверять сигналы на MOSI и SCK и ужаснулся. У меандров очень сильное перерегулирование на переднем и задних фронтах, плюс на SCK сигнал 1.8 В вместо 3.3. не знаете в чём может быть проблема?
Нажмите для просмотра прикрепленного файла
adnega
Попробуйте частоту SPI понизить.
Или глубину выборки увеличить (с 10к).
У осциллографа какая полоса?
На какой частоте работает ядро? SCK получается 50МГц, т.е. Fcpu > 100МГц.
Вы 0xF0 в регистр записываете? Странная картинка для 0xF0.
MySOL
Цитата(adnega @ Apr 13 2014, 15:20) *
Попробуйте частоту SPI понизить.
Или глубину выборки увеличить (с 10к).
У осцилографа какая полоса?

100 МГц полоса. Уменьшение частоты помогло. Частота проца была 72 МГц, соответственно у SPI 36Мгц. Потом сделал 2Мгц. На двух норм. Но неужели железо не позволит теперь делать выше, скажем 10 МГц? Спасибо
adnega
Да хоть 36МГц.
Какой делитель на пробнике? Нужен 1:10.
Ноги должны быть настроены на вывод на частоте 50МГц (у Вас это так, судя по коду).
KnightIgor
Цитата(MySOL @ Apr 13 2014, 12:01) *
Вы оказались правы. Я даже не подумал об этом. Пользуюсь отладочной платой Pinboard и бездумно доверился шелкографии на плате. Надо было сразу проверить. Спасибо! Но теперь возникла другая радость: стал проверять сигналы на MOSI и SCK и ужаснулся. У меандров очень сильное перерегулирование на переднем и задних фронтах, плюс на SCK сигнал 1.8 В вместо 3.3. не знаете в чём может быть проблема?

Не верьте всему, что показывает осциллограф:
- как упоминали, надо щуп x10
- щуп надо отстроить (согласовать) на тестовом сигнале (как правило, есть такой выход у осца) вращением подстроечных резисторов
- хорошо ли сидит земля щупа на земле платы
- щуп есть микроскоп Гейзенберга. Без него выбросов скорее всего нет. Критерием может служить лишь надежность передачи данных.
MySOL
Цитата(KnightIgor @ Apr 13 2014, 19:19) *
Не верьте всему, что показывает осциллограф:
- как упоминали, надо щуп x10
- щуп надо отстроить (согласовать) на тестовом сигнале (как правило, есть такой выход у осца) вращением подстроечных резисторов
- хорошо ли сидит земля щупа на земле платы
- щуп есть микроскоп Гейзенберга. Без него выбросов скорее всего нет. Критерием может служить лишь надежность передачи данных.

Понял, спасибо!

Цитата(adnega @ Apr 13 2014, 16:46) *
Да хоть 36МГц.
Какой делитель на пробнике? Нужен 1:10.
Ноги должны быть настроены на вывод на частоте 50МГц (у Вас это так, судя по коду).

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