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

 
 
5 страниц V  < 1 2 3 4 5 >  
Reply to this topicStart new topic
> Как сделать программную задержку на STM32, без использования таймеров
Tahoe
сообщение Jan 7 2013, 12:38
Сообщение #31


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(KnightIgor @ Jan 7 2013, 12:20) *
Какие грабли, если его читать?

Если только читать - никаких. Однако и здесь, и здесь, при инициализации предлагается запись в DWT_CYCCNT. Как будет вызываться инициализация, единожды или при каждой задержке, оставим за скобками, ибо это отдельный вопрос.

Итого. Я бы рекомендовал исключить строку:
Код
DWT_CYCCNT  = 0;


Цитата(HHIMERA @ Jan 7 2013, 15:59) *
И в Cortex M0 есть???

Ну самостоятельно посмотреть?
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Jan 7 2013, 12:46
Сообщение #32


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Цитата(Tahoe @ Jan 7 2013, 15:38) *
самостоятельно посмотреть?


Смотрел... Дошёл до
Цитата
This document is only available in a PDF version to registered ARM customers.

и усё... )))
Go to the top of the page
 
+Quote Post
SSerge
сообщение Jan 8 2013, 07:16
Сообщение #33


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

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Цитата(HHIMERA @ Jan 7 2013, 19:46) *
Смотрел... Дошёл до

и усё... )))

Так зарегистрируйтесь, это не сложно.
Впрочем, не поможет, в М0 и М0+ такого регистра нет.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Jan 8 2013, 08:52
Сообщение #34


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Цитата(SSerge @ Jan 8 2013, 11:16) *
в М0 и М0+ такого регистра нет.

Вот и я о том же...
И если последние редакции CMSIS в файлах core_cm3.h и core_cm4.h содержат информацию о DWT, то в core_cm0.h она отсутствует напрочь...
Да и в самом железе STM32F0XX DWT не работает...
Go to the top of the page
 
+Quote Post
pitt
сообщение Jan 27 2013, 00:00
Сообщение #35


Местный
***

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



Цитата(HHIMERA @ Jan 7 2013, 06:59) *
Угу... щазз...
А ещё есть code reordering...
Или будете доказывать, что и code reordering "Никакого отношения к оптимизации"???

Не стоит путать божий дар с яичничей, а key word "volatile" с оптимизирующим компилятором FYI


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Jan 27 2013, 09:33
Сообщение #36


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Ну так и не путайте... biggrin.gif

Сообщение отредактировал HHIMERA - Jan 27 2013, 09:33
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Jan 27 2013, 10:23
Сообщение #37


Знающий
****

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



Цитата(Tahoe @ Jan 7 2013, 13:38) *
Итого. Я бы рекомендовал исключить строку:
Код
DWT_CYCCNT  = 0;

Логично. Но один разочек при старте не мешает:
Цитата
"The debugger must initialize this to 0 when first enabling"
(на стр. 11-19 документа ).

Кстати, снова о "подводных" камнях: там же по тексту DWT счетчик явно предлагается для отсчета коротких времен в приложении:
Цитата
Applications and debuggers can use the counter to measure elapsed execution
time. By subtracting a start and an end time, an application can measure time
between in-core clocks (other than when Halted in debug). This is valid to 2^32
core clock cycles (for example,almost 86 seconds at 50MHz).


DWT действительно нет в -M0. Тогда можно использовать SYSTICK: находить разницу между двумя значениями SYST_CVR с учетом значения перезагрузки SYST_RVR. Чаще всего SYSTICK запускают на генерацию перрывания каждые 1ms. То есть, вполне можно запускать программные задержки на меньшие времена (десятки - сотни мкс).

Сообщение отредактировал KnightIgor - Jan 27 2013, 10:36
Go to the top of the page
 
+Quote Post
Tahoe
сообщение Jan 27 2013, 15:05
Сообщение #38


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(KnightIgor @ Jan 27 2013, 14:23) *
Но один разочек при старте не мешает:
Цитата
"The debugger must initialize this to 0 when first enabling"

Дело за малым - как-либо узнать, что текущий "enabling" будет действительно "first", а не "second", "third" или "hundredfivehundred". sm.gif

Хотя решение, конечно, очевидно: просто инициализировать счетчик при старте. По крайней мере, для периодических задач профилирования, это не станет серьезной проблемой. Разве что экхотика какая, например, время стартапа подсчитывается, но и в этом случае, по идее, к моменту перехода на main() подсчет должен быть уже выполнен. Другой экзотики в голову не приходит.


Цитата(KnightIgor @ Jan 27 2013, 14:23) *
DWT счетчик явно предлагается для отсчета коротких времен в приложении

А вот этого не видел. Мерси.


Насчет моих предположений про DWT, вот чуть конкретнее, в контексте отладчика:
Цитата(IAR: What is your application doing inside your microcontroller? Debugging software applications on ARM Cortex-M3 and Cortex-M4 devices[/url)
Data Watchpoint and Trace
The Data Watchpoint and Trace (DWT) provides a set of functions that collect information from the system buses and generates events to the ITM for packetizing and time stamping and further distribution on the SWO channel.

... и далее по тексту, правда инфы не густо.

Go to the top of the page
 
+Quote Post
allsettingsdone
сообщение Jan 31 2013, 12:35
Сообщение #39


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284



Ну а вот я попробывал сделать так:
Код
#define F_CPU 8000000UL
void delay_us(uint32_t us)
{
    for(volatie unsigned int i=0;i<((F_CPU/1000000-3)*us);i++) {}
}

где цифра "3" в условии цикла - это поправка, связанная с тем что на создание и сравнение условия также уходят такты. Я поставил аргумент функции 5 млн (т.е 5 секунд), засекал на внешнем таймере: получается довольно точно 5,3 с. Без поправочного коэффициента получается 8,4 с.
И, кстате, скажите кто знает: что значит "UL" после частоты? И когда обьявляем переменную "uint16_t" - что значит _t ? И всегда ли эта переменная занимает одну ячейку памяти или под неё выделяется целые 32 бита? И что просходит с переменной обьявленной таким способом, если мы записываем в неё например 1млн?
Что плохого/хорошего скажите про всё это?
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 31 2013, 13:13
Сообщение #40


Гуру
******

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



Цитата(allsettingsdone @ Jan 31 2013, 16:35) *
И, кстате, скажите кто знает: что значит "UL" после частоты?

Это значит, что константа имеет тип unsigned long. Этот суффикс имеет смысл приписывать, если код может использоваться на системах с 16-битным типом int (когда 8000000 не помещается в int), что для приведённого примера не актуально.

Цитата(allsettingsdone @ Jan 31 2013, 16:35) *
И когда обьявляем переменную "uint16_t" - что значит _t ?

Ничего это не значит. Тип uint16_t, как и многие другие подобные типы, объявлен в файле stdint.h в соответствии со стандартом C99. Просто кто-то так назвал эти типы.

Цитата(allsettingsdone @ Jan 31 2013, 16:35) *
И всегда ли эта переменная занимает одну ячейку памяти или под неё выделяется целые 32 бита?

Что есть ячейка памяти? Бит? Байт? 2 байта? 4 байта? 16 байт? И т.д. Так или иначе, ответ зависит от контекста: если переменная размещается в регистре или стеке, то скорее всего она занимает 32 бита. Статические переменные могут занимать меньше памяти.

Цитата(allsettingsdone @ Jan 31 2013, 16:35) *
И что просходит с переменной обьявленной таким способом, если мы записываем в неё например 1млн?

Если в uint16_t записать 1000000, то скорее всего там окажется 16960 (то есть срежутся старшие биты).

Цитата(allsettingsdone @ Jan 31 2013, 16:35) *
Что плохого/хорошего скажите про всё это?

Код хорош тем, что прост, но плох тем, что время исполнения зависит от версии компилятора, уровня оптимизации, скорости процессора и т.д.
Кстати, вам совсем не помешает почитать учебник по языку Си.
Go to the top of the page
 
+Quote Post
PoReX
сообщение Jan 31 2013, 13:25
Сообщение #41


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

Группа: Свой
Сообщений: 112
Регистрация: 1-05-09
Из: Ростов-на-Дону
Пользователь №: 48 518



Цитата(allsettingsdone @ Jan 31 2013, 16:35) *
Ну а вот я попробывал сделать так:
Код
#define F_CPU 8000000UL
void delay_us(uint32_t us)
{
    for(volatie unsigned int i=0;i<((F_CPU/1000000-3)*us);i++) {}
}

где цифра "3" в условии цикла - это поправка, связанная с тем что на создание и сравнение условия также уходят такты. Я поставил аргумент функции 5 млн (т.е 5 секунд), засекал на внешнем таймере: получается довольно точно 5,3 с. Без поправочного коэффициента получается 8,4 с.

Лучше уберите этот поправочный коэффициент, а то придет время и понадобится вам задержка меньше чем 3 мкс. Если нужно точно засечь время, лучше использовать таймеры, например, системный.


--------------------
«У современных мобильных телефонов такая же вычислительная мощь, что и у компьютеров NASA в 60-е годы. И в то время этого хватало, чтобы запустить человека в космос, а сегодня — только чтобы запускать птиц в свиней.»
Go to the top of the page
 
+Quote Post
Tahoe
сообщение Jan 31 2013, 14:05
Сообщение #42


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(allsettingsdone @ Jan 31 2013, 16:35) *
когда обьявляем переменную "uint16_t" - что значит _t ? И всегда ли эта переменная занимает одну ячейку памяти или под неё выделяется целые 32 бита?

Аккуратнее с такими вопросами. Грамотного Си-программера, _абсолютно_ не должно волновать, сколько там ячеек занимает uint16_t. Единственное, что он должен твердо помнить, что:
1. Это беззнаковый тип.
2. Что размер этого типа 16 бит.

Когда программер станет опытным, он узнает ответ и на вопрос о "ячейках", но пока, упаси Б-г об этом задумываться. Потому что итог будет печальным - программа на ассемблере, писаная Си-синтаксисом.


Цитата(allsettingsdone @ Jan 31 2013, 16:35) *
И что просходит с переменной обьявленной таким способом, если мы записываем в неё например 1млн?

См. выше. Единственное, что должен знать грамотный Си-программер, это что при записи в uint16_t числа > 0xFFFF, произойдет переполнение переменной этого типа. И, повторюсь, не дай Б-г начать задумываться о чем-то бОльшем. Во всяком случае, на данном этапе.
Go to the top of the page
 
+Quote Post
allsettingsdone
сообщение Jan 31 2013, 16:21
Сообщение #43


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284



Так а на чем же остановиться в поиске функции для програмной задержки?
Go to the top of the page
 
+Quote Post
Tahoe
сообщение Jan 31 2013, 16:43
Сообщение #44


Местный
***

Группа: Свой
Сообщений: 459
Регистрация: 30-03-06
Из: Москва
Пользователь №: 15 600



Цитата(allsettingsdone @ Jan 31 2013, 20:21) *
Так а на чем же остановиться в поиске функции для програмной задержки?

Да на чем угодно, лишь бы написано было понятно и пользоваться удобно:

Код
////////////////////////////////////////////////////////////////////////////////
// DELAY ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#pragma    inline
void    BspDelayTicks(            uint32_t        Ticks )
{
    if (!(SCB_DEMCR & 0x01000000))
    {
        CoreDebug->DEMCR    |=    0x01000000;
        DWT->CYCCNT            =    0;
        DWT->CTRL            |=    1 << DWT_CTRL_CYCCNTENA_Pos;                    // enable the counter
    }

    while( DWT->CYCCNT < Ticks );
}

////////////////////////////////////////////////////////////////////////////////
#pragma    inline
void    BspDelay_uSec( volatile    uint32_t        uSec )
{
    while( uSec-- )
    {
        BspDelayTicks( BSP_MCLK_HZ/1000000 );
    }
}

////////////////////////////////////////////////////////////////////////////////
#pragma    inline
void    BspDelay_mSec( volatile    uint32_t        mSec )
{
    while( mSec-- )
    {
        BspDelayTicks( BSP_MCLK_HZ/1000 );
    }
}
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Jan 31 2013, 19:36
Сообщение #45


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Цитата(Tahoe @ Jan 31 2013, 19:43) *
лишь бы написано было понятно
Код
    if (!(SCB_DEMCR & 0x01000000))
    {
        CoreDebug->DEMCR    |=    0x01000000;

Да вроде как и понятно... но вот глаз режет...

Вроде как ...
Код
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
Go to the top of the page
 
+Quote Post

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

 


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


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