国产化复旦微开发板FM33G0之定时器

二、定时器

先来说一说我最近遇到的一个问题,这是一个关于延时和定时的问题。

  1. 实现功能:
    在程序初始化时,给某引脚拉低之后(在此拉低相当于上电)延时3s,等待充电,然后再将该引脚拉高。

  2. 所遇问题:
    一开始使用系统的嘀嗒定时器,但最久延迟1秒程序就复位或者跑飞了。我使用的时钟是默认的高频RC振荡器,频率是16M,Systick是24位的,这样算下来也是一次性能延时最多1s左右吧。此时我配置的看门狗溢出周期是两秒。当我连续使用Delay_ms(1000);Delay_ms(1000);Delay_ms(1000);时,就会失败。

  3. 解决办法:
    方法一:使用嘀嗒定时器
    重写了us延时和ms延时:【这一段参考了别人的代码】

void Delay_us(uint32 nus)
{
	uint32 tnow, tcnt = 0;
	uint32 reload = SysTick->LOAD;						// LOAD的值   
	uint32 told   = SysTick->VAL;        		      // 初始计数值	SysTick->VAL
	uint32 ticks=nus*16; 						     // 需要的节拍数  (__SYSTEM_CLOCK/1000000)

	while(1)
	{
		tnow = SysTick->VAL;	                    	//取出当前计数值
		if(tnow != told)                               // 计数值刷新
		{	    
			if(tnow < told)
			{		
				tcnt += told - tnow;	                //Systick为递减计数!!!
			}
			else 		
			{				
				tcnt += reload-tnow+told;	    
			}
			told = tnow;
			if(tcnt >= ticks) 
			{	
			  break;			        // 延时时间达到,延时完成
			}
				
		}  
	}
	  return;
}

void Delay_ms(uint32 nms)
{
	uint32 i;
	for(i = 0; i < nms; i++) Delay_us(1000);
}

实现上面的延时之后:

void Delay_LD3s(void)
{
	PA11_ON;            //拉低引脚
	Delay_ms(1000);
	IWDT_Clr();  				//清系统看门狗
	Delay_ms(1000);
	IWDT_Clr();  				//清系统看门狗
	Delay_ms(1000);
	IWDT_Clr();  				//清系统看门狗
	PA11_OFF;	       //拉高引脚
}

因为看门狗设置的是2s溢出周期,延迟3s的话,不加清狗就会造成复位,当然你也可以修改看门狗的设置。
方法二:使用ET计数器。
使用扩展计数器的时候,可以采用循环等待计数完成的思想,也可以使用中断思想,在不影响其他工作的同时完成3s的计数完成。
①延时思想:

    PA11_ON;         //拉低引脚
	ETIMx_ETxCR_CEN_Setable(ETIM2, ENABLE);	//启动定时器
	while(!delay3sFlag)
	{
		  IWDT_Clr();  				//清狗
	}
	delay3sFlag=0;
    PA11_OFF;	       //拉高引脚

delay3sFlag是使用定时器ETIM2,计数到3s的完成标志。至于定时器的配置和中断参考标准代码。

②中断思想

void Delay_LD3s(void)
{
	   PA11_ON;         // 拉低引脚
        ETIMx_ETxCR_CEN_Setable(ETIM2, ENABLE);	//启动定时器
}
int main (void)
{	                          
   while(1)
  {	
     if(delay3sFlag==1)
		{
		       delay3sFlag=0;
               PA11_OFF;	       // 拉高		
		}
   }
}

开启定时器之后,在主函数中等待计数完成,才做相应的操作。

你可能感兴趣的:(国产化复旦微开发板FM33G0之定时器)