基于51单片机的点滴滴速控制及液位检测设计proteus仿真原理图PCB

功能:
0.本系统采用STC89C52作为单片机
1、LCD1602实时显示当前滴速控制等级及当前滴速检测值
2、系统通过控制步进电机来控制滴速,同时使用单片机外部中断检测当前滴速
3、按键可启动/停止输液,按键可更改滴速等级
4、当液位低于最低液位时,系统检测到一个高电平,蜂鸣器报警同时停止输液
5.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:
在这里插入图片描述

PCB :
在这里插入图片描述

主程序:

#include "main.h"
#include "lcd1602.h"
#include "key.h"
#include "28byj48.h"


bit dispFlag = 1;
bit startFlag = 0;
bit refreshFlag = 0;
bit updateFlag = 0;
unsigned int timeCnt = 0; //滴速检测计数
float speedNow = 0; // 滴速
unsigned char datIndex = 0;
int speedNowBuf[2] = 0; // 滴速缓存
unsigned char speedLevel = 1; // 滴速档位, 取1~10

unsigned char tab0[16]; //显示内容缓存

unsigned char index=0;
unsigned char cnt2=0;

void main()
{
    /* 初始化 */
    Timer0_Init();
    Timer1_Init();
    Ext0_Init();

    LCD_Init();
    LCD_Clear();

    LCD_DispStr(0, 0, "SpeedLevel:     ");
    LCD_DispStr(0, 1, "Speed:     d/min");

    while(1)
    {
        if (startFlag == 1 && refreshFlag == 1) //刷新数据
        {
            refreshFlag = 0;
            EX0 = 0;                             //关闭外部中断0
            TR1 = 0;                             //关闭定时器1
            speedNowBuf[datIndex] = timeCnt * 5; //计算n*5ms
            datIndex++;
            if (datIndex >= 2)
            {
                datIndex = 0;
                updateFlag = 1;
            }
            timeCnt = 0;
            TH1 = (65536 - 4608 + 900) / 256; //(65536 - 0.005*11059200/12) / 256
            TL1 = (65536 - 4608 + 900) % 256; //(65536 - 0.005*11059200/12) % 256  5ms
            EX0 = 1; //打开外部中断0
            TR1 = 1; //打开定时器1
        }
        

        if (dispFlag == 1) //定时刷新显示
        {
            dispFlag = 0;
            if (startFlag == 1)
            {
                if (updateFlag == 0) //不更新数据
                {
                    speedNow = 0;
                }
                else //更新数据,求平均值
                {
                    speedNow = 60000 / ((speedNowBuf[0]/2) + (speedNowBuf[1]/2)); //液滴速度计算 2次求平均值
                }
            }
            else
            {
                speedNow = 0;
                updateFlag = 0;
                datIndex = 0;
            }
            
            sprintf(tab0, "%2d", (int)speedLevel);
            LCD_DispStr(13, 0, tab0);
            sprintf(tab0, "%5.1f", (float)speedNow);
            LCD_DispStr(6, 1, tab0);
        }

        if (startFlag == 1) //点滴开启状态
        {
            LED_GREEN_ON;
            LED_RED_OFF;
            if (LIQUID_LEVEL_CHECK == 1) //液位低于最低液位,报警
            {
                BUZZER_ON; //蜂鸣器报警
                startFlag = 0; //停止输液
            }
            else
            {
                BUZZER_OFF;
            }
        }
        else
        {
            LED_GREEN_OFF;
            LED_RED_ON;
        }
        
        if (startFlag == 1) //控制电机转动
        {
            cnt2++;
            if (cnt2 == 15 - speedLevel)
            {
                cnt2 = 0;
                index++;
                if (index > 8)
                {
                    index = 0;
                }
                BYJ48 = ((BYJ48 & 0xF0) | FFW[index]); //取数据
                ULN_DQ3 = BIT3; ULN_DQ2 = BIT2; ULN_DQ1 = BIT1; ULN_DQ0 = BIT0;
            }
            DelayUs10x(10);

        }

        KeyProcess();
    }
}

/***********外部中断0初始化程序****************/
void Ext0_Init() //外部中断0初始化程序
{
    IT0 = 1; //外部中断0负跳变中断
    PX0 = 1; //设置高优先级
    EX0 = 1; //允许外部中断0中断
}

void Ext0_Interrupt() interrupt 0
{
    if (timeCnt < 80) //当连续两次检测时间间隔小于80*5ms=400ms不处理
    {
        TR1 = 1; //开定时器
    }
    else
    {
        refreshFlag = 1;
    }
}

void Timer0_Init(void)
{
    TMOD &= 0xF0;
    TMOD |= 0x01;
    TH0 = 0xDC; //10ms
    TL0 = 0x00;
    TR0 = 1; //启动T0计时
    ET0 = 1; //打开T0中断
    EA = 1;  //打开总中断
}

void Timer0_Intterupt(void) interrupt 1
{
    static unsigned int cnt=0;

	TL0 = 0x66;		//设置定时初始值
	TH0 = 0xFC;		//设置定时初始值 1ms

    cnt++;
    //cnt2++;
    if (cnt >= 500) //500ms
    {
        cnt = 0;
        dispFlag = 1;
    }

//    if (startFlag == 1 && cnt2 == 11 - speedLevel) //控制电机转动
//    {
//        cnt2 = 0;
//        index++;
//        if (index > 8)
//        {
//            index = 0;
//        }
//        BYJ48 = ((BYJ48 & 0xF0) | FFW[index]); //取数据
//	    ULN_DQ3 = BIT3; ULN_DQ2 = BIT2; ULN_DQ1 = BIT1; ULN_DQ0 = BIT0;
//    }
    
}

void Timer1_Init(void)
{
    TMOD &= 0x0F;
    TMOD |= 0x10;
    TH1 = (65536 - 4608 + 900) / 256; //(65536 - 0.005*11059200/12) / 256
    TL1 = (65536 - 4608 + 900) % 256; //(65536 - 0.005*11059200/12) % 256  5ms
    PT1 = 1;
    TR1 = 0; //暂停T1计时
    ET1 = 1; //打开T1中断
    EA = 1;  //打开总中断
}


void Timer1_Intterupt(void) interrupt 3
{

    TH1 = (65536 - 4608 + 900) / 256; //(65536 - 0.005*11059200/12) / 256
    TL1 = (65536 - 4608 + 900) % 256; //(65536 - 0.005*11059200/12) % 256  5ms

    timeCnt++; //每5ms计数一次
    if (timeCnt >= 4000) //20s如果没检测到信号,则清空数据
    {
        datIndex = 0; //数据个数清零
        timeCnt = 0; //5ms计数清零
        updateFlag = 0;
        TR1 = 0; //暂停T1计时
    }
}

仿真演示视频:
https://www.bilibili.com/video/BV1MM4y1A7N3/

实物演示视频:
https://www.bilibili.com/video/BV1qD4y1k7To/

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值