STM32定时器,只说最优解

本文介绍如何利用STM32的定时器实现微秒级别的精确延时,通过设置TIM_Period和TIM_Prescaler参数来控制定时器中断周期,并提供了一个具体的延时函数实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

任务:用TIM做一个硬定时实现us级别的延时。

参考:https://blog.youkuaiyun.com/qq_22252423/article/details/76468161

         https://blog.youkuaiyun.com/anchises/article/details/52101512

分析:操作计数的那个值,控制从哪里到哪里,就可以得到时间。也就是做一个稍大的定时,每1000us中断一次,如果要求延时200us那么我就截取其中一部分时间200段给你,要求500us就截取500段给你,用计数值控制。

控制时间基础为1us。怎么搞呢?上代码。定时器的2个参数!

void TIMX_Config(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE);
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
    TIM_TimeBaseInitStruct.TIM_Period=10000-1;//没意义吗?待定
    TIM_TimeBaseInitStruct.TIM_Prescaler=72-1;// 1us就是这里!
    TIM_TimeBaseInitStruct.TIM_ClockDivision=0;
    TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
    TIM_ITConfig(TIM3, TIM_IT_Update,ENABLE);
    TIM_Cmd(TIM3, ENABLE);
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;                 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        //抢占优先级 0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;	             //子优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;		     //使能
    NVIC_Init(&NVIC_InitStructure);

}

 

上面就配置好了!!!完成延时吧

 

void TIM3_Delay(int us)
{
  uint16_t differ=0xffff-us-5;
  TIM_Cmd(TIM3, ENABLE);-------------------------------------打开TIM
  TIM_SetCounter(TIM3, differ);
	while(differ<0xffff-5)
	{
	  differ=TIM_GetCounter(TIM3);
	}
 TIM_Cmd(TIM3, DISABLE);------------------------------------关闭TIM

}

 

上面一个US基的延时函数!!

 

现在我们不调用void TIM3_Delay(int us) 自己在it看看,分析一下这个 TIM_TimeBaseInitStruct.TIM_Period=10000-1;//没意义吗?待定


 
void TIM3_IRQHandler(void)
{     
  TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
  tiggerqqq();
}

哇喔 10ms翻转一次 怎么回事?

1us的时间基础,前面说:10000-1;//无意思? 这样理解还是不深刻,

这个10000就是在it发挥了作用,10000个1us就是10ms!!!!!!

修改成1000就是1ms了

修改成50000就是50ms进去一次中断(就要这个 别太快)

 

 

总结:72M是系统确定的,

参数TIM_Prescaler=72-1决定了时基1us,

参数TIM_Period=10000-1决定了TIM_Period*时基的时间间隔触发中断。

 延时函数OK 理解IT也OK。

基础知识:

结合前面的按键,我们做一个按键长按功能,

思路是:TIM中断去读KEY的管脚,比如1S读一次1S读一次,如果连续20次都是按下的话,那就是长按啦。

char NOADCARDMODE=0;

void TIM3_IRQHandler(void)
{
	static count=0;	
	TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

	if(GPIO_ReadInputDataBit(TSKEY1GPIO ,TSKEY1GPIOPIN)==Reset)
	{
		count++;
		if(count>=20)
		{
			count=0;
			NOADCARDMODE=1;
		}
	}
	else
		count=0;
}

 

注意:

 

1GPIO_ReadInputDataBit和GPIO_ReadOutputDataBit不同,现在按键是上拉输入哦

2 KEY一直是Set按下去才是Reset

3使用一个循环技巧a++       《-------》 a=a%100+1

 

 

 

基础知识:参考:https://blog.youkuaiyun.com/yx_l128125/article/details/7879506

 

 

+++++++++++++++++++++20180719+++++++++++++++

做Spi通讯LCD的TOUCH的时候发现小延时是没有问题的,而在计数器倒减过来的办法会死机

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值