STM32定时器实现100毫秒保存一次数据到SD卡

假设使用定时器3每1毫秒定时;保存至SD卡的函数是StartSave();

第一种情况:定时器快,主循环慢

1、代码设计1(错误的设计

int cnt = 0; //计数
//TIM3中断处理函数
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) 
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  
        cnt ++;   
    }
}
void main(void)
{
   代码段1
   while(1)
   {
     代码段2
     if(cnt %100 == 0)
     {
	StartSave();
     }
     代码段3
   }
}

分析:第一种设计经测试发现并没有按照预期的100毫秒间隔保存;原因何在呢?
很明显后台程序运行较快,当cnt 变为100的倍数时,主循环可能到达“代码段3”,当主循环再次到达
“代码段2”时,定时器中断已经改变了cnt的值。

2、代码设计2(在这种情况下正确)

int cnt = 0; //计数
unsigned char isOK = 0;
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) 
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  
        if(cnt++ % 100 == 0)
             isOK = 1;
    }
}
void main(void)
{
   代码段1
   while(1)
   {
     代码段2
     if(isOK == 1)
     {
	isOK = 0;
        StartSave();
     }
     代码段3
   }
}

设计2避免了1中所出现的问题。
第二种情况:定时器慢,主循环快
在这种情况下上面的代码设计2就出现问题了。出现保存多了的情况。
原因很明显,isOK这个变量的变化相对于主循环来说变化太慢了。会出现isOK一直为1 的情况。
假设定时器定时1ms,主循环0.5ms周期
1、代码设计1(错误的设计)

void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) 
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  
        cnt++;//该值理论保持时间仅1ms
    }
}
void main(void)
{
   unsigned char saveFin = 0;
   代码段1
   while(1)
   {
     代码段2
     if(cnt%100 )
     {
        StartSave();//明显出现100ms内多次保存的情况,因为主循环快
     }
     代码段3
   }
}

2、代码设计2(正确的设计)

unsigned char saveFin = 0;
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) 
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  
        cnt++;//该值理论保持时间仅1ms
    }
}
void main(void)
{
   unsigned char saveFin = 0;
   代码段1
   while(1)
   {
     代码段2
     if(cnt%100 == 0 && saveFin == 0 )
     {
        saveFin = 1;
        StartSave();
     }
     else
     {
        saveFin = 0; 
     }
     代码段3
   }
}

第三种情况:不能确定定时器和main循环周期哪个快的设计
当然主循环的周期不能大于保存周期100ms

unsigned char isOK = 0;
unsigned int clkCnt = 0;
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) 
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); 
        if(clkCnt++ % 10 == 0)
             cnt++;//该值理论保持时间10ms,需要在主循环中清零
    }
}
void main(void)
{
   unsigned char saveFin = 1;//注意这里的初始值为1,与前面设计不同
   代码段1
   while(1) //循环周期不能大于10ms,否则丢失对cnt的判断
   {
     代码段2
     if(cnt%10 == 0) //例如在100ms--110ms之间时将“保存标志”清零
     {
	saveFin = 0; 
     }
     else  //例如在110ms--200ms之间时完成保存
     {
        if(saveFin == 0)//在110ms--200ms之间只能保存一次的代码设计
        {
           startSave();
           saveFin = 1;
        }
     }
     代码段3
   }
}

 

如果有设计缺陷,欢迎大家参与讨论!

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值