任务:用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的时候发现小延时是没有问题的,而在计数器倒减过来的办法会死机