我使用的是STM32F042C4,我想设置以µs为单位的延迟计时器。但当我设置所有内容时,我会得到一个大2倍的。我正在寻找任何我可能错过的处方药,但我没有找到任何东西。
设置为:
//enable peripheral clock for TIM17
RCC->APB2ENR |= (0x1U << 18);
//Set HSI48 as clock source
while((RCC->CR2 >> 17) & 0x01U != 0x01U){ //wait for HSI48 ready
}
RCC->CR2 |= (0x1U << 16); //Enable HSI48
RCC->CFGR |= 0x00000003U; //Set HSI48 as clock source
//set TIM17 prescaler value for tick every 0,1 ms
TIM17->PSC = 4799;
//call delay func -> 10 000 should result in 1 sec delay, BUT I GET 2 SECONDS
void TIM17_delayUs(10000);
void TIM17_delayUs(uint16_t delay){
TIM17->CNT = 0x0U; //null counter
TIM17->CR1 &= ~(0x1U << 7); //ARR buffer disable
TIM17->ARR = (48*delay)/(prescaler+1); //set delay
TIM17->CR1 |= (0x1U << 7); //ARR buffer enable
TIM17->CR1 |= (0x1U << 0); //enable counter
TIM17->ARR = 0xFFFFU; //reset ARR
while((TIM17->SR & 0x1U) == 0){ //wait for overflow event
}
TIM17->CR1 &= ~(0x1U << 0); //disable timer
TIM17->SR &= ~(0x1U << 0); //clear event flag
}
如果我查看寄存器,我可以看到AHB和APB预分频器是1,所以定时器的时钟源应该是48Mhz。在计时器之前,我看不到另一个预分频器,那么问题出在哪里呢?
STM32F442 的时钟图
TIM17 框图
我找不到错误。但是,如果prescaler
的值是4799,那么TIM17->ARR = (48*delay)/(prescaler+1);
行的求值结果为100,这似乎是错误的。
这段代码本可以用一种更简单的方式编写。代码越少,出错的可能性越低。忘记ARR,TIM启动&停止和中断标志。将ARR保持在最大值(0xffff,默认值(。换句话说,使TIM17成为一个自由运行的定时器,它总是启用的。
// TIM17 Settings
TIM17->PSC = 4799; // Set prescaler
TIM17->CR1 |= TIM_CR1_CEN; // Start timer
TIM17->EGR |= TIM_EGR_UG; // Generate update event for prescaler update
// Delay Function
delay100us(uint16_t us100) {
uint16_t start = TIM17->CNT;
while ((TIM17->CNT - start) < us100);
}