Добрый вечер,
подскажите ответ на такой вот вопрос - как сделать функцию аналогичную HAL_Delay(), только чтобы можно было делать микросекундные задержки?
Можно любой свободный таймер взять, настроить на 1 МГц, тогда 1 "тик" таймера = 1 мкс. И на нем задержку организовать.
@aveal спасибо! Но не сочтите за наглость... 🙂 А можно примерчик? Наверняка кому-то еще пригодилось бы 🙄
void Init_TIM2(void);
void Init_TIM2(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM2_Delay;
TIM2_Delay.TIM_Prescaler = 16 - 1;
TIM2_Delay.TIM_CounterMode = TIM_CounterMode_Up;
TIM2_Delay.TIM_Period = 0;
TIM2_Delay.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2, &TIM2_Delay);
TIM_Cmd(TIM2, ENABLE);
}
void Delay(uint32_t delay)
{
TIM2->ARR = delay;
TIM2->CNT = 0;
while ( TIM2->CNT < delay ) {}
TIM2->ARR = 0;
}
Функция Init_TIM2 инициализирует таймер, а функция Delay включает таймер только в тот момент, когда нужна задержка. В момент, когда я писал этот код, МК у меня работал на 16 МГц, поэтому таймер тикает раз в 1 мкс, т.к. предделитель равен 16 - 1, т.е. 16 МГц/16 = 1 МГц. Этот код написан для stm32f407, но перевести его на f103, думаю, не составит труда. (Инициализация написана на SPL)
TIM2->CNT - регистр, который увеличивается каждый тик таймера. Функция Delay не выйдет из цикла пока в регистре CNT не появится значение равное количеству отсчетов (в мкс). Изначально при входе в эту функцию регистр обнуляется. Регистр CNT является просто счетчиком.
TIM2->ARR - это регистр, который показывает до какого числа должен считать таймер TIM2. В данном случае он просто выполняет роль включения таймера, т.к. при инициализации таймер выключен. Это сделано для того, чтобы он не гонял по кругу без дела, когда он не нужен. В последней строке в регистр ARR записывается нуль, чтобы снова выключить таймер.