51系列--人体身高体重BMI指数检测健康秤

本文主要介绍基于51单片机实现的人体身高体重BMI指数检测健康秤称设计(程序、电路图、PCB以及文档说明书见文末链接)

一、简介

本系统由STC89C52单片机、LCD1602液晶显示、按键、超声波测距、HX711称重传感器模块(0-1000KG)以及模块电源组成。

主要功能介绍如下:
(1)称重传感器进行人体称重,测量范围0-1000kg,实时显示在液晶上。
(2)超声波测量的距离,测量范围0-5m,显示在液晶上。
(3)按键按下,进行BMI值进行计算。BMI值等于重量除以身高的平方。
如果BMI低于18.5,则显示“过轻”字样、如果BMI在18.5-23.9之间,则显示“正常”字样、如果BMI高于24,则显示“过重”字样。
注意:称重/压力传感器上电时,保持没有重物,去皮功能。

二、详细设计方案

(1)电路图设计
单片机最小系统选用STC89C52单片机;称重传感器选用YZC-516C-1T称重传感器模块,并通过HX711专用的24位精度AD转换模块转换后传给单片机系统;身高测量选用的是HC-SR04超声传感器,基于超声波测距功能实现身高测量;
此外还包括LCD1602液晶显示电路、电源供电电路等,具体如下图所示

在这里插入图片描述
(2)PCB设计
PCB设计方案如下图所示,使用的是Altium designer软件
在这里插入图片描述
(3)源程序代码

void main(void)
{
    TMOD|=0x01;		   //设T0为方式1,GATE=1;
    TH0=0;
    TL0=0;
    TIM2Inital();        //定时器初始化
    UART_Init(); //初始化串口

//    led_gl = 0;DelayMs(100);led_gl = 1;
    
    LCD_Init();//初始化液晶显示
    LCD_Clear();
    LCD_Write_String(0,0,"Init.. ");
    
    i = 5;startCheckWireLess=1;//启动检测无线
    while(i-- && wirelessFlag == 0) //此时判断是无线类型
    {UartSendString("ATE0\r\n");  DelayMs(100);}   
    startCheckWireLess=0;
    if(wirelessFlag == 1)
    {
        i = 50;while(i--){DelayMs(100);}//wifi启动 必须延时一定时间        
    //    UartSendString("AT+CWMODE_CUR=3\r\n");// 设置模式
    //    DelayMs(50); 
    //    UartSendString("AT+CWSAP=\"AUAISOUT000\",\"\",1,0\r\n");//设置网络名字及密码
    //    DelayMs(50);
    //    UartSendString("AT+CIPAP_CUR=\"10.10.10.11\"\r\n");//设置本机ip
    //    DelayMs(50);
    //    UartSendString("AT+CIPMODE=0\r\n");//设置ip模式
    //    DelayMs(50);
        UartSendString("AT+CIPMUX=1\r\n");//打开多连接
        DelayMs(50);
        UartSendString("AT+CIPSERVER=1,8080\r\n");//启动端口号
        DelayMs(50);   //以上作为服务端 局域网    
    }
	Weight_Maopi = HX711_Read();  	//读取去皮重量
	DelayMs(10);
	Weight_Maopi = HX711_Read();    

    while(1)
    {
        if(disFlag == 1)  //更新显示
        {
            disFlag = 0;

            csbDelater++;  //声音处理计数
            if(csbDelater>=4) //声音处理
            {
                csbDelater = 0;
                Trip=1;			   //启动一次模块		//不可以使用其他终端 容易造成死循环
                DelayUs2x(4);
                Trip=0;
                while(!Echo);		//当RX为零时等待
                TR0=1;			    //开启计数
                while(Echo);			//当RX为1计数并等待
                TR0=0;
                JlCoun=(long)(TH0*256+TL0);	 //计算数据
                JuLi=(float)(JlCoun*17)/100.0*1.08/1000;     //算出来是m 因为是11.0592M的晶振 11.0592/12
                if(JuLi > 9.99) JuLi = 8.88;//数据超出测量范围
            }

            readWeightFlag++;//计数
            if(readWeightFlag > 3)//达到一定时间 读取重量
            {
                readWeightFlag = 0;//清空标志

                Weight_Shiwu = HX711_Read();	 		//读取实物重量
                Weight_Shiwu = Weight_Maopi - Weight_Shiwu;// Weight_Shiwu - Weight_Maopi;		//获取净重

                if(Weight_Shiwu > 10)	//过滤错误		
                {	
                    Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/430);	//kg计算实物的实际重量		该称重值 针对0-1000kg的传感器												
                }
                else
                {	Weight_Shiwu = 0;}
                if(Weight_Shiwu < 50 ) Weight_Shiwu = 0;	//体重过低清空               
            }
            
			if(key == 0 || getBMIFlag ==1)   //按键按下或者接收到获取命令
			{
                getBMIFlag =0;//清空标志
				if(JuLi > 0)BMI = Weight_Shiwu/10/JuLi/JuLi;	//防止出现除数为0//计算BMI
				else {BMI = 0;}			
			}

			sprintf(dis0,"H:%3.2fm G:%04.1fKg" ,JuLi,(float)Weight_Shiwu/10);//打印	显示	  
			LCD_Write_String(0,0,dis0);//打印显	
			if(BMI <= 18.5)//体重过轻
			{
				sprintf(dis1,"BMI:%4.1f  GQ   " ,BMI);//打印			
			}
			else if(BMI <= 23.9)  //体重合适
			{
				sprintf(dis1,"BMI:%4.1f  ZC   " ,BMI);//打印			
			}
			else	 //体重过重
			{
				sprintf(dis1,"BMI:%4.1f  GZ   " ,BMI);//打印				
			}	
			LCD_Write_String(0,1,dis1);//打印显           
            
            sendDataFlag++;
            if(sendDataFlag >= 8)//发送数据计数	发送蓝牙数据
            {
                sendDataFlag =	0;		//定时发送数据清空
                
                sprintf(dis0,"身高:%3.2fm 体重:%04.1fKg \r\n" ,JuLi,(float)Weight_Shiwu/10);         
                sprintf(dis0,"%sBMI值:%4.1f\r\n" , dis0 , BMI); 
                if(BMI <= 18.5)//体重过轻
                {
                    sprintf(dis0,"%s参考分析:体重过轻\r\n\r\n" , dis0 ); 		
                }
                else if(BMI <= 23.9)  //体重合适
                {
                    sprintf(dis0,"%s参考分析:体重正常\r\n\r\n" , dis0 ); 		
                }
                else	 //体重过重
                {
                    sprintf(dis0,"%s参考分析:体重过重\r\n\r\n" , dis0 ); 		
                }	                
                if(wirelessFlag == 0)UartSendString(dis0);			 //发送	 对应的 数据
                else My_ESP8266_SendStrStr(dis0);			 //发送	 对应的 数据                
            }            
        }
        if(uartTest == 1 && sendDataFlag >= 2)//接收到 测试命令
        {
            uartTest = 0;//取消标志
            if(wirelessFlag == 0)UartSendString("Test Ok!\r\n\r\n");			 //发送	 对应的 数据
            else My_ESP8266_SendStrStr("Test Ok!\r\n\r\n");			 //发送	 对应的 数据    
        }  
    }
}

void TIM2Inital(void)
{
    RCAP2H = (65536-50000)/256;//晶振12M 60ms 16bit 自动重载
    RCAP2L = (65536-50000)%256;
    ET2=1;                     //打开定时器中断
    EA=1;                      //打开总中断
    TR2=1;                     //打开定时器开关
}
void TIM2(void) interrupt 5 using 1//定时器2中断
{
    TF2=0;
    time_50ms++;
    if(time_50ms%2==0)		 //定时更新显示
    {
        disFlag = 1;//标志位置位
    }
    if(uartbusy>0)	   //串口数据采集处理
    {
        uartbusy--;   //说明刚刚接收到数据
    }
    else//长时间没有接受数据 情况接收参数重新接收
    {
        firstin =0;//接收启示标志
        Count=0;//接收计数
    }
}


void UART_Init(void)
{
    SCON  = 0x05;                // SCON: 模式 1, 8-bit UART, 使能接收
    TMOD = 0x02;               // TMOD: timer 1, mode 2, 8-bit 重装
    TH1   = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz
    TL1 = TH1;
    TR1   = 1;                  // TR1:  timer 1 打开
    EA    = 1;                  //打开总中断
    ES    = 1;                  //打开串口中断
}


void uartSendByte(unsigned char dat)
{
    unsigned char time_out;
    time_out=0x00;
    SBUF = dat;              //将数据放入SBUF中
    while((!TI))  //检测是否发送出去
    {
        time_out++;    //未发送出去 进行短暂延时//**All notes can be deleted and modified**//
    }
}

void UartSendString(unsigned char *s)
{
    while(*s!='\0')// \0 表示字符串结束标志,
        //通过检测是否字符串末尾
    {
        uartSendByte(*s);//发送一个字节
        s++;//指向下一个
    }
}

void UART_SER (void) interrupt 4     //串行中断服务程序
{
    unsigned char midVal=0;
    unsigned char r_buf;
    static char rec01 = 0;
    if(RI)                        //判断是接收中断产生
    {
        RI=0;                      //标志位清零
        r_buf = SBUF;
        
        if(startCheckWireLess == 1 && wirelessFlag == 0)//启动检测无线
        {
            if(r_buf == 'O')rec01 = 1;
            else if (rec01 == 1 && r_buf == 'K')
            {
                wirelessFlag = 1; //1表示wifi
            }        
        }
        
        uartbusy = 20;
        if(r_buf=='*')		//接收到起始标志
        {
            firstin = 1; //接收标志成功
            Count = 0;
            tab[Count++]=r_buf;

        }
        else if(firstin == 1)	  //接收到其实标志成功
        {
            tab[Count++]=r_buf;
            if(tab[1] == '%')
            {   
                uartTest = 1;//接收到串口命令  
                firstin =0;
                Count=0;
            }            
            if(Count>=3) //*SM0# //设置值
            {
                if(tab[4] == '#')//**All notes can be deleted and modified**//
                {
                    if(tab[1] == 'B' && tab[2] == 'M')//检测到标志
                    {
                        getBMIFlag = 1;//获取BMI值
//                        setVal = (tab[3] - '0')*10 + (tab[4] - '0')*1; //提取数据     
                    }
                }
                firstin =0;
                Count=0;
            }
        }
    }
    if(TI)  TI=0; //如果是发送标志位,清零       
}

void My_ESP8266_SendStrStr( char *str)//发送数据
{
//    u8 i;
    unsigned char midLen=0;      //数据长度变量
    xdata unsigned char midTab[20]; //中间变量数组
    while(str[midLen]!='\0') midLen++;  //计算数据长度  
//    for(i=0;i<2;i++)
    {
        sprintf(midTab,"AT+CIPSEND = 0, %d \r \n",(unsigned int)midLen);	//打印
        UartSendString(midTab);//发送at命令
        DelayMs(10);//延时一下发送 等待相应
        UartSendString(str);//发送数据
//        UartSendString("\r\n");//发送数据
        DelayMs(6);//延时一下发送 等待相应
    }
}

三、实物图示

如下图所示为HC-SR04超声波传感器、YZC-516C-1T称重传感器模块以及HX711 AD转换模块
在这里插入图片描述

四、附完整资源链接

百度网盘链接: https://pan.baidu.com/s/1yyXPn0CIwzz8rfwZcrZDmg?pwd=usvi
提取码: usvi

数据集介绍:多类道路车辆目标检测数据集 一、基础信息 数据集名称:多类道路车辆目标检测数据集 图片数量: - 训练集:7,325张图片 - 验证集:355张图片 - 测试集:184张图片 总计:7,864张道路场景图片 分类类别: - Bus(公交车):城市道路与高速场景中的大型公共交通工具 - Cars(小型汽车):涵盖轿车、SUV等常见乘用车型 - Motorbike(摩托车):两轮机动车辆,含不同骑行姿态样本 - Truck(卡车):包含中型货运车辆与重型运输卡车 标注格式: YOLO格式标注,包含归一化坐标的边界框与类别标签,适配主流目标检测框架。 数据特性: 覆盖多种光照条件与道路场景,包含车辆密集分布与复杂背景样本。 二、适用场景 自动驾驶感知系统开发: 用于训练车辆识别模块,提升自动驾驶系统对道路参与者的实时检测与分类能力。 交通流量监控分析: 支持构建智能交通管理系统,实现道路车辆类型统计与密度分析。 智慧城市应用: 集成至城市级交通管理平台,优化信号灯控制与道路资源分配。 学术研究领域: 为计算机视觉算法研究提供标准化评测基准,支持多目标检测模型优化。 三、数据集优势 高场景覆盖率: 包含城市道路、高速公路等多种驾驶环境,覆盖车辆静止、行驶、遮挡等现实场景。 精细化标注体系: 采用YOLO标准格式标注,每张图片均经过双重质检,确保边界框与类别标签的精准对应。 类别平衡设计: 四类车辆样本量经科学配比,避免模型训练时的类别偏向问题。 工程适配性强: 可直接应用于YOLO系列模型训练,支持快速迁移至车载计算平台部署。 现实应用价值: 专注自动驾驶核心检测需求,为车辆感知模块开发提供高质量数据支撑。
内容概要:本文介绍了DeepSeek与Mermaid结合实现可视化图表自动化生成的技术及其应用场景。DeepSeek是一款由杭州深度求索人工智能基础技术研究有限公司开发的大语言模型,具有强大的自然语言处理能力,能理解复杂的自然语言指令并生成对应的Mermaid代码。Mermaid是一款基于文本的开源图表绘制工具,能够将简洁的文本描述转化为精美的流程图、序列图、甘特图等。两者结合,通过DeepSeek将自然语言转化为Mermaid代码,再由Mermaid将代码渲染成直观的图表,极大提高了图表制作的效率和准确性。文章详细描述了DeepSeek的发展历程、技术架构及应用场景,Mermaid的基础语法和图表类型,并通过一个电商平台开发项目的实战演练展示了二者结合的具体应用过程。 适合人群:具备一定编程基础和技术理解能力的研发人员、项目经理、数据分析师等。 使用场景及目标:①需求分析阶段,快速生成业务流程图和功能关系图;②设计阶段,生成系统架构图和数据库设计图;③实现阶段,辅助代码编写,提高编码效率;④验证阶段,生成测试用例和测试报告图表,直观展示测试结果。 阅读建议:在学习和使用DeepSeek与Mermaid的过程中,建议读者结合具体项目需求,多实践生成图表和代码,熟悉两者的交互方式和使用技巧,充分利用官方文档和社区资源解决遇到的问题,逐步提高图表绘制和代码编写的准确性和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

541板哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值