Jump to content

    

Чем заменить DWT на STM32F030F4 для задержек delay_us и _ms?

Чем заменить DWT на STM32F030F4 для задержек delay_us и delay_ms ?
На STM32F105RBT6 замечательно работало так:

Спойлер

 

 


#define F_CPU 72000000UL

//--------------------------------------------------------------------------------------------

{//настройка DWT
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // Включаем TRACE
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // Разрешаем DWT счетчик    
}

//--------------------------------------------------------------------------------------------

void _delay_us(uint16_t us)
{
//////////////////////////////////////////////////////////////////////////////////////////////
DWT->CYCCNT = 0; //Обнуляем счетчик    
if (0x00 == us)    return;
uint32_t period = 0;
period = ((F_CPU/1000000)*us)-17;      //17 подобранныq коэфициент в ЛА для STM32F105RB 72мГц ядро, 50мГц порт     
while(DWT->CYCCNT < period){}    
//////////////////////////////////////////////////////////////////////////////////////////////
}
void _delay_ms(uint16_t ms)
{
//////////////////////////////////////////////////////////////////////////////////////////////
DWT->CYCCNT = 0; //Обнуляем счетчик        
uint32_t period = 0;    
period = ((F_CPU/1000)*ms)-17;  //17 подобранныq коэфициент в ЛА для STM32F105RB 72мГц ядро, 50мГц порт         
while(DWT->CYCCNT < period){}    
//////////////////////////////////////////////////////////////////////////////////////////////    
}

 

 

 

Можно ли использовать SysTick без прерываний, если можно, то как это сделать на CMSIS (под Keil 5.26) ?
Если нельзя, то как это сделать на CMSIS на самом, по вашему мнению, ненужном таймере STM32F030F4?

Share this post


Link to post
Share on other sites
16 minutes ago, Donker said:

Если нельзя, то как это сделать на CMSIS на самом, по вашему мнению, ненужном таймере STM32F030F4?

Можно и без прерываний, но с ними все же проще. Делал раньше так (если в проекте не нужна RTOS).

Для примера вполне сгодится. 

 

Spoiler

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// SysTimer (SysTick Timer)
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef RTOS

#include <stm32f0xx.h>

static volatile bool isCountingDone = true;
static uint32_t sysTickBaseFrequencyHz;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

extern "C" void SysTick_Handler()
{
	isCountingDone = true;
	CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk); // Stop Systick
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void stm32f0::SysTimer::setBaseFrequencyHz(uint32_t frequencyHz)
{
	sysTickBaseFrequencyHz = frequencyHz;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

stm32f0::SysTimer::SysTimer()
{
	CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk); // Stop Systick
	NVIC_SetPriority(SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1); // Lowest Priority
	NVIC_EnableIRQ(SysTick_IRQn);
	SysTick->VAL = 0;
	SET_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk); 
	SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); 	// Enable SysTick IRQ
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void stm32f0::SysTimer::delayMs(uint16_t timeMs)
{
	while (not isCountingDone);
	isCountingDone = false;
	CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk); // Stop Systick
	SysTick->LOAD  = (uint32_t)(timeMs * (sysTickBaseFrequencyHz / 1000) - 1); // set reload register
	SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk); 	// Run Systick
	while (not isCountingDone); // Wait SysTickIrq
}
  
#endif

 

 

Share this post


Link to post
Share on other sites

Forger

Спасибо ваш код пригодиться для когда понадобиться неблокирующая задержка, мне же пока требуется простейшая блокирующая.

Ещё вопрос в STM32F030F4 таймер SysTick   24 битный?

Share this post


Link to post
Share on other sites
8 minutes ago, Donker said:

Спасибо ваш код пригодиться для когда понадобиться неблокирующая задержка, мне же пока требуется простейшая блокирующая.

Она и есть блокирующая, см. внимательнее. Этот же код можно переписать без использования обработчика прерываний, он даже проще станет :)

Использую такие задержки в примитивных проектах,

А во всех остальных - RTOS, где этот таймер обязателен (собственно для RTOS он и создан). Поэтому я бы не назвал этот таймер "бесполезным" ;)

Share this post


Link to post
Share on other sites

Если нужна незатейливая busy waiting задержка, можно ваще без таймеров. Замерить количество выполненных __NOP за микросекунду. Можно и такты посчитать. И юзать это число для для расчёта любой другой задержки. 

SysTick 24 бита, да 

Edited by MX_Master

Share this post


