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

📄 ac20-1.c

📁 AVR单片机ATmega16(L)应用实例—红外线感应自动移门
💻 C
📖 第 1 页 / 共 2 页
字号:

//待机状态(40)时的输入开门受挤灵敏度子函数
void input_openforce(void)
{

}

/*=========待机状态(status=40)时的输入关门最大速度=========*/
void input_closemaxspeed(void)
{
if(KEY_ADD==0){delay(30);if(KEY_ADD==0)val++;}
  if(val>9)val=0;
   if(KEY_OK==0){delay(30);
  			   if(KEY_OK==0)
  			   {SREG=0x00;close_max_temp=val;
  				EEPROM_WRITE(close_max_address,val);
  				eep_temp=55;
				EEPROM_WRITE(close_max_address+1,eep_temp);
				PORTA=0x00;
				delay(500);
				SREG|=0x80; }
			   }
  delay(300);
}


/*=========待机状态(status=40)时输入关门最小速度==========*/
void input_closeminspeed(void)
{
if(KEY_ADD==0){delay(30);if(KEY_ADD==0)val++;}
  if(val>9)val=0;
   if(KEY_OK==0){delay(30);
  			   if(KEY_OK==0)
  			   {SREG=0x00;close_min_temp=val;
  				EEPROM_WRITE(close_min_address,val);
  				eep_temp=55;
				EEPROM_WRITE(close_min_address+1,eep_temp);
				PORTA=0x00;
				delay(500);
				SREG|=0x80; }
			   }
  delay(300);
}

//待机状态(40)时的输入关门受挤灵敏度子函数
void input_closeforce(void)
{

}

/*============待机状态(status=40)时输入学习速度=========*/
void input_studyspeed(void)
{
if(KEY_ADD==0){delay(30);if(KEY_ADD==0)val++;}
  if(val>9)val=0;
  if(KEY_OK==0){delay(30);
  			   if(KEY_OK==0)
  			   {SREG=0x00;study_speed_temp=val;
  				EEPROM_WRITE(study_speed_address,val);
  				eep_temp=55;
				EEPROM_WRITE(study_speed_address+1,eep_temp);
				PORTA=0x00;
				delay(500);
				SREG|=0x80; }
			   }
  delay(300);
}


/*================计算出开门关门的加减速曲线===============*/
void fnc_inc_dec(void)
{	 uchar i,x;
 	 x=0; 
	//计算出开门的加速曲线
	open_max=open_max_tab[open_max_temp];//取得开门速度最大脉宽
	open_min=open_min_tab[open_min_temp];//取得开门速度最小脉宽
	//open_max=155;open_min=10;
	open_inc_tab[0]=open_min;open_inc_tab[15]=open_max;
	temp=open_max-open_min;
	temp=temp/15;	
	for(i=14;i>0;i--){x=x+temp;open_inc_tab[i]=open_max-x;}
	//***********************************
	x=0;	
	//计算出开门的减速曲线	
	open_max=open_max_tab[open_max_temp];//取得开门速度最大脉宽
	open_min=open_min_tab[open_min_temp];//取得开门速度最小脉宽	
	//open_max=155;open_min=10;
	open_dec_tab[0]=open_min;open_dec_tab[15]=open_max;
	temp=open_max-open_min;
	temp=temp/15;	
	for(i=1;i<15;i++){x=x+temp;open_dec_tab[i]=open_min+x;}
	//=====================================
	x=0;    
	//计算出关门的加速曲线
	close_max=close_max_tab[close_max_temp];
	close_min=close_min_tab[close_min_temp];
	//close_max=125;close_min=10;
	close_inc_tab[0]=close_min;close_inc_tab[15]=close_max;
	temp=close_max-close_min;
	temp=temp/15;	
	for(i=14;i>0;i--){x=x+temp;close_inc_tab[i]=close_max-x;}
	//***********************************
	x=0;  
	//计算出关门的减速曲线
	close_max=close_max_tab[close_max_temp];
	close_min=close_min_tab[close_min_temp];
	//close_max=125;close_min=10;
	close_dec_tab[0]=close_min;close_dec_tab[15]=close_max;
	temp=close_max-close_min;
	temp=temp/15;	
	for(i=1;i<15;i++){x=x+temp;close_dec_tab[i]=close_min+x;}
	/*************************************************/
}


