基于STM32设计的人体健康检测仪

一、项目介绍

当前文章介绍基于STM32设计的人体健康检测仪。设备采用STM32系列MCU作为主控芯片,配备血氧浓度传感器(使用MAX30102血氧浓度检测传感器)、OLED屏幕和电池供电等外设模块。设备可以广泛应用于医疗、健康等领域。可以帮助医生和病人更好地了解病情变化,提高治疗效果和生活质量。设备也可以用于健康管理、运动监测等场景,帮助用户了解自己的身体状况,保持健康的生活方式。

在项目中,使用了KEIL作为开发平台和工具,通过血氧模块采集人体的心跳和血氧浓度参数,并通过OLED屏幕显示现在的心跳和血氧浓度。同时,通过指标分析,提供采集到的数据与正常指标比对,分析被检测人员的健康状态。采集的数据可通过蓝牙或者WIFI传递给手机APP进行处理,方便用户随时了解自己的身体状况。

本设计采用STM32为主控芯片,搭配血氧浓度传感器和OLED屏幕,实现了人体健康数据的采集和展示,并对采集到的数据进行分析,判断被检测人员的健康状态。同时,设计使用蓝牙或WiFi将采集到的数据传递给手机APP进行处理。

image-20230618132149185

image-20230618132108207

二、项目设计思路

2.1 硬件设计

(1)主控芯片:STM32系列MCU,负责驱动其他外设模块;

(2)血氧浓度传感器:使用MAX30102血氧浓度检测传感器,用于采集人体的心跳和血氧浓度参数;

(3)OLED屏:用于显示现在的心跳和血氧浓度;

2.2 软件设计

(1) 通过血氧模块采集人体的心跳和血氧浓度参数;

(2) 通过OLED屏显示现在的心跳和血氧浓度;

(3) 对采集到的数据进行指标分析,将采集到的数据与正常指标比对,分析被检测人员的健康状态;

(4) 采集的数据可通过蓝牙或WiFi传递给手机APP进行处理。

2.3 技术实现

(1)设计采用AD8232心电图(ECG)模块和MAX30102血氧模块采集心跳和血氧浓度参数,并通过I2C接口连接主控芯片STM32。

(2)OLED屏使用I2C接口与主控芯片STM32连接。

(3)采集到的数据通过算法进行指标分析,将采集到的数据与正常指标比对,判断被检测人员的健康状态。

(4)设备通过蓝牙或WiFi将采集到的数据传递给手机APP进行处理。

三、代码设计

3.1 MAX30102血氧模块代码

I2C协议代码:

#define MAX30102_I2C_ADDR 0xAEvoid MAX30102_I2C_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;I2C_InitTypeDef   I2C_InitStructure;/* Enable GPIOB clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);/* Enable I2C1 and I2C2 clock */RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2, ENABLE);// Configure I2C SCL and SDA pinsGPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // Open-drain outputGPIO_Init(GPIOB, &GPIO_InitStructure);// Configure I2C parametersI2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 100000; // 100KHzI2C_Init(I2C1, &I2C_InitStructure);// Enable I2CI2C_Cmd(I2C1, ENABLE);
}void MAX30102_I2C_WriteReg(uint8_t reg, uint8_t value)
{while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, reg);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_SendData(I2C1, value);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTOP(I2C1, ENABLE);
}uint8_t MAX30102_I2C_ReadReg(uint8_t reg)
{uint8_t value;while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, reg);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTART(I2C1, ENABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Receiver);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));I2C_AcknowledgeConfig(I2C1, DISABLE);value = I2C_ReceiveData(I2C1);I2C_GenerateSTOP(I2C1, ENABLE);return value;
}void MAX30102_I2C_ReadArray(uint8_t reg, uint8_t* data, uint8_t len)
{while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, reg);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTART(I2C1, ENABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, MAX30102_I2C_ADDR, I2C_Direction_Receiver);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));while(len > 1){I2C_AcknowledgeConfig(I2C1, ENABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));*data++ = I2C_ReceiveData(I2C1);len--;}I2C_AcknowledgeConfig(I2C1, DISABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));*data++ = I2C_ReceiveData(I2C1);I2C_GenerateSTOP(I2C1, ENABLE);
}

MAX30102的初始化函数和数据获取函数:

