当前位置: 首页 > 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…...

Android ActionBar 技术深度解析

Android ActionBar 技术深度解析 概述 ActionBar 是 Android 应用中的一个核心 UI 组件,用于提供导航、操作和品牌展示。它通常位于应用窗口的顶部,包含应用的标题、导航按钮、操作项等。ActionBar 自 Android 3.0(API 11)引入,并在 Android 5.0(API 21)后被 Toolbar …...

matlab-数字滤波器设计与实战

文章目录 数字滤波器设计FIR 滤波器设计IIR 滤波器设计巴特沃斯滤波器切比雪夫 I 型滤波器切比雪夫II型椭圆滤波器线性相位与非线性相位零相位响应数字滤波器实战数字滤波器产生延迟的主要原因补偿滤波引入的延迟补偿常量滤波器延迟补偿与频率有关的延迟从信号中除去不需要的频…...

JDK的运作原理

JDK&#xff08;Java Development Kit&#xff09;是Java开发者用来构建、编译、调试和运行Java应用程序的一套工具包。其核心原理涉及到Java语言的编译、执行以及Java虚拟机&#xff08;JVM&#xff09;的运作等多个方面。 1. Java编译原理 Java是一种先编译后解释执行的语言。…...

el-table 实现纵向多级表头

为了实现上图效果&#xff0c;最开始打算用el-row、el-col去实现&#xff0c;但发现把表头和数据分成两大列时&#xff0c;数据太多时会导致所在格高度变高。但由于每一格数据肯定不一样&#xff0c;为保持高度样式一致&#xff0c;就需要我们手动去获取最高格的高度之后再设置…...

Android Studio 下载安装教程(2024 更新版),附详细图文

今天&#xff0c;为大家带来的是Android Studio 2024更新版的下载安装教程&#xff0c;包含详细图文步骤。 随着 Android Studio 的不断更新&#xff0c;自从引入 Koala 系列后&#xff0c;其版本号的命名规则也发生了变化。以本次更新为例&#xff0c;版本号为 2024.2.1&#…...

安全框架:Apache Shiro

安全框架&#xff1a;Apache Shiro 前言您的第一个 Apache Shiro 应用程序Multiple Parts&#xff08;多个部分&#xff09;INI配置[main]部分[users]部分[roles]部分[urls]部分默认过滤器常规启用/禁用 密码学会话管理Remember Me 整合SpringBoot登录登录超时记住我注解登录后…...

泊松融合调研

目录 裁剪加速,速度提升2倍多 cuda版: 效果没测,官方效果不错: 效果不好,parosky/poissonblending 裁剪加速,速度提升2倍多 import os import sys import os os.chdir(os.path.dirname(os.path.abspath(__file__))) current_dir = os.path.dirname(os.path.abspath(__…...

uniapp——App下载文件,打开文档(一)

uniapp如何下载文件、打开文件 文章目录 uniapp如何下载文件、打开文件下载文件下载文件成功返回数据格式 打开文档处理 iOS 打开文件可能失败问题 相关API&#xff1a; uni.downloadFileuni.openDocument 注意&#xff1a; 只支持 GET 请求&#xff0c;需要 POST的&#xff…...

Python 列表的高级索引技巧

列表是 Python 中最常用的数据结构之一&#xff0c;它允许你存储多个元素&#xff0c;并且可以通过索引来访问这些元素。本文将带你深入了解 Python 列表的高级索引技巧&#xff0c;让你在处理数据时更加得心应手。 1.基本索引 首先&#xff0c;我们来看看如何使用基本索引来访…...

UE5.3 虚幻引擎 Windows插件开发打包(带源码插件打包、无源码插件打包)

0 引言 随着项目体量的增大&#xff0c;所有代码功能都放一起很难管理。所以有什么办法可以将大模块划分成一个个小模块吗。当然有&#xff0c;因为虚幻引擎本身就遇到过这个问题&#xff0c;他的解决办法就是使用插件的形式开发。 例如&#xff0c;一个团队开发了文件I/O模块插…...