реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Эффективно и быстро управлять линией порта STM32F407
derun
сообщение May 21 2014, 03:11
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 133
Регистрация: 12-01-05
Из: Украина. Чернигов
Пользователь №: 1 908



Мне необходимо быстро менять состояние линии порта (програмно, без таймеров и прочего аппаратного). Пишу кусочек кода для проверки скорости функций управления линией порта portC.13.
Код
while (1)
{

HAL_GPIO_TogglePin(GPIOC, 1 << 13);

}

Получаю меандр с частотой порядка 2.4MHz.
Это очень медленно. Посмотрел как работает функция и переписал код так:
Код
  while (1)
{

      GPIOC->ODR ^= 1 << 13;
}

Получил меандр 8.4 MHz
Уже лучше, но все равно очень медленно. Учитывая что ядро летает на скорости 168 MHz.
Подскажите пожалуйста как сделать управление эффестивнее и быстрее.

Сообщение отредактировал IgorKossak - May 21 2014, 14:49
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
adnega
сообщение May 21 2014, 03:24
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(derun @ May 21 2014, 11:21) *
Мне необходимо быстро менять состояние линии порта (програмно, без таймеров и прочего аппаратного).
Подскажите пожалуйста как сделать управление эффестивнее и быстрее.

"Без аппаратного" и "эффективнее и быстрее" два противоречащих понятия.
Можете задачу описать подробнее?

Код
while(1)
{
  GPIOC->BSRR = (1 << 13) << 0;
  GPIOC->BSRR = (1 << 13) << 16;
}


Даст Вам максимальную частоту. Включите опримизацию по скорости. Покажите листинг.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 21 2014, 03:54
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



скорость ножки задали? Надо задать максимальную частоту переключения ноги, а то будет наружу будет лезть не пойми че!
Go to the top of the page
 
+Quote Post
scifi
сообщение May 21 2014, 03:56
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Если хочется максимально быстро и именно процессором, то без ассемблера не получится.

Цитата(Golikov A. @ May 21 2014, 12:04) *
скорость ножки задали? Надо задать максимальную частоту переключения ноги, а то будет наружу будет лезть не пойми че!

Неправда. Максимум завалятся фронты, если у осциллографа ёмкость щупа неприлично большая. Частота не изменится.
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 21 2014, 04:06
Сообщение #5


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(adnega @ May 21 2014, 10:34) *
Код
while(1)
{
  GPIOC->BSRR = (1 << 13) << 0;
  GPIOC->BSRR = (1 << 13) << 16;
}

Вариант 2 (какой лучше?):
Код
while(1)
{
  GPIOC->BSRR = (1 << 13);
  GPIOC->BRR = (1 << 13);
}
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 21 2014, 04:08
Сообщение #6


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(scifi @ May 21 2014, 12:06) *
Если хочется максимально быстро и именно процессором, то без ассемблера не получится.
Всё прекрасно получается и без ассемблера.
Код
static __inline volatile uint32_t* bb_bit_address(volatile uint32_t* p, uint_fast8_t bit)
{
    return (
        (volatile uint32_t*) (
            (((uint32_t)p & 0xf0000000UL) | 0x02000000UL)
          + ((((uint32_t)p & 0x000fffffUL)<<5) | (bit<<2))
        )
    );
}

#define _PIN_BITBAND_RD_PTR(XPORT, XPIN, ...)    bb_bit_address(&GPIO##XPORT->IDR, XPIN)
#define _PIN_BITBAND_WR_PTR(XPORT, XPIN, ...)    bb_bit_address(&GPIO##XPORT->ODR, XPIN)

#define _PIN_TOGGLE(XPORT, XPIN, ...)  do {*_PIN_BITBAND_WR_PTR(XPORT, XPIN) = ~*_PIN_BITBAND_RD_PTR(XPORT, XPIN);} while (0)
#define pin_toggle(PIN)            _PIN_TOGGLE(PIN)

И далее в программе:
Код
#define PIN_LED_RED           B,9,H,OUTPUT_PUSH_PULL,SPEED_10MHZ // можно и 50MHZ, но не особо нужно...

pin_init(PIN_LED_RED);

for(;;)
   pin_toggle(PIN_LED_RED);


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
derun
сообщение May 21 2014, 04:26
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 133
Регистрация: 12-01-05
Из: Украина. Чернигов
Пользователь №: 1 908



