求助 点滴速度监控系统设计键盘模块不好使 本人小白 希望各位大虾不吝赐教

2019-07-15 14:42发布

      求助基于89C51 的液体点滴速度监控系统设计的相关资料我的邮箱453505854@qq.com  谢谢各位大虾  好人一生平安
由于是先用proteus仿真看看程序 所以两个检测模块没有画出
我感觉这个题目有点冷门淘宝上没有实物  我也是前阵子看了这个帖子才看到了实现的希望http://bbs.elecfans.com/jishu_480785_1_1.html   
所以如果有大神懂得话  真心求教
顺便问下  检测模块在proteus里可以用什么实现


其中晚上有很多资料都是
sbit E=P2^2;sbit RW=P2^1;sbit RS=P2^0;这么定义的











#include <reg52.h>
#define DB0_DB7 P0
#define busy 0x80
#define SCANPORT P1        
sbit E=P2^7;
sbit RW=P2^6;
sbit RS=P2^5;
sbit P23=P2^3;
unsigned char uca_LineScan[4]={0xEF,0xDF,0xBF,0x7F};//列线扫描电压,分为第1,2,3,4根列线
unsigned char key_ctt[4]={0};
unsigned int time_sq[4]={0};//连续测得的三点的时间
unsigned char speed_bcd[4]={0};
unsigned int speed_ck[4]={0};
unsigned int di_xx[2]={0};
unsigned char speed_sc[2]={0};
unsigned char yy=0,temp;
unsigned int ct=0,ttb=0,xx=0,tt3=0,speedct=0,speed=0,speedcd=10,cott=0;
typedef unsigned char uchar;
uchar code lcd3[]={"0123456789abcdef"};
uchar code lcdnow[]={"NOW:000"};
uchar code lcdset[]={"SET:000"};
unsigned char CONTROL[8]={0x38,0x18,0x98,0x88,0xC8,0x48,0x68,0x28};
unsigned char codes1[8]={0xb8,0x98,0xd8,0xc8,0xe8,0x68,0x78,0x38};///9,18,36,45,54,63,72,81度 顺时针*/
unsigned char codes2[8]={0x38,0x78,0x68,0xe8,0xc8,0xd8,0x98,0xb8}; //9,18,36,45,54,63,72,81度 逆时针
unsigned char counts,pt;
bit flag=1;//度数,正/反转,速度控制
bit a_ac=0;//比较系统标志
unsigned char uc_KeyTemp=0;  //按键键码暂存。
unsigned char uc_ClickCount=0;
unsigned char ucCount;        
void vKeyProcess(unsigned char ucKeyCode);
void bleep();//报警
bit bleept=0;//报警标准
bit moto=0;//电机标志位
void ac();///电机速度比较
void akey();//功能处理A
bit a_key=0;
bit b_key=0;
void getspeed();//速度检测
void stdisplay();//显示
void Delay(unsigned int t);//延时
void delay_50ms(unsigned int t);
void SendCommand(unsigned char ch);//发送命令
void vWriteData(unsigned char ch);//发送数据
void InitLcd();//初始化
void DisplayOneChar(unsigned char x,unsigned y,unsigned char ddata);//按指定位置显示一个字符
void DisplayListChar(unsigned char x, unsigned char y, unsigned char *DData);//按指定位置显示一串字符
//点滴速度检测子程序:
void Delay(unsigned int t)  // delay 40us
{
        //for(;t!=0;t--) ;
        while(t--);
}
void delay_50ms(unsigned int t)
{unsigned int j;
for(;t>0;t--)
   for(j=6245;j>0;j--);
}
void SendCommand(unsigned char ch)//发送命令
{        
        /*CheckBusy();*/
    RS=0;
    RW=0;
    DB0_DB7=ch;
    E=1;
    Delay(1);
    E=0;
    Delay(5);   //delay 40us
}
void vWriteData(unsigned char ch)//发送数据
{   
/*        CheckBusy();        */
        RS=1;
    RW=0;
    DB0_DB7=ch;
    E=1;
    Delay(1);
    E=0;
    Delay(5); //delay 40us
}
//显示子程序流程:
void InitLcd()//初始化
{
        SendCommand(0x38);
        Delay(1);
        SendCommand(0x08); //设置工作方式
        Delay(1);
        SendCommand(0x01); //显示状态设置
        Delay(1);
        SendCommand(0x06); //清屏
        Delay(200);
        SendCommand(0x0c); //输入方式设置
}
void DisplayOneChar(unsigned char x,unsigned y,unsigned char ddata)//按指定位置显示一个字符
{
        y &= 0x1;
        x &= 0xF; //限制X不能大于15,Y不能大于1
        if (y) x |= 0x40; //当要显示第二行时地址码+0x40;
        x |= 0x80; // 算出指令码
        SendCommand(x);
        vWriteData(ddata);        
}
void DisplayListChar(unsigned char x, unsigned char y, unsigned char  *DData)//按指定开始位置显示字符串
{
        unsigned char ListLength;
        ListLength = 0;
        y &= 0x1;
        x &= 0xF; //限制X不能大于15,Y不能大于1
        while (DData[ListLength]>0x20) //若到达字串尾则退出
  {
            if (x <= 0xF) //X坐标应小于0xF
      {
              DisplayOneChar(x, y, DData[ListLength]); //显示单个字符
              ListLength++;
              x++;
       }
   }
}
//键盘扫描子程序流程:
void vShowOneChar(unsigned char ucChar)
{
        switch(ucChar)
                {
                case '0': vWriteData(0x30);break;
                case '1': vWriteData(0x31);break;
                case '2': vWriteData(0x32);break;
                case '3': vWriteData(0x33);break;
                case '4': vWriteData(0x34);break;
                case '5': vWriteData(0x35);break;
                case '6': vWriteData(0x36);break;
                case '7': vWriteData(0x37);break;
                case '8': vWriteData(0x38);break;
                case '9': vWriteData(0x39);break;
                case 'a': vWriteData(0x61);break;
                case 'b': vWriteData(0x62);break;
                case 'c': vWriteData(0x63);break;
                case 'd': vWriteData(0x64);break;
                case 'e': vWriteData(0x65);break;
                case 'f': vWriteData(0x66);break;
                default: break;
                }
}
unsigned char ucKeyScan()
{
        unsigned char ucTemp=0; //扫描状态暂存。
        unsigned char ucRow=0,ucLine=0;//行号,列号。
        for(ucLine=0;ucLine<4;ucLine++) //列扫描
                {
                        SCANPORT=uca_LineScan[ucLine];  //输出扫描电位。
                        ucTemp=SCANPORT&0x0F; //输入扫描电位,并屏蔽高4位。
                        if(ucTemp!=0x0F)                 
                                {                                                                         //判断该列是否有按键按下。
                                switch(ucTemp)
                                        {
                                        case 0x0E: ucRow=10;break; //如果有,则判断行号。
                                        case 0x0D: ucRow=20;break;
                                        case 0x0B: ucRow=30;break;
                                        case 0x07: ucRow=40;break;
                                        default:   ucRow=50;break;
                                        }
                                break;
                                }
                }
        SCANPORT=0x0F; //恢复P2口
        return ucRow+ucLine+1; //返回按键编码。格式为2位数,高位为行号,低位为列号。
}
void vKeyProcess(unsigned char ucKeyCode)
{
SendCommand(0xC4+uc_ClickCount);
if(a_key==1)
{  
switch(ucKeyCode)
{
case 41:vShowOneChar('7');temp=7;break;                                                        
                case 42:vShowOneChar('8');temp=8;break;                                                         
                case 43:vShowOneChar('9');temp=9;break;                                                         
                case 31:vShowOneChar('4');temp=4;break;                                                        
                case 32:vShowOneChar('5');temp=5;break;                                                        
                case 33:vShowOneChar('6');temp=6;break;               
         case 21:vShowOneChar('1');temp=1;break;                                                                  
                case 22:vShowOneChar('2');temp=2;break;        
                case 23:vShowOneChar('3');temp=3;break;                                                                  
                case 12:vShowOneChar('0');temp=0;break;                                                
SendCommand(0xc4+uc_ClickCount);
SendCommand(0x0f);
}
        switch(ucKeyCode)
                {
                case 44:/*vShowOneChar('c');*/temp=12;break;                                                                  //'/'
                case 34:/*vShowOneChar('d')*/temp=13;break;                                                         //'清除'
                case 24:/*vShowOneChar('e')*/temp=14;break;                                                         //'下调'
                case 14:/*vShowOneChar('f')*/temp=15;break;                                                         //'上调'
                case 13:/*vShowOneChar('b');*/temp=11;break;                                                     //'返回'
                case 11:/*vShowOneChar('a');*/temp=10;break;                                                     //'ON/C'
                default:break;
                }
        if(temp==11) //判断按键与上一次所按的键是否相同。
                {
                delay_50ms(10);
                if(uc_ClickCount<255)                                      
                 {        uc_ClickCount++;
                SendCommand(0xc3+uc_ClickCount);
                SendCommand(0x0f);}
                if(uc_ClickCount==3)
                uc_ClickCount=0;
                SendCommand(0xc4+uc_ClickCount);
                SendCommand(0x0f);
                }
if(temp<=9)
{switch(uc_ClickCount)
{
case 0:key_ctt[0]=temp;break;
case 1:key_ctt[1]=temp;break;
case 2:key_ctt[2]=temp;break;
default:break;
}
}
}
}
//点滴速度控制子程序流程:
void int_timer0(void)
{
TMOD=0X10;
TMOD=0X01;
TH0=0X3C;
TL0=0XB0;
TH1=0X3C;
TL1=0XB0;
ET1=1;
TR1=1;
ET0=1;
TR0=1;
EA=1;
IT1=1;
EX1=1;
}
void Timer1() interrupt 3
{
    TH1=0X3c;
    TL1=0Xb0;
        pt++;                                                                                       //控制速度
        if(pt==2)
        {     pt=0;
        if(flag==0&&moto==1)
        P2=(P2&0x0f)|CONTROL[counts];
                if(flag==0&&moto==0)
                P2=(P2&0x0f)|codes2[counts];
                counts++;
                if(counts==8)counts=0;//角度重置
        }
        }
