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

📄 mkq_m8.c.bak

📁 一个使用AVR的M8控制单相电容启动电机的程序
💻 BAK
字号:
//2007-7-19 9:46
//2007-7-18 20:03门控器设计开始
//端口:DUC(PB1) 报警指示灯 低有效 	输出
//		KEY(PB7) 钥匙输入 低有效	输入		
//		TXD(PD1) 串口发送 测试用	输出
//		INT0(PD2)INT1(PD3)密码正确脉冲输入 负脉冲?	输入
//		close(PC0)正转电机控制 低有效	输出
//		open(PC1) 反转电机控制 低有效	输出
//		zh(PC2)   电机线圈继电器控制 低有效		输出
//		XD(PC3)	  门锁紧行程信号 低有效		输入
//		XC(PC4)	  门关上行程信号 低有效		输入
//		XU(PC5)   门开启行程信号 低有效		输入
//DDRX =1 输出 =0输入
//输入时(PORTB=1 使能上拉  PORTB=0 高阻态)
/*             B7654_3210
  DDRB=0x02; //B0000_0010   PB7(输入 高阻 外有上拉 ) PB1(输出 常态出高熄灭)
  PORTB=0x7f;//B0111_1111

  DDRC=0x00; //B0000_0111 	PC(5 4 3)(输入 高阻 外有上拉 ) 2 1 0(输出 常态出高)
  PORTC=0xff;//B1100_0111

  DDRD=0x00; //B0000_0010 	PD3(输入 高阻 外有上拉 ) PD2(输入 上拉) PD1(输出 常态出高)
  PORTD=0xff;//B1111_0111
*/
/*电机控制
	正转 PC0=0 PC2=1  到位 PC0=1
	反转 PC1=0 PC2=0  到位 PC1=1
	PC2控制切换继电器 PC2=1  正转位置 	PC2=0 反转位置
*/
//要有等待电机停止后才能改变转向的处理?!
/*行程开关检测
		XD(PC3)	  门锁紧行程信号 低有效		输入
		XC(PC4)	  门关上行程信号 低有效		输入
		XU(PC5)   门开启行程信号 低有效		输入
	
*/
//用3-8译码器接LED作为输出状态指示  PD765输出常态出低
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//注: 内部函数_delay_ms() 最高延时  262.144mS@1MHz 即 32.768ms@8MHz
//时钟内部8M,不分频
#define	uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define	NOP		asm("nop")
#define	T0_10MS	0x064//定时器--1ms中断定时器重装值(256-x)*8/1000=2
#define CONST_10S	50////////////tst50 
#define CONST_12S	60////////////tst60

//-----------位操作定义----
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 

//报警
#define	ERR_OFF		sbi(PORTB,1)
#define	ERR_ON		cbi(PORTB,1)

//正转 	PC0
#define	LOCK_OFF	sbi(PORTC,0)
#define	LOCK_ON		cbi(PORTC,0)

//反转 	PC1
#define	UNLOCK_OFF	sbi(PORTC,1)
#define	UNLOCK_ON	cbi(PORTC,1)

//切换继电器 PC2 
#define	JDQ_OFF		sbi(PORTC,2)
#define	JDQ_ON		cbi(PORTC,2)


#define	KEY		(PINB&0x80)  //KEY=0x00 钥匙启动开门 电机反转
#define	XCKG	(PINC&0x38)  //0011_1000  0X38 位345有0表示行程开关接通


#define BIT0	0x01
#define BIT1	0x02
#define BIT2	0x04
#define BIT3	0x08
#define BIT4	0x10
#define BIT5	0x20
#define BIT6	0x40
#define BIT7	0x80

// 时间变量
uchar	f_10ms;
uchar	cnt_20ms;
uchar	f_20ms;
uchar	cnt_100ms;
uchar	f_100ms;
uchar	cnt_200ms;
uchar	f_200ms;
uchar	cnt_12s;//反转时限
uchar	f_12s;
uchar	cnt_10s;//正转时限
uchar	f_10s;
uchar	f_key;

//控制变量
uchar	err_f;	//=1报警 
uchar	state;	//0锁紧 1打开 2锁门 3开门 4异常
uchar	key_state;
uchar	blink_b;//=1亮 	=0灭
/////////////////////////////////////////////

void 	timer0_init(void);
void	main_init(void);
void	tim0_mainloop(void);
void	led_alarm(uchar err_f);
void	moto_fan(void);
void	moto_zhen(void);
void	door_state_init(void);
void	keypd_mainloop(void);
void	door_mainloop(void);
void	delay_ms(uint temp);

