⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 charge.c

📁 利用winavr开发的一款三段式充电器的源码
💻 C
字号:
/*****************************************************************
** Project:		充电器
** file : 			charge.c
** date : 			20081205
** author:
** version:		v1.0		   
** description:		控制充电状态,
** ---------------------------------------------------------------
** date : 			 
** author:
** version:		 	   
** description:		 
******************************************************************/


#include "main.h"

//定义充电相关的控制变量
//定义充电控制状态
u08 charge_state = STATE0_INITIAL;	//系统上电后处于初始化状态
u08 charge_flag = false;			//充电的故障标志,0:故障,1正常
//定义充电控制状态
u08 charge_hours = 0;				//系统上电后小时寄存器初始值
u08 charge_seconds = 0;				//系统上电后秒寄存器初始值
u08 charge_hour_flag =false;		//小时时间到标志
u08 charge_second_flag =false;		//秒时间到标志

//软定时器内部寄存器
	static u08 seconds =0;
	static u08 hours =0;
	static u08 minutes=0;


/*****************************************************************
** function:设定/获取充电状态
*****************************************************************/
void SetChargeState( u08 charge)
{
	charge_state =charge;
}
u08 GetChargeState(void)
{
	return charge_state;
}
/*****************************************************************
** function:设定/获取充电标志:0:故障 1正常
*****************************************************************/
void SetChargeFlag( u08 flag)
{
	charge_flag =flag;
}
u08 GetChargeFlag(void)
{
	return charge_flag;
}

/*****************************************************************
** function	:是否充电故障
** 返回		:ture 1:正常,false 0:故障;
*****************************************************************/
u08  GetChargeErr(void)
{
	u08 ret;

	if( GetUK() == 1)
	{
		ret = true;
	}
	else
	{
		ret = false;
	}
	//保证充电标志同步更新
	SetChargeFlag(ret);

	return ret;
}

/*****************************************************************
** function:充电各种状态下的处理函数======充电初始化
*****************************************************************/
void state0_intial_proc(void)
{
	//仅在系统处于该状态时才执行
	while( GetChargeState() == STATE0_INITIAL )
	{
		STAGE_1_CHARGE_OUT = CHARGE_OFF;
	
		STAGE_2_CHARGE_OUT = CHARGE_OFF;
	
		STAGE_3_CHARGE_OUT = CHARGE_OFF;
	
		OVER_CHARGE_OUT	 =	CHARGE_OFF;
	
		SetLed(_LED1,OFF,OFF);
	
		SetLed(_LED2,OFF,OFF);
	
		SetLed(_LED3,OFF,OFF);
	
		SetLed(_LED_ERR,OFF,OFF);
	
		LedUpdate();
		//状态跳转
		SetChargeState(STATE1_JUDGE_UK);
	
	}

}
/*****************************************************************
** function:充电各种状态下的处理函数======第一阶段前UK判断处理
*****************************************************************/
void state1_judge_uk_proc(void)
{
	//仅在系统处于该状态时才执行
	while( GetChargeState() == STATE1_JUDGE_UK )
	{
		if( GetChargeErr() == false )
		{
			ChargeErrorProc();
			break;//因为上面函数里有将状态设置为STATE1_JUDGE_UK 导致死循环 必须跳出
		}
		else
		{
			//设定充电标志为正常,非故障
			SetChargeFlag(true);
			//关闭故障灯
			SetLed(_LED_ERR,OFF,OFF);
			//状态跳转
			SetChargeState(STATE2_STAGE_1);
		}
	}

}
/*****************************************************************
** function:充电各种状态下的处理函数======第一阶段充电处理
*****************************************************************/
void state2_stage_1_proc(void)
{
	//仅在系统处于该状态时才执行
	while( GetChargeState() == STATE2_STAGE_1 )
	{
		//开第一阶段执行灯 闪亮
		SetLed(_LED1,ON,ON);
		//开定时器A
		SetTimerBySecond( TIMER_A );
		//等待定时A
		while(GetTimerBySecond()==false)
		{
			wdt_reset();
		}
		//定时到 开第一阶段输出
		STAGE_1_CHARGE_OUT = CHARGE_ON;
		//开定时器B 20H
		SetTimerByHour( TIMER_B );
		//等待定时B
		while(1)
		{
			wdt_reset();
			//如果U1 ==1
			if( (GetU1() == 1) || (GetTimerByHour()==true))
			{
			//关第一阶段充电输出
				STAGE_1_CHARGE_OUT = CHARGE_OFF;
			//关第一阶段充电指示灯
				SetLed(_LED1,OFF,OFF);
				break;
			}
		}
		//开定时器C
		SetTimerBySecond( TIMER_C );
		//等待定时C
		while(GetTimerBySecond()==false)
		{
			wdt_reset();
		}
		//查询UK状态
		if( GetChargeErr() == false )
		{
		// 跳转到故障处理 等待恢复
			ChargeErrorProc();
		}
		else
		{
		//状态正常跳转	
			SetChargeState(STATE3_STAGE_2);
		}
	}
}