Link to post
Share on other sites
9 minutes ago, MX_Master said:

Если нужна незатейливая busy waiting задержка, можно ваще без таймеров. Замерить количество выполненных __NOP за микросекунду. Можно и такты посчитать. И юзать это число для для расчёта любой другой задержки. 

Это железно прокатит, если код будет выполняется из RAM.

С кодом из FLASH все не так просто.

 

Если же не требуется высокая точность, то, вполне сгодится 

Share this post


Link to post
Share on other sites
45 минут назад, Forger сказал:

если код будет выполняется из RAM.

И за время выполнения этого кода не возникнет ни одного прерывания.

Share this post


Link to post
Share on other sites
Just now, Сергей Борщ said:

И за время выполнения этого кода не возникнет ни одного прерывания.

Судя по исходном посту, прерывания не рассматриваются в принципе  :)

Share this post


Link to post
Share on other sites

Если не секрет для чего вы применяете микросекундные задержки?

Не приопмню чтобы у меня возникала в них потребность

Share this post


Link to post
Share on other sites

Какая тут дремучая ардуинщина: задержки... а дальше и того хуже - ещё и на NOP-ах их делают.... и при этом о Cortex-M7 рассуждают... :shok:

Люди, Вам зачем все эти Cortex-M7? Может вернуться к абдурине? Уж, сорри, но моё мнение: с таким уровнем подхода к алгоритмам работы - ARM осваивать ещё рано.

Share this post


Link to post
Share on other sites
2 minutes ago, jcxz said:

и при этом о Cortex-M7 рассуждают... :shok:

Нет тут никаких M7, речь всего лишь про примитивные вещи для примитивных проектов на старом M0 :)

Share this post


Link to post
Share on other sites
7 минут назад, Forger сказал:

Нет тут никаких M7, речь всего лишь про примитивные вещи для примитивных проектов на старом M0 :)

Здесь может и да. Но в соседних темах эти же персоналии рассуждают о нехватке вычислительной мощности M7. И теперь становятся понятны причины сей нехватки.

Да даже и здесь - неизвестно ведь зачем ТСу эта задержка? С большой долей вероятности можно предположить, что речь снова идёт о банальном абдуриновском ногодрыге или каком-то подобном алгоритме работы... :to_take_umbrage:

Share this post


Link to post
Share on other sites
2 minutes ago, jcxz said:

 И теперь становятся понятны причины сей нехватки.

:acute:

Share this post


Link to post
Share on other sites

Как сказал один умный человек: "люди не хотят читать доки". И это корень большинства вопросов.

Раз автор не указал цель, точность и поправку на прерывания в задержках, то и советы были соответствующие.

Share this post


Link to post
Share on other sites

Вот что мне надо было:

Спойлер

 


#define F_CPU 48000000UL

//----------------------------------------настройка SysTick---------------------------------------------------------------------

SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; //ставим бит номер 0 в 0 (на всякий случай) //т.е. не используем прерывания
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; //SysTick_CTRL_TICKINT_Msk - включаем тактирование от HCLK//SysTick_CTRL_ENABLE_Msk - включаем таймер SysTick
    
//-------------------------------------------------------------------------------------------------------------------------------    

void _delay_us(uint16_t us)
{
//////////////////////////////////////////////////////////////////////////////////////////////    
SysTick->LOAD = ((F_CPU/1000000)*us)-30;    //загружаем число тактов ожидания (не более 2^24)// 30 - вычитание тактор накладных    расходов
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //включаем таймер SysTick
    
while(0x00 == (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)) {}    //0x10000 - бит номер 16 //SysTick_CTRL_COUNTFLAG_Msk //(uint32_t)0x10000U
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //выключение таймер SysTick
//////////////////////////////////////////////////////////////////////////////////////////////
}

void _delay_ms(uint16_t ms)
{
//////////////////////////////////////////////////////////////////////////////////////////////
while(ms)    
  {
    ms--;    
  _delay_us(1000);
  }
//////////////////////////////////////////////////////////////////////////////////////////////    
}

 

 


 

можете предложить как сэкономить байт другой флеша или оперативки, а также предложить научно обоснованную
поправку вместо "30" , она явно великовата, но ЛА  через ногодрыг PB1 трудно понять погрешности
самого ногодрыга.

На DWT всё это было технически совершенней  особенно нравилась что первой строкой:

DWT->CYCCNT = 0; //Обнуляем счетчик
 
начинался отсчёт и поправка требовалась меньше.

Edited by Donker

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now