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

📄 liu3.c

📁 80C51单片机控制程序.设计了一个输液控制器的控制.
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -