stm32之硬件I2C读写MPU6050陀螺仪、加速度传感器应用案例

系列文章目录

1. stm32之I2C通信协议
2. stm32之软件I2C读写MPU6050陀螺仪、加速度传感器应用案例
3. stm32之I2C通信外设


文章目录

  • 系列文章目录
  • 前言
  • 一、电路接线图
  • 二、应用案例代码
  • 三、应用案例分析
    • 3.1 基本思路
    • 3.2 相关库函数介绍
    • 3.3 MPU6050模块
      • 3.1.1 模块初始化
      • 3.1.2 指定地址写
      • 3.1.3 指定地址读


前言

提示:本文主要用作在学习江科大自化协STM32入门教程后做的归纳总结笔记,旨在学习记录,如有侵权请联系作者

本案例实现了一个stm32使用硬件I2C外设通信读写MPU6050陀螺仪、加速度传感器的功能,最终我们将MPU6050的实时数据显示在了OLED上。OLED最上面显示的是设备ID号,左下角三个是加速度传感器的输出数据,分别为X轴、Y轴和Z轴的加速度。右边三个是陀螺仪传感器的输出数据,分别为X轴、Y轴和Z轴的角速度。当我们改变MPU6050传感器的姿态这六个数据就会相应地变化。


一、电路接线图

在这里,stm32作为主机,MPU6050作为从机,是一主一从的模型。

接线方面,MPU6050模块的VCC和GND分别接到电源的正负极进行供电,SCL接到stm32的PB10口,SDA接到stm32的PB11口。XCL和XDA用于扩展的接口这里暂时用不到就先不接。AD0引脚可用于修改从机地址的最低位,如果有需要可以接上,这里由于模块内置了下拉电阻,所以引脚悬空的话相当于接地。最后INT,中断信号输出脚,我们暂时用不到先不接。

由于本次我们使用的是I2C2外设进行硬件I2C通信,经查阅引脚定义表可知I2C2_SCL接在了PB10,I2C2_SDA接在了PB11上,这个注意不要接错了。

注意:根据I2C协议的硬件电路规定SCL和SDA都应该外挂一个上拉电阻的,但是由于MPU6050模块本身内部就已经集成了上拉电阻了,所以这里就不需要再外挂上拉电阻了。

在这里插入图片描述

二、应用案例代码

MPU6050_Reg.h:

#ifndef __MPU6050_REG_H
#define __MPU6050_REG_H#define	MPU6050_SMPLRT_DIV		0x19
#define	MPU6050_CONFIG			0x1A
#define	MPU6050_GYRO_CONFIG		0x1B
#define	MPU6050_ACCEL_CONFIG	0x1C#define	MPU6050_ACCEL_XOUT_H	0x3B
#define	MPU6050_ACCEL_XOUT_L	0x3C
#define	MPU6050_ACCEL_YOUT_H	0x3D
#define	MPU6050_ACCEL_YOUT_L	0x3E
#define	MPU6050_ACCEL_ZOUT_H	0x3F
#define	MPU6050_ACCEL_ZOUT_L	0x40
#define	MPU6050_TEMP_OUT_H		0x41
#define	MPU6050_TEMP_OUT_L		0x42
#define	MPU6050_GYRO_XOUT_H		0x43
#define	MPU6050_GYRO_XOUT_L		0x44
#define	MPU6050_GYRO_YOUT_H		0x45
#define	MPU6050_GYRO_YOUT_L		0x46
#define	MPU6050_GYRO_ZOUT_H		0x47
#define	MPU6050_GYRO_ZOUT_L		0x48#define	MPU6050_PWR_MGMT_1		0x6B
#define	MPU6050_PWR_MGMT_2		0x6C
#define	MPU6050_WHO_AM_I		0x75#endif

MPU6050.h:

#ifndef __MPU6050_H
#define __MPU6050_Hvoid MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);void MPU6050_Init(void);
uint8_t MPU6050_GetID(void);
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);#endif

MPU6050.c:

