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

📄 ac20-1.c

📁 AVR单片机ATmega16(L)应用实例—红外线感应自动移门
💻 C
📖 第 1 页 / 共 2 页
字号:
#include<iom16v.h>		//文件包含
#include<eeprom.h>
#define uchar unsigned char  //变量类型的宏定义
#define uint unsigned int

uchar const seg[10]={0x3f,0x06,0x5b,0x4f,0x66,  //数码管段码设定
                0x6d,0x7d,0x07,0x7f,0x6f};
uchar const act[4]={0xdf,0xbf,0x7f,0xef};        //数码管位码设定

/***********************输入量设定*************************/
uchar stoptime=3;		//靠墙停顿时间设定
uchar study_speed;		//学习时的速度设定
uchar study_speed_temp=4;

uchar open_max,open_min;  //开门最大速度、最小速度设定
uchar open_max_temp=4,open_min_temp=4;

uchar close_max,close_min;  //关门最大速度、最小速度设定
uchar close_max_temp=1,close_min_temp=4;

/*****************输入量的列表****************/
uint const stoptime_tab[10]={500,1000,2000,3000,4000,5000,
	 					6000,7000,8000,9000};
uchar const round_cnt_tab[10]={5,6,7,8,9,10,15,20,25,30};	
uchar const study_speed_tab[10]={5,7,9,11,13,15,
	  							20,25,30,35};	
uchar const open_max_tab[10]={100,120,140,150,155,
	  					160,165,170,175,180};
uchar const open_min_tab[10]={5,7,8,9,10,
	  					15,20,25,30,35};
uchar const close_max_tab[10]={100,120,140,150,155,
	  					160,165,170,175,180};
uchar const close_min_tab[10]={5,7,8,9,10,
	  					15,20,25,30,35};
						
uint round_cnt;  //直流电机旋转的圈数
int changdu;       //实际门扇移动的长度
uint st_changdu;	//设定门扇移动的长度
uint allchangdu_x;  //总长度(中间变量)
uint allchangdu;	//总长度
uint sp_pl;       	//脉冲计数变量
uchar set_status;	//设定状态
uchar status;		//工作状态

/***********临时变量***********/
uint cnt_500;		
uchar fst,val;
uchar temp;
uchar x;uchar FX=0;
uchar eep_temp;

uchar open_inc_tab[16];		//开门加速函数的计算表
uchar open_dec_tab[16];		//开门减速函数的计算表
uchar close_inc_tab[16];		//关门加速函数的计算表
uchar close_dec_tab[16];	//关门减速函数的计算表

uchar openflag;
uchar dis_bit,ddata=0;
/***********************************************/
uchar inc_dec_flag;		//加减速的标志
uchar wide=0;			//加减速的脉冲宽度变量

/****************常量定义***************/
#define L 1;
#define R 0;
#define ON 0;
#define OFF 1;
#define ALL 1
#define HALF 0

/**************端口高低电平定义****************/
#define PWMOUT_0  (PORTD=PORTD|0x80)		//PWM端输出0
#define PWMOUT_1  (PORTD=PORTD&0x7f)		//PWM端输出1
#define SACE_0  (PORTD=PORTD|0x40)			//SACE端输出0
#define SACE_1  (PORTD=PORTD&0xbf)		//SACE端输出1
#define FANXIANG_L  (PORTD=PORTD|0x20)	//方向向左
#define FANXIANG_R  (PORTD=PORTD&0xdf)	//方向向右
#define RELAY_ON  (PORTD=PORTD&0xf7)		//继电器吸合
#define RELAY_OFF  (PORTD=PORTD|0x08)		//继电器断开
#define LOCK_ON  (PORTD=PORTD&0xef)		//锁停门扇打开
#define LOCK_OFF  (PORTD=PORTD|0x10)		//锁停门扇关闭

#define CON_SMAIL  (PORTC&0x01)			//门扇打开微小的距离运行
#define TANTE1 (PINC&0x40)					//门外侧的红外感应探测器1
#define TANTE2 (PINC&0x02)					//门内侧的红外感应探测器2
#define KEY_SET (PINB&0x01)					//按键输入SET
#define KEY_ADD (PINB&0x02)					//按键输入ADD
#define KEY_OK (PINB&0x04)					//按键输入OK
#define OFF_ALLTANTE (PINB&0x08)			//关闭全部的红外感应探测器
#define OFF_TANTE1 (PINB&0x10)				//关闭门外侧的红外感应探测器1
#define HALF_RUN (PIND&0x01)				//门扇半开运行
#define ALLOPEN_STOP (PIND&0x02)			//门扇全开后锁停
#define STOP (PINC&0x10)						//门扇锁停