void Timer0() interrupt 1
{
    TH0=0X3c;
    TL0=0Xb0;
yy++;
if(yy==2)
{
ct++;
tt3++;
yy=0;
if(ct==600)//60秒定时
{
  ct=0;
  xx=0;
  }
if(tt3==20)
{
tt3=0;
di_xx[1]=di_xx[0];
di_xx[0]=xx;
if((di_xx[0]==di_xx[1])&&a_ac==1)
{bleept=1;flag=1;}
}
}
}
void Int1() interrupt 2
{
static cott=0;
cott++;
if(cott==2)
{
  xx++;
  time_sq[2]=time_sq[1];   
  time_sq[1]=time_sq[0];
  time_sq[0]=ct;
if(a_key==0)
  {
  DisplayOneChar(10,0,lcd3[speed/100]);
  DisplayOneChar(11,0,lcd3[speed%100/10]);
  DisplayOneChar(12,0,lcd3[speed%10]);
  DisplayOneChar(10,1,lcd3[xx/100]);
  DisplayOneChar(11,1,lcd3[xx%100/10]);
  DisplayOneChar(12,1,lcd3[xx%10]);
  SendCommand(0xC4+uc_ClickCount);}
  getspeed();
cott=0;
}
}
void stdisplay()
{
DisplayListChar(0,0,lcdnow);
DisplayListChar(0,1,lcdset);
DisplayOneChar(14,0,0x4f);
DisplayOneChar(15,0,0x46);
DisplayListChar(8,0,"S:");
DisplayListChar(8,1,"T:");
}
void main(void)
{
delay_50ms(1);
int_timer0();
InitLcd();
P23=1;
SCANPORT=0x0F;
stdisplay();
while(1)
{
bleep();
if(SCANPORT!=0x0F)
                {
                for(ucCount=0;ucCount<200;ucCount++);

                if(SCANPORT!=0x0F)
                        vKeyProcess(ucKeyScan());
                };
switch(temp)
{
case 13:bleept=0;break;//D
case 14:a_ac=1;b_key=1;if(b_key==1){DisplayOneChar(15,1,0x4f);b_key=0;};SendCommand(0xC4+uc_ClickCount);break;//e
case 15:if(a_key==1){speedcd=key_ctt[0]*100+key_ctt[1]*10+key_ctt[2];uc_ClickCount=0;};break;//f
case 10:a_key=1;akey();break;//a
case 12:a_key=0;akey();break;//c
default:break;
}
}
}
void ac()
{
if(speedct>=(speedcd+5))
{moto=0;flag=0;}
else if(speedct<=(speedcd-5))
{moto=1;flag=0;}
else
flag=1;
}
void bleep()
{
if(a_ac==1)
{if(bleept==1)
P23=0;
if(bleept==0)
P23=1;
}
}
void akey()
{
if(a_key==1)
{SendCommand(0x0c);
DisplayOneChar(14,0,0x4f);
DisplayOneChar(15,0,0x4e); //On
SendCommand(0xc4);
SendCommand(0x0f);
}
if(a_key==0)
{
SendCommand(0x0c);
DisplayOneChar(14,0,0x4f);
DisplayOneChar(15,0,0x46);//Of
}
}
void getspeed()
{
  if(a_ac==1)
  {ac();};
  speed=1200/(time_sq[0]-time_sq[2]);
  speed_ck[3]=speed_ck[2];
  speed_ck[2]=speed_ck[1];   
  speed_ck[1]=speed_ck[0];
  speed_ck[0]=speed;
if((speed_ck[0]!=speed_ck[1]))
{
speed_sc[1]=speed_sc[0];
speed_sc[0]=speed_ck[0];
speedct=(speed_sc[0]+speed_sc[1])/2;
}
else
{if((speed_ck[0]==speed_ck[2])&&(speed_ck[1]==speed_ck[3]))
speedct=(speed_ck[0]+speed_ck[1])/2;     
if((speed_ck[0]==speed_ck[1])||(speed_ck[0]==speed_ck[2]))
speedct=(speed_ck[1]+speed_ck[2])/2;
if((speed_ck[0]!=speed_ck[1])&&(speed_ck[0]!=speed_ck[2])&&(speed_ck[1]==speed_ck[2]))
speedct=(speed_ck[0]+speed_ck[1])/2;
if((speed_ck[0]!=speed_ck[1])&&(speed_ck[0]!=speed_ck[2])&&(speed_ck[1]!=speed_ck[2]))
speedct=(speed_ck[0]+speed_ck[1]+speed_ck[2]+speed_ck[4])/4;}
speed_bcd[2]=speed/100;   
speed_bcd[1]=speed%100/10;
speed_bcd[0]=speed%10;
  if(a_key==0)
  {
  DisplayOneChar(4,0,lcd3[speedct/100]);
  DisplayOneChar(5,0,lcd3[speedct%100/10]);
  DisplayOneChar(6,0,lcd3[speedct%10]);
  DisplayOneChar(4,1,lcd3[speedcd/100]);
  DisplayOneChar(5,1,lcd3[speedcd%100/10]);
  DisplayOneChar(6,1,lcd3[speedcd%10]);
  SendCommand(0xC4+uc_ClickCount);
  }
  }


1.png
2.png
1.png
2.png
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。