#include "stm32f10x.h"                  // Device header
#include "MPU6050_Reg.h"#define MPU6050_ADDRESS		0xD0void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{uint32_t Timeout;Timeout = 10000;while (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS){Timeout --;if (Timeout == 0){break;}}
}void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{I2C_GenerateSTART(I2C2, ENABLE);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);I2C_SendData(I2C2, RegAddress);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);I2C_SendData(I2C2, Data);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);I2C_GenerateSTOP(I2C2, ENABLE);
}uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;I2C_GenerateSTART(I2C2, ENABLE);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);I2C_SendData(I2C2, RegAddress);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);I2C_GenerateSTART(I2C2, ENABLE);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);I2C_AcknowledgeConfig(I2C2, DISABLE);I2C_GenerateSTOP(I2C2, ENABLE);MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED);Data = I2C_ReceiveData(I2C2);I2C_AcknowledgeConfig(I2C2, ENABLE);return Data;
}void MPU6050_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);I2C_InitTypeDef I2C_InitStructure;I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_ClockSpeed = 50000;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_Init(I2C2, &I2C_InitStructure);I2C_Cmd(I2C2, ENABLE);MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);MPU6050_WriteReg(MPU6050_CONFIG, 0x06);MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);
}uint8_t MPU6050_GetID(void)
{return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{uint8_t DataH, DataL;DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);*AccX = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);*AccY = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);*AccZ = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);*GyroX = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);*GyroY = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);*GyroZ = (DataH << 8) | DataL;
}

主程序main.c:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"uint8_t ID;
int16_t AX, AY, AZ, GX, GY, GZ;int main(void)
{OLED_Init();MPU6050_Init();OLED_ShowString(1, 1, "ID:");ID = MPU6050_GetID();OLED_ShowHexNum(1, 4, ID, 2);while (1){MPU6050_GetData(&AX, &AY, &AZ, &GX, &GY, &GZ);OLED_ShowSignedNum(2, 1, AX, 5);OLED_ShowSignedNum(3, 1, AY, 5);OLED_ShowSignedNum(4, 1, AZ, 5);OLED_ShowSignedNum(2, 8, GX, 5);OLED_ShowSignedNum(3, 8, GY, 5);OLED_ShowSignedNum(4, 8, GZ, 5);}
}

完整工程:stm32之硬件I2C读写MPU6050陀螺仪、加速度传感器

三、应用案例分析

在这里插入图片描述

3.1 基本思路

  • 第一步,开启I2C外设和对应GPIO口的时钟。
  • 第二步,把I2C外设对应的GPIO口初始化为复用开漏输出模式。
  • 第三步,使用结构体对整个I2C进行配置。
  • 第四步,I2C_Cmd,使能I2C。

以上就是I2C外设配置的基本思路了,接下来我们只需要在上一章软件I2C通信模块的基础上进行修改即可,把软件实现的时序用硬件I2C接口替换掉。

3.2 相关库函数介绍

在这里我们只选择部分重点需要掌握的函数进行讲解,一些讲烂了的函数就不讲了,比如初始化什么的,其实写完了就会发现套路都是差不多的,只是外设不一样而已。

1. 生成起始、终止信号

void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);

I2C_GenerateSTART函数用于生成起始信号,I2C_GenerateSTOP函数用于生成终止信号。

2. 应答位配置

void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);

该函数用于配置应答位,ENABLE就是应答,DISABLE就是非应答,原理就是操作控制寄存器ACK位。

3. 发送数据

void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);

该函数用于发送一个字节数据,其实现原理就是将一个字节的数据写入到DR数据寄存器。

4. 接收数据

uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);

该函数用于接收一个字节数据,其实现原理就是从DR寄存器中读取一个字节数据。

5. 发送七位地址专用函数

void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);

该函数用于进行从机寻址时序,即从机地址(7位)+读写标志位(1位),第二个参数I2C_Direction决定读写标志位,当指定为I2C_Direction_Transmitter时表示为写,当指定为I2C_Direction_Receiver时表示为读。

6. I2C事件状态监控函数

函数原型ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);
功能该函数用于检查指定的 I2C 事件是否发生
参数
I2Cx: 指定要使用的 I2C 外设,可以是 I2C1、I2C2 或其他可用的 I2C 实例
I2C_EVENT: 指定要检查的 I2C 事件
返回值typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
成功返回SUCCESS,表示指定的 I2C 事件发生。失败返回ERROR,表示指定的 I2C 事件未发生

