找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1949|回复: 2
收起左侧

多路流量计实现

[复制链接]
ID:298182 发表于 2018-3-29 09:49 | 显示全部楼层 |阅读模式
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^0;   //ds18b20与单片机连接口
sbit RS=P1^1;  //液晶数据/命令选择端   
sbit RW=P1^2;
sbit EN=P1^3;  //液晶使能端
sbit lamp1 = P3^0;
sbit lamp2 = P3^1;
sbit p37=P3^6;    //流量正常运行接口
sbit p36=P3^7;    //温度报警接口
sbit p14=P1^4;   //功能按键接口
sbit p15=P1^5;  
sbit p16=P1^6;  
uchar       number[10];  //存储定时器IT0和IT1发出的频率   
unsigned long int      a,temp,temp2,temp4; //累计频率
float        f,zong;
uint         motorspeed,  tvalue,   counter=0; //脉冲数
uchar        a1,a2,a3,a4,a5;//瞬时速度的个十百千万位
uchar        v1,v2,v3,v4,v5; //瞬时速度的个十百千万位
uchar        n1,n2,n3,n4,n5,n6,n7,n8,n9;
uchar        tflag,d,g,kai,j,j1,j2,b;
uchar       num,count,key1num,year,mouth,dat,hour,minute,sound;
uint         temp1,temp3,temp5; //记录瞬时频率速度
uint  d_flag;
uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20}; //0-9数字和显示无

/************************延时子程序**************************/
void delay (uint z)  
{
int x,y;
  
for(x=z;x>0;x--)  
for(y=120;y>0;y--);  
}  
/***************延时1us子程序**********************/  
void delay_18B20(unsigned int i)//延时1微秒
{
while(i--);
}

/***************液晶显示写指令*******************************/      
void wr_com(unsigned char com)  //写指令  
{
   
   delay(1);   //延时1ms
    RS=0;    //写命令设置
    RW=0;    //并行数据的读写
    EN=0;    //使能为0
    P2=com;    //输入命令
    delay(1);   //延时1ms
    EN=1;    //使能为1
    delay(1);   //延时1ms
    EN=0;    //使能为0
}
  /************液晶显示写数据**************************/
void wr_dat(unsigned char dat)//写数据
{
   
   delay(1);
   //延时1ms
    RS=1;    //写数据设置
    RW=0;    //并行数据的读写
    EN=0;    //使能为0
    P2=dat;    //输入数据
    delay(1);   //延时1ms
    EN=1;    //使能为1
    delay(1);   //延时1ms
    EN=0;    //使能为0
}  

/***********水流量计算程序与数据转换程序******************/
void loop (uint flag,uint flag1)
{
uint    zong1;
if(g==0)  //判断时间是否到      
{   
  zong =flag;
}
g=1; //将标志为为1
if(zong>=1000) //判断总流量后三位是否大于1000  
{
  a++;   //总流量前六位加1   
  zong=0; //后三位清零  
}   
if(a>=1000000) //总流量前六位大于1百万  
{   
  a=0; //总流量前六位清零  
}
zong1=(int)zong ; //总流量后三位转换为整形     
n9=a/100000;      //总流量9位全部分配  
n8=a%100000/10000;  
n7=a%10000/1000;   
n6=a%1000/100;  
n5=a%100/10;  
n4=a%10;
n3=zong1%1000/100;
n2=zong1%100/10;
n1=zong1%10;   

//瞬时速度计算
a5 = flag1/10000%10;
  a4 = flag1/1000%10;
a3 = flag1/100%10;
a2 = flag1/10%10;
a1 = flag1%10;
}   
/***********水流量计算程序与数据转换程序******************/
void loop1(unsigned long int flag ,uint flag1)
{
unsigned long int    zong1,sd;
int pos;

zong1=flag;
sd = flag1;
temp1=0;
temp3=0;
number[9] = zong1/100000000;
  number[8] = zong1/100000000%10;
number[7] = zong1/10000000%10;
number[6] = zong1/1000000%10;
number[5] = zong1/100000%10;
number[4] = zong1/10000%10;
number[3] = zong1/1000%10;
number[2] = zong1/100%10;
number[1] = zong1/10%10;
number[0] = zong1%10;

  delay(1000);

  v5 = sd/10000;
  v4 = sd/1000%10;
  v3 = sd/100%10;
  v2 = sd/10%10;
  v1 = sd%10;
  d_flag= 0;
// sd=sd;

}
void loopzong()
{
unsigned long int k;
uint  V_z;
k=temp4+temp+temp2;
V_z=temp1+temp2+temp3;
temp1=temp2=temp3=0;
    number[9] = k/100000000;
  number[8] = k/100000000%10;
number[7] = k/10000000%10;
number[6] = k/1000000%10;
number[5] = k/100000%10;
number[4] = k/10000%10;
number[3] = k/1000%10;
number[2] = k/100%10;
number[1] = k/10%10;
number[0] = k%10;

delay(1000);
v5 = V_z/10000;
v4 = V_z/1000%10;
v3 = V_z/100%10;
v2 = V_z/10%10;
v1 = V_z%10;

}

void loopclock(uchar time,uchar x) //将时分秒写入屏幕
{
  uchar shi,ge;
  shi=time/10;
  ge=time%10;
  wr_com(0x80+0x40+x);
  wr_dat(0x30+shi);
  wr_dat(0x30+ge);
}

/**********************流量程序*******************************/  
void liuliang()  
{

  while(d==20)        //时间到?   
  {  
   d=0;            //d清零
   
   d_flag = 1;
   b=TH0*256+TL0;           //读取频率
   temp4+=b;
   temp5=b;
   sound++;
   if(sound==60)
   {
    sound=0;
    minute++;
    if(minute==60)
    {
     minute=0;
     hour++;
     if(hour==24)
     {
      hour = 0;
     }
      loopclock(hour,4);
     
    }
      loopclock(minute,7);
   }
    loopclock(sound,10);
   if(b>=20&&b<40)  //最小流量继电器一工作
   {
    lamp1 = 0 ;
    lamp2 = 1;
   }
   else if(b*10>=80)   //最大流量继电器2工作
   {
    lamp1 = 1;
    lamp2 = 0;
   
   }
   else  if(b*10>=40&&b*10<80)    //到达额定值继电器一关闭
   {
    lamp1 = 1;
    lamp2 = 1;
   }
   TH0=0x00;        //计数器清零     
   TL0=0x00;
   g=0;             //时间标志位   
  }
}  
/**************第一页显示子程序***************************/
void   display1()
{   
wr_dat(0x3a);   //显示:            
wr_com(0x80);  //水流量(t)显示     
wr_dat(0x46);      //F
wr_dat(0x4c);     //L
wr_dat(0x4f);   //O
wr_dat(0x57);    //W
wr_dat(0x31);
wr_dat(0x3a);   
wr_dat(0x20);

wr_com(0x80+0x40);//空多少格
    wr_dat(table[n9]);     
wr_dat(table[n8]);     
wr_dat(table[n7]);
    wr_dat(0x2e);       //显示小数点        
wr_dat(table[n6]);     
wr_dat(table[n5]);     
wr_dat(table[n4]);
wr_dat(table[n3]);     
wr_dat(table[n2]);     
wr_dat(table[n1]);   
  wr_com(0x80+0x40+20);//空多少格
wr_dat(table[a4]);
wr_dat(table[a3]);     
wr_dat(table[a2]);     
wr_dat(table[a1]);  
}

/**************第二页显示子程序**********************/  
/*void display2()  
{   
     
//  wr_dat(table[j2]); //价格的显示
// wr_dat(0x2e);
// wr_dat(table[j1]);  
// wr_dat(0x5c);  
// wr_dat(0x2f);  
// wr_dat(0x74);  
// wr_dat(0x20);
// wr_dat(0x20);  
// wr_dat(0x20);
wr_dat(0x3a);   //显示:            
wr_com(0x80);  //水流量(t)显示     
wr_dat(0x46);      //F
wr_dat(0x4c);     //L
wr_dat(0x4f);   //O
wr_dat(0x57);    //W
wr_dat(0x32);
wr_dat(0x3a);   
wr_dat(0x20);
  
  
} */
/**************第三页显示子程序**********************/  

