【STM32-学习笔记-6-】DMA

news2025/1/13 20:27:21

文章目录

  • DMA
    • Ⅰ、DMA框图
    • Ⅱ、DMA基本结构
    • Ⅲ、不同外设的DMA请求
    • Ⅳ、DMA函数
    • Ⅴ、DMA_InitTypeDef结构体参数
      • ①、DMA_PeripheralBaseAddr
      • ②、DMA_PeripheralDataSize
      • ③、DMA_PeripheralInc
      • ④、DMA_MemoryBaseAddr
      • ⑤、DMA_MemoryDataSize
      • ⑥、DMA_MemoryInc
      • ⑦、DMA_DIR
      • ⑧、DMA_BufferSize
      • ⑨、DMA_Mode
      • ⑩、DMA_M2M
      • ①①、DMA_Priority
    • Ⅵ、DMA配置示例
      • DMA+AD多通道
        • 1. ADC单次扫描+DMA数据转运
        • 2. ADC连续扫描+DMA循环转运

DMA

Ⅰ、DMA框图

image-20241227112815688

Ⅱ、DMA基本结构

image-20241227112841087

Ⅲ、不同外设的DMA请求

image-20241227113057979

Ⅳ、DMA函数

// 重置指定的DMA通道寄存器为默认值
void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);

// 初始化指定的DMA通道,根据初始化结构体配置参数
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);

// 初始化DMA初始化结构体的默认值
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);

// 开启或关闭指定的DMA通道
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);

// 开启或关闭DMA通道的中断
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);

// 设置DMA当前数据计数器的值
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); 

// 获取DMA当前数据计数器的值
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);

// 获取DMA标志状态
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
// 清除DMA标志
void DMA_ClearFlag(uint32_t DMAy_FLAG);

// 获取DMA中断状态	
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
// 清除DMA中断待处理位
void DMA_ClearITPendingBit(uint32_t DMAy_IT);

Ⅴ、DMA_InitTypeDef结构体参数

①、DMA_PeripheralBaseAddr

指定DMA通道的外设基地址外设寄存器-起始地址

    • 类型uint32_t
    • 取值范围:任意有效的外设地址
    • 作用:这是DMA操作的外设端的起始地址,例如ADC、USART等外设的数据寄存器地址

②、DMA_PeripheralDataSize

指定外设寄存器的数据宽度配置DMA传输时外设数据的大小

  • 该参数可以是@ref DMA_peripheral_data_size

    • 宏定义解释

      1. DMA_PeripheralDataSize_Byte
        • 描述:表示外设数据大小为1字节(8位)
          • 每次DMA传输的数据大小为1字节
      2. DMA_PeripheralDataSize_HalfWord
        • 描述:表示外设数据大小为半字(16位)
          • 每次DMA传输的数据大小为2字节
      3. DMA_PeripheralDataSize_Word
        • 描述:表示外设数据大小为1字(32位)
          • 每次DMA传输的数据大小为4字节

      宏函数

      1. IS_DMA_PERIPHERAL_DATA_SIZE(SIZE)
        • 描述:检查给定的外设数据大小设置是否有效
        • 参数SIZE,代表DMA的外设数据大小
        • 功能:检查SIZE是否等于DMA_PeripheralDataSize_ByteDMA_PeripheralDataSize_HalfWordDMA_PeripheralDataSize_Word中的任一个。
        • 返回值:如果SIZE有效,返回1(真),否则返回0(假)

③、DMA_PeripheralInc

指定外设地址寄存器是否递增

    • 类型uint32_t
    • 取值范围
      • DMA_PeripheralInc_Disable:外设地址不递增
      • DMA_PeripheralInc_Enable:外设地址递增
    • 作用:控制外设地址在每次数据传输后是否递增

④、DMA_MemoryBaseAddr

指定DMA通道的内存基地址存储器-起始地址

    • 类型uint32_t
    • 取值范围:任意有效的内存地址
    • 作用:这是DMA操作的内存端的起始地址,例如一个缓冲区的起始地址

⑤、DMA_MemoryDataSize

指定内存数据宽度存储器-数据宽度

    • 类型uint32_t
    • 取值范围
      • DMA_MemoryDataSize_Byte:数据宽度为8位
      • DMA_MemoryDataSize_HalfWord:数据宽度为16位
      • DMA_MemoryDataSize_Word:数据宽度为32位
    • 作用:确定内存数据的大小

⑥、DMA_MemoryInc

指定内存地址寄存器是否递增指定存储器-是否递增

    • 类型uint32_t
    • 取值范围
      • DMA_MemoryInc_Disable:内存地址不递增
      • DMA_MemoryInc_Enable:内存地址递增
    • 作用:控制内存地址在每次数据传输后是否递增

⑦、DMA_DIR

指定数据传输方向,即外设是数据源还是数据目标指定外设站点是源还是目标

    • 类型uint32_t
    • 取值范围
      • DMA_DIR_PeripheralSRC外设是数据源,内存是数据目标
      • DMA_DIR_PeripheralDST:外设是数据目标,内存是数据源
    • 作用:确定数据传输的方向

⑧、DMA_BufferSize

指定DMA通道的缓冲区大小,以数据单元为单位

  • DMA_InitStruct.DMA_BufferSize = Size; 传递Size个大小为<数据宽度>的数据

    • 类型uint32_t
    • 取值范围:0到65535
    • 作用:确定要传输的数据量。数据单元的大小取决于DMA_PeripheralDataSizeDMA_MemoryDataSize的配置,具体取决于传输方向

⑨、DMA_Mode

指定DMAy通道的工作模式是否要自动重装

    • 类型uint32_t
    • 取值范围
      • DMA_Mode_Normal正常模式,传输完成后停止
      • DMA_Mode_Circular:循环模式(自动重装),传输完成后从头开始
    • 作用:确定DMA传输的模式。循环模式不适用于内存到内存的传输

⑩、DMA_M2M

是否使用软件触发存储器到存储器

    • 类型uint32_t
    • 描述:指定DMA通道是否用于内存到内存的传输
    • 取值范围
      • DMA_M2M_Disable不使用内存到内存传输
      • DMA_M2M_Enable使用内存到内存传输
    • 作用:确定DMA通道是否用于内存到内存的传输

①①、DMA_Priority

指定DMA通道的软件优先级

  • 按需求配置

    • 类型uint32_t
    • 取值范围
      • DMA_Priority_Low低优先级
      • DMA_Priority_Medium中优先级
      • DMA_Priority_High高优先级
      • DMA_Priority_VeryHigh非常高优先级
    • 作用:确定DMA通道的优先级,影响多个DMA请求的处理顺序

Ⅵ、DMA配置示例

#include "stm32f10x.h"                  // Device header

uint32_t Temp_Size;//存储数据计数器的值

void MyDMA_Init(uint32_t Source, uint32_t Dest, uint32_t Size)//参数需为两个数组的数组名
{
	Temp_Size = Size;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	DMA_InitTypeDef DMA_InitStruct;
	DMA_InitStruct.DMA_PeripheralBaseAddr = Source;//外设寄存器-起始地址
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设寄存器-数据宽度(此处为1byte)
	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//指定外设地址寄存器-是否递增
	DMA_InitStruct.DMA_MemoryBaseAddr = Dest;//存储器-起始地址
	DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器-数据宽度
	DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存储器-是否递增
	DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设站点是源还是目标
	DMA_InitStruct.DMA_BufferSize = Size;//传递Size个大小为<数据宽度>的数据
	DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//指定DMAy通道的工作模式(是否要自动重装)
	DMA_InitStruct.DMA_M2M = DMA_M2M_Enable;//是否使用软件触发(存储器到存储器)
	DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的软件优先级
	DMA_Init(DMA1_Channel1, &DMA_InitStruct);
	
	DMA_Cmd(DMA1_Channel1, DISABLE);//使能或失能DMA
}

void MyDMA_Transfer(void)//调用函数则开始转运
{
	DMA_Cmd(DMA1_Channel1, DISABLE);//失能DMA
	DMA_SetCurrDataCounter(DMA1_Channel1, Temp_Size);//设置DMA当前数据计数器的值
	DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMA
	
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET)//获取DMA标志状态(等待转运完成)
	DMA_ClearFlag(DMA1_FLAG_TC1);//清除DMA标志位
}

DMA+AD多通道

