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

I2C(一):存储器模式:stm32作为主机对AT24C02写读数据

存储器模式:在HAL库中,I2C有专门对存储器外设设置的库函数

I2C(一):存储器模式的使用

  • 1、I2C轮询式写读AT24C02一页数据
  • 2、I2C轮询式写读AT24C02多页数据
  • 3、I2C中断式写读AT24C02一页数据
  • 4、I2C使用DMA式写读AT24C02一页数据

1、I2C轮询式写读AT24C02一页数据

AT24C02 是一款常见的 2 Kbit(256 字节)I²C 接口的 EEPROM(电可擦可编程只读存储器)。它的存储结构如下:

存储容量:AT24C02 的总存储容量为 2 Kbit(即 256 字节)
页(Page)大小:AT24C02 的每一页(Page)的大小为 8 字节。
写数据时,最多一次型写入1页(8字节),超过即会从页的开头覆盖
读数据时,没有限定字节数。

①I2C.c文件的代码如下

#include "I2C.h"/*** @brief:I2C1初始化函数*/
I2C_HandleTypeDef hi2c1;                            //I2C初始化结构体
void I2C1_Init(void)
{/* 1、对I2C1进行初始化 */__HAL_RCC_I2C1_CLK_ENABLE();                    //使能I2C1的时钟hi2c1.Instance = I2C1;                          //选择I2C1hi2c1.Init.ClockSpeed = 100000;                 //通信速率100K,标志模式HAL_I2C_Init(&hi2c1);
}/*** @brief:HAL_I2C_Init()调用此函数*/
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{GPIO_InitTypeDef GPIO_Init;                     //IO口初始化结构体if(hi2c->Instance == I2C1){/* I2C1引脚的初始化:PB6 = SCL,PB7 = SDA*/__HAL_RCC_GPIOB_CLK_ENABLE();              //使能GPIOB的时钟GPIO_Init.Mode = GPIO_MODE_AF_OD;           //复用开漏输出GPIO_Init.Pin = GPIO_PIN_6 | GPIO_PIN_7;    //PB6和PB7GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;      //最大输出速度:低HAL_GPIO_Init(GPIOB, &GPIO_Init);}else if(hi2c->Instance == I2C2){}
}

②I2C.h文件的代码如下

#ifndef __I2C_H
#define __I2C_H#include "stm32f1xx_hal.h"
extern I2C_HandleTypeDef hi2c1;                            //I2C初始化结构体
void I2C1_Init(void);#endif

③main.c文件的代码如下

#include "stm32f1xx_hal.h"
#include "STM32_RCC_Init.h"
#include "UART.h"
#include "I2C.h"#define AT24C02_Address 0xA0uint8_t WriteData[8] = {1,2,3,4,5,6,7,88};
uint8_t ReadData[8];int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);I2C1_Init();printf("启动判断!\r\n");/* 存储器模式:对AT24C02第一页进行写 */HAL_I2C_Mem_Write(&hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, WriteData, 8, 1000);//I2C1,从机地址,从机内部地址,每次传输的数据大小,需要写入的数据缓冲区,需要写入多少个数据/* 查询从机知否准备就绪 */if(HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_Address, 20, 1000) == HAL_OK)//I2C1,从机地址,查询次数,超时时间{/* 存储器模式:向从机第一页读取数据 */HAL_I2C_Mem_Read(&hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, ReadData, 8, 1000);}else{printf("芯片忙碌!\r\n");}/* 将读取到的数据通过串口打印 */for(uint8_t i = 0; i<8; i++){printf("ReadData[%d] = %d\r\n",i,ReadData[i]);}while(1){}	
}

在这里插入图片描述

2、I2C轮询式写读AT24C02多页数据

①I2C.c文件的代码如下

#include "I2C.h"/*** @brief:I2C1初始化函数*/
I2C_HandleTypeDef hi2c1;                            //I2C初始化结构体
void I2C1_Init(void)
{/* 1、对I2C1进行初始化 */__HAL_RCC_I2C1_CLK_ENABLE();                    //使能I2C1的时钟hi2c1.Instance = I2C1;                          //选择I2C1hi2c1.Init.ClockSpeed = 100000;                 //通信速率100K,标志模式HAL_I2C_Init(&hi2c1);
}/*** @brief:HAL_I2C_Init()调用此函数*/
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{GPIO_InitTypeDef GPIO_Init;                     //IO口初始化结构体if(hi2c->Instance == I2C1){/* I2C1引脚的初始化:PB6 = SCL,PB7 = SDA*/__HAL_RCC_GPIOB_CLK_ENABLE();              //使能GPIOB的时钟GPIO_Init.Mode = GPIO_MODE_AF_OD;           //复用开漏输出GPIO_Init.Pin = GPIO_PIN_6 | GPIO_PIN_7;    //PB6和PB7GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;      //最大输出速度:低HAL_GPIO_Init(GPIOB, &GPIO_Init);}else if(hi2c->Instance == I2C2){}
}

②I2C.h文件的代码如下

#ifndef __I2C_H
#define __I2C_H#include "stm32f1xx_hal.h"
extern I2C_HandleTypeDef hi2c1;                            //I2C初始化结构体
void I2C1_Init(void);#endif

③main.c文件的代码如下

#include "stm32f1xx_hal.h"
#include "STM32_RCC_Init.h"
#include "UART.h"
#include "I2C.h"#define AT24C02_Address 0xA0uint8_t WriteData[16] = {1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1};
uint8_t ReadData[16];int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);I2C1_Init();printf("启动判断!\r\n");uint8_t i = 0;for(i = 0; i<2; i++){/* 存储器模式:对AT24C02的页进行写 */HAL_I2C_Mem_Write(&hi2c1, AT24C02_Address, i*8, I2C_MEMADD_SIZE_8BIT, &WriteData[i*8], 8, 1000);//while(HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_Address, 20, 1000) != HAL_OK);HAL_Delay(10);}/* 查询从机知否准备就绪 */if(HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_Address, 20, 1000) == HAL_OK)//I2C1,从机地址,查询次数,超时时间{/* 存储器模式:向从机读取数据 */HAL_I2C_Mem_Read(&hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, ReadData, 16, 1000);}else{printf("芯片忙碌!\r\n");}/* 将读取到的数据通过串口打印 */for(i = 0; i<16; i++){printf("ReadData[%d] = %d\r\n",i,ReadData[i]);}while(1){}	
}

在这里插入图片描述

3、I2C中断式写读AT24C02一页数据

实验要求:连接PB0的按键按下后,单片机主机向从机AT24C02写入数据。连接PB1的按键按下后,主机向从机AT24C02读取数据,然后通过串口打印。

①Key.c文件的代码如下

#include "Key.h"/*** 按键引脚的初始化,使用PB0和PB1*/
void Key_GPIO_Init(void)
{/* 1、开启GPIOB的时钟 */__HAL_RCC_GPIOB_CLK_ENABLE();/* 2、对GPIOB0进行配置 */GPIO_InitTypeDef GPIO_Init;GPIO_Init.Pin = GPIO_PIN_0|GPIO_PIN_1;      //选择PB0GPIO_Init.Mode = GPIO_MODE_INPUT;           //选择输入模式GPIO_Init.Pull = GPIO_PULLUP;               //选择上拉模式HAL_GPIO_Init(GPIOB, &GPIO_Init);
}/*** @brief:判断是按键1按下还是按键2按下*/
uint8_t Key_Scan(void)
{uint8_t Key_Num = 0;if(PB0_IN == GPIO_PIN_RESET)        //PB0按下{HAL_Delay(10);                  //延时消抖while(PB0_IN == GPIO_PIN_RESET);Key_Num =  1;}if(PB1_IN == GPIO_PIN_RESET)        //PB1按下{HAL_Delay(10);                  //延时消抖while(PB1_IN == GPIO_PIN_RESET);Key_Num =  2;}  return Key_Num;
}