//****************************
void timer0_init(void)
{
	//T0定时10ms
	TCCR0 = 0x00; //stop
 	TCNT0 = T0_10MS; //setup	
	TCCR0 = 0x03; //start timer	--64分频--1M内部系统时钟--10ms中断一次	
	TIMSK = 0x01; //溢出中断TOIE0
}

//************************************
SIGNAL(SIG_OVERFLOW0)//T0溢出中断10ms
{
	TCNT0 = T0_10MS;	
	f_10ms=1;	
}	

//************************************
void	main_init(void)
{
  DDRB=0x02; //B0000_0010   PB7(输入 高阻 外有上拉 ) PB1(输出 常态出高熄灭)
  PORTB=0x7f;//B1111_1111

  DDRC=0x07; //B0000_0111 	PC(5 4 3)(输入 高阻 外有上拉 ) 2 1 0(输出 常态出高)
  PORTC=0xff;//B1111_1111

//DDRD=0x02; //B0000_0010 	PD3(输入 高阻 外有上拉 ) PD2(输入 上拉) PD1(输出 常态出高)
//PORTD=0xf7;//B1111_0111
	DDRD=0xf0; //B1111_0000 	PD3(输入 高阻 外有上拉 ) PD2(输入 上拉) PD1(输出 常态出高)
	PORTD=0x0f;//B0000_1111
   
	timer0_init();
	cnt_20ms=2;
	cnt_100ms=5;
	cnt_200ms=2;
	cnt_10s=CONST_10S;
	cnt_12s=CONST_12S;	
}

//************************************
//10ms一次中断产生检测时间20ms,报警时间100ms 时限保护10s 12s
void	tim0_mainloop(void)
{
	if(f_10ms==1)
	{
		f_10ms=0;
		if(--cnt_20ms==0)//判断按钮
		{
			cnt_20ms=2;f_20ms=1;
			if(--cnt_100ms==0)//闪烁时间
			{
				cnt_100ms = 2;f_100ms = 1;
				if(--cnt_200ms==0)//行程开关检测时间
				{
					cnt_200ms=2;f_200ms=1;
					if(--cnt_10s==0)//正转时间
					{
						cnt_10s=CONST_10S;f_10s=1;	
					}
					if(--cnt_12s==0)//反转时间
					{
						cnt_12s=CONST_12S;f_12s=1;	
					}
				}
			}
		}
	}
}
//************************************
//错误报警 输入参数=1 报警 =0 不报警
void	led_alarm(uchar alarm)
{
	if((alarm==1)&&(f_100ms==1))	//同时满足 100ms时间到,报警标志为1
	{
		f_100ms=0;
		if(blink_b==0)
		{
			ERR_ON;blink_b=1;
		}
		else
		{
			ERR_OFF;blink_b=0;
		}
	}
}

//************************************
void	moto_zhen(void)
{
	JDQ_OFF;
	_delay_ms(10);
	LOCK_ON;//正转锁紧	
}
//************************************
void	moto_fan(void)
{
	JDQ_ON;
	_delay_ms(10);
	UNLOCK_ON;//反转松开
}
//************************************
void	door_state_init(void)//门状态起始判断
{
	uchar	temp;
	temp=XCKG;
	temp>>=3;
	err_f=0;ERR_OFF;
	//上电后若门合上,但未锁定100,执行锁定  
	//若门锁紧 进入0
	//若门全开 进入4
	//若门安装初态111 进入11 
	//若行程开关位置有冲突,报警,直到正确为止 包括 000 010 110
	//对于执行报警或锁紧的步骤,要加入上电初始化标志powon_f=1;
	
	temp=7;
	switch(temp)//PC5(解锁) 4(关上) 3(锁紧) 
	{
		case 0://000	行程开关位置有冲突 报警
			state=8;err_f=1;
			break;
		case 1://001解锁+关闭---启动锁紧并一直报警直到门锁紧为止
			moto_zhen();f_10s=0;cnt_10s=CONST_10S;
			state=3;
			err_f=1;
			break;
		case 2://010	行程开关位置有冲突 报警
			state=8;err_f=1;
			break;		
		case 3://011	门全开
			state=2;
			break;		
		case 4://100已经锁紧
			state=0;			break;		case 5://101	门安装初态 门合上但行程开关不到位	启动锁紧并一直报警直到门锁紧为止
			moto_zhen();f_10s=0;cnt_10s=CONST_10S;
			state=3;			
			err_f=1;
			break;
		case 6://110	行程开关位置有冲突 报警
			state=8;err_f=1;
			break;
		case 7://111 	门安装初态111  门未合上
			state=4;err_f=1;
			break;
	}
	//101 111为安装初态处理 (锁紧机构在中间,既未锁紧也未解锁)
	//001为可能的断电恢复处理(门合上且解锁)
	//000 010 110为行程开关不正常组合,应解除故障再操作!
	PORTD|=0XF0;PORTD&=(state<<4);//状态指示
}

//************************************
void	door_mainloop(void)
{
	uchar	temp;
	if(!f_200ms)return;
	f_200ms=0;
	temp=XCKG;
	temp>>=3;
	err_f=0;ERR_OFF;//暂时关闭报警
	switch(state)
	{
		case 0://锁紧
			switch(temp)//锁紧态,只有按钮和密码板脉冲才能开启。
			{
				case 4:if(f_key){state=1;moto_fan();f_12s=0;cnt_12s=CONST_12S;}//进入开门初始态  
					break;
				default:state=8;f_key=0;err_f=1;
					break;	
				//3 5 7 行程开关位置错误 此错误只有手动使门锁紧行程开关合上=0,才能恢复
			}
			break;
			
		case 1://正开门态
			switch(temp)
			{
				case 3: state=2;UNLOCK_OFF;f_key=0;
					break;//完成开门
				default:
					if(f_12s==1)
					{
						state=8;f_key=0;UNLOCK_OFF;err_f=1;//门规定时间解不了锁
						if(temp==4){state=6;}//门一直锁紧
					}
						
					break;
			}
			break;

		case 2://打开
			switch(temp)
			{
				case 3: 
					break;//门已打开
				case 1:	//门被合上
					state=3;moto_zhen();f_10s=0;cnt_10s=CONST_10S;//进入关门态
					break;
				default:state=8;err_f=1;
					break;	
			}		
			break;
			
		case 3://正锁门态
			switch(temp)
			{
				case 4:	state=0;LOCK_OFF;
					break;//门锁
				default:if(f_10s==1){state=8;LOCK_OFF;err_f=1;}//门规定时间锁不上
					break;
			}		
			break;	
		
		case 4://安装等关门
			err_f=1;
			switch(temp)
			{
				case 5:state=5;moto_zhen();f_10s=0;cnt_10s=CONST_10S;//进入关门态
					break;	
				default:break;	
			}
			break;
			
		case 5://安装的锁门
			err_f=1;
			switch(temp)
			{
				case 4:	state=0;LOCK_OFF;err_f=0;
					break;//门锁
				default:if(f_10s==1){state=8;LOCK_OFF;}//门规定时间锁不上
					break;
			}		
			break;							
		case 6://门一直锁紧,只有按键能使它退出			
			switch(temp)//锁紧态,只有按钮和密码板脉冲才能开启。
			{
				case 4:
					if(f_key){state=1;moto_fan();f_12s=0;cnt_12s=CONST_12S;}//进入开门初始态  
					else{err_f=1;}
					break;
				default:state=8;f_key=0;err_f=1;
					break;	
			}
			break;	
					
		case 8://异常 只有门全开和门锁紧正常 才能退出异常
			switch(temp)
			{
				case 3:	state=2;break;//门开
				case 4:	state=0;break;//门锁
				default:err_f=1;break;
			}		
			break;
		
		default: break;
		
	}		

	//开门解锁后的关门(开门解锁后,没有手动拉开门导致报警,此时又手动合上门,如何处理?)
	//不会出现,因为close开关紧贴门边的
	//关门过程中的开门(在门合上正在锁紧的过程中,里面手动按下开门按钮或外面密码板有信号,如何处理?)
	//关门过程中不响应开门!
	PORTD|=0XF0;PORTD&=state<<4;//状态指示
	if((blink_b==1)&&(err_f==1)){ERR_ON;}
}

//************************************
void	keypd_mainloop(void)
{
	uchar	temp;
	static uchar	keystate;
	if((f_20ms==1)&&(f_key==0))
	{
		f_20ms=0;
		temp = PINB;
		switch(keystate)
		{
			case 0:/*有键按下*/
				if((temp&BIT7)==0)	keystate=1;
				break;
			case 1://确认有键
				if((temp&BIT7)==0)	{keystate=2;}
				else {keystate=0;}
				break;
			case 2://等待释放
				if((temp&BIT7)!=0) 
				{
					keystate=0;
					f_key=1;
				}
				break; 
		}
	}
}
//************************************
int main(void)
{
	main_init();
	door_state_init();

	sei();
	while(1)
	{
		tim0_mainloop();//10ms时间处理
		led_alarm(err_f);//100ms报警闪烁
		keypd_mainloop();//20ms检测按键和密码脉冲---》fkey=1;
		door_mainloop();//200ms根据行程开关和KEY进行响应处理
	}
}

/*
0 锁紧
1 门开中
2 门开
3 门锁中
4 门装待关
5 门装正锁
6 门无法解锁
8 异常*/

⌨️ 快捷键说明

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