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

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Как сделать программную задержку на STM32, без использования таймеров
Firer
сообщение Feb 10 2012, 12:51
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 294
Регистрация: 7-01-05
Пользователь №: 1 832



Пожалуйста подскажите.
Пишу в FreeRTOS.
Нужно написать библиотеку работы с LCD.
Там нужна задержка около 1мкс.
Как ее сделать?
Может функцию на ассемблере кто подскажет?
Потому что Keil оптимизирует в ничто вот такой код:
i = 100;
while (i --)
;
Go to the top of the page
 
+Quote Post
Porty
сообщение Feb 10 2012, 13:11
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 246
Регистрация: 28-05-08
Из: г. Ижевск
Пользователь №: 37 893



используй специально для этого предназначенное ключевое слово "volatile", оно говорит компилятору чтоб не оптимизировал значение и работу с этой переменной или кодом.

volatile int i;

...

i = 100;
while (i --)
;
Go to the top of the page
 
+Quote Post
MikeC
сообщение Feb 10 2012, 13:13
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 2-09-05
Пользователь №: 8 169



Попробуйте вставить __no_operation() в тело цикла.
Go to the top of the page
 
+Quote Post
ChipKiller
сообщение Feb 10 2012, 13:15
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 26-12-11
Пользователь №: 69 097



Цитата("Firer")
Может функцию на ассемблере кто подскажет?
Код
XTAL_CLK    equ    24000 ; частота тактирования в килогерцах
....

Delay_us    PROC
        push {lr,r4}
del_us     mov    r4,#((XTAL_CLK/1000)/3)
del1u    subs r4,r4,#1
        bne    del1u
        subs r0,r0,#1
        bne    del_us        
        pop {lr,r4}
        bx    lr
    ENDP
Go to the top of the page
 
+Quote Post
Firer
сообщение Feb 10 2012, 13:46
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 294
Регистрация: 7-01-05
Пользователь №: 1 832



C volatile все равно оптимизит.
Вот я тут сам нашаманил.
Вопрос - на сколько тактов процессора эта функция делает задержку? Сам цикл.
Вносит ли переход сброс конвейера и глотает ли он доп.циклы?
Или 10*2 циклов получается ровно?


__asm void delay_us(void)
{
mov r0,#10
loop
subs r0,#1
bne loop
}
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 10 2012, 17:10
Сообщение #6


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

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



Цитата(Firer @ Feb 10 2012, 16:46) *
C volatile все равно оптимизит.
Не верю.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 10 2012, 17:19
Сообщение #7


Гуру
******

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



Цитата(Firer @ Feb 10 2012, 17:46) *
Вопрос - на сколько тактов процессора эта функция делает задержку? Сам цикл.

Железобетонный способ - измерить с секундомером. Для этого делается задержка не на 10 циклов, а на 10^9 циклов или около того. Не слишком маленькая, чтобы погрешность отсчёта времени была мала, и не слишком большая, чтобы не уснуть с секундомером в руке.
Кстати, задержки для LCD, как правило, не должны быть точными. Обычно достаточно, чтобы было "гарантированно не меньше N циклов".
Go to the top of the page
 
+Quote Post
Юрий_СВ
сообщение Feb 10 2012, 17:59
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 4-05-08
Пользователь №: 37 272



Цитата(Firer @ Feb 10 2012, 16:46) *
Вопрос - на сколько тактов процессора эта функция делает задержку? Сам цикл.
Вносит ли переход сброс конвейера и глотает ли он доп.циклы?
Или 10*2 циклов получается ровно?

ПМСМ, переход (кроме последнего раза) будет заново заполнять конвеер.
(не заполняет тогда, когда не выполняется условие - нет перехода)

Лучше 1 раз посчитать, используя системный таймер, с предделением 1.
(Вызов функции тоже переход с заполнением конвеера.)

Более того, время выполнения, возможно, будеть зависеть от модели контроллера (разрядность памяти)
и настроек регистра доступа к памяти.

Мне тоже интересна эта тема. Если посчитаете системным таймером - поделистесь, пожалуйста.

По крайней мере на IAR вариант с volatile у меня работает.
Код
void delay_y()
{
volatile u32_t i, ty;
for(i=0; i<10000; i++) ty=GPIOA_ODR;
}


И ещё замечание.. практически гарантировано не будет заоптимизировано обращение к портам.
Но ваш вариант лучше - точнее.

Сообщение отредактировал Юрий_СВ - Feb 10 2012, 18:40
Go to the top of the page
 
+Quote Post
ukpyr
сообщение Feb 10 2012, 18:10
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



Код
    inline void _delay_loops(U32 loops) {
        asm volatile (
            "1: SUBS %[loops], %[loops], #1 \n"
            "   BNE 1b \n"
            : [loops] "+r"(loops)
        );
    }
    #define delay_us( US ) _delay_loops( (U32)((double)US * F_CPU / 3000000.0) )
    #define delay_ms( MS ) _delay_loops( (U32)((double)MS * F_CPU / 3000.0) )
    #define delay_s( S )   _delay_loops( (U32)((double)S  * F_CPU / 3.0) )
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 11 2012, 06:34
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



В простых примерах от Keil есть программные задержки. Работают.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 11 2012, 07:47
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Вот такое еще работает: DelayMS(2);


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Feb 11 2012, 11:38
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Firer @ Feb 10 2012, 13:51) *
Пожалуйста подскажите.
Пишу в FreeRTOS.
Нужно написать библиотеку работы с LCD.
Там нужна задержка около 1мкс.
Как ее сделать?

Посмотрите DWT счетчик (DWT_CYCCN, описано тут и здесь): присутствует во всех Cortex по стандарту ARM. Это 32-битное слово, которое "тикает" с частотой ядра.
Счетчик надо проинициализировать (включить):
Код

    #define    DWT_CYCCNT    *(volatile uint32_t *)0xE0001004
    #define    DWT_CONTROL   *(volatile uint32_t *)0xE0001000
    #define    SCB_DEMCR     *(volatile uint32_t *)0xE000EDFC

    if (!(DWT_CONTROL & 1))
    {
        SCB_DEMCR  |= 0x01000000;
        DWT_CYCCNT  = 0;
        DWT_CONTROL|= 1; // enable the counter
    }


Задержки можно организовывать так:

Код
uint32_t DWT_Get(void)
{
    return DWT_CYCCNT;
}
__inline
uint8_t DWT_Compare(int32_t tp)
{
    return (((int32_t)DWT_Get() - tp) < 0);
}

void DWT_Delay(uint32_t us) // microseconds
{
    int32_t tp = DWT_Get() + us * (SystemCoreClock/1000000));
    while (DWT_Compare(tp));
}


Безусловно, по причине задержек исполнения самих инструкций абсолютно точно не будет. Однако же, скажем при 72MHz ядра, даже для 1мкс аддитивная составляющая будет небольшой и постоянной.

Сообщение отредактировал KnightIgor - Feb 11 2012, 11:49
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 11 2012, 16:05
Сообщение #13


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(KnightIgor @ Feb 11 2012, 17:38) *
Посмотрите DWT счетчик

Ух ты! Отличная штука, не знал про неё. Проверил на STM32F103 - работает.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 11 2012, 18:31
Сообщение #14


Гуру
******

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



Действительно, очень интересно. Спасибо за наводку!
Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 15 2012, 17:02
Сообщение #15


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Очень жаль, что остальные счётчики все 8-битные.
На оффтопике (LPC17xx) для счётчика циклов достаточно RIT, который остался в наследство от предыдущих LPC а для осевого тика времени в Cortex-M3 стандартизированный таймер нашёлся.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 20:03
Рейтинг@Mail.ru


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