历史上的今天
返回首页

历史上的今天

今天是:2024年10月21日(星期一)

正在发生

2018年10月21日 | STM32学习之:定时器程序设计探讨

2018-10-21 来源:eefocus

假设使用定时器3每1毫秒定时;保存至SD卡的函数是StartSave();
第一种情况:定时器快,主循环慢
1、代码设计1(错误的设计)
[cpp] view plain copy
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(在这种情况下正确)
[cpp] view plain copy
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(错误的设计)
[cpp] view plain copy
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(正确的设计)
[cpp] view plain copy
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
[cpp] view plain copy
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  
   }  
}

推荐阅读

史海拾趣

Fortiming Corporation公司的发展小趣事

背景:在电子行业,成本控制和供应链管理是企业竞争力的重要体现。

发展:Fortiming不断优化供应链管理流程,与上游供应商建立长期稳定的合作关系,确保原材料的稳定供应和质量可靠。同时,公司还通过技术创新和工艺改进,降低生产成本,提高产品竞争力。这些措施使得Fortiming在激烈的市场竞争中保持了良好的盈利能力。

Amphenol Thermometrics公司的发展小趣事

背景:在电子行业,成本控制和供应链管理是企业竞争力的重要体现。

发展:Fortiming不断优化供应链管理流程,与上游供应商建立长期稳定的合作关系,确保原材料的稳定供应和质量可靠。同时,公司还通过技术创新和工艺改进,降低生产成本,提高产品竞争力。这些措施使得Fortiming在激烈的市场竞争中保持了良好的盈利能力。

场效应半导体(Cmos)公司的发展小趣事

高通(Qualcomm)在移动通信领域的迅猛发展也离不开CMOS技术的支持。高通在CMOS技术研发方面投入了大量资源,成功地将CMOS技术应用于其移动通信芯片产品中。这些芯片产品以其卓越的性能和出色的功耗控制而广受手机制造商的青睐。随着移动通信技术的不断进步,高通在CMOS技术方面的创新也不断推动着移动通信产业的发展。

HARTING公司的发展小趣事

韩国三星电子(Samsung Electronics)在CMOS技术方面也取得了显著成就。作为一家综合性电子企业,三星电子在CMOS技术研发方面投入了大量资金和人力资源。通过不断的技术创新和生产优化,三星电子成功推出了多款高性能、低功耗的CMOS芯片产品,广泛应用于智能手机、平板电脑等电子产品中。这些产品以其卓越的性能和出色的品质赢得了市场的广泛认可,使三星电子在全球半导体市场上占据了一席之地。

ECI公司的发展小趣事

ECI公司深知品质对于企业生存的重要性。因此,公司建立了严格的质量管理体系,从原材料的采购到生产流程的每一个环节都进行严格的质量控制。此外,ECI还引入了国际先进的质量检测设备和技术,确保产品的每一个细节都符合高品质的要求。正是这种对品质的坚持和追求,让ECI公司在竞争激烈的电子行业中脱颖而出。

高通(GENITOP)公司的发展小趣事

1964年,超霸电池的前身——金山工业集团在中国香港地区成立,最初专注于生产9伏干电池,以满足当时收音机等电子产品的需求。这一时期的超霸电池以其稳定的质量和可靠的性能迅速在市场上站稳脚跟。随着电子产品的普及,金山工业敏锐地捕捉到市场机遇,逐步扩大生产规模,为后续的发展奠定了坚实基础。

问答坊 | AI 解惑

我的硬件之路---致初学者

小人物的心路历程《我的硬件之路》…

查看全部问答>

直流电平转换——TI解决方案

在多电平系统中,直流电平转换是很常见的事情,这直接关系到一个系统设计的成败,TI在直流电平转换上的方案还是不错的,如SN74LVC4245(3.3V~5V),SN74AVC8T245(1.2V~3.6V)等,附件是TI的相关器件的详细介绍。 …

查看全部问答>

关于LPC1343的USB_HID键盘的端点数据发送问题

我用lpc1343枚举了一个USB HID键盘设备,描述符我用的USB 键盘的,以前用过没问题的。 用end1 发送键盘数据,但是空闲时段一直发送0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00.但是按键数据又是正常的,就是表象没什么影响。不知道会不会对别的有影 ...…

查看全部问答>

上海汉的信息技术股份有限公司 --诚招嵌入式软件工程师

上海汉的信息技术股份有限公司  诚招嵌入式软件工程师 任职要求: 1.本科以上学历,计算机软件或相关专业,2年以上工作经验。 2.具有2年以上C++语言,linux或unix开发经验。 3.熟悉嵌入式开发。 4.懂日语者优先。 有意者请将简历发 ...…

查看全部问答>

关于单片机与PC机的串口通信问题。急!

单片机与PC机的串口通信时,刚开始的时候传的数据是正确的,工作一段时间,传的数据就出现错误,当向PC机传固定的一个数据时,还出现时而正确,时而错误的情形,不知道这是为什么。…

查看全部问答>

evc模拟器不能用

我装了EVC还有模型器,为什么不模拟器不能用…

查看全部问答>

iar 2.2 编译release版时出错,请教大虾们

Building configuration: gas - Release Error[e16]: Segment DATA16_Z (size: 0xb9 align: 0x1) is too long for segment definition. At least 0x38 more bytes needed. The pro××em occurred while processing the segment placement comma ...…

查看全部问答>

msp430f149控制DHT11温湿度传感器的串口程序

哪位大侠写过msp430f149控制DHT11温室读传感器的串口显示程序,我调了好久总是不能显示数据 ?不知道什么原因?高手帮忙啊,不胜感激之至!! 串口程序; #include  \"usart.h\"struct DHT_data{ unsigned char DH_H;    ...…

查看全部问答>

请打大牛们指导一下,ucos的中断处理是不是有问题?

ucos ii 的中断处理过程是这样的(直接上代码): {      OSIntEnter();     //Call ISR...     OSIntExit ();     return; } OSIntExit () { #if OS_CRITICAL_METHOD == 3&n ...…

查看全部问答>