Вначале настраиваем таймер
NOTE: Код приведен для частоты тактирования МК = 16МГц. Для другой частоты заменить 16 на нужное значение частоты, в МГц (см. код).
// инициализация таймера - делитель на 16 (при 16МГц - 1 мкс)
void timer_6_init(void)
{
TIM_TimeBaseInitTypeDef TIMER_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
TIM_TimeBaseStructInit(&TIMER_InitStructure);
TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIMER_InitStructure.TIM_Period = 16;
TIMER_InitStructure.TIM_Prescaler = 1;
TIM_TimeBaseInit(TIM6, &TIMER_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// считаем один раз
TIM_SelectOnePulseMode(TIM6, TIM_OPMode_Single);
}
После реализуем две функции задержки, в которые можно передавать время — на которое вызывается задержка в мс и мкс.
uint8_t volatile f_timer_6_end; void wait_us(uint32_t n_usec) { f_timer_6_end = 0; TIM6->PSC = 0; TIM6->ARR = (uint16_t)(16 * n_usec); TIM_Cmd(TIM6, ENABLE); // для того чтобы установился
PSC
TIM6->EGR |= TIM_EGR_UG; TIM6->SR &= ~TIM_SR_UIF; TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE); TIM_Cmd(TIM6, ENABLE); while(f_timer_6_end == 0); } void wait_ms(uint32_t n_msec) { f_timer_6_end = 0; TIM6->PSC = 1000 - 1; TIM6->ARR = (uint16_t)(16 * n_msec); // для того чтобы установился
PSC
TIM6->EGR |= TIM_EGR_UG; TIM6->SR &= ~TIM_SR_UIF; TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE); TIM_Cmd(TIM6, ENABLE); while(f_timer_6_end == 0); }
Данные функции настраивают параметр таймера — число до которого нужно считать. И включает таймер, и уходит в цикл
while(f_timer_6_end == 0){}
Выход из этого цикла возможен, только когда произойдет прерывание — таймер досчитает до нужного значения (см. код ниже). Естественно прерывания в это время должны быть включены.
void TIM6_IRQHandler(void)
{
extern uint8_t volatile f_timer_6_end;
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
TIM6->SR &= ~TIM_SR_UIF;
f_timer_6_end = 1;
TIM_Cmd(TIM6, DISABLE);
TIM_ITConfig(TIM6, TIM_IT_Update, DISABLE);
}