【STM32项目开源】基于STM32的智能点滴输液系统

目录

一、设计背景和意义

1.1设计背景

1.2设计意义

二、实物效果展示

2.1实物图片

2.2实物演示视频

三、硬件功能简介

3.1项目功能详解

3.2元器件清单

四、主框图与软件流程图

五、硬件PCB展示

六、软件程序设计

七、项目资料包内容

资料获取:查看主页介绍"充哥单片机设计"


一、设计背景和意义

1.1设计背景

本课题的立意根植于一个普遍而严峻的临床现实:传统静脉输液的监护模式因其高度依赖人力,正日益成为医疗安全链条上的脆弱一环。护士需要不间断地巡查,凭借肉眼判断滴速、估算余液、感知药液温度,这种模式不仅极大地增加了医护人员的劳动负荷,更因不可避免的疲劳与疏忽,潜藏着液空回血、滴速失控、药液冷刺激等诸多风险,直接关乎患者的生命安全。尽管市场上已有高端智能输液泵产品,但其令人望而却步的成本和操作复杂性,如同一道数字鸿沟,将其牢牢禁锢于重症监护室,无法惠及普通病房与基层医疗场景。因此,本研究的核心意义在于发起一场对传统输液监护模式的普惠式革新,它不仅仅是一个技术项目,更是一次对智慧医疗"落地难"问题的务实回应。

1.2设计意义

我们致力于打造的不仅是一台冰冷的机器,更是一位不知疲倦的"智能护士"。它通过精确的自动化监护与控制,将医护人员从机械重复的劳动中解放出来,使其能更专注于更高价值的诊疗决策;它通过及时可靠的报警与远程监控功能,构筑起一道坚实的安全屏障,极大提升了患者的治疗体验与安全感。更重要的是,本设计所坚持的低成本、易用性原则,旨在打破高端医疗技术的应用壁垒,使其能够真正下沉到社区医院、乡镇卫生院乃至家庭病床,这对于促进医疗资源的公平可及、推动"全民健康"目标的实现,具有深远而积极的社会意义。

二、实物效果展示

2.1实物图片

2.2实物演示视频

【开源】基于STM32的智能点滴输液系统

三、硬件功能简介

3.1项目功能详解

  1. 传感器检测:M03非接触式液位检测,DS18B20检测药液温度,红外对管检测药液滴速。
  2. 数据显示:0.96OLED屏幕显示全部的传感器数据以及传感器的阈值等数据。
  3. 执行机构:通过继电器控制加热片,步进电机控制滴速。
  4. 连接蓝牙APP:系统通过JW01蓝牙模块连接手机蓝牙APP,实现数据上传。
  5. App远程监控:通过App远程监控全部传感器数据。
  6. 阈值数据设定:系统通过按键设定阈值。
  7. 自动模式:根据设定的滴速上下限、温度阈值判断。当检测到的滴速低于下限,步进电机正转加快滴速同时蜂鸣器报警提醒,当检测到滴速高于上限,步进电机反转减缓滴速同时蜂鸣器报警提醒;当检测到到温度低于设定阈值,自动打开加热片对药液进行加热同时蜂鸣器报警提醒;非接触式液位传感器检测到药液为无时,蜂鸣器报警提醒。

3.2元器件清单

  1. STM32F103C8T6主控
  2. 0.96OLED 显示屏幕
  3. JDY-31蓝牙模块
  4. M03非接触式液位传感器
  5. 红外对管滴速检测
  6. DS18B20温度检测
  7. 蜂鸣器声光报警
  8. 加热片
  9. 步进电机
  10. 按键

四、主框图与软件流程图

主框图

流程图

五、硬件PCB展示

六、软件程序设计

cpp 复制代码
#include "sys.h"
#include "delay.h"
#include "gpio.h"
#include "OLED_I2C.h"
#include "ds18b20.h"
#include "timer.h"
#include "usart1.h"
#include "exti.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "adc.h"

#define STM32_RX1_BUF       Usart1RecBuf 
#define STM32_Rx1Counter    RxCounter
#define STM32_RX1BUFF_SIZE  USART1_RXBUFF_SIZE