1. ADC单次扫描+DMA数据转运
#include "stm32f10x.h"                  // Device header
//模拟量转换为数字量
//AD多通道(ADC扫描模式+DMA数据转运)

uint16_t Dest_Data[4];

void AD_Init(void)
{	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//开启DMA时钟
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟(72MHz/6=12MHz)
	
	//配置GPIO
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_41Cycles5);//配置ADC常规通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_41Cycles5);//配置ADC常规通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_41Cycles5);//配置ADC常规通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_41Cycles5);//配置ADC常规通道
	
	//配置ADC
	ADC_InitTypeDef ADC_InitStruct;
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//将ADC配置为独立或操作双模式
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发
	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//单次转换or连续转换
	ADC_InitStruct.ADC_ScanConvMode = ENABLE;//非扫描模式or扫描模式
	ADC_InitStruct.ADC_NbrOfChannel = 4;//指定要转换的ADC通道的数量
	ADC_Init(ADC1, &ADC_InitStruct);

	//配置DMA	
	DMA_InitTypeDef DMA_InitStruct;
	DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设寄存器-起始地址
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设寄存器-数据宽度(此处为1byte)
	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//指定外设地址寄存器-是否递增
	DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)Dest_Data;//存储器-起始地址
	DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器-数据宽度
	DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存储器-是否递增
	DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设站点是源还是目标
	DMA_InitStruct.DMA_BufferSize = 4;//传递Size个大小为<数据宽度>的数据
	DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//指定DMAy通道的工作模式(是否要自动重装)
	DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//是否使用软件触发(存储器到存储器)
	DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的软件优先级
	DMA_Init(DMA1_Channel1, &DMA_InitStruct);
	
	
	ADC_DMACmd(ADC1, ENABLE);//开启ADC的DMA功能
	DMA_Cmd(DMA1_Channel1, ENABLE);//使能或失能DMA
	ADC_Cmd(ADC1, ENABLE);//开启ADC
	
	//ADC复位+校准
	ADC_ResetCalibration(ADC1);//重置ADC校准,准备进行校准操作
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//获取ADC重置校准状态,检查是否完成
	ADC_StartCalibration(ADC1);//开始ADC校准
	while(ADC_GetCalibrationStatus(ADC1) == SET);//获取ADC校准状态,检查是否完成
}

void AD_GetValue(void)//获取模拟值
{
	//选择不同的通道或取ADC值
	DMA_Cmd(DMA1_Channel1, DISABLE);//失能DMA
	DMA_SetCurrDataCounter(DMA1_Channel1, 4);//设置DMA当前数据计数器的值
	DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMA
	
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开启软件启动ADC转换,用于软件触发转换--启动
	
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET)//获取DMA标志状态(等待转运完成)
	DMA_ClearFlag(DMA1_FLAG_TC1);//清除DMA标志位

}
2. ADC连续扫描+DMA循环转运
#include "stm32f10x.h"                  // Device header
//模拟量转换为数字量
//AD多通道(ADC连续扫描+DMA循环转运)

uint16_t Dest_Data[4];

void AD_Init(void)
{	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//开启DMA时钟
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟(72MHz/6=12MHz)
	
	//配置GPIO
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_41Cycles5);//配置ADC常规通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_41Cycles5);//配置ADC常规通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_41Cycles5);//配置ADC常规通道
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_41Cycles5);//配置ADC常规通道
	
	//配置ADC
	ADC_InitTypeDef ADC_InitStruct;
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//将ADC配置为独立或操作双模式
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发
	ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//单次转换or连续转换**********************************************
	ADC_InitStruct.ADC_ScanConvMode = ENABLE;//非扫描模式or扫描模式
	ADC_InitStruct.ADC_NbrOfChannel = 4;//指定要转换的ADC通道的数量
	ADC_Init(ADC1, &ADC_InitStruct);

	//配置DMA	
	DMA_InitTypeDef DMA_InitStruct;
	DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设寄存器-起始地址
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设寄存器-数据宽度(此处为1byte)
	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//指定外设地址寄存器-是否递增
	DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)Dest_Data;//存储器-起始地址
	DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器-数据宽度
	DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存储器-是否递增
	DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设站点是源还是目标
	DMA_InitStruct.DMA_BufferSize = 4;//传递Size个大小为<数据宽度>的数据
	DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;//指定DMAy通道的工作模式(是否要自动重装)******************************
	DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//是否使用软件触发(存储器到存储器)
	DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的软件优先级
	DMA_Init(DMA1_Channel1, &DMA_InitStruct);
	
	ADC_DMACmd(ADC1, ENABLE);//开启ADC的DMA功能
	DMA_Cmd(DMA1_Channel1, ENABLE);//使能或失能DMA
	ADC_Cmd(ADC1, ENABLE);//开启ADC
	
	//ADC复位+校准
	ADC_ResetCalibration(ADC1);//重置ADC校准,准备进行校准操作
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//获取ADC重置校准状态,检查是否完成
	ADC_StartCalibration(ADC1);//开始ADC校准
	while(ADC_GetCalibrationStatus(ADC1) == SET);//获取ADC校准状态,检查是否完成

	ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开启软件启动ADC转换,用于软件触发转换--启动********************************
}
//*****************************************************************************************

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

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