/****************EEPROM内部地址定义*********************/
#define stoptime_address 10
#define study_speed_address 15
#define open_max_address 20
#define open_min_address 25 
#define close_max_address 30
#define close_min_address 35

/***********************************************************/
uchar openstop;			//门全开后停止不动的标志
uchar tante_flag;			//门外侧的红外感应探测器1允许使用的标志

/******************函数声明***********************/
void start(void);			
//void fai_zhan(void);

/****************延时子函数*******************/
void delay(uint k)
{
uint i,j;
for(i=0;i<k;i++){
for(j=0;j<1500;j++)
{;}}
}

/*==========初始化单片机I/O口子函数==========*/
void init_IO(void)             
{DDRA=0x7f;                    
 PORTA=0x00;
 DDRB=0xe0;					   
 PORTB=0xff;
 DDRC=0x01;					   
 PORTC=0xff;
 DDRD=0xf8;
 PORTD=0xff;
 //-----------------------------
 PWMOUT_0;
 SACE_0;
 TCCR0=0x04;
 TCNT0=0xd9;
 GICR=0x40;/*c0;*/
 MCUCR=0x02;/*0a;*/
 TIMSK=0x01;
 TCCR2=0x71;
 FANXIANG_R;
round_cnt=0;
changdu=0;
sp_pl=0;
allchangdu=0;
changdu=0;
st_changdu=0;
status=0;
inc_dec_flag=0;
//***********************************
eep_temp=0;
EEPROM_READ(stoptime_address+1,eep_temp);
if(eep_temp==55)
{EEPROM_READ(stoptime_address,stoptime);}
//************************************
eep_temp=0;
EEPROM_READ(open_max_address+1,eep_temp);
if(eep_temp==55)
{EEPROM_READ(open_max_address,open_max_temp);}
//*************************************
eep_temp=0;
EEPROM_READ(open_min_address+1,eep_temp);
if(eep_temp==55)
{EEPROM_READ(open_min_address,open_min_temp);}
//*************************************
eep_temp=0;
EEPROM_READ(close_max_address+1,eep_temp);
if(eep_temp==55)
{EEPROM_READ(close_max_address,open_max_temp);}
//*************************************
eep_temp=0;
EEPROM_READ(close_min_address+1,eep_temp);
if(eep_temp==55)
{EEPROM_READ(close_min_address,open_min_temp);}
//*************************************
eep_temp=0;
EEPROM_READ(study_speed_address+1,eep_temp);
if(eep_temp==55)
{EEPROM_READ(study_speed_address,study_speed_temp);}
}

/*===================================================*/
/***定时器T0的1ms中断,用于数码管显示及检测运行状态的马达堵转情况***/
#pragma interrupt_handler timer0:10
void timer0(void)
{SREG|=0x80;
round_cnt++;
dis_bit++;
if(dis_bit>2)dis_bit=0;
if(fst==1)cnt_500++;
if(cnt_500>500){fst=2;round_cnt=0;cnt_500=0;}

switch(dis_bit)
{
case 0:PORTA=seg[status%10];PORTB=act[0];break;
case 1:PORTA=seg[(status%100)/10];PORTB=act[1];break;
case 2:PORTA=seg[status/100];PORTB=act[2];break;
default:break;
}
TCNT0=0xd9;
switch (status)
		{	//门全开后转状态10
		case 0:if(round_cnt>200){status=10;}break;
			//门全关后转状态30停止	
		case 20:if(round_cnt>200){status=30;}break;
		case 50:if(round_cnt>100){/*reset;*/}break;
		case 60:if(round_cnt>100){/*reset*/}break;
		case 70:if(round_cnt>100){/*reset*/}break;
		//开门慢速状态80时,间隔500ms,分二次判断撞墙后,转状态90	
		case 80:{if((fst==0)&&(round_cnt>150))fst=1;
			 	if((fst==2)&&(round_cnt>150))status=90;
				}break;
		//开门慢速状态85时,间隔500ms,分二次判断撞墙后,转状态90	
		case 85:{if((fst==0)&&(round_cnt>200))fst=1;
			 	if((fst==2)&&(round_cnt>200))status=90;
				}break;
		//关门加速状态100时, 判断撞人后,转状态105	
		case 100:if(round_cnt>300){status=105;sp_pl=0;}break;
		//关门全速状态110时, 判断撞人后,转状态116	
		case 110:if(round_cnt>30){status=116;sp_pl=0;}break;
		case 120:if(round_cnt>100){status=116;sp_pl=0;}break;
		//关门慢速状态130时,门合拢后转状态140停止 
		case 130:if(changdu<=8){if(round_cnt>200)status=140;}
				  break;
		default:break;
		}
}


/*======INT0的马达光电编码器中断=========*/
#pragma interrupt_handler ext_int0:2
void ext_int0(void)
{SREG|=0x80;
round_cnt=0;
if(status<90)changdu++;
if(changdu>9999)changdu=9999;
if((status>90)&&(status<140))changdu--;
if(changdu<=0){changdu=0;}
if(inc_dec_flag)sp_pl++;
if(sp_pl>9999)sp_pl=9999;
}


/*==========开门时的加速子函数===========*/
void open_inc_speed(uint sp_pl)
{
	switch (sp_pl)
		{
		case 1:wide=open_inc_tab[0];break;	
		case 5:wide=open_inc_tab[1];break;		
		case 10:wide=open_inc_tab[2];break;
		case 20:wide=open_inc_tab[3];break;	
		case 25:wide=open_inc_tab[4];break;		
		case 35:wide=open_inc_tab[5];break;
		case 45:wide=open_inc_tab[6];break;	
		case 50:wide=open_inc_tab[7];break;
		case 60:wide=open_inc_tab[8];break;
		case 65:wide=open_inc_tab[9];break;	
		case 75:wide=open_inc_tab[10];break;		
		case 85:wide=open_inc_tab[11];break;
		case 90:wide=open_inc_tab[12];break;	
		case 100:wide=open_inc_tab[13];break;	
		case 105:wide=open_inc_tab[14];break;	
		case 115:wide=open_inc_tab[15];inc_dec_flag=0;break;		
		default:break;
		}
		OCR2=wide;
}


/*==========门扇半开运行的减速子函数===========*/
void openhalf_dec_speed(uint sp_pl)
{
	switch (sp_pl)
		{
		case 1:wide=open_dec_tab[15];break;	
		case 15:wide=open_dec_tab[14];break;		
		case 30:wide=open_dec_tab[13];break;
		case 45:wide=open_dec_tab[12];break;	
		case 60:wide=open_dec_tab[11];break;		
		case 70:wide=open_dec_tab[10];break;
		case 80:wide=open_dec_tab[9];break;	
		case 90:wide=open_dec_tab[8];break;
		case 100:wide=open_dec_tab[7];break;
		case 105:wide=open_dec_tab[6];break;	
		case 110:wide=open_dec_tab[5];break;		
		case 113:wide=open_dec_tab[4];break;
		case 116:wide=open_dec_tab[3];break;	
		case 119:wide=open_dec_tab[2];break;	
		case 122:wide=open_dec_tab[1];break;
		case 125:wide=open_dec_tab[0];break;	
		case 128:wide=open_dec_tab[0]-6;inc_dec_flag=0;break;		
		default:break;
		}
		OCR2=wide;
}


/*========开门时的减速子函数==========*/
void open_dec_speed(uint sp_pl)
{
	switch (sp_pl)
		{
		case 1:wide=open_dec_tab[15];break;	
		case 15:wide=open_dec_tab[14];break;		
		case 30:wide=open_dec_tab[13];break;
		case 45:wide=open_dec_tab[12];break;	
		case 60:wide=open_dec_tab[11];break;		
		case 70:wide=open_dec_tab[10];break;
		case 80:wide=open_dec_tab[9];break;	
		case 90:wide=open_dec_tab[8];break;
		case 100:wide=open_dec_tab[7];break;
		case 105:wide=open_dec_tab[6];break;	
		case 110:wide=open_dec_tab[5];break;		
		case 113:wide=open_dec_tab[4];break;
		case 116:wide=open_dec_tab[3];break;	
		case 119:wide=open_dec_tab[2];break;	
		case 122:wide=open_dec_tab[1];break;	
		case 125:wide=open_dec_tab[0];inc_dec_flag=0;break;		
		default:break;
		}
		OCR2=wide;
}


/*==========关门时的加速子函数============*/
void close_inc_speed(uint sp_pl)
{
	switch (sp_pl)
		{
		case 1:wide=close_inc_tab[0];break;	
		case 5:wide=close_inc_tab[1];break;		
		case 10:wide=close_inc_tab[2];break;
		case 20:wide=close_inc_tab[3];break;	
		case 25:wide=close_inc_tab[4];break;		
		case 35:wide=close_inc_tab[5];break;
		case 45:wide=close_inc_tab[6];break;	
		case 50:wide=close_inc_tab[7];break;
		case 60:wide=close_inc_tab[8];break;
		case 65:wide=close_inc_tab[9];break;	
		case 75:wide=close_inc_tab[10];break;		
		case 85:wide=close_inc_tab[11];break;
		case 90:wide=close_inc_tab[12];break;	
		case 100:wide=close_inc_tab[13];break;	
		case 105:wide=close_inc_tab[14];break;	
		case 115:wide=close_inc_tab[15];inc_dec_flag=0;break;		
		default:break;
		}
		OCR2=wide;
}


