任务:我们用TIM做一个us级别的延时。
路子1:做一个很小的定时,每1us就中断一次,你现在如果要延时200us那么我就做这个动作200次!
路子2:做一个稍大的定时,比如1000us中断一次,你现在如果要延时200us那么我就截取其中一部分时间段给你,用计数值控制。
其中路子2比较好,在前面博文已经实践了。
现在是说一说路子了的模块。
头文件:
#ifndef __TIM4ER_H #define __TIM4ER_H #include "stm32f10x_tim.h" #include "stm32f10x_rcc.h" void Do_TIM4_Init(void); void TIMDelay_Nus(int Times); void TIMDelay_Nms(int Times); #endif
#include "TIM4er.h" #define TIM4Period 8 #define TIM4Prescaler 9 void Do_TIM4_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); TIM_TimeBaseStruct.TIM_Period=TIM4Period; TIM_TimeBaseStruct.TIM_Prescaler=TIM4Prescaler; TIM_TimeBaseStruct.TIM_ClockDivision=0; TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStruct); TIM_ARRPreloadConfig(TIM4,ENABLE); } void TIMDelay_Nus(int Times)//u16 Times { TIM4->CR1 |=TIM_CR1_CEN; while(Times--) { while((TIM4->SR & TIM_FLAG_Update)==RESET); TIM4->SR &= ~TIM_FLAG_Update; } TIM4->CR1 &=~TIM_CR1_CEN; } void TIMDelay_Nms(int Times) { while(Times--) { TIMDelay_Nus(1000); } }
现在分析一下:
void TIMDelay_Nus(int Times)//u16 Times { TIM4->CR1 |=TIM_CR1_CEN;-------------------------------------打开TIM while(Times--) { while((TIM4->SR & TIM_FLAG_Update)==RESET);------定时器到了溢出 TIM4->SR &= ~TIM_FLAG_Update; -----再次开始计数 } TIM4->CR1 &=~TIM_CR1_CEN;------------------------------------关闭TIM }
很好理解吧 一次溢出就是1us如何做到的?
72M 除以两个数 TIM4Period TIM4Prescaler
72000000
————————————=1 000 000HZ =1US
9*8
测试结果 1us误差比较大呀。int qq=0;
void revseqq(void)
{
qq=qq?0:1;
}
while(1)
{
TIMDelay_Nus(1);
revseqq();
}
再试试前面的路子呢?
误差更大一点!
while(1)
{
TIM3_Delay(1);
revseqq();
}