相关文章

IoT平台在设备远程运维中的应用

IoT平台是物联网技术的核心组成部分&#xff0c;实现了设备、数据、应用之间的无缝连接与交互。通过提供统一的设备管理、数据处理、安全监控等功能&#xff0c;IoT平台为企业构建了智能化、可扩展的物联网生态系统。在设备远程运维领域&#xff0c;IoT平台发挥着至关重要的作用…

浅谈云计算05 | 云存储等级及其接口工作原理

一、云存储设备 在当今数字化飞速发展的时代&#xff0c;数据已然成为个人、企业乃至整个社会的核心资产。从日常生活中的珍贵照片、视频&#xff0c;到企业运营里的关键业务文档、客户资料&#xff0c;数据量呈爆炸式增长。面对海量的数据&#xff0c;如何安全、高效且便捷地存…

网络传输层TCP协议

传输层TCP协议 1. TCP协议介绍 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一个要对数据的传输进行详细控制的传输层协议。 TCP 与 UDP 的不同&#xff0c;在于TCP是有连接、可靠、面向字节流的。具体来说&#xff0c;TCP设置了一大…

【Linux系列】`find / -name cacert.pem` 文件搜索

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【论文笔记】Sign Language Video Retrieval with Free-Form Textual Queries

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Sign Language Video Retr…

Observability:将 OpenTelemetry 添加到你的 Flask 应用程序

作者&#xff1a;来自 Elastic jessgarson 待办事项列表可以帮助管理与假期计划相关的所有购物和任务。使用 Flask&#xff0c;你可以轻松创建待办事项列表应用程序&#xff0c;并使用 Elastic 作为遥测后端&#xff0c;通过 OpenTelemetry 对其进行监控。 Flask 是一个轻量级…

网站目录权限加固

说明 在一个入侵链路中&#xff0c;往往是利用某个安全漏洞&#xff0c;向服务器写入或上传一个webshell&#xff08;后门&#xff09;&#xff0c;再通过webshell提权或进行后续渗透入侵行为。 这个过程中&#xff0c;获取webshell是最关键最重要的一个步骤&#xff0c;如能在…

qt QPainter setViewport setWindow viewport window

使用qt版本5.15.2 引入viewport和window目的是用于实现QPainter画出来的内容随着窗体伸缩与不伸缩两种情况&#xff0c;以及让QPainter在widget上指定的区域(viewport)进行绘制/渲染&#xff08;分别对应下方demo1&#xff0c;demo2&#xff0c;demo3&#xff09;。 setViewpo…

一些计算机零碎知识随写(25年1月)-1

我原以为世界上有技术的那批人不会那么闲&#xff0c;我错了&#xff0c;被脚本真实了。 今天正隔着画画呢&#xff0c;手机突然弹出几条安全告警通知。 急忙打开服务器&#xff0c;发现问题不简单&#xff0c;直接关服务器重装系统..... 首先&#xff0c;不要认为小网站&…

分布式锁Redisson详解,Redisson如何解决不可重入,不可重试,超时释放,主从一致问题的分析解决(包括源码简单分析)

目录 1. Redisson解决不可重入锁导致的死锁问题 2. 不可重试问题 Pub/Sub 的优势 锁释放的发布逻辑 3. 超时释放的问题 1. 锁的超时释放机制背景 2. 源码分析 2.1 锁的获取 2.2 看门狗机制 2.3 看门狗续期实现 2.4 手动设置锁的过期时间 总结 4. 主从一致性 问题…

【微服务】面试 4、限流

微服务限流技术总结 一、微服务业务面试题引入 在微服务业务面试中&#xff0c;限流是重要考点&#xff0c;常与分布式事务、分布式服务接口幂等解决方案、分布式任务调度等一同被考查。面试官一般会询问项目中是否实施限流及具体做法&#xff0c;回答需涵盖限流原因、采用的方…

爬虫基础之爬取歌曲宝歌曲批量下载

声明&#xff1a;本案列仅供学习交流使用 任何用于非法用途均与本作者无关 需求分析: 网站:邓紫棋-mp3在线免费下载-歌曲宝-找歌就用歌曲宝-MP3音乐高品质在线免费下载 (gequbao.com) 爬取 歌曲名 歌曲 实现歌手名称下载所有歌曲 本案列所使用的模块 requests (发送…

树莓派-5-GPIO的应用实验之GPIO的编码方式和SDK介绍

文章目录 1 GPIO编码方式1.1 管脚信息1.2 使用场合1.3 I2C总线1.4 SPI总线2 RPI.GPIO2.1 PWM脉冲宽度调制2.2 静态函数2.2.1 函数setmode()2.2.2 函数setup()2.2.3 函数output()2.2.4 函数input()2.2.5 捕捉引脚的电平改变2.2.5.1 函数wait_for_edge()2.2.5.2 函数event_detect…

Scala分布式语言二(基础功能搭建、面向对象基础、面向对象高级、异常、集合)

章节3基础功能搭建 46.函数作为值三 package cn . itbaizhan . chapter03 // 函数作为值&#xff0c;函数也是个对象 object FunctionToTypeValue { def main ( args : Array [ String ]): Unit { //Student stu new Student() /*val a ()>{"GTJin"…

CVE-2025-22777 (CVSS 9.8):WordPress | GiveWP 插件的严重漏洞

漏洞描述 GiveWP 插件中发现了一个严重漏洞&#xff0c;该插件是 WordPress 最广泛使用的在线捐赠和筹款工具之一。该漏洞的编号为 CVE-2025-22777&#xff0c;CVSS 评分为 9.8&#xff0c;表明其严重性。 GiveWP 插件拥有超过 100,000 个活跃安装&#xff0c;为全球无数捐赠平…

支付宝租赁小程序提升租赁行业效率与用户体验

内容概要 在当今数字化的世界里&#xff0c;支付宝租赁小程序的出现构建了一种新的租赁模式&#xff0c;使得用户在使用过程中体验更加流畅。想象一下&#xff0c;你在寻找租赁服务时&#xff0c;不再需要繁琐的流程和冗长的等待&#xff0c;只需通过手机轻松点击几下&#xf…

关于使用FastGPT 摸索的QA

近期在通过fastGPT&#xff0c;创建一些基于特定业务场景的、相对复杂的Agent智能体应用。 工作流在AI模型的基础上&#xff0c;可以定义业务逻辑&#xff0c;满足输出对话之外的需求。 在最近3个月来的摸索和实践中&#xff0c;一些基于经验的小问题点&#xff08;自己也常常…

服务器/电脑与代码仓gitlab/github免密连接

git config --global user.name "xxxx" git config --global user.email "xxxxxx163.com" #使用注册GitHub的邮箱 生成对应邮箱的密码对 ssh-keygen -t rsa -b 4096 -C "xxxxxx163.com" 把公钥id_rsa.pub拷贝到github中 Setting----->…

【C语言系列】函数递归

函数递归 一、递归是什么&#xff1f;1.1尾递归 二、递归的限制条件三、递归举例3.1举例一&#xff1a;求n的阶乘3.2举例二&#xff1a;顺序打印一个整数的每一位 四、递归与迭代4.1举例三&#xff1a;求第n个斐波那契数 五、拓展学习青蛙跳台问题 一、递归是什么&#xff1f; …

springboot 默认的 mysql 驱动版本

本案例以 springboot 3.1.12 版本为例 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.12</version><relativePath/> </parent> 点击 spring-…