📄 mkq_m8.c.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 + -