32位单片机周期性计时的问题

周期性闪烁LED的方式有一下两种,但第二种方式有问题由此引发C语言在32位机中计算时间间隔时的问题,此现象在PIC32和STM32中都有且一致

u32  TickCounter_32;
u16  TickCounter_16;
 
 
void SysTickHandler(void)
{
	TickCounter_32++;
	TickCounter_16++;
}
 
/**
 * @brief LED闪烁1
 */ 
void RefreshLed1(void)
{
	static u32 TickBase_32=0;
 
	if( TickCounter_32 - TickBase_32 > 1000){
		TickBase_32 = TickCounter_32;
		
		LED_TOGGLE();
	}
}
 
/**
 * @brief LED闪烁2
 */  
void RefreshLed2(void)
{
	static u16 TickBase_16=0;
 
	if( TickCounter_16 - TickBase_16 > 1000){
		TickBase_16 = TickCounter_16;
		
		LED_TOGGLE();
	}
} 

RefreshLed1在32位机中工作正常,两个u32相减结果仍是u32

RefreshLed2异常,表现现象为闪烁一段时间后不再闪烁
当TickCounter_16大于65535变为0,自增到500后,但TickBase_16 = 65000左右时
计算过程如下 500-65000 = -535, -535>1000,Flase所以程序不会再进入LED闪烁程序
具体计算过程如下 0x01F4 - 0xFDE8   = 0xFFFF040C(数据总线为32位) 
                                 500        - 65000      = -64500  >1000 条件不成立
                 
可更改为以下RefreshLed2_1 or RefreshLed2_2:
两种方式本质是一种方式,要将TickCounter_16 - TickBase_16的结果强制转化为u16

具体计算过程如下 0x01F4 - 0xFDE8   = 0xFFFF040C = (u16)0xFFFF040C = 0x040C = 1036
                                 500        - 65000                                                                        = 1036  >1000 条件成立

/**
 * @brief LED闪烁2_1
 */  
void RefreshLed2_1(void)
{
	static u16 TickBase_16=0;
 
	if( (u16)(TickCounter_16 - TickBase_16) > 1000){
		TickBase_16 = TickCounter_16;
		
		LED_TOGGLE();
	}
} 
 
/**
 * @brief LED闪烁2_2
 */  
void RefreshLed2_2(void)
{
	static u16 TickBase_16=0;
	u16 TickInterval;
 
	TickInterval = TickCounter_16 - TickBase_16;
	if( TickInterval > 1000){
		TickBase_16 = TickCounter_16;
		
		LED_TOGGLE();
	}
} 
 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值