#define Coil_8B_A  {A=1;B=0;C=0;D=0;}//A相通电,其他相断电
#define Coil_8B_AB {A=1;B=1;C=0;D=0;}//AB相通电,其他相断电
#define Coil_8B_B  {A=0;B=1;C=0;D=0;}//B相通电,其他相断电
#define Coil_8B_BC {A=0;B=1;C=1;D=0;}//BC相通电,其他相断电
#define Coil_8B_C  {A=0;B=0;C=1;D=0;}//C相通电,其他相断电
#define Coil_8B_CD {A=0;B=0;C=1;D=1;}//CD相通电,其他相断电
#define Coil_8B_D  {A=0;B=0;C=0;D=1;}//D相通电,其他相断电
#define Coil_8B_DA {A=1;B=0;C=0;D=1;}//DA相通电,其他相断电

#define Coil_OFF   {A=0;B=0;C=0;D=0;}//全部断电
int flag = 0;
int PulseCount = 0;     //记录脉冲
int Speed = 0;          //滴速
int speed_min = 60;      //滴速下限
int speed_max = 180;     //滴速上限
float temperature=0.0;  //温度
float set_tempval=10.0; //温度设置值

u8 shuaxin = 0;  //刷新标志
u8 setFlag = 0;  //设置标志
u8 NoWater = 0;  //缺水标志
u8 shanshuo = 0; //shanshuo
u8 direction = 0;//方向标志
char display[16];

void Usart1RxBufClear(void) //清除串口接收缓存
{
	  memset(STM32_RX1_BUF, 0, STM32_RX1BUFF_SIZE);//清除缓存
		STM32_Rx1Counter = 0; 
}

void InitDisplay(void)   //初始化显示
{
	  unsigned char i=0;
	
		for(i=0;i<6;i++)OLED_ShowCN(i*16+16,0,i+8,0);//显示中文:智能点滴系统
	  for(i=0;i<2;i++)OLED_ShowCN(i*16,2,i+0,0);//显示中文:滴速
	  for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+2,0);//显示中文:温度
	  for(i=0;i<2;i++)OLED_ShowCN(i*16,6,i+4,0);//显示中文:药水
	  OLED_ShowChar(32,6,':',2,0);
}

void displaySetValue(void)  //显示设置的值
{
	  if(setFlag == 1 || setFlag == 2)
		{
				sprintf(display,"%003d",(int)speed_min);
				OLED_ShowStr(40, 4, (u8*)display, 2,setFlag+1-1);//显示滴速下限
				sprintf(display,"%003d",(int)speed_max);
				OLED_ShowStr(40, 6, (u8*)display, 2,setFlag+1-2);//显示滴速上限
		}
		if(setFlag == 3)
		{
				sprintf(display,"%4.1fC",set_tempval);
				OLED_ShowStr(40, 4, (u8*)display, 2,setFlag+1-3);//显示温度
		}
}


void keyscan(void)   //按键扫描
{
	 unsigned char i=0;
	
	 if(KEY1 == 0 || strstr(STM32_RX1_BUF,"k1") != NULL) //设置键
	 {
			delay_ms(20);
		  if(KEY1 == 0 || strstr(STM32_RX1_BUF,"k1") != NULL)
			{
				  Usart1RxBufClear();
					while(KEY1 == 0);
				  setFlag ++;
				  if(setFlag == 1)
					{
							OLED_CLS();    //清屏
						  for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+14,0);//显示中文:设置滴速
						  for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+22,0);//显示中文:下限
							for(i=0;i<2;i++)OLED_ShowCN(i*16,6,i+24,0);//显示中文:上限
						  OLED_ShowChar(32,4,':',2,0);
						  OLED_ShowChar(32,6,':',2,0);
						  OLED_ShowStr(62, 4, "/min", 2,0);
						  OLED_ShowStr(62, 6, "/min", 2,0);
//                        displaySetValue();
					}
					if(setFlag == 3)
					{
							OLED_CLS();    //清屏
						  for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+18,0);//显示中文:设置温度
					}
					if(setFlag >= 4)
					{
						  setFlag = 0;
							OLED_CLS();    //清屏
						  InitDisplay();
						  if(NoWater==0)
									OLED_ShowCN(56,6,7,1);//显示中文:无
							else
									OLED_ShowCN(56,6,6,1);//显示中文:有  
//                            displaySetValue();
					}
					displaySetValue();   //显示没有设置值
			}
	 }
	 if(KEY2 == 0 || strstr(STM32_RX1_BUF,"k2") != NULL ||get_flag ==1) //加键
	 {
			delay_ms(100);
		  if(KEY2 == 0 || strstr(STM32_RX1_BUF,"k2") != NULL ||get_flag ==1)
			{
                get_flag = 0;
					Usart1RxBufClear();
				  if(setFlag == 1)
					{
							if(speed_max-speed_min>1)speed_min++;
					}
					if(setFlag == 2)
					{
							if(speed_max<999)speed_max++;
					}
					if(setFlag == 3)
					{
							if(set_tempval<99.9)set_tempval+=0.1;
					}
					displaySetValue();   //显示没有设置值
			}
	 }
	 if(KEY3 == 0 || strstr(STM32_RX1_BUF,"k3") != NULL) //减键
	 {
			delay_ms(100);
		  if(KEY3 == 0 || strstr(STM32_RX1_BUF,"k3") != NULL)
			{
					Usart1RxBufClear();
				  if(setFlag == 1)
					{
							if(speed_min>0)speed_min--;
					}
					if(setFlag == 2)
					{
							if(speed_max-speed_min>1)speed_max--;
					}
					if(setFlag == 3)
					{
							if(set_tempval>0)set_tempval-=0.1;
					}
					displaySetValue();   //显示没有设置值
			}
	 }
}

void Usart1SendData(void)  //串口发送
{
	printf("滴速:%d\r\n",Speed);
	printf("液位:%d\r\n",NoWater);
	printf("温度:%0.1f\r\n",temperature);
}

int main(void)
{
		delay_init();	           //延时函数初始化	 
    NVIC_Configuration();	   //中断优先级配置
	  I2C_Configuration();     //IIC初始化
	  delay_ms(200); 
	  OLED_Init();             //OLED液晶初始化
	  OLED_CLS();              //清屏
	  InitDisplay();
		KEY_GPIO_Init();        //按键引脚初始化
	  MOTOR_GPIO_Init();     //步进电机初始化
	  DS18B20_GPIO_Init();
	  EXTIX_Init();
	  DS18B20_Init();         //初始化显示
	  uart1_init(9600);
	  TIM3_Init(99,719);   //定时器初始化
      Adc_Init();
		while(1)
		{ 
			   keyscan();  //按键扫描
			   if(setFlag == 0)   //不在设置状态下
				 {
//                     Get_Water_Value(&Water_Value);
					   if((Speed!=0)&&((Speed<speed_min)||(Speed>speed_max))&&shanshuo)   //滴速不在范围,闪烁显示
						 {
								 OLED_ShowStr(32, 2,":         ", 2,0);     //显示空白
						 }
					   else
						 {
								 sprintf(display,": %003d/min ",(int)Speed);
								 OLED_ShowStr(32, 2, (u8*)display, 2,0);//显示滴速
						 }
					   if(Speed!=0)
						 {
								 if(Speed<speed_min) direction=1;         //滴速过慢,电机正转,模拟放开调节阀
								 else if(Speed>speed_max) direction=2;    //滴速过快,电机反转,模拟收紧调节阀
							   else direction=0;  //在正常滴速范围,电机停止
						 }
						 else
						 {
								 direction=0;  //停止
						 }
					 
						 if(shuaxin == 1)
						 {
								 shuaxin = 0;
								 temperature=ReadTemperature();           //读取温度
							   if(temperature < set_tempval)relay = 1;  //温度低于设置值,开启加热
							   else relay = 0;                          //温度达到设置值,关闭加热
							 
							   Usart1SendData();  //数据1秒发送一次

						 }
						 if(temperature<set_tempval && shanshuo)      //温度不在范围,闪烁显示
						 {
							  	OLED_ShowStr(32, 4,":         ", 2,0);     //显示空白
						 }
						 else
						 {
								 sprintf(display,": %4.1fC",temperature);
								 OLED_ShowStr(32, 4, (u8*)display, 2,0);//显示温度
							   
						 }
						 if(water == 1)   //无药水
						 {
									if(NoWater==0)
									OLED_ShowCN(56,6,7,1);//显示中文:无
									NoWater  = 0;    //缺水标志
						 }
						 else
						 {
								 if(NoWater==1)
								 OLED_ShowCN(56,6,6,1);//显示中文:有
								 NoWater  = 1;
						 }
				 }
			   delay_ms(10);
		}
}