I2C_EVENT可以是预定义的一些事件常量,如:

事件描述
I2C_EVENT_MASTER_MODE_SELECT主机模式选择事件(EV5)
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED主机发送模式选择事件(EV6)
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED主机接收模式选择事件(EV6)
I2C_EVENT_MASTER_BYTE_TRANSMITTING主机字节正在发送中(EV8)
I2C_EVENT_MASTER_BYTE_TRANSMITTED主机字节发送完成(EV8_2)
I2C_EVENT_MASTER_BYTE_RECEIVED主机字节接收完成(EV7)

3.3 MPU6050模块

MPU6050模块主要封装了一个模块初始化函数以及一个指定地址写函数和一个指定地址读函数。

3.1.1 模块初始化

1. 开启I2C外设和对应GPIO口的时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

这里I2C1和I2C2都是APB1的外设,注意不要搞错了。

2. 把I2C外设对应的GPIO口初始化为复用开漏输出模式

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

3. 使用结构体对整个I2C进行配置

I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_ClockSpeed = 50000;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_Init(I2C2, &I2C_InitStructure);

I2C_Mode: I2C 模式配置,这里选择I2C_Mode_I2C,即标准的 I2C 模式。STM32 的 I2C 外设还支持 I2C 模式和 SMBus 模式。

I2C_ClockSpeed: 时钟速度配置,这里选择50KHz。该参数控制 SCL 引脚的频率,进而影响 I2C 总线的通信速率。典型的 I2C 时钟速度可以是 100 kHz(标准模式),400 kHz(快速模式),或更高的速率,具体根据应用需求设置。

I2C_DutyCycle: 占空比配置,这里选择I2C_DutyCycle_2,即设置 I2C 时钟的占空比为 2(即高电平与低电平时间的比例)。该参数仅在 I2C 工作在快速模式(400 kHz 或更高)时有效,用于调整时钟信号的高低电平时间比例。

I2C_Ack: 应答配置,这里选择I2C_Ack_Enable,即启用 I2C 的应答功能(ACK)。当 I2C 接收到数据后,启用 ACK 功能可以让从设备(或主设备)自动发送一个应答信号,以表示数据接收成功。

I2C_AcknowledgedAddress: 应答地址模式配置,这里选择了I2C_AcknowledgedAddress_7bit,即将 I2C 的应答地址模式设置为 7 位地址模式。I2C 设备地址可以是 7 位或 10 位,此处选择 7 位模式。

I2C_OwnAddress1: 设备地址配置,这里选择了0x00,即设置当前 I2C 外设的主地址为 0x00。在从设备模式下,这个地址用于从设备识别自己的地址。在主设备模式下,地址参数的作用较小。

4. I2C_Cmd,使能I2C

I2C_Cmd(I2C2, ENABLE);

到这里,整个I2C2外设就初始化完了,接下来就是进行MPU6050模块的初始化配置了。

5. MPU6050初始化配置

MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);//接触睡眠,选择陀螺仪时钟
MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);//六个轴均不待机
MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);//采用分频为10
MPU6050_WriteReg(MPU6050_CONFIG, 0x06);//滤波参数给最大
//陀螺仪和加速度计都选择最大量程
MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);
MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);

3.1.2 指定地址写

1. 发送起始信号(EV5)

I2C_GenerateSTART(I2C2, ENABLE);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);

2. 发送从机地址和方向位(EV6)

I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);

3. 发送数据(寄存器地址)(EV8)

I2C_SendData(I2C2, RegAddress);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);

4. 发送数据(写入寄存器数据)(EV8_2)

I2C_SendData(I2C2, Data);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);

5. 发送终止信号

I2C_GenerateSTOP(I2C2, ENABLE);

3.1.3 指定地址读

1. 发送起始信号(EV5)

I2C_GenerateSTART(I2C2, ENABLE);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);

2. 发送从机地址和方向位(EV6)

I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);

3. 发送数据(寄存器地址)(EV8_2)

I2C_SendData(I2C2, RegAddress);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);

注意:这里由于是写时序的最后一个发送数据,所以还是使用I2C_EVENT_MASTER_BYTE_TRANSMITTED等待EV8_2稳妥点。

4. 重新发送起始信号(EV5)

I2C_GenerateSTART(I2C2, ENABLE);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);

5. 发送从机地址和方向位(EV6)

I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver);
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);

注意:这里有两个EV6事件,分别是主机作为发送端的I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED和主机作为接收端的I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED,不要搞错了。

6. 接收最后一个字节数据前设置

I2C_AcknowledgeConfig(I2C2, DISABLE);
I2C_GenerateSTOP(I2C2, ENABLE);

在接收最后一个字节之前设置ACK为非应答,设置停止位。

7. 接收数据(EV7)

MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED);
Data = I2C_ReceiveData(I2C2);

8. 恢复默认ACK状态

I2C_AcknowledgeConfig(I2C2, ENABLE);

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

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

相关文章

52 mysql 启动过程中常见的相关报错信息

前言 我们这里主要是看一下 service mysql start, service mysql stop 的过程中的一些常见的错误问题 这些 也是之前经常碰到, 但是 每次都是 去搜索, 尝试 1, 2, 3, 4 去解决问题 但是 从来未曾思考过 这个问题到底是 怎么造成的 The server quit without updating PID fil…

【系统架构设计】开发管理

【系统架构设计】开发管理 前言项目的范围、时间与成本项目范围管理项目时间管理项目成本管理 配置管理和文档管理配置管理文档管理 软件需求管理人力资源管理软件的运行与评价软件过程改进 前言 影响软件研发项目全局的因素是管理水平&#xff0c;而技术只影响局部&#xff0…

vrrp协议,主备路由器的选举

当VRRP备份组中的所有备份路由器&#xff08;BACKUP&#xff09;具有相同的优先级时&#xff0c;选举新的主路由器&#xff08;MASTER&#xff09;的过程将基于以下规则&#xff1a; IP地址优先&#xff1a;如果备份路由器的优先级相同&#xff0c;那么具有最高IP地址的路由器…

深入理解XML与JSON:数据交换格式的比较与应用

1.XML与JSON的概念 XML是一种标记语言&#xff0c;它允许开发者定义自己的标签来描述数据。其结构由元素、属性和文本内容组成。格式如下&#xff1a; <bookstore><book><title>XML Developers Guide</title><author>John Doe</author>&…

我的sql我做主!Mysql 的集群架构详解之组从复制、半同步模式、MGR、Mysql路由和MHA管理集群组

目录 Mysql 集群技术一、Mysql 在服务器中的部署方法1.1 在Linux下部署mysql1.1.1 安装依赖性&#xff1a;1.1.2 下载并解压源码包1.1.3 源码编译安装mysql1.1.4 部署mysql 二、Mysql的组从复制2.1 配置mastesr2.2 配置salve2.3 当有数据时添加slave22.4 延迟复制2.5 慢查询日志…

Python爬虫02

xml 和html 区别 jsonpath模块 场景 多层嵌套的复杂字典直接提取数据 安装 pip install jsonpath使用 from jsonpath import jsonpathret jsonpath(dict, jaonpath语法规则字符串)语法规则 eg: lxml模块&xpath语法 谷歌浏览器 xpath helper 插件 作用对当前页面…

Oracle(ORA-00210、ORA-00202)控制文件错误

现象描述 数据库启动失败&#xff0c;系统显示如下错误信息&#xff1a; ORA-00210: cannot open the specified control file ORA-00202: control file: /opt/workshop/omu/database/control03.ctl可能原因可能原因 控制文件错误导致数据库启动失败。 处理步骤 以oracle用…

HIS系统|HIS系统开发源码

在数字医疗时代&#xff0c;医院信息系统&#xff08;HIS&#xff09;的开发至关重要。本文将深入探讨在开发HIS系统时需要关注的主要事项&#xff0c;从系统架构到数据安全&#xff0c;为医疗机构提供实用的开发指南。 1、需求分析与系统规划 在开发HIS系统的初期&#xff0c…

机器学习:svm算法原理的优缺点和适应场景

1、概述&#xff1a; 基本原理&#xff1a; 间隔&#xff08;Margin&#xff09;&#xff1a;SVM试图找到一个超平面&#xff0c;这个超平面不仅能够区分不同的类别&#xff0c;而且具有最大的间隔。间隔是数据点到超平面的最近距离。支持向量&#xff08;Support Vectors&am…

day45 代码随想录 | 单调栈考点

739. 每日温度 请根据每日 气温 列表&#xff0c;重新生成一个列表。对应位置的输出为&#xff1a;要想观测到更高的气温&#xff0c;至少需要等待的天数。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 例如&#xff0c;给定一个列表 temperatures [73, …

使用PyInstaller打包带图标的软件

使用PyInstaller打包带图标的软件&#xff0c;需要遵循一系列步骤。下面是一个详细的指南&#xff1a; 一、准备图标文件 下载或创建图标文件&#xff1a;首先&#xff0c;需要准备一个图标文件&#xff0c;通常是.ico格式。如果手头上没有.ico格式的图标&#xff0c;可以使用…

HTML5手机端通用网站模板源码

文章目录 1.设计来源1.1 主界面1.2 文章信息界面1.3 文章列表界面1.4 双列文章列表界面1.5 通用标签界面1.6 联系我界面1.7 折叠框标签界面1.8 相关界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作…

UE 【材质编辑】自定义ShadingMode

【UE 4.27.2】 在UE中提供了多种多样的ShadingMode&#xff0c;相当于一种风格化的处理方案(整体全面的流程调整)&#xff0c;切换ShadingMode可以看到不同的显示效果&#xff1a; 通过简单的拓展&#xff0c;我们可以实现自定义的ShadingMode&#xff0c;使得我们切换到自己的…

DevOps学习笔记

记录以下DevOps学习笔记&#xff0c;这里是笔记的入口汇总&#xff0c;可以直观的看到所有的笔记&#xff0c;还没有入口的部分&#xff0c;在下正在努力编写中。 gitlab jenkins docker docker安装 artifactory 1.artifactory安装 2.artifactory使用 计算机网络 1.dn…

MySQL:约束

目录 一、概述二、创建测试三、外键约束3.1 数据准备3.2 添加外键3.3 删除外键3.4 增加外键约束 一、概述 约束主要用于作用在表中字段上的规则&#xff0c;用于限制存储在表中的数据。 保证数据库中数据的正确性、有效性和完整性。 约束描述关键字主键约束非空并且唯一PRIMARY…

【Vue】Echart渲染数据时页面不显示内容

背景 做的一个对话交互的功能&#xff0c;根据后台返回的数据&#xff0c;渲染成Echart图表展示因为图表种类多&#xff0c;因此根据不同图表单独做了一个个vue组件&#xff0c;将数据根据展示类型传到这些子组件中进行渲染无论哪种图表&#xff0c;第一次展示时都能正常展示&…

【Threejs学习】材质灯光投影

一、光源分类 环境光(AmbientLight)&#xff1a;会均匀的照亮场景中的所有物体。无方向&#xff0c;不能投射阴影。平行光(DirectionalLight)&#xff1a;沿特定方向散发的光&#xff0c;发出的光线都是平行的。例如太阳光&#xff0c;可投射阴影。点光源(PointLight)&#xf…

基础闯关5

一、XTuner简介 XTuner 是一个高效、灵活、全能的轻量化大模型微调工具库。 高效 支持大语言模型 LLM、多模态图文模型 VLM 的预训练及轻量级微调。XTuner 支持在 8GB 显存下微调 7B 模型&#xff0c;同时也支持多节点跨设备微调更大尺度模型&#xff08;70B&#xff09;。自…

【前端面试】挖掘做过的nextJS项目4——全栈性案例

展示使用 Next.js 搭建一个全栈服务的过程——前端通过 RPC 协议上传文件到public目录,支持前端引用文件 服务器的文件系统目录与HTTP 服务器的文件系统目录与HTTP(超文本传输协议)之间的关系是通过Web服务器软件来建立的。Web服务器软件负责接收HTTP请求,解析请求中的UR…

足球大小球预测及足球大数据之机器学习预测大小球

足球运动是当今世界上开展最广、影响最大、最具魅力、拥有球迷数最多的体育项目之一&#xff0c;尤其是欧洲足球&#xff0c;每年赛事除了五大联赛&#xff08;英超、西甲、德甲、法甲、意甲&#xff09;之外&#xff0c;还会有欧冠&#xff08;欧洲冠军联赛&#xff09;&#…