void display3()  
{   
wr_dat(0x3a);    //显示:                    
wr_com(0x80);  //水流量(t)显示     
wr_dat(0x46);      //F
wr_dat(0x4c);     //L
wr_dat(0x4f);   //O
wr_dat(0x57);    //W
if(kai==1)
{
  wr_dat(0x32);
}
if(kai==2)
{
    wr_dat(0x33);
}
if(kai==3)
{
  wr_dat(0x34);
}
wr_dat(0x3a);   
wr_dat(0x20);
wr_com(0x80+0x40);//空多少格//水流量(kg)显示  
wr_dat(table[number[9]]);
wr_dat(table[number[8]]);  
wr_dat(table[number[7]]);  
wr_dat(table[number[6]]);
wr_dat(table[number[5]]);
wr_dat(table[number[4]]);
wr_dat(table[number[3]]);  
wr_dat(table[number[2]]);  
wr_dat(table[number[1]]);
wr_dat(table[number[0]]);
wr_com(0x80+0X40+20);//空多少格
wr_dat(table[v5]);
wr_dat(table[v4]);
wr_dat(table[v3]);     
wr_dat(table[v2]);     
wr_dat(table[v1]);
  wr_dat(0x2e);       //显示小数点  
wr_dat(0x20);  
wr_dat(0x6b);  
wr_dat(0x67);   
}
/*****************控制流量测量的开关程序***********************/  
void kaiguan1()  
{
if(p14==0)         //按键按下?  
{
  delay(2);  
  if(p14==0)     
  {
   delay(2);   
   p36=~p36;    //P3.6取反
//   if(kai ==0)
//   {
//    TR0=~TR0;    //TR0取反  
//   }

   while(p14==0);//按键松开   
  }     
}  
}  
/**************界面切换开关程序********************/  
void kaiguan2()  
{
if(p15==0)         //按键按下?  
{
    delay(2);   
    if(p15==0)
  {
   delay(2);  
  // kai=~kai;     //P3.6取反
   kai++;
   if(kai>=4)
   {
      kai = 0;
   }
   while(p15==0);//按键松开?     
  }   
}  
}
void kaiguan3()  
{
if(p16==0)         //按键按下?  
{
    delay(5);   
    if(p16==0)
  {
   key1num++;//时间设置键按下次数记录
   while(p16==0);
   switch(key1num)
   {
   case 1:
   
   wr_com(0x80+0x40+11);//光标定位到秒位置        
  // wr_com(0x0f);//光标开始闪烁提示用户调整时?
   break;
   case 2:
    wr_com(0x80+0x40+8);//光标定位到分钟位置  
    break;
    case 3:
     wr_com(0x80+0x40+5);//光标定位到小时位置   
    break;
    case 4:
       wr_com(0x0c);//取消光标闪烁
    key1num=0;//按键次数统计归零,用于下一次统计
       break;
   }
   
  // while(p16==0);//按键松开?     
  }   
}  
if(key1num!=0)
{
  if(p14==0)   
  {   
   delay(5);//延时去抖
   if(p14==0)
  
   {
    while(p14==0);//等待按键释放后才进行操作
      
    switch(key1num)//根据key1num的值确定光标的位置,从而确定对时分秒的哪一个进行调整
      
    {      
     case 1: //设置秒的值      
      sound++;        
     if(sound==60)        
     sound=0;
            
     loopclock(sound,10);
            
     wr_com(0x80+0x40+11);//将光标冲重新返回到秒的位置,因为写数据指针自动加
            
     break;
         
     case 2:
     //设置分钟的值        
     minute++;      
     if(minute==60)        
     minute=0;
            
     loopclock(minute,7);        
     wr_com(0x80+0x40+8);        
     break;
         
     case 3:
     //设置小时的值        
     hour++;        
     if(hour==24)      
      hour=0;
           
      loopclock(hour,4);        
     wr_com(0x80+0x40+5);
     break;
         
    }      
     
   }
   
  }  
}
}  
/**********************程序初始化******************************/
void lcd_init ()
{
   //液晶使能端为0  
wr_com(0x38);          //液晶初始设置  
wr_com(0x0c);  
wr_com(0x06);  
wr_com(0x01);  
wr_com(0x40);
wr_dat(0x06);          //写CGRAM写字模  
wr_dat(0x09);  
wr_dat(0x09);     
wr_dat(0x06);   
wr_dat(0x00);  
wr_dat(0x00);  
wr_dat(0x00);
wr_dat(0x00);      
zong=0;           //总流量(带小数点)  
TMOD=0x15;            //设定定时器0为计数功能,定时器为1为定时功能
TH1=(65536-50000)/256;//定时器1赋出值50ms  
TL1=(65536-50000)%256;
TH0=0x00;              //定时器0赋初值0次  
TL0=0x00;
EN=0;
ET1=1;                  //开启定时器1中断  
TR1=1;                  //开启定时器1  
TR0=1;                  //开启计数器0  
EX1=1; //开启外部中断0  
IT1=1; //设置成下降沿触发方式
EX0=1; //开启外部中断0  
IT0=1; //设置成下降沿触发方式
EA=1;                   //开启总中断   
p16=1;                  //p16为1  
p15=1;                  //p15为1
p14=1;                  //p14为1            
zong=0;                 //总流量的后三位赋初值  
a=0;
                 //总流量的前六位赋初值  
j=20;                   //水价赋初值  
j2=2;                   //水价个位赋初值  
j1=0;            //水价小数位赋初值  
kai=0;
}
/********************主程序****************************/
void main()  
{   
int dt=100;
lcd_init();    //初始化显示            
while(1)
{        
  kaiguan1();   //控制水流量的测量   
  kaiguan2();   //控制显示界面
   
  liuliang();   //流量测量
   
   switch(kai)
   {
      case 0:
         
       wr_dat(0x01);
       kaiguan3();
      loopclock(hour,4);  loopclock(minute,7);  loopclock(sound,10);
    // loop(temp4,temp5);      //水流量计算程序与数据转换程序
    // display1();  //显示第一页界面
     break;
     case 1:
     wr_dat(0x01);
       loop1(temp2,temp3);
         display3(); //显示第三页界面
      break;
     case 2:
       wr_dat(0x01);
       loop1(temp,temp1);
         display3(); //显示第三页界面
     break;
     case 3:
      wr_dat(0x01);
     loopzong();
       display3(); //显示第三页界面
     break;
   }
}  
}
/******************定时器1中断**********************/  
void time1() interrupt  3  
{  
TH1=(65536-50000)/256;//定时器1初值定时50ms  
TL1=(65536-50000)%256;
d++;         //20ms后d加1

  
}  
void _INT1() interrupt 2
{  
temp++;
temp1++;
}  
void _INT0() interrupt 0
{
temp2++;
temp3++;
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:303039 发表于 2018-4-24 21:34 | 显示全部楼层
这个是1602显示么
回复

使用道具 举报

ID:62509 发表于 2020-6-18 14:54 | 显示全部楼层
有些好奇,如果有,那真是高人呀!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表