当前位置: 首页 > news >正文

基于STM32设计的生理监测装置

一、项目功能要求

设计并制作一个生理监测装置,能够实时监测人体的心电图、呼吸和温度,并在LCD液晶显示屏上显示相关数据。

随着现代生活节奏的加快和环境的变化,人们对身体健康的关注程度越来越高。为了及时掌握自身的生理状况,进行健康管理和疾病预防,监测身体的生理参数成为一种重要的需求。因此,设计一个能够实时监测人体的心电图、呼吸和温度的生理监测装置具有重要的意义。

该生理监测装置主要用于个人健康管理和远程监护等应用场景。个人健康管理方面,用户可以通过这个装置了解自己的心电图、呼吸和体温等生理参数,及时发现异常情况并采取相应的措施,如调整生活习惯、咨询医生等。远程监护方面,装置可以将实时的生理参数数据传输到云端或其他设备,供医生或家属远程查看,以便及时干预和诊断。

与传统的生理监测设备相比,该装置具有以下优势:

  1. 实时性:装置能够实时监测和显示心电图、呼吸和温度等生理参数,用户可以随时了解自己的身体状况。
  2. 简便性:装置采用便携式设计,用户可以随身携带,方便随时监测。
  3. 实用功能:通过对采集到的数据进行分析和判断,装置可以提供简单的健康状况提示,帮助用户及时发现问题并采取措施。
  4. 扩展性:装置可以添加报警功能、存储功能和无线通信功能等增强功能,满足不同用户的需求。

这个生理监测装置的设计和制作有助于提高个人健康管理的水平,为用户提供及时、准确的生理参数信息,以便更好地保护身体健康。同时,它也可以为医生和家属提供远程监护的手段,帮助他们随时了解病人的生理状况。该装置在现代健康管理和医疗保健领域具有广阔的应用前景和市场潜力。

image-20230714105710669

image-20230714110031142

二、基本要求

【1】心电信号监测:

  • 采用PulseSensor传感器获取心电信号。
  • 进行AD转换,将模拟信号转换为数字信号。
  • 使用STM32F103C8T6单片机进行数据处理。
  • 在LCD显示屏上显示心电图。

【2】呼吸信号监测:

  • 采用PulseSensor传感器获取呼吸信号。
  • 进行AD转换,将模拟信号转换为数字信号。
  • 使用STM32F103C8T6单片机进行数据处理。
  • 在LCD显示屏上显示呼吸数据。

【3】温度监测:

  • 采用MT70传感器测量人体温度。
  • 进行AD转换,将模拟信号转换为数字信号。
  • 使用STM32F103C8T6单片机进行数据处理。
  • 在LCD显示屏上显示温度数据,测量精度不大于0.10℃。

【4】人体健康状况判断:

  • 根据测量到的生理参数数据,进行简单的健康状况判断。
  • 使用STM32F103C8T6单片机进行数据分析与判断。

二、发挥部分

  1. 健康状况判断:
    • 分析心电图、呼吸和温度等数据,根据预设的阈值判断是否存在异常情况。
    • 在LCD显示屏上显示人体健康状况的简单提示信息。
  2. 其他增强功能:
    • 可以添加报警功能,当监测到异常情况时,通过声音或震动提醒用户。
    • 可以存储和记录历史数据,以便后续分析和参考。
    • 可以添加无线通信模块,将实时数据传输到其他设备或云端进行远程监测。

三、设计方案

【1】主控芯片:

  • 选择STM32F103C8T6单片机作为主控芯片,具有足够的GPIO、ADC等功能,并可方便地集成硬件模块。

【2】显示屏:

  • 选择0.96寸IIC接口的OLED显示屏,具有高分辨率和低功耗的特点,适合用于显示监测数据。

【3】传感器:

  • 心电信号采集使用PulseSensor传感器输出。
  • 呼吸信号采集使用PulseSensor传感器输出。
  • 温度测量使用MT70传感器。

【4】AD转换:

  • 选择ADS1292作为心电信号和呼吸信号的AD转换芯片。
  • 在STM32F103C8T6单片机上配置ADC,用于温度传感器的AD转换。

【5】数据处理与显示:

  • 使用STM32F103C8T6单片机进行数据处理和健康状况判断。
  • 通过IIC接口将数据发送给OLED显示屏进行实时显示。

【6】健康状况判断算法:

  • 根据心电图、呼吸和温度数据的变化趋势和预设的阈值进行简单的健康状况判断。

四、代码实现

4.1 采集代码

ADS1292模块,进行3路模拟信号采集转换实现代码。

#include "stm32f10x.h"// 定义SPI接口引脚
#define ADS1292_SPI       SPI1
#define ADS1292_CS_PIN    GPIO_Pin_4
#define ADS1292_CS_PORT   GPIOA// 定义命令字节
#define ADS1292_CMD_SDATAC     0x11  // 停止连续数据传输命令
#define ADS1292_CMD_RREG       0x20  // 读寄存器命令
#define ADS1292_CMD_WREG       0x40  // 写寄存器命令
#define ADS1292_CMD_START      0x08  // 启动数据转换命令// 函数声明
void ADS1292_SPI_Config(void);
void ADS1292_Start_Conversion(void);int main(void)
{// 初始化系统时钟、GPIO等// ...// 配置ADS1292的SPI接口ADS1292_SPI_Config();// 启动ADS1292的数据转换ADS1292_Start_Conversion();// 定义读取数据的命令字节
#define ADS1292_CMD_RDATAC     0x10// 定义数据缓冲区大小
#define BUFFER_SIZE  100// 数据缓冲区
uint8_t dataBuffer[BUFFER_SIZE];while (1)
{// 启动数据转换ADS1292_Start_Conversion();// 等待一段时间,确保数据转换完成// 这里可以根据具体情况调整延时时间Delay(100); // 假设延时100毫秒// 读取采集到的数据GPIO_ResetBits(ADS1292_CS_PORT, ADS1292_CS_PIN);SPI_SendData(ADS1292_SPI, ADS1292_CMD_RDATAC);while (SPI_I2S_GetFlagStatus(ADS1292_SPI, SPI_I2S_FLAG_BSY) == SET);for (int i = 0; i < BUFFER_SIZE; i++){SPI_SendData(ADS1292_SPI, 0xFF); // 发送一个无关的字节以触发数据传输while (SPI_I2S_GetFlagStatus(ADS1292_SPI, SPI_I2S_FLAG_RXNE) == RESET);dataBuffer[i] = SPI_ReceiveData(ADS1292_SPI); // 读取接收到的数据}GPIO_SetBits(ADS1292_CS_PORT, ADS1292_CS_PIN);// 处理采集到的数据// ...// 循环进行其他操作// ...
}
}// 配置ADS1292的SPI接口
void ADS1292_SPI_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;// 使能SPI时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);// 配置CS引脚为推挽输出GPIO_InitStructure.GPIO_Pin = ADS1292_CS_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADS1292_CS_PORT, &GPIO_InitStructure);// 配置SPI引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置SPI参数SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(ADS1292_SPI, &SPI_InitStructure);// 使能SPISPI_Cmd(ADS1292_SPI, ENABLE);
}// 启动ADS1292的数据转换
void ADS1292_Start_Conversion(void)
{// 禁用ADS1292的连续数据传输模式GPIO_ResetBits(ADS1292_CS_PORT, ADS1292_CS_PIN);SPI_SendData(ADS1292_SPI, ADS1292_CMD_SDATAC);while (SPI_I2S_GetFlagStatus(ADS1292_SPI, SPI_I2S_FLAG_BSY) == SET);GPIO_SetBits(ADS1292_CS_PORT, ADS1292_CS_PIN);// 发送启动转换命令GPIO_ResetBits(ADS1292_CS_PORT, ADS1292_CS_PIN);SPI_SendData(ADS1292_SPI, ADS1292_CMD_START);while (SPI_I2S_GetFlagStatus(ADS1292_SPI, SPI_I2S_FLAG_BSY) == SET);GPIO_SetBits(ADS1292_CS_PORT, ADS1292_CS_PIN);
}

代码里调用ADS1292_Start_Conversion()函数启动数据转换,等待一段时间确保数据转换完成。通过发送ADS1292_CMD_RDATAC命令并读取数据缓冲区,从ADS1292模块中读取采集到的数据。

4.2 OLED显示屏驱动代码

包含了基本的初始化、清屏、设置位置、显示字符串、显示数字和显示浮点数等功能。

#include "stm32f10x.h"
#include "delay.h"
#include "i2c.h"#define OLED_ADDRESS 0x78 // OLED显示屏的I2C地址// OLED缓存数组(128x64像素,每个字节代表8个像素)
unsigned char OLED_Buffer[128 * 8];// 向OLED显示屏发送命令
void OLED_WriteCmd(unsigned char cmd) {I2C_Start();I2C_SendByte(OLED_ADDRESS);I2C_SendByte(0x00); // 发送命令标志位I2C_SendByte(cmd);I2C_Stop();
}// 向OLED显示屏发送数据
void OLED_WriteData(unsigned char data) {I2C_Start();I2C_SendByte(OLED_ADDRESS);I2C_SendByte(0x40); // 发送数据标志位I2C_SendByte(data);I2C_Stop();
}// 初始化OLED显示屏
void OLED_Init() {// 初始化I2C总线I2C_Init();// 初始化OLED显示屏OLED_WriteCmd(0xAE); // 关闭显示OLED_WriteCmd(0xD5); // 设置时钟分频因子OLED_WriteCmd(0x80); // 默认值OLED_WriteCmd(0xA8); // 设置驱动路数OLED_WriteCmd(0x3F); // 1/64 驱动OLED_WriteCmd(0xD3); // 设置显示偏移OLED_WriteCmd(0x00); // 默认值OLED_WriteCmd(0x40); // 设置显示开始行OLED_WriteCmd(0x8D); // 设置电荷泵OLED_WriteCmd(0x14); // 使能电荷泵OLED_WriteCmd(0x20); // 设置内存地址模式OLED_WriteCmd(0x00); // 水平寻址模式OLED_WriteCmd(0xA1); // 设置段重定义OLED_WriteCmd(0xC8); // 设置COM扫描方向OLED_WriteCmd(0xDA); // 设置COM硬件引脚配置OLED_WriteCmd(0x12); // 默认值OLED_WriteCmd(0x81); // 设置对比度控制OLED_WriteCmd(0xCF); // 默认值OLED_WriteCmd(0xD9); // 设置预充电周期OLED_WriteCmd(0xF1); // 默认值OLED_WriteCmd(0xDB); // 设置VCOMH Deselect LevelOLED_WriteCmd(0x40); // 默认值OLED_WriteCmd(0xA4); // 设置全局显示OLED_WriteCmd(0xA6); // 设置显示方式,默认正常显示OLED_Clear(); // 清屏OLED_WriteCmd(0xAF); // 打开显示
}// 清屏
void OLED_Clear() {for (int i = 0; i < 8; i++) {OLED_WriteCmd(0xB0 + i); // 设置页地址for (int j = 0; j < 128; j++) {OLED_WriteCmd(0x00); // 清空数据OLED_Buffer[j + i * 128] = 0x00;}}
}// 设置显示位置
void OLED_SetPos(unsigned char row, unsigned char column) {OLED_WriteCmd(0xB0 + row); // 设置页地址OLED_WriteCmd(0x00 + (8 * column & 0x0F)); // 设置列低地址OLED_WriteCmd(0x10 + ((8 * column >> 4) & 0x0F)); // 设置列高地址
}// 显示字符串
void OLED_ShowString(const char* str) {while (*str) {for (int i = 0; i < 8; i++) {OLED_WriteData(font8x16[(*str - ' ')*16 + i]); // 显示字体数据OLED_Buffer[column + row * 128] = font8x16[(*str - ' ')*16 + i]; // 更新缓存column++;}str++;}
}// 显示数字
void OLED_ShowNum(int num, unsigned char digit) {char str[10];sprintf(str, "%d", num);OLED_ShowString(str);
}// 显示浮点数
void OLED_ShowFloat(float num, unsigned char decimal) {char str[10];sprintf(str, "%.*f", decimal, num);OLED_ShowString(str);
}

4.3 OLED显示体温、心率

#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"// 定义体温值和心率值
float temperature = 37.6;
int heartRate = 90;int main(void) {// 初始化OLED显示屏OLED_Init();// 清屏OLED_Clear();// 设置字体大小OLED_SetFontSize(16);// 设置显示位置OLED_SetPos(0, 0);// 显示体温值OLED_ShowString("Temperature: ");OLED_ShowFloat(temperature, 1);// 设置显示位置OLED_SetPos(2, 0);// 显示心率值OLED_ShowString("Heart Rate: ");OLED_ShowNum(heartRate, 0);while (1) {// 主循环}
}

五、总结

本文章描述了生理监测装置整个项目的设计方案,设计过程;通过采集心电图、呼吸和温度数据,并使用STM32F103C8T6单片机进行数据处理和显示,实现了实时监测和显示生理参数的功能。提出了健康状况判断和其他增强功能的设计思路。该装置可以用于个人的健康监测和远程监护等场景,具有一定的实用性和扩展性。

相关文章:

基于STM32设计的生理监测装置

一、项目功能要求 设计并制作一个生理监测装置&#xff0c;能够实时监测人体的心电图、呼吸和温度&#xff0c;并在LCD液晶显示屏上显示相关数据。 随着现代生活节奏的加快和环境的变化&#xff0c;人们对身体健康的关注程度越来越高。为了及时掌握自身的生理状况&#xff0c…...

Go-Python-Java-C-LeetCode高分解法-第五周合集

前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接&#xff1a;LeetCode-Go-Python-Java-C Go-Python-Java-C-LeetCode高分解法-第一周合集 Go-Python-Java-C-LeetCode高分解法-第二周合集 Go-Python-Java-C-LeetCode高分解法-第三周合集 G…...

【前端知识】前端加密算法(base64、md5、sha1、escape/unescape、AES/DES)

前端加密算法 一、base64加解密算法 简介&#xff1a;Base64算法使用64个字符&#xff08;A-Z、a-z、0-9、、/&#xff09;来表示二进制数据的64种可能性&#xff0c;将每3个字节的数据编码为4个可打印字符。如果字节数不是3的倍数&#xff0c;将会进行填充。 优点&#xff1…...

leetcode 925. 长按键入

2023.9.7 我的基本思路是两数组字符逐一对比&#xff0c;遇到不同的字符&#xff0c;判断一下typed与上一字符是否相同&#xff0c;不相同返回false&#xff0c;相同则继续对比。 最后要分别判断name和typed分别先遍历完时的情况。直接看代码&#xff1a; class Solution { p…...

[CMake教程] 循环

目录 一、foreach()二、while()三、break() 与 continue() 作为一个编程语言&#xff0c;CMake也少不了循环流程控制&#xff0c;他提供两种循环foreach() 和 while()。 一、foreach() 基本语法&#xff1a; foreach(<loop_var> <items>)<commands> endfo…...

Mojo安装使用初体验

一个声称比python块68000倍的语言 蹭个热度&#xff0c;安装试试 系统配置要求&#xff1a; 不支持Windows系统 配置要求: 系统&#xff1a;Ubuntu 20.04/22.04 LTSCPU&#xff1a;x86-64 CPU (with SSE4.2 or newer)内存&#xff1a;8 GiB memoryPython 3.8 - 3.10g or cla…...

艺术与AI:科技与艺术的完美融合

文章目录 艺术创作的新工具生成艺术艺术与数据 AI与互动艺术虚拟现实&#xff08;VR&#xff09;与增强现实&#xff08;AR&#xff09;机器学习与互动性 艺术与AI的伦理问题结语 &#x1f389;欢迎来到AIGC人工智能专栏~艺术与AI&#xff1a;科技与艺术的完美融合 ☆* o(≧▽≦…...

Android常用的工具“小插件”——Widget机制

Widget俗称“小插件”&#xff0c;是Android系统中一个很常用的工具。比如我们可以在Launcher中添加一个音乐播放器的Widget。 在Launcher上可以添加插件&#xff0c;那么是不是说只有Launcher才具备这个功能呢&#xff1f; Android系统并没有具体规定谁才能充当“Widget容器…...

探索在云原生环境中构建的大数据驱动的智能应用程序的成功案例,并分析它们的关键要素。

文章目录 1. Netflix - 个性化推荐引擎2. Uber - 实时数据分析和决策支持3. Airbnb - 价格预测和优化5. Google - 自然语言处理和搜索优化 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专…...

jupyter 添加中文选项

文章目录 jupyter 添加中文选项1. 下载中文包2. 选择中文重新加载一下&#xff0c;页面就变成中文了 jupyter 添加中文选项 1. 下载中文包 pip install jupyterlab-language-pack-zh-CN2. 选择中文 重新加载一下&#xff0c;页面就变成中文了 这才是设置中文的正解&#xff…...

系列十、Java操作RocketMQ之批量消息

一、概述 RocketMQ可以一次性发送一组消息&#xff0c;那么这一组消息会被当做一个消息进行消费。 二、案例代码 2.1、pom 同系列五 2.2、RocketMQConstant 同系列五 2.3、BatchConsumer package org.star.batch.consumer;import cn.hutool.core.util.StrUtil; import lom…...

leetcode1两数之和

题目&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你…...

近年GDC服务器分享合集(四): 《火箭联盟》:为免费游玩而进行的扩展

如今&#xff0c;网络游戏采用免费游玩&#xff08;Free to Play&#xff09;加内购的比例要远大于买断制&#xff0c;这是因为前者能带来更低的用户门槛。甚至有游戏为了获取更多的用户&#xff0c;选择把原来的买断制改为免费游玩&#xff0c;一个典型的例子就是最近的网易的…...

android反射详解

1&#xff0c;反射的定义 一般情况下&#xff0c;我们使用某个类时必定知道它是什么类&#xff0c;是用来做什么的&#xff0c;并且能够获得此类的引用。于是我们直接对这个类进行实例化&#xff0c;之后使用这个类对象进行操作。 反射则是一开始并不知道我要初始化的类对象是…...

Python 反射和动态执行

反射主要应用于类的对象上&#xff0c;在运行时&#xff0c;将对象中的属性和方法反射出来&#xff0c;通过字符串对对象成员&#xff08;属性、方法&#xff09;进行查找、获取、删除、添加成员等动作&#xff0c;是一种基于字符串的事件驱动技术。 python是一门动态语言&…...

计算机网络常见端口号

端口号标识了一个主机上进行通信的不同的应用程序。比如网站服务器80端口一般都是开启的&#xff0c;等你来连接。 端口划分&#xff1a; &#xff08;1&#xff09;常用端口&#xff0c;公共端口&#xff08;保留给公共服务所使用&#xff09;&#xff0c;端口号为0-1023之间…...

SpringBoot / Vue 对SSE的基本使用(简单上手)

一、SSE是什么&#xff1f; SSE技术是基于单工通信模式&#xff0c;只是单纯的客户端向服务端发送请求&#xff0c;服务端不会主动发送给客户端。服务端采取的策略是抓住这个请求不放&#xff0c;等数据更新的时候才返回给客户端&#xff0c;当客户端接收到消息后&#xff0c;…...

Qt串口基本设置与协议收发

前言 1.一直都想要做一个Qt上位机&#xff0c;趁着这个周末有时间&#xff0c;动手写一下 2.comboBox没有点击的信号&#xff0c;所以做了一个触发的功能 3.Qt的数据类型很奇怪&#xff0c;转来转去的我也搞得很迷糊 4.给自己挖个坑&#xff0c;下一期做一个查看波形的上位…...

interview3-微服务与MQ

一、SpringCloud篇 &#xff08;1&#xff09;服务注册 常见的注册中心&#xff1a;eureka、nacos、zookeeper eureka做服务注册中心&#xff1a; 服务注册&#xff1a;服务提供者需要把自己的信息注册到eureka&#xff0c;由eureka来保存这些信息&#xff0c;比如服务名称、…...

kafka详解一

kafka详解一 1、消息引擎背景 根据维基百科的定义&#xff0c;消息引擎系统是一组规范。企业利用这组规范在不同系统之间传递语义准确的消息&#xff0c;实现松耦合的异步式数据传递. 即&#xff1a;系统 A 发送消息给消息引擎系统&#xff0c;系统 B 从消息引擎系统中读取 A…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...