/*========================主函数=======================*/
void main(void)
{	
init_IO();//初始化
RELAY_OFF;			//关闭继电器
delay(500);			//延时500mS
RELAY_ON;			//打开继电器
delay(500);			//延时500mS
fnc_inc_dec();			//计算出开门关门的加减速曲线
SREG=0x80;			//开全局中断
	while(1)
    {	
		if(set_status>0)
		{SREG=0x00;fnc_inc_dec();SREG=0x80;}

		/**********检测全开停止**********/
		if(ALLOPEN_STOP==0)openstop=1;		//门全开后停止
			else	openstop=0;					//门全开后回去
		switch (status)			   //工作状态
		{		
		case 0:{		//学习--开门	
			 		wide=study_speed_tab[study_speed_temp];
					FANXIANG_R;SACE_0;
					OCR2=wide;TCCR2=0x71;
					}break;

		case 10:{		//撞墙后停止
			 	 	SACE_0;TCCR2=0x31;wide=0;
			 		OCR2=wide;	
					round_cnt=0;
					changdu=0;
					delay(2000);
					SACE_0;//PWMOUT_0;
					TCCR2=0x71;
					status=20;round_cnt=0;
					}break;

		case 20:{		//学习--关门	
			 		wide=study_speed_tab[study_speed_temp];
					FANXIANG_L;SACE_0;
			 		OCR2=wide;TCCR2=0x71;
					}break;

		case 30:{		//门合拢后停止	
			 		TCCR2=0x31;
			 		wide=0;
			 		OCR2=wide;
					PWMOUT_0;SACE_0;
					//delay(2000);
					//write eeprom
					allchangdu_x=changdu;
					//st_changdu=allchangdu;
					round_cnt=0;
					changdu=0;
					status=40;
					}break;

		case 40:{		//待机状态status=40
			 		switch(set_status)		//设定状态
					{
					//待机状态(status=40)时的正常工作子函数
			 		case 0:normal_work();break;
					//待机状态(status=40)时的输入门靠墙停顿时间子函数
					case 1:input_stoptime();break;
					//待机状态(status=40)时的输入开门最大速度子函数
			 		case 2:input_openmaxspeed();break;
					//待机状态(status=40)时的输入开门最小速度子函数
					case 3:input_openminspeed();break;
					//待机状态(status=40)时的输入开门受挤灵敏度子函数
					case 4:input_openforce();break;
					//待机状态(status=40)时的输入关门最大速度子函数
			 		case 5:input_closemaxspeed();break;
					//待机状态(status=40)时的输入关门最小速度子函数
					case 6:input_closeminspeed();break;
					//待机状态(status=40)时的输入关门受挤灵敏度子函数
					case 7:input_closeforce();break;
					//待机状态(status=40)时的输入学习速度子函数
					case 8:input_studyspeed();break;
			 		default:break;
					}
					if(KEY_SET==0)		//设定状态键按下
					{delay(30);if(KEY_SET==0)set_status++;
					val=0;	
					if(set_status>8)set_status=0;		//设定状态范围0~8
					delay(300);}
					
					}break;	

		case 50:{		//开门加速过程
			 		TCCR2=0x71;SACE_0;FANXIANG_R;
						if(st_changdu>(200))
						{inc_dec_flag=1;
						open_inc_speed(sp_pl);
						if(wide>=open_inc_tab[15])status=60;
						}
						else status=80;
					}break;	

		case 60:{		//开门全速过程
			 		TCCR2=0x71;
					FANXIANG_R;
					inc_dec_flag=0;
					wide=open_inc_tab[15];OCR2=wide;
					sp_pl=0;
					if(changdu>=(st_changdu-200))status=70;
					}break;	

		case 70:{		//开门减速过程
			 		TCCR2=0x71;
			 		FANXIANG_R;
					inc_dec_flag=1;
					open_dec_speed(sp_pl);
					if(wide<=open_dec_tab[0])status=80;
					}break;	

		case 80:{		//开门慢速过程
			 		if(openflag==HALF)	//全开门的判断
					{
		            TCCR2=0x71;
			 		wide=(open_dec_tab[0]);OCR2=wide;
					inc_dec_flag=0;
					FANXIANG_R;SACE_0;
					if(changdu>(st_changdu-1))
					{wide=(open_dec_tab[0]-6);OCR2=wide;}
					if(changdu>st_changdu)status=90;
					}
					else			//半开门的判断
					{
					TCCR2=0x71;
			 		wide=(open_dec_tab[0]);OCR2=wide;
					inc_dec_flag=0;
					FANXIANG_R;SACE_0;
					}
					}break;

		case 85:{		//关门过程中探头感应到人来后又慢速开门过程
			 		TCCR2=0x71;
			 		wide=(open_dec_tab[0])+1;OCR2=wide;
					inc_dec_flag=0;
					FANXIANG_R;
					SACE_0;
					if(openflag==HALF)
					{if(changdu>st_changdu)status=90;}
					}break;				
		
		case 90:{		//靠墙过程
			 		if(openstop==1)		//门全开后停止不回去
					//***********************
			 		{TCCR2=0x31;fst=0;cnt_500=0;
			 		SACE_0;PWMOUT_0;
					wide=0;
					OCR2=wide;
					round_cnt=0;
					sp_pl=0;
					}
					else					//否则门全开后还要回去
					{
					TCCR2=0x31;
			 		SACE_0;PWMOUT_0;
					wide=0;
					OCR2=wide;
					round_cnt=0;
					sp_pl=0;
					st_changdu=allchangdu;changdu=allchangdu;
					
//靠墙停止时间
					do{delay(stoptime_tab[stoptime]);}while(TANTE1==0);
					delay(stoptime_tab[stoptime]);
					st_changdu=allchangdu;changdu=allchangdu;
					
//转到关门加速过程(状态100)
					status=100;sp_pl=0;
					wide=close_inc_tab[0];
					round_cnt=0;FX=0;
					}
					}break;

		case 100:{	//关门加速过程
			 		SACE_0;
					TCCR2=0x71;
					FANXIANG_L;
					inc_dec_flag=1;
					close_inc_speed(sp_pl);

					//此关门加速过程中,探头感应到人来,转状态105
					if(FX==1){status=105;sp_pl=0;}
					//否则无人来,且关门过程已加速到最快,转状态110
					else if(wide>=close_inc_tab[15])status=110;
					}break;

		case 105:{	//向左减速过程 
					TCCR2=0x71;
					FANXIANG_L;
					inc_dec_flag=1;
					close_down_speed(sp_pl);
					//close_dec_speed(sp_pl);
					if (wide<=close_dec_tab[0])
					{wide=open_dec_tab[0];
					  OCR2=wide;inc_dec_flag=0;

					  //向左减速到最慢后,延时一会儿 
					  delay(700);
					  //*****************
					     FANXIANG_R;inc_dec_flag=0;
						SACE_0;
						status=85;//转状态85
					}
					}break;	

		case 110:{	//关门全速过程
			 		TCCR2=0x71;
					FANXIANG_L;
					inc_dec_flag=0;
					wide=close_inc_tab[15];OCR2=wide;
					sp_pl=0;

					//此关门全速过程中,探头感应到人来,转状态115
					if(FX==2){status=115;sp_pl=0;}
					
//否则无人来,且关门长度已过大半,转状态120
					else if(changdu<=200)status=120;
					}break;	

		case 115:{	//向左减速过程  
					TCCR2=0x71;
					FANXIANG_L;
					inc_dec_flag=1;
					close_dec_speed(sp_pl);

					//向左减速到最慢
					if (wide<=close_dec_tab[0])
					{if(changdu>250)//如关门只关了一点
					     {wide=open_dec_tab[0];OCR2=wide;												inc_dec_flag=0;
					     FANXIANG_R;inc_dec_flag=0;
						SACE_0;
						delay(200);//延时一会儿
						status=85;//转状态85
						 }
					//如关门已关了大半,调用开门启动子函数
					  else {delay(300);start();}
					}
					}break;	

		case 116:{//向左突然减速过程 	 
					TCCR2=0x71;
					FANXIANG_L;
					inc_dec_flag=1;
					close_down_speed(sp_pl);
					if (wide<=close_dec_tab[0])
					{if(changdu<250)
					     {wide=open_dec_tab[0];OCR2=wide;												inc_dec_flag=0;
					     FANXIANG_R;inc_dec_flag=0;
						SACE_0;delay(20/*0*/);
						status=85;
						 }
					  else {delay(30/*0*/);start();}
					}
					}break;	

		case 120:{//关门时减速过程 
					TCCR2=0x71;
					FANXIANG_L;
					inc_dec_flag=1;
					close_dec_speed(sp_pl);
					if(wide<=close_dec_tab[0])status=130;
					}break;	

		case 130:{	//关门慢速过程	
			 		//此关门慢速过程中,探头感应到人来,
			 		//调用开门启动子函数
			 		if(FX==4){start();}
					else
			 		{TCCR2=0x71;
			 		SACE_0;
					inc_dec_flag=0;
					FANXIANG_L;
					wide=close_dec_tab[0];OCR2=wide;
					}
					}break;	

		case 140:{	//门合拢后停止	
			 		TCCR2=0x31;	
			 		wide=0;OCR2=wide;
					PWMOUT_0;SACE_0;
					round_cnt=0;
					changdu=0;
					//delay(1000);
					status=40;SACE_0;
					round_cnt=0;
					sp_pl=0;
					changdu=0;
					}break;

		case 180:{	//紧急停止
			 		inc_dec_flag=0;
			 		PWMOUT_0;SACE_1;
					wide=0;
					OCR2=wide;
					TCCR2=0x31;
					//延时一会儿
					delay(3000);
					//转状态0,进入学习状态
					status=0;
					}break;
			default:break;
		}


if((status==60)&&(round_cnt>20))status=180; //开门全速过程中,如撞人转状态180
//*****************************************
if(tante_flag==0)	//外部探头允许工作
				   {
//门外侧的红外感应探测器1感应到人来,以及状态40时,调用开门启动子函数
if((TANTE1==0)&&(status==40)&&(set_status==0))
{delay(30);if(TANTE1==0)changdu=0;start();}
//****************************
//门外侧的红外感应探测器1感应到人来,以及状态100时,标志FX置1
if((TANTE1==0)&&(status==100)&&(set_status==0))
{delay(30);if(TANTE1==0)FX=1;}
//*****************************
//门外侧的红外感应探测器1感应到人来,以及状态110时,标志FX置2
if((TANTE1==0)&&(status==110)&&(set_status==0))
{delay(30);if(TANTE1==0)FX=2;}
//******************************
//门外侧的红外感应探测器1感应到人来,以及状态130时,标志FX置4
if((TANTE1==0)&&(status==130)&&(set_status==0))
{delay(30);if(TANTE1==0)FX=4;}
//*******************************
//门内侧的红外感应探测器2感应到人来,以及状态40时,调用开门启动子函数
if((TANTE2==0)&&(status==40)&&(set_status==0))
{delay(30);if(TANTE2==0)changdu=0;start();}
//****************************
//门内侧的红外感应探测器2感应到人来,以及状态100时,标志FX置1
if((TANTE2==0)&&(status==100)&&(set_status==0))
{delay(30);if(TANTE2==0)FX=1;}
//*****************************
//门内侧的红外感应探测器2感应到人来,以及状态110时,标志FX置2
if((TANTE2==0)&&(status==110)&&(set_status==0))
{delay(30);if(TANTE2==0)FX=2;}
//****************************
//门内侧的红外感应探测器2感应到人来,以及状态130时,标志FX置4
if((TANTE2==0)&&(status==130)&&(set_status==0))
{delay(30);if(TANTE2==0)FX=4;}
					}
//******************************
if(tante_flag==1)
 {			
if((TANTE2==0)&&(status==40)&&(set_status==0))
{delay(30);if(TANTE2==0)changdu=0;start();}
//****************************
//门内侧的红外感应探测器2感应到人来,以及状态100时,标志FX置1
if((TANTE2==0)&&(status==100)&&(set_status==0))
{delay(30);if(TANTE2==0)FX=1;}
//*****************************
//门内侧的红外感应探测器2感应到人来,以及状态110时,标志FX置2
if((TANTE2==0)&&(status==110)&&(set_status==0))
{delay(30);if(TANTE2==0)FX=2;}
//门内侧的红外感应探测器2感应到人来,以及状态130时,标志FX置4
if((TANTE2==0)&&(status==130)&&(set_status==0))
{delay(30);if(TANTE2==0)FX=4;}
					}
		}
}


/*===================开门启动子函数==================*/
void start(void)
{
wide=open_inc_tab[0];
FANXIANG_R;
OCR2=wide;
TCCR2=0x71;
status=50;
sp_pl=0;
round_cnt=0;

}

⌨️ 快捷键说明

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