Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F103
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Firer
Компилятор Keil.
Код в вечном цикле меняет состояние выходного бита порта.
Кварц 8МГц. SYSCLK=8*9=72МГц
APB1=72/2, APB2=72
порт настроен на макс.частоту 50МГц.
прерывания все запрещены.
Ядро работает на 72МГц - MCO включал убедился осциллографом вижу 72МГц.

Реально порт дергается с частотой около 3МГц. В чем дело?
Как минимум должно быть около 36МГц меандр.
-SANYCH-
Для начала не плохо было бы посмотреть во что скомпилировался Ваш вечный цикл (посмотреть что там в асме). А вообще такие вещи нужно писать на асме или делать асмовские вставки. Думаю после этого часть вопросов отпадет сама по себе.
scifi
Цитата(Firer @ Apr 16 2012, 22:00) *
Как минимум должно быть около 36МГц меандр.

Ну-ну, мечтайте дальше.
Как сказано выше, код цикла может скомпилироваться неоптимально.
Кроме того, скорость GPIO в серии STM32F1xx точно меньше скорости процессора. На сколько именно - в документации не написано, надо экспериментировать. Встречал упоминания о том, что мост AHB-APB добавляет 2 цикла задержки. И вот эти "50 МГц" - это всего лишь крутизна фронтов, то есть на частоту переключения не влияет.
Кстати, в серии STM32F2xx совсем другая история.
Firer
Коллеги спасибо за подсказки!
Код я посмотрел ассемблерный. Так что имею права на мечту, ну не 36МГц, ну 10 хотя бы. А то выходит 3.

while (1)
XLED0_TGL;

На асме это:
metka: ldr r1,[r0,0x80c]
eor r1,r1,#0x200
str r1,[r0,#0x80c]
b metka

т.е. 4 такта? Или я не прав?
Ну если еще мост добавит 2 раза по 2 цикла задержки, то выходит около 10 тактов?
А это 7.2МГц а не 3.6.
scifi
Цитата(Firer @ Apr 16 2012, 23:35) *
т.е. 4 такта? Или я не прав?

Очень часто инструкция выполняется не за 1 такт. В документе "Cortex-M3 Technical Reference Manual" описывается время выполнения инструкций. Дополнительные задержки могут возникать при обращении процессора к внешним шинам (APB, флэш и прочее).
Кроме того, более оптимальный код такой:
Код
int pdata1 = 0x0000, pdata2 = 0x0200;
while (1)
{
    PORT = pdata1;
    PORT = pdata2;
}

Ну и компилировать с максимальной оптимизацией по скорости.
А на ассемблере можно сделать оптимально без оглядки на компилятор.

Update:
Да, забыл.
Цитата(Firer @ Apr 16 2012, 23:35) *
Ну если еще мост добавит 2 раза по 2 цикла задержки, то выходит около 10 тактов?
А это 7.2МГц а не 3.6.

Нет, это не 10, а 20 тактов. Одна итерация цикла в таком виде - это половина периода ("0" - 10 циклов, "1" - 10 циклов, ...).
SBE
Разбирался когда-то с этим.

STR в порт на STM32 действительно занимает 2 такта (ну не совсем так, но упростим для вашего случая), но вы не забывайте еще и про переход. А вот его влияние на время исполнение приведенного кода уже замысловатее из-за тактов ожидания флеши и буфера предвыборки. Там будет зависимость от того на какой адрес идет переход, и от размера и времени выполнения команд, на которые идет переход.
Попробуйте, не будет ли приведенный вами код по времени исполнения зависеть от адреса метки rolleyes.gif

Линейный код, состоящий из STR, будет как и должно выполняться за 2 такта на каждое обращение, и обеспечивать обещанную частоту переключения 18МГц.


zöner
а LDR ?
a1ien
Переход тоже гдето в 2 така выливается. Тоесть цикл записи в порт самый оптимизированный(а не тот что приведен выше) занимает около 6 тактов,соответственно 12 тактов запись патерна. Тоесть теоретически 6-7 мгц это максимум что можно получить при генерации меандра.
SBE
Цитата(a1ien @ Apr 17 2012, 23:29) *
Переход тоже гдето в 2 така выливается. Тоесть цикл записи в порт самый оптимизированный(а не тот что приведен выше) занимает около 6 тактов,соответственно 12 тактов запись патерна. Тоесть теоретически 6-7 мгц это максимум что можно получить при генерации меандра.

Это вы оптимист насчет перехода, 2 в идеальном случае.
Цитата
Branches take one cycle for instruction and then pipeline reload for target instruction. Non-taken branches are 1 cycle total.
Taken branches with an immediate are normally 1 cycle of pipeline reload (2 cycles total). Taken branches with register
operand are normally 2 cycles of pipeline reload (3 cycles total). Pipeline reload is longer when branching to unaligned 32-bit
instructions in addition to accesses to slower memory. A branch hint is emitted to the code bus that permits a slower system
to pre-load. This can reduce the branch target penalty for slower memory, but never less than shown here.

А если вспомнить про 2 такта ожидания при обращении к флеш на 72МГц для STM32F103, и небольшую глубину буфера предвыборки, то если память мне не изменяет, то и 5 тактов можно получить.
С оптимизацией тож не все так очевидно, какой код там самый оптимизированный. Из-за нюансов внутренней архитектуры легко получаются чудеса.

Цикл из двух записей в порт и перехода на 72МГц действительно по минимуму 6 тактов, т.е. генерация меандра 12МГц. Но можно получить и в 1.5 раза медленее на том же исходном коде.
koyodza
Цитата(scifi @ Apr 16 2012, 22:17) *
Встречал упоминания

Вот там посмотрите http://caxapa.ru/182481.html
Реально 2-3 такта на каждую команду, если в коротком цикле только две записи в порт
nicks80
Цитата(Firer @ Apr 16 2012, 22:00) *
Компилятор Keil.
Код в вечном цикле меняет состояние выходного бита порта.
Кварц 8МГц. SYSCLK=8*9=72МГц
APB1=72/2, APB2=72
порт настроен на макс.частоту 50МГц.
прерывания все запрещены.
Ядро работает на 72МГц - MCO включал убедился осциллографом вижу 72МГц.

Реально порт дергается с частотой около 3МГц. В чем дело?
Как минимум должно быть около 36МГц меандр.


Когда с STM32F4 игрался то дергал ногу с частотой проца. те 2 раза ниже.
А параметры отвечающие за частоту работы порта отвечали за фронт сигнала на пине (т.е. управляли током работы PIO).
ViKo
В Keil есть симулятор, в котором прекрасно видно, за сколько тактов выполняется команда, а также можно запустить "секундомер" - в строке состояния Keil.
scifi
Цитата(ViKo @ Oct 1 2012, 17:53) *
В Keil есть симулятор, в котором прекрасно видно, за сколько тактов выполняется команда, а также можно запустить "секундомер" - в строке состояния Keil.

Вопрос в том, насколько точен этот симулятор. Насколько я понимаю, они стараются делать его приближенным к реальному кремнию, но гарантий не дают.
ViKo
Цитата(scifi @ Oct 1 2012, 17:07) *
Вопрос в том, насколько точен этот симулятор. Насколько я понимаю, они стараются делать его приближенным к реальному кремнию, но гарантий не дают.

Я не уверен, что симулятор учитывает чтение и использование команд в буфере. Но в остальном, понять, сколько тактов занимает последовательность команд, можно. Keil показывает количество тактов и время, а мы гордо пройдем мимо? Давайте сначала посмотрим на числа, что он показывает, а потом будем отвергать. Уж 36 MHz меандр он точно не покажет. sm.gif
Lukdut
Для быстрого дрыга пинами очень актуальным будет использование BitBand-a. Что за зверь и как юзать может доступно поведать Insider's Guide на русском даже языке.
Однако ж даже с ним 32Мгц не ждите.
PS прошу прощения за "вражий сайт", но файл больше чем 2мб и посему не прикреплябелен(
KARLSON
Если нужно использовать порт как выход для прямоугольных импульсов, почему бы не использовать таймер. Например в MSP430 можно вывод подключить напрямую к таймеру, и если я не ошибаюсь можно получить частоту половину частоты тактирования. Наверняка есть функция и у STM32.
scifi
Цитата(KARLSON @ Oct 2 2012, 08:30) *
Наверняка есть функция и у STM32.

С таймерами STM32 вообще чудеса творить можно.
YAM
Хоть тема довольно старая, но я посмотрел на своем 103-м при 72MHz
Линейный цикл
STR R1, [R0]
STR R1, [R0, #0x4]
....................................
дергает ногами с частотой 72/4 =18MHz
т.е. изменение пина происходит с интервалом 27.(7) nS
ViKo
Цитата(YAM @ Oct 3 2012, 09:03) *
STR R1, [R0]
STR R1, [R0, #0x4]

Лучший код. Одно и то же значение записывается в регистр установки выходов, потом в регистр сброса. Команда выполняется за два такта.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.