①I2C.c文件的代码如下

#include "I2C.h"/*** @brief:I2C1初始化函数*/
I2C_HandleTypeDef hi2c1;                            //I2C初始化结构体
void I2C1_Init(void)
{/* 1、对I2C1进行初始化 */__HAL_RCC_I2C1_CLK_ENABLE();                    //使能I2C1的时钟hi2c1.Instance = I2C1;                          //选择I2C1hi2c1.Init.ClockSpeed = 100000;                 //通信速率100K,标志模式HAL_I2C_Init(&hi2c1);/* 配置I2C1的NVIC */HAL_NVIC_SetPriority(I2C1_EV_IRQn,3,0);HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
}/*** @brief:HAL_I2C_Init()调用此函数*/
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{GPIO_InitTypeDef GPIO_Init;                     //IO口初始化结构体if(hi2c->Instance == I2C1){/* I2C1引脚的初始化:PB6 = SCL,PB7 = SDA*/__HAL_RCC_GPIOB_CLK_ENABLE();              //使能GPIOB的时钟GPIO_Init.Mode = GPIO_MODE_AF_OD;           //复用开漏输出GPIO_Init.Pin = GPIO_PIN_6 | GPIO_PIN_7;    //PB6和PB7GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;      //最大输出速度:低HAL_GPIO_Init(GPIOB, &GPIO_Init);}else if(hi2c->Instance == I2C2){}
}

②I2C.h文件的代码如下

#ifndef __I2C_H
#define __I2C_H#include "stm32f1xx_hal.h"
extern I2C_HandleTypeDef hi2c1;                            //I2C初始化结构体
void I2C1_Init(void);#endif

③main.c文件的代码如下

#include "stm32f1xx_hal.h"
#include "STM32_RCC_Init.h"
#include "UART.h"
#include "I2C.h"
#include "Key.h"#define AT24C02_Address 0xA0uint8_t WriteData[8] = {1,2,3,4,5,6,7,8};
uint8_t ReadData[8];int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);I2C1_Init();Key_GPIO_Init();printf("启动判断!\r\n");while(1){switch(Key_Scan()){case 1://按键PB0按下if(HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_Address, 20, 1000) == HAL_OK){/* 存储器模式:对AT24C02的页进行写,且开启写入完成中断 */HAL_I2C_Mem_Write_IT(&hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, WriteData, 8);}break;case 2://按键PB1按下if(HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_Address, 20, 1000) == HAL_OK){/* 存储器模式:对AT24C02的页进行读,且开启读取完成中断 */HAL_I2C_Mem_Read_IT(&hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, ReadData, 8);}break;      }}	
}

④stm32f1xx_it.c文件的代码如下

#include "stm32f1xx_hal.h"   
#include "stm32f1xx_it.h" 
#include "I2C.h" 
#include "UART.h"/*** I2C1中断服务函数 */
void I2C1_EV_IRQHandler(void)
{HAL_I2C_EV_IRQHandler(&hi2c1);//中断服务总函数
}/******************* 下面的中断的回调函数 ***************************/
/*** 存储器模式:I2C1主机发送完成中断回调函数*/
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
{if(hi2c->Instance == I2C1){printf("发送完成了!\r\n");}else if(hi2c->Instance == I2C2){}
}/*** 存储器模式:I2C1主机读取完成中断回调函数*/
extern uint8_t ReadData[8];
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
{if(hi2c->Instance == I2C1){printf("读取完成了!\r\n");for(uint8_t i = 0; i<8; i++){printf("ReadData[%d] = %d\r\n",i,ReadData[i]);}}else if(hi2c->Instance == I2C2){}
}

在这里插入图片描述

4、I2C使用DMA式写读AT24C02一页数据

实验要求:连接PB0的按键按下后,单片机主机向从机AT24C02写入数据。连接PB1的按键按下后,主机向从机AT24C02读取数据,然后通过串口打印。
在这里插入图片描述I2C的DMA非常的难用,需要配置I2C的NVIC中断和配置I2C的中断函数。才会调用I2C的DMA中断。还不知直接使用I2C的中断回调函数。
①I2C.c文件的代码如下

#include "I2C.h"/*** @brief:I2C1初始化函数*/
I2C_HandleTypeDef hi2c1;                            //I2C初始化结构体
void I2C1_Init(void)
{/* 1、对I2C1进行初始化 */__HAL_RCC_I2C1_CLK_ENABLE();                    //使能I2C1的时钟hi2c1.Instance = I2C1;                          //选择I2C1hi2c1.Init.ClockSpeed = 100000;                 //通信速率100K,标志模式HAL_I2C_Init(&hi2c1);/* 配置I2C1的NVIC */HAL_NVIC_SetPriority(I2C1_EV_IRQn,3,0);HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
}/*** @brief:HAL_I2C_Init()调用此函数*/
DMA_HandleTypeDef hdma1_I2C_Tx;                     //DMA1配置结构体
DMA_HandleTypeDef hdma1_I2C_Rx;                     //DMA1配置结构体
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{GPIO_InitTypeDef GPIO_Init;                     //IO口初始化结构体if(hi2c->Instance == I2C1){/* I2C1引脚的初始化:PB6 = SCL,PB7 = SDA*/__HAL_RCC_GPIOB_CLK_ENABLE();               //使能GPIOB的时钟GPIO_Init.Mode = GPIO_MODE_AF_OD;           //复用开漏输出GPIO_Init.Pin = GPIO_PIN_6 | GPIO_PIN_7;    //PB6和PB7GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;      //最大输出速度:低HAL_GPIO_Init(GPIOB, &GPIO_Init);/* 2、初始化DMA1的通道6 */__HAL_RCC_DMA1_CLK_ENABLE();                                   //使能DMA1的时钟hdma1_I2C_Tx.Instance = DMA1_Channel6;                         //选择DMA1的通道6hdma1_I2C_Tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;   //外设站点数据宽度,8位hdma1_I2C_Tx.Init.PeriphInc = DMA_PINC_DISABLE;                //外设地址是否递增,选择不自增hdma1_I2C_Tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;      //内存站点数据宽度,8位hdma1_I2C_Tx.Init.MemInc = DMA_MINC_ENABLE;                    //内存地址是否递增,选择自增hdma1_I2C_Tx.Init.Direction = DMA_MEMORY_TO_PERIPH;            //传输方向:这里选择内存---->寄存器hdma1_I2C_Tx.Init.Mode = DMA_NORMAL;                           //计数器传输模式:选择不自动重装hdma1_I2C_Tx.Init.Priority = DMA_PRIORITY_MEDIUM;              //通道1传输优先级,选择中等__HAL_LINKDMA(&hi2c1,hdmatx,hdma1_I2C_Tx);                     //将I2C1_TX和DMA1通道6连接起来HAL_DMA_Init(&hdma1_I2C_Tx);/* 配置DMA1通道6的NVIC */HAL_NVIC_SetPriority(DMA1_Channel6_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);/* 3、配置DMA1的通道7 */hdma1_I2C_Rx.Instance = DMA1_Channel7;                         //选择DMA1的通道7hdma1_I2C_Rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;   //外设站点数据宽度,8位hdma1_I2C_Rx.Init.PeriphInc = DMA_PINC_DISABLE;                //外设地址是否递增,选择不自增hdma1_I2C_Rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;      //内存站点数据宽度,8位hdma1_I2C_Rx.Init.MemInc = DMA_MINC_ENABLE;                    //内存地址是否递增,选择自增hdma1_I2C_Rx.Init.Direction = DMA_PERIPH_TO_MEMORY;            //传输方向:这里选择寄存器---->内存hdma1_I2C_Rx.Init.Mode = DMA_NORMAL;                           //计数器传输模式:选择不自动重装hdma1_I2C_Rx.Init.Priority = DMA_PRIORITY_MEDIUM;              //通道1传输优先级,选择中等__HAL_LINKDMA(&hi2c1,hdmarx,hdma1_I2C_Rx);                     //将I2C1_RX和DMA1通道7连接起来HAL_DMA_Init(&hdma1_I2C_Rx);/* 配置DMA1通道6的NVIC */HAL_NVIC_SetPriority(DMA1_Channel7_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);}else if(hi2c->Instance == I2C2){}
}

②I2C.h文件的代码如下

#ifndef __I2C_H
#define __I2C_H#include "stm32f1xx_hal.h"
extern I2C_HandleTypeDef hi2c1;                            //I2C初始化结构体
extern DMA_HandleTypeDef hdma1_I2C_Tx;                     //DMA1配置结构体
extern DMA_HandleTypeDef hdma1_I2C_Rx;                     //DMA1配置结构体
void I2C1_Init(void);#endif

③main.c文件的代码如下

#include "stm32f1xx_hal.h"
#include "STM32_RCC_Init.h"
#include "UART.h"
#include "I2C.h"
#include "Key.h"#define AT24C02_Address 0xA0uint8_t WriteData[8] = {1,2,3,4,5,6,7,8};
uint8_t ReadData[8];int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);I2C1_Init();Key_GPIO_Init();printf("启动判断!\r\n");while(1){switch(Key_Scan()){case 1://按键PB0按下if(HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_Address, 20, 1000) == HAL_OK){/* 存储器模式:对AT24C02的页进行写,且开启DMA写入完成中断 */HAL_I2C_Mem_Write_DMA(&hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, WriteData, 8);}break;case 2://按键PB1按下if(HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_Address, 20, 1000) == HAL_OK){/* 存储器模式:对AT24C02的页进行读,且开启DMA读取完成中断 */HAL_I2C_Mem_Read_DMA(&hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, ReadData, 8);}break;      }}	
}

④stm32f1xx_it.c文件的代码如下

#include "stm32f1xx_hal.h"   
#include "stm32f1xx_it.h" 
#include "I2C.h" 
#include "UART.h"/*** I2C1中断服务函数 */
void I2C1_EV_IRQHandler(void)
{HAL_I2C_EV_IRQHandler(&hi2c1);//中断服务总函数
}
/*** DMA1通道6的中断服务函数 */
void DMA1_Channel6_IRQHandler(void)
{HAL_DMA_IRQHandler(&hdma1_I2C_Tx);
}/*** DMA1通道7的中断服务函数 */
void DMA1_Channel7_IRQHandler(void)
{HAL_DMA_IRQHandler(&hdma1_I2C_Rx);
}
/******************* 下面的中断的回调函数 ***************************/
/*** 存储器模式:I2C1的DMA发送完成中断回调函数*/
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
{if(hi2c->Instance == I2C1){printf("发送完成了!\r\n");}else if(hi2c->Instance == I2C2){}
}/*** 存储器模式:I2C1的DMA读取完成中断回调函数*/
extern uint8_t ReadData[8];
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
{if(hi2c->Instance == I2C1){printf("读取完成了!\r\n");for(uint8_t i = 0; i<8; i++){printf("ReadData[%d] = %d\r\n",i,ReadData[i]);}}else if(hi2c->Instance == I2C2){}
}

在这里插入图片描述

相关文章:

I2C(一):存储器模式:stm32作为主机对AT24C02写读数据

存储器模式&#xff1a;在HAL库中&#xff0c;I2C有专门对存储器外设设置的库函数 I2C&#xff08;一&#xff09;&#xff1a;存储器模式的使用 1、I2C轮询式写读AT24C02一页数据2、I2C轮询式写读AT24C02多页数据3、I2C中断式写读AT24C02一页数据4、I2C使用DMA式写读AT24C02一…...

scrapy 教程

Scrapy Tutorial In this tutorial, we’ll assume that Scrapy is already installed on your system. If that’s not the case, see Installation guide. We are going to scrape quotes.toscrape.com, a website that lists quotes from famous authors. This tutorial …...

2025元旦源码免费送

我们常常在当下感到时间慢&#xff0c;觉得未来遥远&#xff0c;但一旦回头看&#xff0c;时间已经悄然流逝。对于未来&#xff0c;尽管如此&#xff0c;也应该保持一种从容的态度&#xff0c;相信未来仍有许多可能性等待着我们。 免费获取源码。 更多内容敬请期待。如有需要可…...

高级架构五 设计模式

一 设计模式七大原则 1.1. 设计模式目的 编写软件过程中&#xff0c;程序员面临着来自 耦合性&#xff0c;内聚性以及可维护性&#xff0c;可扩展性&#xff0c;重用性&#xff0c;灵活性 等多方面的挑战&#xff0c;设计模式是为了让程序(软件)&#xff0c;具有更好的&#…...

RFID手持机与RFID工业平板在仓储物流管理系统中的选型

概述 随着物联网技术在仓储物流管理系统中的普及&#xff0c;RFID手持机与RFID工业平板作为基于RFID技术手持式读写器的两种重要终端设备形态&#xff0c;得到了广泛应用。尽管RFID手持机与RFID工业平板都具备读写 RFID标签的基本功能&#xff0c;使用场景较为类似&#xff0c…...

IoC设计模式详解:控制反转的核心思想

前言&#xff1a;在软件开发中&#xff0c;设计模式是一种经过验证的、在特定场景下能有效解决问题的解决方案。控制反转&#xff08;Inversion of Control&#xff0c;IoC&#xff09; 作为一种设计模式&#xff0c;通过让程序的控制流和对象管理反转&#xff0c;从而使得代码…...

《云原生安全攻防》-- K8s安全配置:CIS安全基准与kube-bench工具

在本节课程中&#xff0c;我们来了解一下K8s集群的安全配置&#xff0c;通过对CIS安全基准和kube-bench工具的介绍&#xff0c;可以快速发现K8s集群中不符合最佳实践的配置项&#xff0c;及时进行修复&#xff0c;从而来提高集群的安全性。 在这个课程中&#xff0c;我们将学习…...

LINUX下载编译gtk

下载 选择自己合适的版本 GNOME / gtk GitLab 下载meson GNOME / gtk GitLab 编译 BUILD_DIRbuilddir INSTALL_DIR${HOME}/gtk-resultMESON_PATHpwd/meson-1.6.1/meson.py${MESON_PATH} setup \--prefix ${INSTALL_DIR} \${BUILD_DIR}cd builddir${MESON_PATH} compile…...

基于VSCode软件框架的RISC-V IDE MRS2正式上线发布

基于VSCode软件框架的RISC-V IDE MRS2正式上线发布 一、概述 MounRiver Studio Ⅱ(MRS2)为MounRiver Studio的换代版本&#xff0c;从V2.1开始&#xff0c;框架更换至更现代的VSCode&#xff0c;并深度定制开发。在工程管理、代码编辑、编译、调试等方面均兼容之前版本&#…...

AWS re:Invent 2024 - Dr. Werner Vogels 主题演讲

今年&#xff0c;我有幸亲临现场参加了所有的 keynote&#xff0c;每一场都让我感受到深深的震撼。无论是全新的功能发布&#xff0c;还是令人眼前一亮的新特性展示&#xff0c;每一场 keynote 都精彩纷呈&#xff0c;充满干货&#xff0c;值得反复学习和回味。 恰好&#xff…...

前端小案例——520表白信封

前言&#xff1a;我们在学习完了HTML和CSS之后&#xff0c;就会想着使用这两个东西去做一些小案例&#xff0c;不过又没有什么好的案例让我们去练手&#xff0c;本篇文章就提供里一个案例——520表白信封 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主…...

FPGA随记——过约束

什么是过约束&#xff1f; 从字面意思来看&#xff0c;所谓过约束是指约束过紧了。这个“过”体现在setup requirement变小了&#xff0c;对于单周期路径&#xff0c;这个值通常与时钟周期一致&#xff0c;但在过约束情况下&#xff0c;等效于这个值变小了&#xff0c;也就是时…...

如何利用云计算进行灾难恢复?

云计算环境下的灾难恢复实践指南 天有不测风云&#xff0c;企业的IT系统也一样&#xff0c;我见过太多因为没有做好灾备而吃大亏的案例。今天就和大家聊聊如何用云计算来做灾难恢复。 一个惊心动魄的真实案例&#xff1a;某电商平台的主数据中心因为市政施工不小心挖断了光纤…...

【华为OD-E卷 - 九宫格按键输入 100分(python、java、c++、js、c)】

【华为OD-E卷 - 九宫格按键输入 100分&#xff08;python、java、c、js、c&#xff09;】 题目 九宫格按键输入&#xff0c;有英文和数字两个模式&#xff0c;默认是数字模式&#xff0c;数字模式直接输出数字&#xff0c;英文模式连续按同一个按键会依次出现这个按键上的字母…...

基于AI大模型的医院SOP优化:架构、实践与展望

一、引言 1.1 研究背景与意义 近年来,人工智能(AI)技术取得了迅猛发展,尤其是大模型的出现,为各个领域带来了革命性的变化。在医疗领域,AI 医疗大模型正逐渐崭露头角,展现出巨大的应用潜力。随着医疗数据的海量积累以及计算能力的大幅提升,AI 医疗大模型能够对复杂的…...

Linux快速入门-一道简单shell编程题目

编写一个 Shell 程序。 功能&#xff1a;在用户家目录下创建一个文件夹myshell&#xff1b;进入此文件夹&#xff1b;在文件中创建文件aa.sh&#xff0c;如果文件夹或文件存在&#xff0c;则提示对象已存在&#xff0c;不创建。 代码编写 #!/bin/bash#获取用户家目录:方便后…...

Hive如何创建自定义函数(UDF)?

目录 1 自定义UDF函数基础 2 自定义UDF函数案例 3 创建临时函数 4 创建永久函数 1 自定义UDF函数基础 1. 内置函数:Hive 自带了一些函数...

聊聊前端框架中的process.env,env的来源及优先级(next.js、vue-cli、vite)

在平时开发中&#xff0c;常常使用vue、react相关脚手架创建项目&#xff0c;在项目根目录可以创建.env、.env.[mode]&#xff08;mode为development、production、test)、.env.local等文件&#xff0c;然后在项目中就可以通过process.env来访问相关的环境变量了。 下面针对如下…...

linux shell脚本 【分支结构case...in 、循环结构、函数】内附练习

1.思维导图 2.练习 1.定义一个find函数&#xff0c;查找ubuntu和root的gid 2.定义一个数组&#xff0c;写一个函数完成对数组的冒泡排序 bubble() {n${#arr[*]}for((i0;i<n-1;i));dofor((j0;j<n-1-i;j));doif ((arr[j]>arr[j1]));thentemp${arr[j]}arr[j]${arr[j1]}a…...

VSCode 终端显示“pnpm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本”

VSCode 终端显示“pnpm : 无法加载文件 C:\Program Files\nodejs\npm.ps1&#xff0c;因为在此系统上禁止运行脚本”VSCode 终端显示“pnpm : 无法加载文件 C:\Program Files\nodejs\npm.ps1&#xff0c;因为在此系统上禁止运行脚本”解决方案&#xff1a; 1.用get-ExecutionP…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...