/*==========关门时的减速子函数============*/
void close_dec_speed(uint sp_pl)
{
	switch (sp_pl)
		{
		case 1:wide=close_dec_tab[15];break;	
		case 15:wide=close_dec_tab[14];break;		
		case 30:wide=close_dec_tab[13];break;
		case 45:wide=close_dec_tab[12];break;	
		case 60:wide=close_dec_tab[11];break;		
		case 70:wide=close_dec_tab[10];break;
		case 80:wide=close_dec_tab[9];break;	
		case 90:wide=close_dec_tab[8];break;
		case 100:wide=close_dec_tab[7];break;
		case 105:wide=close_dec_tab[6];break;	
		case 110:wide=close_dec_tab[5];break;		
		case 113:wide=close_dec_tab[4];break;
		case 116:wide=close_dec_tab[3];break;	
		case 119:wide=close_dec_tab[2];break;	
		case 122:wide=close_dec_tab[1];break;	
		case 125:wide=close_dec_tab[0];inc_dec_flag=0;break;		
		default:break;
		}
		OCR2=wide;
}

/*==========关门突然撞人时的减速子函数===========*/
void close_down_speed(uint sp_pl)
{
	switch (sp_pl)
		{
		case 1:wide=close_dec_tab[15];break;	
		case 2:wide=close_dec_tab[14];break;		
		case 3:wide=close_dec_tab[13];break;
		case 4:wide=close_dec_tab[12];break;	
		case 5:wide=close_dec_tab[11];break;		
		case 6:wide=close_dec_tab[10];break;
		case 7:wide=close_dec_tab[9];break;	
		case 8:wide=close_dec_tab[8];break;
		case 9:wide=close_dec_tab[7];break;
		case 10:wide=close_dec_tab[6];break;	
		case 11:wide=close_dec_tab[5];break;	
		case 12:wide=close_dec_tab[4];break;
		case 13:wide=close_dec_tab[3];break;	
		case 14:wide=close_dec_tab[2];break;	
		case 15:wide=close_dec_tab[1];break;	
		case 16:wide=close_dec_tab[0];inc_dec_flag=0;break;		
		default:break;
		}
		OCR2=wide;
}


/*======待机状态(status=40)时的正常工作子函数=======*/
void normal_work(void)
{
if(TANTE1==0)
					{delay(30);
			   		if(TANTE1==0)tante_flag=1;
					}
					else        tante_flag=0;
					//************************
					if((PIND&0x02)==0)
					{delay(30);
			  		 if((PIND&0x02)==0)openflag=HALF;
					 }
					 else		openflag=ALL;
					 //***************************
					 if((PIND&0x10)==0)
					 {delay(30);
     				 if((PIND&0x10)==0)openstop=1;
					 }
					 else		openstop=0;
	if(openflag==ALL)
			 		{allchangdu=allchangdu_x;
			 		st_changdu=allchangdu;}
					else
					{allchangdu=(allchangdu_x/2)+30;
			 		st_changdu=allchangdu;}
					
					//if(changdu<30)
					{TCCR2=0x71;SACE_0;inc_dec_flag=0;
					sp_pl=0;wide=0;OCR2=wide;
					round_cnt=0;PWMOUT_0;}
					//else	{status=130;}	
		 
}


/*=========待机状态(status=40)时的输入门靠墙停顿时间=========*/
void input_stoptime(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;stoptime=val;
  				EEPROM_WRITE(stoptime_address,val);
  				eep_temp=55;
				EEPROM_WRITE(stoptime_address+1,eep_temp);
				PORTA=0x00;
				delay(500);
				SREG|=0x80; }
			   }
  delay(300);
}


/*==========待机状态(status=40)时的输入开门最大速度===========*/
void input_openmaxspeed(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;open_max_temp=val;
  				EEPROM_WRITE(open_max_address,val);
  				eep_temp=55;
				EEPROM_WRITE(open_max_address+1,eep_temp);
				PORTA=0x00;
				delay(500);
				SREG|=0x80; }
			   }
  delay(300);
}


/*=======待机状态(status=40)时的输入开门最小速度==========*/
void input_openminspeed(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;open_min_temp=val;
  				EEPROM_WRITE(open_min_address,val);
  				eep_temp=55;
				EEPROM_WRITE(open_min_address+1,eep_temp);
				PORTA=0x00;
				delay(500);
				SREG|=0x80; }
			   }
  delay(300);
}

⌨️ 快捷键说明

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