/*****************************************************************
** function:充电各种状态下的处理函数======第2阶段充电处理
*****************************************************************/
void state3_stage_2_proc(void)
{
	//仅在系统处于该状态时才执行
	while( GetChargeState() == STATE3_STAGE_2 )
	{
		//开第2阶段执行灯 闪亮
		SetLed(_LED2,ON,ON);
		//开定时器D
		SetTimerBySecond( TIMER_D );
		//等待定时D
		while(GetTimerBySecond()==false)
		{
			wdt_reset();
		}
		//定时到 开第2阶段输出
		STAGE_2_CHARGE_OUT = CHARGE_ON;
		//开定时器E 2H
		SetTimerByHour( TIMER_E );
		//等待定时E
		while(1)
		{
			wdt_reset();
			//如果U2 ==1
			if( (GetU2() == 1) || (GetTimerByHour()==true))
			{
			//关第2阶段充电输出
				STAGE_2_CHARGE_OUT = CHARGE_OFF;
			//关第2阶段充电指示灯
				SetLed(_LED2,OFF,OFF);
				break;
			}
		}
		//开定时器F
		SetTimerBySecond( TIMER_F );
		//等待定时F
		while(GetTimerBySecond()==false)
		{
			wdt_reset();
		}
		//查询UK状态
		if( GetChargeErr() == false )
		{
		// 跳转到故障处理 等待恢复
			ChargeErrorProc();
		}
		else
		{
		//状态正常跳转	
			SetChargeState(STATE4_STAGE_3);
		}
	}
}
/*****************************************************************
** function:充电各种状态下的处理函数======第3阶段充电处理
*****************************************************************/
void state4_stage_3_proc(void)
{
	//仅在系统处于该状态时才执行
	while( GetChargeState() == STATE4_STAGE_3 )
	{
		//开第3阶段执行灯 闪亮
		SetLed(_LED3,ON,ON);
		//开定时器D
		SetTimerBySecond( TIMER_G );
		//等待定时D
		while(GetTimerBySecond()==false)
		{
			wdt_reset();
		}
		//定时到 开第3阶段输出
		STAGE_3_CHARGE_OUT = CHARGE_ON;
		//开定时器h 1H
		SetTimerByHour( TIMER_H );
		//等待定时H
		while(1)
		{
			wdt_reset();
			if( GetTimerByHour()==true)
			{
			//关第3阶段充电输出
				STAGE_3_CHARGE_OUT = CHARGE_OFF;
			//关第3阶段充电指示灯
				SetLed(_LED3,OFF,OFF);
			//故障指示灯闪亮
				SetLed(_LED_ERR,ON,ON);
			//充电玩出输出高电平
				OVER_CHARGE_OUT = CHARGE_ON;
			//打开1 2 3 阶段指示灯,常亮 表面充电完毕
				SetLed(_LED1,ON,OFF);
				SetLed(_LED2,ON,OFF);
				SetLed(_LED3,ON,OFF);
				break;
			}
		}

		//查询UK状态 等待为0
		while( GetUK() == 1 )
		{
			wdt_reset();
		}

		SetChargeState(STATE0_INITIAL);//返回初始化状态


	}
}


/*****************************************************************
** function:充电各种状态下的处理函数======故障处理
*****************************************************************/
void ChargeErrorProc(void)
{
	//开故障灯常亮
	SetLed(_LED_ERR,ON,OFF);
	//将状态恢复到初始化后的UK判断
	SetChargeState (STATE1_JUDGE_UK);
}


//////////////////////////////////////////////////// //定时相关处理
//系统基准节拍: 50ms中断间隔
//
SIGNAL( SIG_OVERFLOW1 )
{
	static u16 cnt;

  	TCNT1     = (65535 - 50000);	//50ms中断一次						

	if( cnt++ > 20 )				//1s到
	{
		cnt = 0;
	


		seconds++;
		//////////////////////////////////////////////////秒定时器判断
		if( charge_seconds > 1 && charge_second_flag ==false )
		{
			if( seconds >= charge_seconds )
			{
				charge_second_flag = true;//可通过设定定时器复位该标志
			}	
		}
		/////////////////////////////////////////////////// 1分钟到
		if( seconds >=60 )
		{
			seconds = 0;
			
			minutes ++;

			if( minutes >=60 )
			{
				minutes =0;
				
				hours++	 ;
				////////////////////////////////////////////时定时器判断
				if( 
					( charge_hours >= 1)  &&  //应该为》=1,否则1小时定时无法实现
					( charge_hour_flag == false )
				  )
				{
					if( hours >= charge_hours )
					{
						charge_hour_flag = true;//可通过设定定时器复位该标志
					}	
				}
				if(hours >= 24)
				{
					hours =0;						
				}
			}
		
		}
			
	}
}

//设定小时级定时器
void SetTimerByHour( u08 setval)
{
	cli();
	if( setval >= 24 )
	{
		charge_hours = 24;
	}
	else
	{
		charge_hours = setval;

		hours =0;//d定时器复位

		minutes =0 ;

	}	charge_hour_flag = false;

	sei();
}
//读取小时定时器标志,是否定时到
u08 GetTimerByHour( void)
{
	return 	  charge_hour_flag;
}
//设定秒级定时器 最大定时60s
void SetTimerBySecond( u08 setval)
{
		cli();

	if( setval >= 60 )
	{
		charge_seconds = 60;
	}
	else
	{
		charge_seconds = setval;


	}
		seconds = 0;

		charge_second_flag = false;

		sei();
}
//读取秒定时器标志,是否定时到
u08 GetTimerBySecond( void)
{
	return 	  charge_second_flag;
}













⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -