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;                          //选择I2C1
    hi2c1.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和PB7
        GPIO_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 0xA0

uint8_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;                          //选择I2C1
    hi2c1.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和PB7
        GPIO_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 0xA0

uint8_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;      //选择PB0
    GPIO_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;                          //选择I2C1
    hi2c1.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和PB7
        GPIO_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 0xA0

uint8_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;                          //选择I2C1
    hi2c1.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和PB7
        GPIO_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的通道6
        hdma1_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的通道7
        hdma1_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 0xA0

uint8_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)
  {
  
  }
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

发表文章去哪里投稿?软文推广常见的几种渠道类型

在互联网高度繁荣的当下&#xff0c;人们获取信息的门槛愈发降低&#xff0c;投放信息渠道的类型也五花八门。但想要获得理想的推广效果&#xff0c;信息投放渠道在其中发挥着不小的作用。发表文章去哪里投稿&#xff1f;下面就让我们来了解一下软文推广常见的几种渠道类型。 一…

QComboBox中使用树形控件进行选择

事情是这样的&#xff0c;要在一个ComboBox中通过树形结构进行内容的选择。 默认的QComboBox展开是下拉的列表。因此需要定制一下。 效果就是这样的 实现上面效果的核心代码就是下面这样的 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { treenew…

Unity 读Excel,读取xlsx文件解决方案

Unity读取表格数据 效果&#xff1a; 思路&#xff1a; Unity可以解析Json&#xff0c;但是读取Excel需要插件的帮助&#xff0c;那就把这个功能分离开&#xff0c;读表插件就只管读表转Json&#xff0c;Unity就只管Json解析&#xff0c;中间需要一个存储空间&#xff0c;使用…

Linux之ARM(MX6U)裸机篇----7.蜂鸣器实验

一&#xff0c;蜂鸣器模块 封装步骤&#xff1a; ①初始化SNVS_TAMPER这IO复用为GPIO ②设置SNVS_TAMPPER这个IO的电气属性 ③初始化GPIO ④控制GPIO输出高低电平 bsp_beep.c: #include "bsp_beep.h" #include "cc.h"/* BEEP初始化 */ void beep_init…

前端学习DAY29(1688侧边栏)

完整代码、 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>1688导航条</title><style>…

NLP模型工程化部署

文章目录 一、理论-微服务、测试与GPU1&#xff09;微服务架构2&#xff09;代码测试3&#xff09;GPU使用 二、实践-封装微服务&#xff0c;编写测试用例和脚本&#xff0c;并观察GPU1&#xff09;微服务封装(RestFul和RPC)2&#xff09;测试编写(unit_test\api_test\load_tes…

重生之我在异世界学编程之数据结构与算法:深入队列篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 一、概述二、链表节点结构三、队列结构四、基…

在线机考|2024华为实习秋招春招编程题(最新)——第2题_订单取餐顺序_300分(五)

题目内容 肯德基店销售炸鸡、薯条、可乐三种实物,准备三种食物的速度一样,且三种食物同时制作;三种食物同时制作,按订单顺序进行分发食物。现在有N个订单,每个订单用连续三位数组元素表示,数组的元素是对应食物的份数。N最大为100万,每个订单里每份食物最多100万份。请计…

SAP SD信贷管理后台配置(上)

后台系统功能配置 1、定义信贷控制范围 说明&#xff1a; 信贷控制区域是一个控制单元&#xff0c;用于指定和检查合作伙伴的信用额度&#xff1b;信用控制区域可以包含一个或多个公司&#xff0c;但一个公司无法分配给多个信贷控制区域&#xff1b;在信用控制区域内&#x…

​虚幻引擎UE5渲染不够快的解决办法

​虚幻引擎是由Epic Games公司开发的一款功能强大、全球最开放且先进的实时 3D 创作工具&#xff0c;广泛应用于游戏、影视、建筑可视化、虚拟现实等多个领域&#xff01;虚幻引擎UE5如何实现在网上极速渲染呢&#xff1f;本文提供云渲染和云电脑两套方案用于渲染提速&#xff…

算力股开盘大涨,电光科技7连板

12 月 30 日&#xff0c;尽管北证 50 指数半日跌超 3% 再创调整新低&#xff0c;全市场超 4200 股飘绿&#xff0c;但算力概念股却逆势活跃&#xff0c;电光科技实现 7 连板。以下是对这一现象的具体分析&#xff1a; 原因分析 政策利好&#xff1a;上海近日印发《关于人工智能…

kanzi做3d时钟屏保

用kanzi做一个3d屏保 1. blender制作3d数字模型 下载一些好看的字体文件&#xff0c;用blender建模字体模型&#xff0c;导出fbx格式 2. 新建kanzi工程 导入fbx模型&#xff0c;创建节点&#xff0c;时分秒节点&#xff0c;最上面放一个按钮&#xff0c;用来点击 根据喜好…

logback之自定义pattern使用的转换器

目录 &#xff08;1&#xff09;场景介绍 &#xff08;2&#xff09;定义转换器BizCallerConverter &#xff08;3&#xff09;logback配置conversionRule &#xff08;4&#xff09;测试效果 前文《logback之pattern详解以及源码分析》已经介绍了pattern&#xff0c;以及…

QTDemo:串口调试工具

项目简介 本项目通过QT框架设计一款可以在Windows、Linux等平台的跨平台串口助手&#xff0c;串口功能能够满足基本的调试需求。 本项目采用的版本为&#xff1a;QT5.14 visual studio 2022 进行开发。 项目源码&#xff1a;https://github.com/say-Hai/MyCOMDemo 项目页面&am…

Selenium+Java(21):Jenkins发送邮件报错Not sent to the following valid addresses解决方案

问题现象 小月妹妹近期在做RobotFrameWork自动化测试,并且使用Jenkins发送测试邮件的时候,发现报错Not sent to the following valid addresses,明明各个配置项看起来都没有问题,但是一到邮件发送环节,就是发送不出去,而且还不提示太多有用的信息,急的妹妹脸都红了,于…

AI 智能助手对话系统

一个基于 React 和 Tailwind CSS 构建的现代化 AI 对话系统&#xff0c;提供流畅的用户体验和丰富的交互功能。 项目链接&#xff1a;即将开放… 功能特点 &#x1f916; 智能对话&#xff1a;支持与 AI 助手实时对话&#xff0c;流式输出回答&#x1f4c1; 文件处理&#xff…

Design Compiler:两种工作模式(线负载模式和拓扑模式)

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 Design Compiler可以以线负载模式或拓扑模式启动&#xff0c;必须选择其中一个模式。在拓扑模式下还可使用多模式和UPF模式&#xff1a;多模式允许在多种工作…

应急响应练习

文章目录 web1web2 web1 题目要求&#xff1a; 前景需要&#xff1a; 小李在值守的过程中&#xff0c;发现有CPU占用飙升&#xff0c;出于胆子小&#xff0c;就立刻将服务器关机&#xff0c;这是他的服务器系统&#xff0c;请你找出以下内容&#xff0c;并作为通关条件&#…

从零开始构建直播APP美颜功能:直播美颜SDK的开发实践指南

本文将从零开始&#xff0c;详细探讨如何开发一款功能完善的直播美颜SDK&#xff0c;帮助开发者快速集成美颜功能。 一、明确需求与功能设计 开发美颜功能的第一步是明确需求。直播场景中的美颜需求通常包括以下几点&#xff1a; 实时滤镜&#xff1a;提供多种风格的滤镜&am…

.NET周刊【12月第4期 2024-12-22】

国内文章 dotnet 简单使用 ICU 库进行分词和分行 https://www.cnblogs.com/lindexi/p/18622917 本文将和大家介绍如何使用 ICU 库进行文本的分词和分行。 dotnet 简单聊聊 Skia 里的 SKFontMetrics 的各项属性作用 https://www.cnblogs.com/lindexi/p/18621674 本文将和大…