forked from LonelyWolf/stm32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
delay.c
71 lines (58 loc) · 2.12 KB
/
delay.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stm32l1xx_rcc.h>
#include <misc.h>
#include <delay.h>
funcCallback_TypeDef delay_CallBack;
// TIM6 IRQ handler
void TIM6_IRQHandler(void) {
DELAY_TIM->SR = 0xfffe; // Clear the TIMx's interrupt pending bit (TIM6 rises only UPDATE IT)
if (delay_CallBack) delay_CallBack(); // Call callback function if it non NULL
}
// Init delay timer
void Delay_Init(funcCallback_TypeDef func_CallBack) {
NVIC_InitTypeDef NVICInit;
// Configure basic timer TIM6
// Overflow every half second
// One timer tick = 0,00005s = 0.05ms = 50us
RCC->APB1ENR |= DELAY_TIM_PERIPH; // Enable the TIMx peripheral
DELAY_TIM->CR1 |= TIM_CR1_ARPE; // Auto-preload enable
// DELAY_TIM->PSC = 1600; // TIMx prescaler [ PSC = APB1clock / (PWMfreq * OVFCounter) ]
DELAY_TIM->PSC = SystemCoreClock / 20000; // Delay timer prescaler, must be 1600
DELAY_TIM->ARR = 9999; // Delay timer auto reload value (20000 ticks pers second)
DELAY_TIM->EGR = TIM_EGR_UG; // Generate an update event to reload the prescaler value immediately
// TIMx IRQ
NVICInit.NVIC_IRQChannel = DELAY_TIM_IRQN;
NVICInit.NVIC_IRQChannelCmd = ENABLE;
NVICInit.NVIC_IRQChannelPreemptionPriority = 0x07; // middle priority
NVICInit.NVIC_IRQChannelSubPriority = 0x07; // middle priority
NVIC_Init(&NVICInit);
delay_CallBack = func_CallBack;
if (delay_CallBack) DELAY_TIM->DIER |= TIM_DIER_UIE; // Enable TIMx interrupt
DELAY_TIM->CR1 |= TIM_CR1_CEN; // Counter enable
}
// Disable delay timer
void Delay_Disable(void) {
RCC->APB1ENR &= ~DELAY_TIM_PERIPH; // Disable the TIMx peripheral
}
// Enable delay timer without full initialization
// note: Delay_Init() must be called before
void Delay_Enable(void) {
RCC->APB1ENR |= DELAY_TIM_PERIPH; // Enable the TIMx peripheral
}
// Loop delay for 1 millisecond
void Delay_msec(void) {
volatile uint16_t tStart;
volatile uint16_t tEnd;
volatile uint16_t tDiff;
tStart = DELAY_TIM->CNT;
do {
tEnd = DELAY_TIM->CNT;
if (tEnd < tStart) tDiff = 9999 - tStart + tEnd; else tDiff = tEnd - tStart;
} while (tDiff < 19);
}
// Loop delay for mSecs milliseconds
void Delay_ms(uint32_t mSecs) {
while (mSecs > 0) {
Delay_msec();
mSecs--;
}
}