#include<reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ok 0x00; //地址接收成功,给主机返回OK
#define over 0x01; //本次通信成功,给主机返回OVER结束
#define succ 0x02; //本次通信成功
#define fail 0x04; //表示本次通信不成功
sbit key1=P1^2;
sbit key2=P1^3;
sbit key3=P1^4;
sbit key4=P1^5;
/******ch1-ch10控制十路分区********/
sbit ch1=P0^0;
sbit ch2=P0^1;
sbit ch3=P0^2;
sbit ch4=P0^3;
sbit ch5=P0^4;
sbit ch6=P0^5;
sbit ch7=P0^6;
sbit ch8=P0^7;
sbit ch9=P2^7;
sbit ch10=P2^6;
sbit alarmout=P2^2;
sbit gaodi=P2^1;
sbit scl=P1^0;
sbit sda=P1^1;
sbit CLK_165=P2^4;
sbit LD_165=P2^5;
sbit DATA_165=P2^3;
sbit ALARM=P3^7;
uchar table[2];
uchar bdata numl,numh;
sbit numl0=numl^0;
sbit numl1=numl^1;
sbit numl2=numl^2;
sbit numl3=numl^3;
sbit numl4=numl^4;
sbit numl5=numl^5;
sbit numl6=numl^6;
sbit numl7=numl^7;
sbit numh0=numh^0;
sbit numh1=numh^1;
sbit numh2=numh^2;
sbit numh3=numh^3;
sbit numh4=numh^4;
sbit numh5=numh^5;
sbit numh6=numh^6;
sbit numh7=numh^7;
void delay(uchar z) //长延时函数
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay1() // 短延时函数
{;;}
/***********I2C总线通信,24C02*********************/
void start() //开始信号
{
sda=1;
delay1();
scl=1;
delay1();
sda=0;
delay1();
}
void stop() //停止信号
{
sda=0;
delay1();
scl=1;
delay1();
sda=1;
delay1();
}
void respons() //应答信号
{
uchar i;
scl=1;
delay1();
while((sda==1)&&(i<250))i++;
scl=0;
delay1();
}
void write_byte(uchar date) //写字节函数
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay1();
sda=CY;
delay1();
scl=1;
delay1();
}
scl=0;
delay1();
sda=1;
delay1();
}
uchar read_byte() //读字节函数
{
uchar i,k;
scl=0;
delay1();
sda=1;
delay1();
for(i=0;i<8;i++)
{
scl=1;
delay1();
k=(k<<1)|sda;
scl=0;
delay1();
}
return k;
}
void write_add(uchar address,uchar date) //把数据写入确定地址
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
delay(3);
}
uchar read_add(uchar address) //从确定地址读数据
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
/******74LS165并口转串口输入********/
uint shift() //两个165级联函数,数据并入串出
{
uint i,Read_data=0x0000;
uint data_buf;
LD_165=0;
delay1();
LD_165=1;
for(i=0;i<16;i++)
{
Read_data<<=1;
if(DATA_165)
{
Read_data|=0x0001;
}
CLK_165=0;
_nop_();
CLK_165=1;
delay1();
}
data_buf=Read_data; //数据保存在data_buf
return(data_buf);
}
/************4个I/O口扫描12个按键************/
void scansky(uchar a,uchar b,uchar c,uchar d,uchar shu,uchar e,uchar add) //键盘扫描函数
{
uchar temp,num;
key1=a;
key2=b;
key3=c;
key4=d;
temp=P1;
temp=temp&shu;
if(temp!=shu)
{
delay(8);
temp=P1; //去抖
temp=temp&shu;
if(temp!=shu)
{
temp=P1;
temp=temp&shu;
if(temp==e)
{
while(temp!=shu) //等待松手
{
temp=P1;
temp=temp&shu;
}
num=read_add(add);
delay(2);
num++;
if(num==2)
num=0;
write_add(add,num);
delay(5);
}
}
}
}
/* 串口初始化函数 **串口通信芯片使用MAX488全双工通信*/
void init_serial()
{
TMOD = 0x20; // 定时器T1使用工作方式2
TH1 = 250;
TL1 = 250;
TR1 = 1; // 开始计时
PCON = 0x80; // SMOD = 1
SCON = 0xd0; // 工作方式,9位数据位,波特率9600kbit/s,允许接收
}
/* 接收数据函数 */
uchar recive(uchar addrass)
{
uchar i,temp;
/* 接收地址 */
RI = 0;
while(!RI);
temp=SBUF;
RI = 0;
if((RB8==1)&&(addrass==temp)) //如果地址接收成功请求主机发送数据,给主机返回OK
{
TI=0;
TB8=0;
SBUF=ok;
while(!TI);
TI=0;
}
/* 接收数据 */
for(i=0;i<2;i++)
{
while(!RI);
table[i]=SBUF;
RI = 0;
}
if((table[1]&0xfc)==0xfc) // 接收到的数据跟事先预设好的数据校检,成功,发送OVER结束
{
TI=0;
TB8=0;
SBUF=over;
while(!TI);
TI=0;
return succ;
}
else
return fail;
}
void init() //主函数初始化 关闭所有分区
{
write_add(1,0); //把数据写入24c02
write_add(2,0);
write_add(3,0);
write_add(4,0);
write_add(5,0);
write_add(6,0);
write_add(7,0);
write_add(8,0);
write_add(9,0);
write_add(0,0);
alarmout=1;
}
void main()
{
uchar num,read_date,flag;
uint temp;
init();
init_serial();
while(1)
{
flag=recive(0x00); //0x00从机地址
if(flag==0x02)
{
numl=table[0];
numh=table[1];
write_add(1,numl0); //把数据写入24c02
write_add(2,numl1);
write_add(3,numl2);
write_add(4,numl3);
write_add(5,numl4);
write_add(6,numl5);
write_add(7,numl6);
write_add(8,numl7);
write_add(9,numh0);
write_add(0,numh1);
}
if(ALARM==0)
{
delay(5);
if(ALARM==0)
{
while(!ALARM);
num++;
num=num%2;
if(num==1)
{
ch1=0;
ch2=0;
ch3=0;
ch4=0;
ch5=0;
ch6=0;
ch7=0;
ch8=0;
ch9=0;
ch10=0;
alarmout=0;
}
}
}
if(num!=1)
{
temp=shift();
if(((gaodi==0)&&((temp&0x0001)==0x0001))||((gaodi==1)&&((temp&0x0001)==0x0000))) //第一分区,在高或低电平判断74LS165是否有有效信号输入
ch1=0;
else
{
scansky(1,1,1,0,0x1c,0x18,1); // 扫描CH1建
read_date=read_add(1); //读取24c02数据
if(read_date==1)
ch1=0;
else
ch1=1;
}
if(((gaodi==0)&&((temp&0x0002)==0x0002))||((gaodi==1)&&((temp&0x0002)==0x0000)))
ch2=0;
else
{ // ch2=~ch2;
scansky(1,1,0,1,0x2c,0x28,2); // 扫描CH2建
read_date=read_add(2);
if(read_date==1)
ch2=0;
else
ch2=1;
}
if(((gaodi==0)&&((temp&0x0004)==0x0004))||((gaodi==1)&&((temp&0x0004)==0x0000)))
ch3=0;
else
{
scansky(1,0,1,1,0x34,0x30,3); // 扫描CH3建
read_date=read_add(3);
if(read_date==1)
ch3=0;
else
ch3=1;
}
if(((gaodi==0)&&((temp&0x0008)==0x0008))||((gaodi==1)&&((temp&0x0008)==0x0000)))
ch4=0;
else
{
scansky(1,1,1,0,0x1c,0x14,4); // 扫描CH4建
read_date=read_add(4);
if(read_date==1)
ch4=0;
else
ch4=1;
}
if(((gaodi==0)&&((temp&0x0010)==0x0010))||((gaodi==1)&&((temp&0x0010)==0x0000)))
ch5=0;
else
{
scansky(1,1,0,1,0x2c,0x24,5); // 扫描CH5建
read_date=read_add(5);
if(read_date==1)
ch5=0;
else
ch5=1;
}
if(((gaodi==0)&&((temp&0x0020)==0x0020))||((gaodi==1)&&((temp&0x0020)==0x0000)))
ch6=0;
else
{
scansky(0,1,1,1,0x38,0x30,6); // 扫描CH6建
read_date=read_add(6);
if(read_date==1)
ch6=0;
else
ch6=1;
}
if(((gaodi==0)&&((temp&0x0040)==0x0040))||((gaodi==1)&&((temp&0x0040)==0x0000)))
ch7=0;
else
{
scansky(1,1,1,0,0x1c,0x0c,7); // 扫描CH7建
read_date=read_add(7);
if(read_date==1)
ch7=0;
else
ch7=1;
}
if(((gaodi==0)&&((temp&0x0080)==0x0080))||((gaodi==1)&&((temp&0x0080)==0x0000)))
ch8=0;
else
{
scansky(1,0,1,1,0x34,0x24,8); // 扫描CH8建
read_date=read_add(8);
if(read_date==1)
ch8=0;
else
ch8=1;
}
if(((gaodi==0)&&((temp&0x0100)==0x0100))||((gaodi==1)&&((temp&0x0100)==0x0000)))
ch9=0;
else
{
scansky(0,1,1,1,0x38,0x28,9); // 扫描CH9建
read_date=read_add(9);
if(read_date==1)
ch9=0;
else
ch9=1;
}
if(((gaodi==0)&&((temp&0x0200)==0x0200))||((gaodi==1)&&((temp&0x0200)==0x0000)))
ch10=0;
else
{
scansky(1,1,0,1,0x2c,0x0c,0); //扫描CH10
read_date=read_add(0);
if(read_date==1)
ch10=0;
else
ch10=1;
}
if(((gaodi==0)&&((temp|0xfc00)!=0xfc00))||((gaodi==1)&&((temp&0x03ff)!=0x03ff))||(num==1)) // 当74LS165有有效信号或NUM==1,开启报警输出
alarmout=0;
else
alarmout=1;
}
}
} |