Нужно просто быстро. Порт сконфигурирован на 100 MHz.
Попробовал предложенный способ:
Код
  while (1)
{
        GPIOC->BSRRH = (1 << 13);
      GPIOC->BSRRL = (1 << 13);
}

Этот вариант работает быстрее получил частоту 14 MHz
Думаю этого будет вполне достаточно.
Посмотрел код дизассемблером, выглядит прилично думаю врядли смогу его сильно оптимизировать.
Спасибо всем за советы и adnega за его вариант решения.

Сообщение отредактировал IgorKossak - May 21 2014, 14:51
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
adnega
сообщение May 21 2014, 04:27
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(demiurg_spb @ May 21 2014, 12:18) *
Всё прекрасно получается и без ассемблера.

Bitband для GPIO есть не у всех процессоров STM32, так что лучше не подсаживать)
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 21 2014, 04:44
Сообщение #9


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(derun @ May 21 2014, 11:36) *
Этот вариант работает быстрее получил частоту 14 MHz
Думаю этого будет вполне достаточно.
Посмотрел код дизассемблером, выглядит прилично думаю врядли смогу его сильно оптимизировать.

12 тактов на весь цикл? Многовато. А листинг покажите.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 21 2014, 04:52
Сообщение #10


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(adnega @ May 21 2014, 12:37) *
Bitband для GPIO есть не у всех процессоров STM32, так что лучше не подсаживать)
Ну да.
Но когда есть, то почему бы не пользоваться...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 21 2014, 04:57
Сообщение #11


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(demiurg_spb @ May 21 2014, 12:02) *
Ну да.
Но когда есть, то почему бы не пользоваться...

Потому что в данном случае вы не выиграете ничего.
Go to the top of the page
 
+Quote Post
derun
сообщение May 21 2014, 05:00
Сообщение #12


Частый гость
**

Группа: Свой
Сообщений: 133
Регистрация: 12-01-05
Из: Украина. Чернигов
Пользователь №: 1 908



Цитата(ViKo @ May 21 2014, 10:54) *
12 тактов на весь цикл? Многовато. А листинг покажите.

GPIOC->BSRRL = (1 << 13);
080002d8: ldr r3, [pc, #16] ; (0x80002ec <main+116>)
080002da: mov.w r2, #8192 ; 0x2000
080002de: strh r2, [r3, #24]
117 GPIOC->BSRRH = (1 << 13);
080002e0: ldr r3, [pc, #8] ; (0x80002ec <main+116>)
080002e2: mov.w r2, #8192 ; 0x2000
080002e6: strh r2, [r3, #26]
120 }
080002e8: b.n 0x80002d8 <main+96>

Как-то так
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 21 2014, 05:08
Сообщение #13


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(ViKo @ May 21 2014, 13:07) *
Потому что в данном случае вы не выиграете ничего.
Ну давайте померяемся...
Напишите макрос, инвертирующий состояние линии GPIO без BB и посмотрите, что получится...
На STM32F103 разница очевидна.

Код
8000bb2:    6823          ldr    r3, [r4, #0]
8000bb4:    ea6f 0203     mvn.w    r2, r3
8000bb8:    602a          str    r2, [r5, #0]
8000bba:    e7fa          b.n    8000bb2 <Reset_Handler+0xc2>

Итого по предварительной оценке 18МГц при тактовой 72МГц.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ViKo
сообщение May 21 2014, 05:14
Сообщение #14


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(demiurg_spb @ May 21 2014, 12:18) *
Ну давайте померяемся...
Напишите макрос, инвертирующий состояние линии GPIO без BB и посмотрите, что получится...
На STM32F103 разница очевидна.

Давайте по-другому. rolleyes.gif Будем не инвертировать предыдущее состояние, а конкретно задавать то 0, то 1. Мой "макрос" уже выдан чуть выше.
Отдельно обращу внимание, что в обычном варианте можно одновременно изменить состояние не одного бита, а целой группы. Причем, некоторые можно установить, а некоторые сбросить.

Цитата(derun @ May 21 2014, 12:10) *
Как-то так

А оптимизация не задана?
Go to the top of the page
 
+Quote Post
scifi
сообщение May 21 2014, 05:16
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(derun @ May 21 2014, 13:10) *
Как-то так

Плохенький листинг. Четыре инструкции просятся, чтобы их вынесли за цикл. Оптимизация по скорости не была включена, видимо.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 07:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01478 секунд с 7
ELECTRONIX ©2004-2016