SPI на STM32 не будет работать без подтягивающих резисторов и даже тогда будет работать плохо


8

Я пытался заставить SPI1 на STM32F103C8 ( Blue Pill Board) работать правильно в течение некоторого времени. Поскольку я только начинаю изучать ARM, я просто пытаюсь сместить данные в регистр сдвига 74HC595 и зафиксировать их, чтобы загорелся байт светодиодов. Я не читаю никаких данных, поэтому у меня есть только линии MOSI, SCK и SS.

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

Основная проблема сейчас заключается в том, что, если я не включаю подтягивающие резисторы на всех линиях (MOSI, SCK и SS), микроконтроллер ничего не выводит ни на одну линию (проверяется с помощью области). Кроме того, после добавления подтягивающих резисторов время нарастания импульсов очень медленное, поэтому я не могу использовать слишком высокую частоту (с подтягивающими резисторами 10 кОм я ограничен до 250 кГц SCK, и переключение до 330 Ом (около 4 МГц). Я работаю над макетом, но даже тогда с AVR и запутанной проводкой я мог получить SPI на 4 МГц, работающий без проблем без каких-либо добавленных резисторов, и формы сигнала были более чистыми.

Вот две картинки (извините за плачевное состояние экрана моего прицела), передающих байт 0b01110010 с тактовой частотой 250 кГц. Верхний след - SCK, а нижний - MOSI. Первое изображение с подтягивающими резисторами 10 кОм, а второе с подтягивающими резисторами 330 Ом, которые делают сигналы намного приятнее (но они не нужны).

Буду признателен за помощь, чтобы выяснить, что происходит.

Подтягивающие резисторы 10 кОм и тактовая частота 250 кГц

Подтягивающие резисторы 330 Ом и 250 кГц делают форму волны намного лучше

Соответствующие части моего кода:

#define SS_LOW        GPIOA->BSRR |= 1 << 4 + 16;
#define SS_HIGH        GPIOA->BSRR |= 1 << 4;

// SPI GPIO configuration
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIOA->CRL |= 0b0011 << 4 * 4;    // Set pin A4 as PP out 50mHz for SS
GPIOA->CRL |= 0b1011 << 5 * 4;    // Set pin A5 AltFunc PP out 50mHz for SCK
GPIOA->CRL |= 0b1011 << 7 * 4;    // Set pin A7 AltFunc PP out 50mHz for MOSI
SS_HIGH;

// SPI1 configuration
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;        // Enable SPI1 clock
SPI1->CR1 |= SPI_CR1_SSM;        // Software SS
SPI1->CR1 |= SPI_CR1_SSI;
SPI1->CR1 |= SPI_CR1_BR_0;        // Set prescaler
SPI1->CR1 |= SPI_CR1_BR_1;
SPI1->CR1 |= SPI_CR1_BR_2;
SPI1->CR1 |= SPI_CR1_MSTR;        // Master mode
SPI1->CR1 |= SPI_CR1_SPE;        // Enable SPI

// Transmit byte
SS_LOW;
SPI1->DR = 0b01110010;
while(!(SPI1->SR & SPI_SR_TXE));
while(SPI1->SR & SPI_SR_BSY);
SS_HIGH;

Каковы ваши настройки? Как ваши провода связаны? Вы используете нестандартную доску или макет?
Тарик Веллинг

Я использую макет. 74hc595 питается от 3,3 В платы с голубыми таблетками (точнее: revspace.nl/File:Bluepill.jpg ). Единственные провода, идущие от и к сдвиговому регистру - это MOSI, SCK и SS. Я уверен, что проводка правильная, я проверял ее много раз (и еще раз, прежде чем ответить вам).
jjpprr

Ответы:


12

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

Значение сброса GPIOA_CRL составляет 0x4444 4444. Таким образом, каждый вывод инициализируется с 0b0100, если вы делаете | = 0b0011, вы получаете 0b0111, который является выходом с открытым стоком. То же самое с 0b1011 становится 0b1111, и это альтернативная функция открытого стока.

Так что вам нужно сделать что-то вроде этого:

// Reset pin configuration
GPIOA->CRL &= ~(0b1111 << 4 * 4);  // Reset Pin A4
GPIOA->CRL &= ~(0b1111 << 5 * 4);  // Reset Pin A5
GPIOA->CRL &= ~(0b1111 << 7 * 4);  // Reset Pin A7
GPIOA->CRL |= 0b0011 << 4 * 4;  // Set pin A4 as PP out 50mHz for SS
GPIOA->CRL |= 0b1011 << 5 * 4;  // Set pin A5 AltFunc PP out 50mHz for SCK
GPIOA->CRL |= 0b1011 << 7 * 4;  // Set pin A7 AltFunc PP out 50mHz for MOSI

Это было оно!! Большое спасибо, я знал, что это будет так просто. Я должен был прочитать первую строку в GPIOA_CRL таблицы данных, я просто предположил, что значение сброса было все нули. Теперь это работает шарм.
jjpprr

@jjpprr ну, мне потребовалось некоторое время, чтобы понять :-) Рад, что смог помочь. Если вы собираетесь использовать I²C на F103, будьте готовы к тяжелой поездке, я помню, что это ужасно.
Арсенал

: O приму это во внимание, после запуска и запуска USART наступит очередь I2C. Спасибо за внимание.
jjpprr

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

Это было только с F103 или другими чипами stm32? Потому что я планировал использовать его просто для ознакомления с микросхемами stm32, а затем перейти к F091 для небольших проектов и F446 для более требовательных.
jjpprr
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.