void MAX30102_Init(void)
{MAX30102_I2C_Init();// Reset the deviceMAX30102_I2C_WriteReg(0x09, 0x40);HAL_Delay(100);MAX30102_I2C_WriteReg(0x09, 0x00);// Set FIFO average to 4 samplesMAX30102_I2C_WriteReg(0x08, 0x03);// Set LED pulse amplitudeMAX30102_I2C_WriteReg(0x0C, 0x1F);MAX30102_I2C_WriteReg(0x0D, 0x1F);// Set sample rate to 100HzMAX30102_I2C_WriteReg(0x0F, 0x04);// Enable the red LED onlyMAX30102_I2C_WriteReg(0x11, 0x02);// Read the temperature value to start a readingMAX30102_I2C_ReadReg(0x1F);
}uint32_t MAX30102_GetHeartRate(void)
{uint8_t buffer[MAX30102_FIFO_DEPTH*4];MAX30102_Data sensor_data = {0};uint16_t ir_value;uint16_t red_value;uint8_t byte_count, fifo_overflow;// Check if any data is available in FIFObyte_count = MAX30102_I2C_ReadReg(0x06) - MAX30102_I2C_ReadReg(0x04);if(byte_count > 0){fifo_overflow = MAX30102_I2C_ReadReg(0x09) & 0x80;// Read the data from FIFOMAX30102_I2C_ReadArray(0x07, buffer, byte_count);// Parse the datafor(int i=0; i<byte_count; i+=4){ir_value = ((uint16_t)buffer[i] << 8) | buffer[i+1];red_value = ((uint16_t)buffer[i+2] << 8) | buffer[i+3];// Update the sensor dataMAX30102_UpdateData(&sensor_data, ir_value, red_value);}if(!fifo_overflow && MAX30102_CheckForBeat(sensor_data.IR_AC_Signal_Current)){return MAX30102_HeartRate(sensor_data.IR_AC_Signal_Previous, 16);}}return 0;
}

数据处理函数:

void MAX30102_UpdateData(MAX30102_Data* data, uint16_t ir_value, uint16_t red_value)
{int32_t ir_val_diff = ir_value - data->IR_AC_Signal_Current;int32_t red_val_diff = red_value - data->Red_AC_Signal_Current;// Update IR AC and DC signalsdata->IR_AC_Signal_Current = (ir_val_diff + (7 * data->IR_AC_Signal_Previous)) / 8;data->IR_DC_Signal_Current = (ir_value + data->IR_AC_Signal_Current + (2 * data->IR_DC_Signal_Current)) / 4;data->IR_AC_Signal_Previous = data->IR_AC_Signal_Current;// Update Red AC and DC signalsdata->Red_AC_Signal_Current = (red_val_diff + (7 * data->Red_AC_Signal_Previous)) / 8;data->Red_DC_Signal_Current = (red_value + data->Red_AC_Signal_Current + (2 * data->Red_DC_Signal_Current)) / 4;data->Red_AC_Signal_Previous = data->Red_AC_Signal_Current;// Update IR and Red AC signal peak-to-peak valuesif(data->IR_AC_Signal_Current > data->IR_AC_Max)data->IR_AC_Max = data->IR_AC_Signal_Current;else if(data->IR_AC_Signal_Current < data->IR_AC_Min)data->IR_AC_Min = data->IR_AC_Signal_Current;if(data->Red_AC_Signal_Current > data->Red_AC_Max)data->Red_AC_Max = data->Red_AC_Signal_Current;else if(data->Red_AC_Signal_Current < data->Red_AC_Min)data->Red_AC_Min = data->Red_AC_Signal_Current;
}uint8_t MAX30102_CheckForBeat(int32_t ir_val)
{static uint8_t beat_detection_enabled = 1;static uint32_t last_beat_time = 0;static int32_t threshold = 0x7FFFFF;uint32_t delta_time;int32_t beat_amplitude;if(beat_detection_enabled){// Increment the beat counterMAX30102_beat_counter++;// Calculate the threshold valuethreshold += (ir_val - threshold) / 8;// Check if a beat has occurredif(ir_val > threshold && MAX30102_beat_counter > 20){delta_time = micros() - last_beat_time;last_beat_time = micros();beat_amplitude = ir_val - threshold;if(delta_time < 1000 || delta_time > 2000 || beat_amplitude < 20 ||beat_amplitude > 1000) { return 0; }// Reset the beat counter and set the threshold valueMAX30102_beat_counter = 0;threshold = ir_val;return 1;}
}return 0;
}uint32_t MAX30102_HeartRate(int32_t ir_val, uint8_t samples) { int32_t ir_val_sum = 0;
// Calculate the sum of IR values
for(int i=0; i<samples; i++)
{ir_val_sum += MAX30102_IR_Sample_Buffer[i];
}// Calculate the average IR value
ir_val_sum /= samples;// Calculate the heart rate
return (uint32_t)(60 * MAX30102_SAMPLING_FREQUENCY / (ir_val - ir_val_sum));
}

3.2 OLED显示屏驱动代码

I2C协议代码:

#define SSD1306_I2C_ADDR 0x78void SSD1306_I2C_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;I2C_InitTypeDef   I2C_InitStructure;/* Enable GPIOB clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);/* Enable I2C1 and I2C2 clock */RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2, ENABLE);// Configure I2C SCL and SDA pinsGPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // Open-drain outputGPIO_Init(GPIOB, &GPIO_InitStructure);// Configure I2C parametersI2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 100000; // 100KHzI2C_Init(I2C1, &I2C_InitStructure);// Enable I2CI2C_Cmd(I2C1, ENABLE);
}void SSD1306_I2C_WriteReg(uint8_t reg, uint8_t value)
{while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, SSD1306_I2C_ADDR, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, 0x00);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_SendData(I2C1, reg);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_SendData(I2C1, value);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTOP(I2C1, ENABLE);
}void SSD1306_I2C_WriteArray(uint8_t* data, uint16_t len)
{while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, SSD1306_I2C_ADDR, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));while(len--){I2C_SendData(I2C1, *data++);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));}I2C_GenerateSTOP(I2C1, ENABLE);
}

SSD1306的初始化函数和数据更新函数:

#define SSD1306_WIDTH 128
#define SSD1306_HEIGHT 64
#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH*SSD1306_HEIGHT/8)uint8_t SSD1306_Buffer[SSD1306_BUFFER_SIZE];void SSD1306_Init(void)
{SSD1306_I2C_Init();// Turn display offSSD1306_DisplayOff();// Set the clock to a high value for faster data transferSSD1306_I2C_WriteReg(0x0F, 0x80);// Set multiplex ratio to default value (63)SSD1306_I2C_WriteReg(0xA8, 0x3F);// Set the display offset to 0SSD1306_I2C_WriteReg(0xD3, 0x00);// Display start line is 0SSD1306_I2C_WriteReg(0x40, 0x00);// Set segment remap to invertedSSD1306_I2C_WriteReg(0xA1, 0xC0);// Set COM output scan direction to invertedSSD1306_I2C_WriteReg(0xC8, 0xC0);// Disable display offset shiftSSD1306_I2C_WriteReg(0xD7, 0x9F);// Set display clock divide ratio/oscillator frequency to default value (8/0xF0)SSD1306_I2C_WriteReg(0xD5, 0xF0);// Enable charge pump regulatorSSD1306_I2C_WriteReg(0x8D, 0x14);// Set memory addressing mode// Set the display to normal mode (not inverted)
SSD1306_I2C_WriteReg(0xA6, 0xA6);// Set the contrast to a default value of 127
SSD1306_I2C_WriteReg(0x81, 0x7F);// Turn the display back on
SSD1306_DisplayOn();// Clear the display buffer
SSD1306_ClearBuffer();// Update the display with the cleared buffer
SSD1306_UpdateDisplay();
}void SSD1306_UpdateDisplay(void) { uint8_t column, page;
}for(page=0; page<8; page++)
{SSD1306_I2C_WriteReg(0xB0+page, 0x00);SSD1306_I2C_WriteReg(0x10, 0x00);SSD1306_I2C_WriteReg(0x00, 0x00);for(column=0; column<SSD1306_WIDTH; column++){SSD1306_I2C_WriteArray(&SSD1306_Buffer[column + page*SSD1306_WIDTH], 1);}
}
}
void SSD1306_ClearBuffer(void) { memset(SSD1306_Buffer, 0x00, sizeof(SSD1306_Buffer)); }void SSD1306_SetPixel(uint8_t x, uint8_t y, uint8_t color) { if(x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) { return; }
}if(color)
{SSD1306_Buffer[x + (y/8)*SSD1306_WIDTH] |= (1 << (y%8));
}
else
{SSD1306_Buffer[x + (y/8)*SSD1306_WIDTH] &= ~(1 << (y%8));
}
}

四、总结

本设计采用STM32为主控芯片,配合血氧浓度传感器和OLED屏幕,实现了人体健康数据的采集和展示,并通过算法对采集到的数据进行分析,判断被检测人员的健康状态。同时,设计使用蓝牙或WiFi将采集到的数据传递给手机APP进行处理。设计基本满足了人体健康检测仪的技术要求和环境要求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/13926.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平板光波导中导模的(注意不是泄露模)传播常数β的matlab计算(验证了是对的)

参照的是导波光学_王建(清华大学)的公式(3-1-2、3-1-3)&#xff0c;算的参数是这本书的图3-3的。 function []PropagationConstantsMain() clear;clc;close all lambda01.55;%真空或空气中的入射波长&#xff0c;单位um k02*pi/lambda0; m3;%导模阶数(需要人为指定) n11.62;%芯…

网络知识点之-路由

本文章收录至《网络》专栏&#xff0c;点击右上角专栏图标可访问本专栏&#xff01; 路由&#xff08;routing&#xff09;是指分组从源到目的地时&#xff0c;决定端到端路径的网络范围的进程。路由工作在OSI参考模型第三层——网络层的数据包转发设备。路由器通过转发数据包来…

MySQL数据库配置及创建用户和授权

注意&#xff1a; 都是基于MySQL8.0以上版本 1、检查是否安装过sql [rootlocalhost ~]# rpm -[qa](https://so.csdn.net/so/search?qqa&spm1001.2101.3001.7020) | grep mysql[rootlocalhost ~]# rpm -qa | grep [mariadb](https://so.csdn.net/so/search?qmariadb&…

Spark(37):Streaming DataFrame 和 Streaming DataSet 创建

目录 0. 相关文章链接 1. 概述 2. socket source 3. file source 3.1. 读取普通文件夹内的文件 3.2. 读取自动分区的文件夹内的文件 4. kafka source 4.1. 导入依赖 4.2. 以 Streaming 模式创建 Kafka 工作流 4.3. 通过 Batch 模式创建 Kafka 工作流 5. Rate Source…

随笔03 考研笔记整理

图源&#xff1a;文心一言 上半年的博文整理&#xff0c;下半年依然会更新考研类的文章&#xff0c;有需要的小伙伴看向这里~~&#x1f9e9;&#x1f9e9; 另外&#xff0c;这篇文章可能是我上半年的努力成果之一&#xff0c;因此仅关注博主的小伙伴能够查看它~~&#x1f9e…

嵌入式系统中的GPIO控制:从理论到实践与高级应用

本文将探讨嵌入式系统中的GPIO(通用输入输出)控制,着重介绍GPIO的原理和基本用法。我们将使用一个实际的示例项目来演示如何通过编程配置和控制GPIO引脚。将基于ARM Cortex-M微控制器,并使用C语言进行编写。 GPIO是嵌入式系统中最常见且功能最强大的接口之一。它允许硬件工…

基于RK3588+FPGA+AI算法定制的智慧交通与智能安防解决方案

随着物联网、大数据、人工智能等技术的快速发展&#xff0c;边缘计算已成为当前信息技术领域的一个热门话题。在物联网领域&#xff0c;边缘计算被广泛应用于智慧交通、智能安防、工业等多个领域。因此&#xff0c;基于边缘计算技术的工业主板设计方案也受到越来越多人的关注。…

linux 指令 第3期

cat cat 指令&#xff1a; 首先我们知道一个文件内容属性 我们对文件操作就有两个方面&#xff1a;对文件内容和属性的操作 扩展&#xff1a;echo 指令 直接打印echo后面跟的字符串 看&#xff1a; 这其实是把它打印到了显示器上&#xff0c;我们也可以改变一下它的打印位置…

网络层中一些零碎且易忘的知识点

异构网络&#xff1a;指传输介质、数据编码方式、链路控制协议以及数据单元格式和转发机制不同&#xff0c;异构即物理层和数据链路层均不同RIP、OSPF、BGP分别是哪一层的协议&#xff1a; -RIPOSPFBGP所属层次应用层网络层应用层封装在什么协议中UDPIPTCP 一个主机可以有多个I…

Bootloader

Bootloader 一段有下载和引导功能的程序 下载应用程序引导使MCU运行在应用程序中&#xff0c;只在有更新请求或者APP无效的时候才会激活 APP和Bootloader都存在Flash中Flash Driver用来擦除APP&#xff0c;下载临时存放在RAM中&#xff0c;下载完成后复位释放。一般随用随下&a…

Pytorch个人学习记录总结 玩俄罗斯方块の深度学习小项目

目录 前言 模型成果演示 训练过程演示 代码实现 deep_network tetris test train 前言 当今&#xff0c;深度学习在各个领域展现出了惊人的应用潜力&#xff0c;而游戏开发领域也不例外。俄罗斯方块作为经典的益智游戏&#xff0c;一直以来深受玩家喜爱。在这个项目中&…

Python web实战 | 用 Flask 框架快速构建 Web 应用【实战】

概要 Python web 开发已经有了相当长的历史&#xff0c;从最早的 CGI 脚本到现在的全栈 Web 框架&#xff0c;现在已经成为了一种非常流行的方式。 Python 最早被用于 Web 开发是在 1995 年&#xff08;90年代早期&#xff09;&#xff0c;当时使用 CGI 脚本编写动态 Web 页面…

spring启动流程 (6完结) springmvc启动流程

SpringMVC的启动入口在SpringServletContainerInitializer类&#xff0c;它是ServletContainerInitializer实现类(Servlet3.0新特性)。在实现方法中使用WebApplicationInitializer创建ApplicationContext、创建注册DispatcherServlet、初始化ApplicationContext等。 SpringMVC…

68. 文本左右对齐

题目链接&#xff1a;力扣 解题思路&#xff1a;遍历单词数组&#xff0c;确定每一行的单词数量&#xff0c; 之后就可以得到每一个需要补充的空格数量。从而得到单词之间需要补充的空格数量。具体算法如下&#xff1a; 确定每一行的单词数量 初始值&#xff1a; num 0&…

【JavaWeb】正则表达式

&#x1f384;欢迎来到边境矢梦的csdn博文&#xff0c;本文主要讲解Java 中正则表达式 的相关知识&#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1faf0;&#x1faf0;&am…

2023年的深度学习入门指南(22) - 百川大模型13B的运行及量化

2023年的深度学习入门指南(22) - 百川大模型13B的运行及量化 不知道上一讲的大段代码大家看晕了没有。但是如果你仔细看了会发现&#xff0c;其实代码还是不全的。比如分词器我们就没讲。 另外&#xff0c;13B比7B的改进点也没有讲。 再有&#xff0c;对于13B需要多少显存我们…

ios 查看模拟器沙盒的路径

打一个断点运行程序&#xff0c;在xcode consol底部控制台输入&#xff1a; po NSHomeDirectory() 复制路径粘帖到前往文件夹打开沙盒缓存文件夹

golang pprof

pprof是一个用于分析数据的可视化和分析工具&#xff0c;由谷歌公司的开发团队使用go语言编写成的。一般用于对golang资源占用进行分析。不是原创&#xff0c;参考&#xff1a;https://juejin.cn/post/7122473470424219656 1. 通过页面查看golang运行情况 访问 http://127.0.0…

ppt怎么压缩到10m以内?分享好用的压缩方法

PPT是一种常见的演示文稿格式&#xff0c;有时候文件过大&#xff0c;我们会遇到无法发送、上传的现象&#xff0c;这时候简单的解决方法就是压缩其大小&#xff0c;那怎么才能将PPT压缩到10M以内呢&#xff1f; PPT文件大小受到影响的主要因素就是以下几点&#xff1a; 1、图…

Keepalived 在CentOS安装

下载 有两种下载方式&#xff0c;一种为yum源下载&#xff0c;另一种通过源代码下载&#xff0c;本文章使用源代码编译下载。 官网下载地址&#xff1a;https://www.keepalived.org/download.html wget https://www.keepalived.org/software/keepalived-2.0.20.tar.gz --no-…