Нужна помощь в управлении регистрами во встроенной сборке (STM32F103 "BluePill") - PullRequest
1 голос
/ 09 января 2020

У меня есть простой код, который я хочу получить. То, что я пытаюсь сделать, это как можно быстрее включить и выключить контакт PA8 на STM32F103 «BluePill» с помощью сборки. У меня проблемы с правильным синтаксисом.

__asm__ volatile (    
  "ldr r2, = (1<<8)  \n\t"  
  "str r2, = [odr]   \n\t"
  "ldr r2, = ~(1<<8) \n\t"
  "str r2, = [odr]   \n\t"
  : [odr] "=r" (GPIOA->regs->ODR)
);

Компилятор выдает эту ошибку:

Compiling .pio/build/genericSTM32F103C8/src/main.ino.cpp.o
/tmp/ccLofo6i.s: Assembler messages:
/tmp/ccLofo6i.s:46: Error: invalid pseudo operation -- `str r2,=[odr]'
/tmp/ccLofo6i.s:48: Error: invalid pseudo operation -- `str r2,=[odr]'
*** [.pio/build/genericSTM32F103C8/src/main.ino.cpp.o] Error 1

Обычно Libmaple позволяет мне использовать GPIOA-> regs-> ODR для управления регистрами с использованием побитовых операций, но на практике я не мог скорость переключения выше 2 МГц. Я также очень плохо знаком со встроенной сборкой.

РЕДАКТИРОВАТЬ:

Поэтому я попробовал то, что предложил Шут:

volatile uint32 * odr = (GPIOA-> regs-> ODR ); * odr = (1 << 8); * odr = 0; </p>

Но PlatformIO жалуется, что «значение типа« uint32 »нельзя использовать для инициализации сущности типа« volatile uint32 * »и компилятора тоже:

неверный преобразование из 'uint32 {aka long unsigned int}' в 'uint32 * {aka long unsigned int *}' [-fpermissive]

Однако я попытался улучшить исходный код сборки:

asm volatile (

"ldr r2, = (1<<8) \n\t"
"str r2, [%[odr]] \n\t"
"ldr r2, = 0      \n\t"
"str r2, [%[odr]] \n\t"

: [odr] "= r" (GPIOA_BASE-> ODR)

);

, и это прекрасно компилируется но он не делает то, что я ожидал. PA8 читает 3.3v, но он не колеблется вообще. Если я изменяю (GPIOA_BASE-> ODR) на (GPIOA-> regs-> ODR), то я получаю сигнал не напряжения PA8, ни колебания. В чем здесь может быть проблема? Чтобы ответить и Дэвиду, и old_timer, я хочу в основном воссоздать то, что сделал этот парень:

http://cliffle.com/blog/pushing-pixels/#continue -читание

В этом посте вы увидите, что он использовал команды store и load для быстрой проверки максимальной скорости переключения периферийного устройства GPIO, w Хотя, очевидно, есть и другие вещи, которые могут ограничивать скорость переключения, все, что я действительно ищу, это получить как минимум 36 МГц от вывода GPIO. Я знаю, что это абсолютно возможно, потому что я настроил TIMER1 на stm32 для быстрой генерации колебаний, но таймеры ограничивают этот битрейг-проект VGA, который я хочу сделать, я надеялся, что Inline Assembly будет немного более гибкой. Еще одна вещь, которая привела меня к использованию Assembly, - это то, что я прочитал:

'Теоретический максимум для переключения булавки - это две инструкции хранилища сборки, которые должны быть не менее 2 циклов при 72 МГц или 36 МГц'

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

...