void EXTI0_IRQHandler(void)
{
	 PulseCount++;
	 EXTI_ClearITPendingBit(EXTI_Line0);  //清除LINE0线路挂起位
}

void TIM3_IRQHandler(void)//定时器3中断服务程序,用于记录时间
{ 
	  static u16 timeCount1 = 1000;
	  static u16 timeCount2 = 4000;
	  static u16 timeCount3 = 0;
	  static u8 index = 0;
	
		if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
		{ 
				TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除中断标志位  
				
				timeCount1 ++;
				timeCount2 ++;
				timeCount3 ++;
				
				if(timeCount1>=1000)  //1s
				{
						timeCount1 = 0;
					  shuaxin = 1;
				}
				if(timeCount2 >= 1000)  //1s
				{
						timeCount2 = 0;
					  Speed = PulseCount * 60;   //获取计数值,转化为滴/每分钟
					  PulseCount = 0;
				}
				if(timeCount3>=300)  //300ms
				{
						timeCount3 = 0;
					  
					  shanshuo = !shanshuo;
					  if(!setFlag)
						{
								if(NoWater==0)  //无药水,蜂鸣器一直报警
								{
										beep = 1;
										LED1_ON;
										LED2_ON;
										
								}
								else
								{
										if(((Speed!=0)&&((Speed<speed_min)||(Speed>speed_max)))||temperature<set_tempval)  //滴速温度不在范围,蜂鸣器报警
										{
												beep = ~beep;
												
												if(flag == 0)
												{
													flag = 1;
													LED1_ON;
													LED2_OFF;
													
												}
												else
												{
													LED1_OFF;
													LED2_ON;
													flag = 0;
												}
												 
										}
										else
										{
												beep = 0;
										}	
								}
						}
						else
						{
								beep = 0;
						}
				}
				if(direction == 0)       //步进电机停止
				{
					 Coil_OFF ;
				}
				else if(direction == 1)  //步进电机正转
				{
						switch(index) 
						{
								case 0:Coil_8B_A;break; 
								case 1:Coil_8B_AB;break;  
								case 2:Coil_8B_B; break; 
								case 3:Coil_8B_BC;break; 
								case 4:Coil_8B_C; break; 
								case 5:Coil_8B_CD;break;  
								case 6:Coil_8B_D; break; 
								case 7:Coil_8B_DA;break; 
						}
						index ++; 
						if(index == 8) index = 0;
				}
				else if(direction == 2)  //步进电机反转
				{
						switch(index) 
						{
								case 0:Coil_8B_DA;break; 
								case 1:Coil_8B_D;  break;  
								case 2:Coil_8B_CD; break; 
								case 3:Coil_8B_C;  break; 
								case 4:Coil_8B_BC; break; 
								case 5:Coil_8B_B;  break;  
								case 6:Coil_8B_AB; break; 
								case 7:Coil_8B_A;  break; 
						}
						index ++; 
						if(index == 8) index = 0;
				}
	  }
}

七、项目资料包内容

资料获取:查看主页介绍"充哥单片机设计"

相关推荐
正点原子5 小时前
正点原子 x STM32:智能加速边缘AI应用开发!
人工智能·stm32·嵌入式硬件
田甲5 小时前
【STM32】基于串口的bootloader
stm32·单片机·嵌入式硬件
杰尼君6 小时前
STM32CubeMX笔记(11)-- AD模块使用
笔记·stm32·嵌入式硬件
lingzhilab9 小时前
零知IDE——STM32F407VET6与ADS1115模数转换器实现多通道数据采集显示系统
stm32·单片机·开源
xxy.c12 小时前
基于IMX6ULL的时钟,定时器(EPIT,GPT)
单片机·嵌入式硬件·fpga开发
happygrilclh13 小时前
stm32L496 flash 分配
stm32·单片机·嵌入式硬件
古译汉书13 小时前
嵌入式铁头山羊STM32-各章节详细笔记-查阅传送门
数据结构·笔记·stm32·单片机·嵌入式硬件·个人开发
自由的好好干活14 小时前
从0开始使用LabVIEW操作数据采集卡-概述和新建新建项目
嵌入式硬件·labview
一枚码农~17 小时前
STM32红外与LED控制实战
单片机·嵌入式硬件