Proteus仿真运行

求:超声波水位控制系统Proteus仿真及程序
要求:能实现自动控制,在此设计上进行修改即可

#include <reg51.h>
#include <intrins.h>    
#include "main.h"     
uchar code TabNumASCII[10] =    {'0','1','2','3','4','5','6','7','8','9'};
bool    g_flag = isNo;        
bool    g_flag05s = isNo;    
uchar     ucCount = 0;                
uint    uiH = 80;            
uint    uiL = 30;            
uint    uiD = 100;             
bool    g_flagSwitch = isNo;    
bool    g_flagBeepTimer = isNo;            
void delay10us(void)        
{
    unsigned char i;
    _nop_();
    i = 2;
    while (--i);
}
void delay100us(void)        
{
    uchar i;
    _nop_();
    i = 47;
    while (--i);
}
void delay125us(void)        
{
    unsigned char i;
    i = 60;
    while (--i);
}
void delay5ms(void)        
{
    unsigned char i, j;
    i = 10;
    j = 183;
    do
    {
        while (--j);
    } while (--i);
}
void delay500ms(void)        
{
    unsigned char i, j, k;
    _nop_();
    i = 4;
    j = 205;
    k = 187;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}            
void initIO(void)                    
{
    P0 = 0xff;
    P1 = 0xff;
    P2 = 0xff;
    P3 = 0xff;
}
void initTimer0(void)        
{
    TMOD &= 0xF0;        
    TMOD |= 0x01;        
    TL0 = 0;                
    TH0 = 0;            
    //TR0 = 1;               
    ET0 = 1;              
    EA = 1;                     
}
void initTimer1(void)        
{    
    TMOD &= 0x0F;        
    TMOD |= 0x10;        
    TL1 = 0xB0;        
    TH1 = 0x3C;        
    TR1 = 1;        
    ET1 = 1;      
}
void zd0(void) interrupt 1          
{
    g_flag = isYes;                            
    if(++ucCount >= 8)
    {
        ucCount = 0;
        g_flag05s = isYes;                    
    }
    TL0 = 0;        
    TH0 = 0;            
}
void tm1_isr() interrupt 3 using 1
{
    static uchar count = DATA_switchTime;
    static uchar uiCount = 1200;                    
    static uint uiCount_BeepTimer = DATA_BeepTimer;
    TL1 = 0xB0;        
    TH1 = 0x3C;    
    if (g_flagSwitch == isNo)
    {
        if (count-- == 0)             
        {
            count = DATA_switchTime;
            g_flagSwitch = isYes;
            // TR1 = 0;
        }
    }    
    if(g_flagBeepTimer == isNo)
    {
        if (uiCount-- == 0)               
        {
            uiCount = 1200;
            if(uiCount_BeepTimer-- == 0)
            {
                uiCount_BeepTimer = DATA_BeepTimer; 
                g_flagBeepTimer = isYes;
                // TR1 = 0;
            }                
        }
    }
}
void exint1() interrupt 2 
{
    EX1 = 0;             
    TR0 = 0;                   
}  
void LCD_waitNotBusy(void)
{
    uchar sta;
    IO_LCD_Data = 0xFF; 
    io_LCD_RS = 0;
    io_LCD_RW = 1;
    do
    {
        io_LCD_E = 1;
        _nop_();
        _nop_();
        sta = P0;     
        io_LCD_E = 0;        
    }while(sta & 0x80); 
}
void LCDWriteCommand(uchar command,bool ifReadBusy) 
{
    if (ifReadBusy == isReadBusy) LCD_waitNotBusy(); 
    io_LCD_RS = 0;
    io_LCD_RW = 0;    
    IO_LCD_Data = command;    
    io_LCD_E = 1;
    _nop_();
    _nop_();
    io_LCD_E = 0;    
}
void LCDWriteData(uchar dat) 
{
    LCD_waitNotBusy(); 
    io_LCD_RS = 1;
    io_LCD_RW = 0;
    IO_LCD_Data = dat;    
    io_LCD_E = 1; 
    _nop_();
    _nop_();
    io_LCD_E = 0;
}
void initLCD1602(void) 
{
    uchar    i;    
    IO_LCD_Data = 0;                            
    for(i = 0; i < 3; i++)                    
    {
        LCDWriteCommand(0x38,isNotReadBusy);    
        delay5ms();
    }
    
    LCDWriteCommand(0x38,isReadBusy); 
    LCDWriteCommand(0x08,isReadBusy); 
    LCDWriteCommand(0x01,isReadBusy); 
    LCDWriteCommand(0x06,isReadBusy); 
    LCDWriteCommand(0x0F,isReadBusy); 
}
void putOneCharToLCD1602(uchar line, uchar position, uchar ucData)
{
    line &= DATA_LineMax;
    position &= DATA_PositionMax;
    if (line == DATA_LineTow) position |= 0x40;         
    position |= 0x80;                                     
    LCDWriteCommand(position, isReadBusy);     
    LCDWriteData(ucData);     
}
void putLineCharsToLCD1602(uchar line, uchar position, uchar count, uchar code *ucData)
{
    uchar i;
    for(i = 0; i < count; i++)    
    {
        putOneCharToLCD1602(line, position + i, ucData[i]);    
    }
}
void    putThreeCharToLCD1602(uchar line, uchar position, uint uiNumber)
{
    uiNumber %= 1000;
    putOneCharToLCD1602(line, position, TabNumASCII[uiNumber / 100]);
    putOneCharToLCD1602(line, ++position, TabNumASCII[uiNumber % 100 / 10]);
    putOneCharToLCD1602(line, ++position, TabNumASCII[uiNumber % 100 % 10]);        
}    
uchar GetKey(void)
{    
    uchar KeyTemp = (IO_KEY | DATA_KEY_ORL);
    if( KeyTemp != DATA_KEY_Null )
    {
        uchar CountTemp = 0;
        do
        {
            delay125us();
            if(KeyTemp != (IO_KEY | DATA_KEY_ORL)) return 0;                
        } while(++CountTemp > Data_Key20msCountMax);             
        while((IO_KEY | DATA_KEY_ORL) != DATA_KEY_Null);         
        return KeyTemp;    
    }
    return 0;
}
uchar  INC_Number(uchar Number, uchar Min, uchar Max)
{
    if(Number >= Max) return Min; else return (++ Number);    
}
uchar  DEC_Number(uchar Number, uchar Min, uchar Max)
{
    if(Number <= Min) return Max; else return (-- Number);    
}    
void execute_key_task(uchar ucKeyValue)    
{
    uchar state = 0;
    uchar keyValue = 0;    
    if(ucKeyValue != DATA_KEY_Set) return;    
    putLineCharsToLCD1602(lineTow, 8, 8, "C:000cm ");        
    putThreeCharToLCD1602(lineOne, 8 + 2, uiD);    
    while(1)
    {
        keyValue = GetKey();    
        if(keyValue == 0) continue;
        switch(keyValue)
        {
            case DATA_KEY_Set:
            {
                            switch(state)
                {
                    case 0:            
                    {
                        state = 1;                        
                        putThreeCharToLCD1602(lineOne, 0 + 2, uiH);                
                    }
                    break;
                    case 1:
                    {
                        uchar tempMax = uiD - DATA_uiD_Min;
                        if(tempMax < 2 + 2) tempMax = 2 + 2;                        
                        if(uiH > tempMax) 
                        {
                            uiH = tempMax;
                            putThreeCharToLCD1602(lineOne, 0 + 2, uiH);
                        }
                        else if(uiH < 2 + 2)
                        {
                            uiH = 2 + 2;    
                            putThreeCharToLCD1602(lineOne, 0 + 2, uiH);
                        }                            
                        state = 2;
                        putThreeCharToLCD1602(lineTow, 0 + 2, uiL);
                    }
                    break;
                    case 2:
                    {
                        if(uiL > uiH - 2) 
                        {
                            uiL = uiH - 2;
                            putThreeCharToLCD1602(lineTow, 0 + 2, uiL);
                        }
                        return;        
                    }
                    break;
                }    
            }
            break;
            case DATA_KEY_INC:
            {
                switch(state)
                {
                    case 0:
                    {
                        uiD = INC_Number(uiD, DATA_uiD_Min, DATA_uiD_Max);
                        putThreeCharToLCD1602(lineOne, 8 + 2, uiD);            
                    }
                    break;
                    case 1:
                    {
                        uchar tempMax = uiD - DATA_uiD_Min;
                        if(tempMax < 2 + 2) tempMax = 2 + 2;
                        uiH = INC_Number(uiH, 2, tempMax);                        
                        putThreeCharToLCD1602(lineOne, 0 + 2, uiH);    
                    }
                    break;
                    case 2:
                    {
                        uiL = INC_Number(uiL, 0, uiH - 2);    
                        putThreeCharToLCD1602(lineTow, 0 + 2, uiL);    
                    }
                    break;
                }
            }
            break;
            case DATA_KEY_DEC:
            {
                switch(state)
                {
                    case 0:
                    {
                        uiD = DEC_Number(uiD, DATA_uiD_Min, DATA_uiD_Max);                    
                        putThreeCharToLCD1602(lineOne, 8 + 2, uiD);
                    }
                    break;
                    case 1:
                    {
                        uchar tempMax = uiD - DATA_uiD_Min;
                        if(tempMax < 2 + 2) tempMax = 2 + 2;
                        uiH = DEC_Number(uiH, 2, tempMax);                        
                        putThreeCharToLCD1602(lineOne, 0 + 2, uiH);    
                    }
                    break;
                    case 2:
                    {
                        uiL = DEC_Number(uiL, 0, uiH - 2);    
                        putThreeCharToLCD1602(lineTow, 0 + 2, uiL);    
                    }
                    break;
                }
            }
            break;
        }
    }
}
void buzzerCall(void)
{
    uchar    i;    
    for(i = 0; i < 90; i++)
    {
        io_Buzzer = 0;
        delay100us();
        io_Buzzer = 1;
        delay100us();
        delay100us();        
    }
    delay100us();    
    delay100us();    
}
bool CalculatedWaterLevel(void)
{
    uchar     i = 8 + 2;                    
    uint      uiTime;                        
    ulong     ulDis;                            
    uiTime = TH0 << 8 | TL0;    
    ulDis = (uiTime * 3.40) / 200;         
    TH0 = 0;
    TL0 = 0;    
    if((ulDis > uiD) || (g_flag == isYes )) 
        ioLed_Red = ! ioLed_Red;                            
        ioLed_Green = ! ioLed_Green;
        ioLed_Yellow = ! ioLed_Yellow;
        if(buzzerCallFlag == isCall)
        {
            buzzerCall();                
        }
        return isNo;                                
    }
    else
    {
        ulDis = uiD - ulDis;                    
        if(ulDis > uiH)                        
        {
            io_Control_Inlet = isio_Control_Inlet_OFF;
            io_Control_Outlet = isio_Control_Outlet_ON;    
            g_flagSwitch = isNo;
            ioLed_Red = ! ioLed_Red;            
            ioLed_Green = isLedOFF;        
            ioLed_Yellow = isLedOFF;                
            if(ulDis - uiH > (uiD - uiH) / DATA_alarmCoefficient) 
            {
                buzzerCall();                    
            }
        }
        else if(ulDis < uiL)                
            if(g_flagSwitch == isYes)
            {        
                io_Control_Outlet = isio_Control_Outlet_OFF;    
                io_Control_Inlet = isio_Control_Inlet_ON;    
                g_flagSwitch = isNo;
            }    
            ioLed_Red = isLedOFF;
            ioLed_Green = isLedOFF;
            ioLed_Yellow = ! ioLed_Yellow;                
            if( uiL - ulDis > uiL / DATA_alarmCoefficient)/
            {
                buzzerCall();                    
            }    
        }
        else                                    
        {    
            ioLed_Red = isLedOFF;
            ioLed_Green = ! ioLed_Green;
            ioLed_Yellow = isLedOFF;        
        }
        putThreeCharToLCD1602(lineTow, i, ulDis);
        return isYes;    
    }
}
void main(void)
{
    initIO();        
    delay500ms();         
    initLCD1602();     »¯    
    putLineCharsToLCD1602(lineOne, 8, 8, "D:000cm ");        putThreeCharToLCD1602(lineOne, 8 + 2, uiD);        
    putLineCharsToLCD1602(lineOne, 0, 8, "H:000cm ");    
    putThreeCharToLCD1602(lineOne, 0 + 2, uiH);        
    putLineCharsToLCD1602(lineTow, 0, 8, "L:000cm ");    
    putThreeCharToLCD1602(lineTow, 0 + 2, uiL);        
    putLineCharsToLCD1602(lineTow, 8, 8, "C:000cm ");    
    initTimer0();        
    initTimer1();
    io_Control_Inlet = isio_Control_Inlet_OFF;    
    io_Control_Outlet = isio_Control_Outlet_ON;
    g_flagSwitch = isNo;    
    while(1)
    {
        io_US_TX = 1;                  
        delay10us();
        io_US_TX = 0;
        while(io_US_RX == 0);            
        TR0 = 1;                            
        IT1 = 1;                         
        EX1 = 1;                       
        while(EX1 == 1 && g_flag == isNo)
        {
            uchar ucKeyValue = GetKey();                    
            if(ucKeyValue) execute_key_task(ucKeyValue);    
        }
        if(CalculatedWaterLevel() == isNo) continue;                
        TR0 = 0;    
        TL0 = 0;        
        TH0 = 0;        
        g_flag = isNo;
        ucCount = 0;
        g_flag05s = isNo;
        TR0 = 1;                    
        while(g_flag05s == isNo)    
        {            
            uchar ucKeyValue = GetKey();
            if(ucKeyValue) 
            {
                if(ucKeyValue == DATA_KEY_DEC)
                {
                    g_flagBeepTimer = isNo;
                }
                execute_key_task(ucKeyValue);    
            }                
        }    
        TR0 = 0;    
        TL0 = 0;    
        TH0 = 0;    
        g_flag = isNo;    
        if(g_flagBeepTimer == isYes)
        {
            buzzerCall();        
        }        
    }
}
![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/644007526386176.png "#left")





现在这个代码有什么问题吗?

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这是一个超声波水位控制系统的程序,在Proteus仿真中可以进行仿真。

  1. 程序架构

超声波水位控制系统的程序主要有以下几个部分构成:

①IO口初始化和定时器初始化:开启定时器0和定时器1的中断,请单击此处查看详细信息。

②超声波测量和计算距离:控制超声波模块的发送和接收,计算水位高度和距离,并做出相应的控制反应。

③键盘读取、显示和操作:读取用户输入的键值,根据用户的操作进行相应的显示和操作。

  1. 关键函数解析

(1) execute_key_task():根据用户输入的键值执行相应的操作,包括设置水位上下限和告警系数,以及响铃操作等。

(2) CalculatedWaterLevel():根据超声波信号计算水位高度和距离,并做出相应的控制反应,包括控制进水和排水阀门、控制LED灯的亮灭以及响铃操作等。

(3) initLCD1602():初始化LCD1602,设置数据位、显示模式和清屏等参数。

(4) putOneCharToLCD1602():向LCD1602的指定位置写入字符。

(5) putLineCharsToLCD1602():向LCD1602的指定
如果我的回答解决了您的问题,请采纳!