📄 liu3.c
字号:
#include<func.h>
#include <at89x52.h>
#include <absacc.h>
#define LCD_WCOM XBYTE[0xfcff]
#define LCD_RCOM XBYTE[0xfeff]
#define LCD_WDAT XBYTE[0xfdff]
#define LCD_RDAT XBYTE[0xffff]
extern void Initial(void);
extern void delay(uint shu);
extern void display(uchar *tab);
extern void commution(void);
/*全局变量********************************/
uchar key;
uchar Dis_buff[16]="1:W S:100 C: "; //后面的空格也是显示速度
uchar sec;
uint dingshi,dingshi1;
uchar warn,cur_speed,set_speed,set_speed_sp,av[3]; //av[3]数组存放三次测量的速度值
/*全局标志*********************************/ //cur_speed表示当前滴速 set_speed表示设置滴速
bit F_key,F_auto; //F_key有/无按键;F_auto(主控)自动/(从控)手动
void dis_speed(uchar dat,uchar dis_9);
void fun0(void); //加速
void fun1(void); //减速
uchar judge(void); //判断速度差
void adjust(void); //调节
void communition(void)//串行通信
/*##############################################*/
//中断区/////////////////////////////////////////
////键盘中断--中断1
void keydec(void) interrupt 0 //中断号为0,表示外部中断0
{
uchar i,keyd;
delay(4000); ////////////////////延时,去抖动
if((P1&0x0f)!=0x0f) //有键按下
{
F_key=1; //标志位置1
EX0=0; //禁止外部中断0
P1_4=0; P1_5=1; //检测第一排的4个键,将第一列置低电平
for(keyd=0,i=0;i<2;i++) //判断是哪个键按下,并计算键值
{
if(!P1_0){key=keyd+i;break;}
else if(!P1_1){key=keyd+i+2;break;}
else if(!P1_2){key=keyd+i+4;break;}
else if(!P1_3){key=keyd+i+6;break;}
else {P1_4=1; P1_5=0;} //将第一列置低电平
}
P1_4=0; P1_5=0; //恢复初始状态
IE0=0; //循环中断时使INT0先为1后为0使中断标志寄存器置位,中断返回时要清0
EX0=1; //开外部中断0
}
}
//定时器1中断,工作在方式2
void timer1(void)interrupt 3 //中断号为3,定时器1中断,定义一个内部时钟,也为串口波特率发生器
{
TH1=0xfd; TL1=0xfd; //装初值,波特率为9600
if(++dingshi1==3072) //就是(dingshi+1)==3072,TMOD应该是在初始化的时候设置好的
{
dingshi1=0;
++dingshi ; //dingshi为10ms数量级
}
if(++dingshi==100) //秒位加1
++sec;
}
液位到达警戒值报警
void timer0(void)interrupt 1 //中断号为1,表示为定时器0中断,工作在计数状态初值为255
{
TR0=0; //关闭定时器0
delay(10000); //延时
if(P3_4==0) //T0脚为0,病人紧急情况报警,液位到达警戒值
{
F_warn=1; //报警标志位置1
warn=0x02; //为第二种报警情况
Dis_buff[6]='!';//将报警信息送显示缓冲区
Dis_buff[7]='!';
Dis_buff[8]='2';
}
else
{
TH0=TL0=255; //重装初值
TR0=1; //启动T0,下降沿则记数器加1
}
}
//外部中断1
void intr1(void)interrupt 2 //中断号为2,表示外部中断1,计算液体滴速
{
uchar F_warn3=0,F_warn4=0,i;//定义中间变量
uchar dis_sp; //中间变量
uint time_sp; //定义一个时间变量
TR0=ET0=0; EX1=0; //关闭T0,禁止T0中断,禁止外中断1
av[2]=av[1];av[1]=av[0]; //存前两次测量值
time_sp=dingshi+sec*100; //记时扩大100倍矫正 dingshi+sec*100;
av[0]=(uchar)(60*100/time_sp); //60*100/timesp为矫正后测得的滴速
if(av[0]>60) //滴速较大时,为保证测量的准确性,
{ // 采取三次采样求平均的方法
time_sp=av[0]+av[1]+av[2];
cur_speed=(uchar)(time_sp/3); //计算当前滴速
}
else cur_speed=av[0];
Dis_buff[14]=cur_speed%10+'0'; //存放滴速的个位
dis_sp=cur_speed/10;
Dis_buff[13]=dis_sp%10+'0'; //存放滴速的十位
Dis_buff[12]=dis_sp/10+'0'; //存放滴速的百位
if(Dis_buff[12]=='0')Dis_buff[12]=' ';//百位为0,则输出空格
display(Dis_buff); //显示速度
TH1=0xe8; TL1=0xe8; //重装初值
dingshi=0; sec=0; //定时时间清0
for(i=0;i<3;i++)
{if(av[i]>150)F_warn3++;} //滴速大于150,滴速过快标志启动
if(F_warn3==3)
{
F_warn=1; //有报警信号
warn=0x03; //为第三种报警信号
Dis_buff[6]='!'; //报警信息送显示缓冲区
Dis_buff[7]='!';
Dis_buff[8]='3';
display(Dis_buff); //显示
}
for(i=0;i<3;i++)
{if(av[i]<20)F_warn4++;} //滴速小于20,滴速过慢信号启动
if(F_warn4==3) //三次测量值都低于规定滴速最小值
{
F_warn=1; //报警信号标志置位
warn=0x04; //为第四种报警信号
Dis_buff[6]='!'; //报警信息送显示缓冲区
Dis_buff[7]='!';
Dis_buff[8]='4';
display(Dis_buff); //显示
}
IE1=0; EX1=1; //开外中断1
}
else
{
ET0=TR0=1; //重新启动内部时钟T0
}
}
//串行通信
void comm(void)interrupt 4 //中断号为4,表示串行口中断
{
commution(); //调用串行通信函数
}
//主函数//////////////////////////////////////////////
void main(void)
{
{
IP=0x10; //设置串口为高中断优先级
TMOD=0x26; //T1定时,方式2;T0计数,方式2
TH1=TL1=0xe8; //装初值
TL1=TL0=255; //装初值,扩展为中断,来一个脉冲则计满溢出
} //初始化
uchar judge_dat,i; //judge_dat
delay(65000);
P1_4=0; P1_5=0;
P1_6=0; P1_7=0; P3_5=0; //T1口置0,
av[0]=av[1]=av[2]=100; //设滴速初值
display(Dis_buff); //显示开机界面,速度为100
dingshi=0; sec=0; //内部时钟初值设为0
F_key=0; F_auto=1; //开始为从控F_key有无键按下;F_auto(主控)自动/从控(手动)
set_speed=set_speed_sp=100; //初始速度为100
IT0=1;IE0=0;EX0=1; //外部中断0为边沿触发方式,IE0初值为0,中断来了硬件会将它置1,允许外部中断0
if(key==2) //紧急情况报警,此功能不受主机控制
{
F_warn=1; P2_2=1;P2_3=0; //报警标志位置位,启动声光报警
warn=0x01; //为第一种报警情况
Dis_buff[6]='!'; //报警信息送显
Dis_buff[7]='!';
Dis_buff[8]='1';
display(Dis_buff);
};break;
else //为其它情况时按下述处理
{
if(!F_auto) //处在从控状态
switch(key)
{
case 0:fun0();break; //按键加速speed++
case 1:fun1();break; //按键减速speed--
case 3: //手动取消报警
{
P2_2=0;P2_3=1; //取消报警
Dis_buff[2]='H'; //'H'是hand的意思
F_warn=0; warn=0x00;
};break;
case 4: //键4为反转、全速控制键
{
P1_6=1; //反转准备
while(!P3_2) //外部中断0产生
{
P1_7=1;
delay(300);
P1_7=0;
delay(300); //全速
display(Dis_buff);
};break;
}
case 5: //键5为正转、全速控制键
{
P1_6=0;
while(!P3_2)
{
P1_7=1;
delay(300);
P1_7=0;
delay(300); //全速
display(Dis_buff);
}
};break;
}
Dis_buff[2]='A'; //否则为主控自动调节
TI=0; RI=0; ES=1;
adjust();
//键0:从控按键加速
void fun0(void)
{
uint i;
F_key=1;Dis_buff[2]='H'; //'H'是hand的意思
while(!P3_2) //进行加速,但最大加至150
{
if(++set_speed_sp>150)set_speed_sp=150;//set-speed-sp为从机设置的速度值
dis_speed(set_speed_sp,0); //显示从控设置的速度
for(i=0;i<25000 && !P3_2&&!F_warn;i++);//等待
}
}
//键1:从控按键减速
void fun1(void)
{
uint i;
F_key=1; Dis_buff[2]='H'; //'H'是hand的意思
while(!P3_2) //外中断0,有键按下,减速,最底减至20
{
if(--set_speed_sp<20)set_speed_sp=20;
dis_speed(set_speed_sp,0); //显示从控设置的速度
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -