#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit key0=P3^0;//按键0
sbit key1=P3^1;//按键1
sbit key2=P3^3;//按键2
sbit key3=P3^4;//按键3
sbit led0=P1^0;//数码管0
sbit led1=P1^1;//数码管1
sbit led2=P1^2;//数码管2
sbit led3=P1^3;//数码管3
sbit scl=P1^6;//24c02scl端
sbit sda=P1^5;//24c02scd端
sbit out=P1^7;//输出端
sbit in=P3^2;//输入
code uchar ascled[12]={
0x3f,0x06,0x5b,0x4f,0x66, //0,1,2,3,4
0x6d,0x7d,0x07,0x7f,0x6f, //5,6,7,8,9
0x71,0x00}; //F,''
/*****************函数列表**********************/
uchar x24c02_read(uchar addr); //从24c02的地址addr中读取一个字节数据
void x24c02_write(uchar addr,uchar info); //向24c02的addr地址中写入一字节数据info
void x24c02_init(); //24c02初始化子程序
void delay(uchar x);//延时子程序ms
void flash();//24c02延时子程序nop
void start();//24c02ic开始
void stop();//24c02ic停止
void ack();//24c02ic应答
void nack();//24c02ic不应答
void writex(uchar j);//24c02ic写1byte数据
void dsp();//显示子程序
void delay(uchar i);//us延时
void delay1(uchar i);//us延时
uchar readx();//24c02ic读1byte数据
/****************全局变量定义*******************/
uchar ktemp;
uchar disp[4];
uint count;//预设报警值
uint zs;//转速值
uint time0;//
uint time1;//记时器
bit begin1;//T1开始启动标志
uchar ltj=1;//高低速
uint js;//脉冲计数器
ulong t0;
ulong t1;
bit key_set;//设置标志
uchar disp_i[4];//显示闪动标志
uint disp_c;//闪动显示计数器//借用time0
uint disp_j;//闪动显示定时//借用time1
bit ss=0;//闪动标志
uint bj;//报警输出信号定时
bit en_bj=0;//允许报警标志
bit bjing=0;//报警中
//m:菜单级数 mi:参数标号 bh:检测保护时间1-10
uchar bh=0;
uchar m=0,mi=0;//借用zs,js
uchar bhtm=0;//保护检测
//bit cmi=0;//参数设置改变标志//借用bjing
/**********************************************/
void int_ex0() interrupt 0 using 0
{
/*外部中断0*/
delay1(20);
if(key_set==0){///0 非设置状态
if(in==0){
if(ltj==1)
{
js++;
EA=0;
TR0=0;
TL0=0xaf; //50ms
TH0=0x3c; /*计数初值重装*/
if(begin1==0)
{ //开始记数
begin1=1;
js=0;
TR1=0;
TL1=0xaf; //50ms
TH1=0x3c; /*计数初值重装*/
TR1=1; /*启动T1*/
}
/*启动T0*/
TR0=1;
time0=0;
EA=1;
}
else
{
if(begin1==0)
{
begin1=1;
EA=0;
TR0=0;
zs=0;
/*启动T0*/
TL0=0xaf; //50ms
TH0=0x3c; /*计数初值重装*/
TR0=1;
time0=0;
EA=1;
}
else
{
EA=0;
TR0=0;
begin1=0;
if(time0==0)
{
zs=0;
}
else
{//计算转速
t0=(time0*50000+(TH0*256+TL0)-0x3caf);
if(t0>0){zs=60000000/t0;}
}
if(zs
if(en_bj==1)
{
out=1;
bjing=1;//报警
}
}
disp[3]=(zs%10000)/1000;//显示转速
disp[2]=(zs%1000)/100;
disp[1]=(zs%100)/10;
disp[0]=zs%10;
TL0=0xaf; //50ms
TH0=0x3c; /*计数初值重装*/
TR0=1;
time0=0;
EA=1;
}
}
}
//
}///0
}
void timer0(void)interrupt 1 using 0//记时定时中断
{uchar t;
//////
if(key_set==0){///0 非设置状态
time0++;
TL0=0xaf; //50ms
TH0=0x3c; /*计数初值重装*/
TR0=1;
/*启动T1*/
t=time0%20;
if(t==0){en_bj=0;}
if(time0>1200)//超时
{
time0=0;
disp[3]=0;
disp[2]=0;
disp[1]=0;
disp[0]=0;
zs=0;
if(en_bj==1)
{
out=1;
bjing=1;//报警
}
}
}///0
}
void timer1(void)interrupt 3 using 0//1s记时定时中断
{
/*T1中断服务程序入口*/
//////
if(key_set==0){///0 非设置状态
time1++;
if(time1==20)//1s
{ EA=0;
TR1=0;
//计算转速
///////////////////
t0=time0*50000+(TH0*256+TL0)-0x3caf;
t1=1000000-t0;
t0=60*js*t0;
zs=60*js+t0/t1;
if(zs>6000){zs=0;}
if(zs
if(en_bj==1)
{
if(bhtm>=bh)
{
out=1;
bjing=1;//报警
}
bhtm++;
}
}
else
{
bhtm=0;
}
if(zs==0)
{ ///////
///////
disp[3]=0;
disp[2]=0;
disp[1]=0;
disp[0]=0;
}
else
{
disp[3]=zs/1000;//显示转速
disp[2]=(zs%1000)/100;
disp[1]=(zs%100)/10;
disp[0]=zs%10;
}
begin1=0;
js=0;
time0=0;
time1=0;
en_bj=0;//非保护状态
}
//////
TL1=0xaf; //50ms
TH1=0x3c; /*计数初值重装*/
TR1=1; /*启动T1*/
EA=1;
}///0
}
void delay(uchar i)
{ uchar j;
for(j=0;j<=i;j++);
}
void delay1(uchar i)
{ uchar j;
for(j=0;j<=i;j++);
}
void flash()
{
_nop_();
_nop_();
_nop_();
//_nop_();
//_nop_();
}
void x24c02_init()
{
scl=1;
flash();
sda=1;
flash();
}
void start()
{
sda=1;
flash();
scl=1;
flash();
sda=0;
flash();
scl=0;
flash();
}
void stop()
{
sda=0;
flash();
scl=1;
flash();
sda=1;
flash();
}
void ack()
{
sda=0;
flash();
scl=1;
flash();
scl=0;
flash();
}
void nack()
{
sda=1;
flash();
scl=1;
flash();
scl=0;
flash();
}
void writex(uchar j)
{
uchar i,temp;
temp=j;
for (i=0;i<8;i++){
temp=temp<<1;
scl=0;
flash();
sda=CY;
flash();
scl=1;
flash();
}
scl=0;
flash();
sda=1;
flash();
}
uchar readx()
{
uchar i,j,k=0;
scl=0;
flash();
sda=1;
for (i=0;i<8;i++){
flash();
scl=1;
flash();
if (sda==1) j=1;
else j=0;
k=(k<<1)│j;
scl=0;
flash();
}
return(k);
}
uchar x24c02_read(uchar addr)
{
uchar i;
start();
writex(0xa0);
ack();
writex(addr);
ack();
start();
writex(0xa1);
ack();
i=readx();
nack();
stop();
delay(10);
return(i);
}
void x24c02_write(uchar addr,uchar info)
{
//EA=0; //中断总禁止
start();
writex(0xa0);
ack();
writex(addr);
ack();
writex(info);
ack();
stop();
//EA=1;//中断开//设置状态禁止所有外部中断
}
void getdate(void)
{uchar da5,da4,da3,da2,da1,da0;
x24c02_init();
da0=(x24c02_read(0x00)%10);
da1=(x24c02_read(0x01)%10);
da2=(x24c02_read(0x02)%10);
da3=(x24c02_read(0x03)%10);
da4=(x24c02_read(0x04)%10);
da5=(x24c02_read(0x05)%10);
ltj=(x24c02_read(0x06)%10);
count=da3*1000+da2*100+da1*10+da0;
bh=da5*10+da4;
if(bh>99){bh=0;}
if(count>6000){count=6000;}
if(ltj>1){ltj=1;}
}
void savedate(void)
{uchar da5,da4,da3,da2,da1,da0;
da5=bh/10;
da4=bh%10;
da3=count/1000;
da2=(count%1000)/100;
da1=(count%100)/10;
da0=count%10;
dsp();
x24c02_init();
x24c02_write(0x00,da0);
x24c02_write(0x00,da0);
dsp();
x24c02_write(0x01,da1);
x24c02_write(0x01,da1);
dsp();
x24c02_write(0x02,da2);
x24c02_write(0x02,da2);
dsp();
x24c02_write(0x03,da3);
x24c02_write(0x03,da3);
dsp();
x24c02_write(0x04,da4);
x24c02_write(0x04,da4);
dsp();
x24c02_write(0x05,da5);
x24c02_write(0x05,da5);
dsp();
x24c02_write(0x06,ltj);
x24c02_write(0x06,ltj);
dsp();
}
//动态显示
void dsp(void)
{
P2=ascled[disp[0]];led0=0;delay(50);led0=1;//led0=0显示,=1不显示
P2=ascled[disp[1]];led1=0;delay(50);led1=1;
P2=ascled[disp[2]];led2=0;delay(50);led2=1;
P2=ascled[disp[3]];led3=0;delay(50);led3=1;
}
//闪烁动态显示有效
void en_dsp(void)
{disp_j=0;
disp_i[0]=0x0;//显示闪动标志 0显示
disp_i[1]=0x0;
disp_i[2]=0x0;
disp_i[3]=0x0;
}
//闪烁动态显示
void dsp_flash(void)
{
disp_j++;
if(disp_j>240)
{disp_j=0;
disp_i[disp_c]=!(disp_i[disp_c]&0x01);
}
P2=ascled[disp[0]];led0=disp_i[0];delay(50);led0=1;//led0=0显示,=1不显示
P2=ascled[disp[1]];led1=disp_i[1];delay(50);led1=1;
P2=ascled[disp[2]];led2=disp_i[2];delay(50);led2=1;
P2=ascled[disp[3]];led3=disp_i[3];delay(50);led3=1;
}
void display(void)
{
//设定状态时如果有键按下就不闪烁
if((ss==0)││(ktemp!=0x1b))
{
dsp();
}
else
{
dsp_flash();
}
}
void kbscan(void)//键盘扫描
{ uchar temp,i;//0
temp=P3;
ktemp=temp&0x1b;//检查key0,key1,key2,key3 00011011
if (ktemp!=0x1b)
{//1
for(i=0;i<250;i++){display();}
temp=P3;
if(ktemp==(temp&ktemp))
{//2
//keyval=ktemp;//记录键值
if(key_set==1)
{//3
switch(ktemp){
case 0x1a://key0
{
/////////////////
m++;
if(m>2){m=1;}
switch(m){
case 1:////显示参数名称
ss=0;disp_c=0;en_dsp();
switch(mi){
case 0:
disp[3]=11;////显示设定参数mi=0显示预设报警值,1显示保护检测时间
disp[2]=11;
disp[1]=10;
disp[0]=1;
dsp();
break;
case 1:
disp[3]=11;////显示设定参数mi=0显示预设报警值,1显示保护检测时间
disp[2]=11;
disp[1]=10;
disp[0]=2;
dsp();
break;
case 2:
disp[3]=11;////显示设定参数mi=0显示预设报警值,1显示保护检测时间,2显示高低转速测量
disp[2]=11;
disp[1]=10;
disp[0]=3;
dsp();
break;
}
break;
case 2:////显示参数
ss=1;en_dsp();
switch (mi){//显示设定参数mi=0显示预设报警值,1显示保护检测时间
case 0:
disp[3]=count/1000;
disp[2]=(count%1000)/100;
disp[1]=(count%100)/10;
disp[0]=count%10;
for(i=0;i<150;i++){dsp();}
break;
case 1:
disp[3]=11;
disp[2]=11;
disp[1]=bh/10;
disp[0]=bh%10;
for(i=0;i<150;i++){dsp();}
break;
case 2:
disp[3]=11;
disp[2]=11;
disp[1]=11;
disp[0]=ltj;
for(i=0;i<150;i++){dsp();}
break;
}
break;
}
/////////////////
}
case 0x19://key1
{
break;
}
case 0x13://key2
{
//闪动位移
if(ss==1)
{
switch (mi){
case 0:
en_dsp();////预设转速4位显示
disp_c++;
if(disp_c>3){disp_c=0;}
break;
case 1:
en_dsp();////输出保护时间2位显示
disp_c++;
if(disp_c>1){disp_c=0;}
break;
case 2:
break;
}
}
if(m==1)
{//保存数据退出设置状态
savedate();
//借用后恢复
//bjing=0;
m=0;
mi=0;
key_set=0;
ss=0;
en_dsp();
disp[0]=0;
disp[1]=0;
disp[2]=0;
disp[3]=0;
for(i=0;i<150;i++){dsp();}
if(ltj==1)
{
TMOD=0x11;TL0=0xaf;TH0=0x3c;TL1=0xaf;TH1=0x3c;ET0=1;ET1=1;TR0=1;TR1=1;
}
EA=1;//数据保存允许中断
}
break;
}
case 0x0b://key3
{
/////////////////
if(m==1)
{ disp_c=0;
mi++;if(mi>2){mi=0;}
switch(mi){
case 0:
disp[3]=11;////显示设定参数mi=0显示预设报警值,1显示保护检测时间
disp[2]=11;
disp[1]=10;
disp[0]=1;
dsp();
break;
case 1:
disp[3]=11;////显示设定参数mi=0显示预设报警值,1显示保护检测时间
disp[2]=11;
disp[1]=10;
disp[0]=2;
dsp();
break;
case 2:
disp[3]=11;////显示设定参数mi=0显示预设报警值,1显示保护检测时间
disp[2]=11;
disp[1]=10;
disp[0]=3;
dsp();
break;
}
}
else
{
m=0;
switch(mi){
case 0:
disp[disp_c]++;
if(disp[disp_c]>9){disp[disp_c]=0;}
if((disp[3]*1000+disp[2]*100+disp[1]*10+disp[0])>6000)
{ //如果超出设定范围
disp[3]=0;disp[2]=0;disp[1]=0;disp[0]=0;
}
count=disp[3]*1000+disp[2]*100+disp[1]*10+disp[0];
dsp_flash();
break;
case 1:
disp[disp_c]++;
if(disp[disp_c]>9){disp[disp_c]=0;}
bh=disp[1]*10+disp[0];
dsp_flash();
break;
case 2:
disp[disp_c]++;
if(disp[disp_c]>1){disp[disp_c]=0;}
ltj=disp[0];
dsp_flash();
break;
}
}
break;
}
}
}//3
else
{//4
switch(ktemp){
case 0x1a://key0
{
////////////////
//禁止测转速
EA=0;
key_set=1;
en_bj=0;//如果设定状态允许报警标志0
out=0;//
/////
//bjing=0;
///disp_c=0;//time0
/////
m=1;
disp[3]=11;////显示设定参数mi=0显示预设报警值,1显示保护检测时间
disp[2]=11;
disp[1]=10;
disp[0]=1;
for(i=0;i<150;i++){dsp();}
break;
}
case 0x19://key1
{
//允许报警
en_bj=1;
break;
}
}
}//4
}//2
}//1
}//0
main()
{uchar i;
out=0;
key_set=0;
disp[0]=0;
disp[1]=0;
disp[2]=0;
disp[3]=0;
for(i=0;i<250;i++)display();
getdate();
en_dsp();
//////
time0=0;time1=0;zs=0;bj=0;js=0;begin1=0;bjing=0;
EA=0;EX0=1;IT0=1;PT1=1;//CPU关中断,INT0请求中断,设定INT0触发方式
if(ltj==1)
{
TMOD=0x11;TL0=0xaf;TH0=0x3c;TL1=0xaf;TH1=0x3c;ET0=1;ET1=1;TR0=1;TR1=1; /*50ms,T1T0工作在定时器方式1,T1开中断,启动T1*/
}
else
{
TMOD=0x11;TL0=0xaf;TH0=0x3c;ET0=1;TR0=1;
}
EA=1;
//////
begin:
if(bjing==1)
{
bj++;
if(bj>500)
{
bjing=0;out=0;//清除报警
bj=0;bhtm=0;
}
}
else
{
bj=0;
}
display();
kbscan();
goto begin;
}
上一篇:51单片机12M晶振的延时程序
下一篇:单片机复位电路的可靠性设计及精典实用复位电路
推荐阅读最新更新时间:2024-03-16 15:09