24:【stm32】DMA数据搬运

news2024/11/15 15:34:58

DMA数据搬运

  • 1、DMA的简介
  • 2、STM32中的DMA结构
  • 3、案列
    • 3.1、将数组DataA中的数据搬运到DataB中
    • 3.2、ADC扫描模式+DMA

1、DMA的简介

DMA是直接存储器存取,它可以提供外设寄存器和存储器,存储器与存储器之间的高速数据的传输,无需CPU的干预,这样节省了CPU的资源。简单来说DMA就是数据的搬运工

STM32中的存储器:
在这里插入图片描述DMA的3种搬运方式:
1.存储器------>存储器(数据的拷贝)
在这里插入图片描述

2.存储器------>外设(将某数据写入串口寄存器TDR)
在这里插入图片描述

3.外设--------->存储器(将串口接收寄存器RDR的数据搬运到内存,避免数据的覆盖)
在这里插入图片描述

2、STM32中的DMA结构

在单片机中12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道)。每个通道都支持软件触发和特定的硬件触发。而在STM32F103C8T6中只有DMA1(7个通道),且挂载在AHB总线上面。
在这里插入图片描述
由于Flash存储是只读存储器,所以DMA转运的数据不能存储在Flash存储器里面,这是不允许的,所以只能存储在SRAM存储器里面

  • DMA请求
    DMA请求就是DMA触发,由如下图可知,每个通道的硬件请求都是特定的,比如:TIM2_CH1的请求不能通过DMA1的通道2对DMA进行触发。但是每个通道都有软件请求。所以每个通道都支持软件触发和特定的硬件触发。软件触发一般用在存储器------>存储器(数据的拷贝)。
    在这里插入图片描述
    在这里插入图片描述

  • DMA基本结构细节
    由下图所示:外设寄存器和存储器里面有起始地址,数据宽度。是否自增。
    1.起始地址:数据从哪里转运到哪里
    2.数据宽度:每次转运的数据有多大(Byte(uint8_t)/HalfWord(uint16_t)/Word(uint32_t))
    3.地址是否自增:第一次转运完成后,进行下一次转运时是否发生地址的偏移。
    4.传输计数器:总共需要几次转运,是一个自减的计数器。为0就不转运了。
    【注】传输计数器变为0后,自增的地址也会恢复到起始地址。
    5.自动重装器:传输计数器减为0后,是否恢复初值,又开始转运。如果没有开启自动重装器。
    6.M2M:触发控制,为1时就是软件触发,为0就是硬件触发。
    【注】软件触发一般用于存储器到存储器的转运,触发一次,以最快的要求计数器清0。所以,软件触发不能和自动重装器同时用

7.DMA开始转运的3大调节:
①DMA开关必须关闭
②计数器必修大于0
③必须要有触发源

如果转运完成,计数器清0 。想要进行第二次转运,则想要关闭DMA,写入计数器次数,然后给触发源,开启DMA。

在这里插入图片描述

3、案列

3.1、将数组DataA中的数据搬运到DataB中

在这里插入图片描述
与之相关的标准库编程接口:
在这里插入图片描述

我们先查看变量存储在哪个存储器当中?

#include "stm32f10x.h"                 
#include "OLED.h"

uint8_t a = 10;
int main(void)
{
	OLED_Init();
	OLED_Clear();
	
	OLED_ShowNum(1,1,a,2);
	OLED_ShowHexNum(2,1,(uint32_t)&a,8);
	while(1)
	{
		
	}
}

OLED屏幕上面显示的是:
10
20000000/ /变量的地址为0x20000000,代表变量存储在SRAM存储器中

我们查看常量存储在哪个存储器当中?

#include "stm32f10x.h"                 
#include "OLED.h"

const uint8_t a = 10;
int main(void)
{
	OLED_Init();
	OLED_Clear();
	
	OLED_ShowNum(1,1,a,2);
	OLED_ShowHexNum(2,1,(uint32_t)&a,8);
	while(1)
	{
		
	}
}

OLED屏幕上面显示的是:
10
08000E40/ /变量的地址为0x08000E40,代表常量存储在Flash存储器中

数据拷贝的代码如下:
MyDMA.c文件的代码如下:

#include "stm32f10x.h"                  // Device header

uint8_t My_Size;

void MyDMA_Init(uint32_t ADDrA,uint32_t ADDrB,uint8_t Size)
{
	My_Size = Size;
	//1.开启时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	
	//2.DMA1的通道1的初始化,软件触发非自动重装
	DMA_InitTypeDef DMA_InitStruct;
	DMA_InitStruct.DMA_PeripheralBaseAddr = ADDrA;//外设站点的起始地址
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//数据宽度,8位
	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//是否自增,这里选择自增
	
	DMA_InitStruct.DMA_MemoryBaseAddr = ADDrB;//存储器的起始地址
	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;//传输计数器
	DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//是否自动重装,这里选择不自动重装
	DMA_InitStruct.DMA_M2M = DMA_M2M_Enable;//是否软件触发
	DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//优先级
	
	DMA_Init(DMA1_Channel1,&DMA_InitStruct);//DMA1的通道1
	
	DMA_Cmd(DMA1_Channel1,DISABLE);
}

void My_DMA_TransFer(void)//DMA开启搬运的函数
{
	DMA_Cmd(DMA1_Channel1,DISABLE);//关闭DMA
	DMA_SetCurrDataCounter(DMA1_Channel1,My_Size);//写入传输计数器的值
	DMA_Cmd(DMA1_Channel1,ENABLE);//开启DMA
	
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//等待搬运完成
	DMA_ClearFlag(DMA1_FLAG_TC1);//手动清除标志位
}

主程序文件的代码如下:

/*
	存储器------>存储器(数据的拷贝)DMA的使用
*/

#include "stm32f10x.h"                 
#include "OLED.h"
#include "Delay.h"
#include "MyDMA.h"

uint8_t DataA[] = {01,02,03,04};
uint8_t DataB[] = {0,0,0,0};

int main(void)
{
	OLED_Init();
	OLED_Clear();
	MyDMA_Init((uint32_t)DataA,(uint32_t)DataB,4);
	
	OLED_ShowString(1,1,"DataA:");
	OLED_ShowString(3,1,"DataB:");
	
	OLED_ShowHexNum(1,8,(uint32_t)DataA,8);//显示DataA的地址
	OLED_ShowHexNum(3,8,(uint32_t)DataB,8);//显示DataB的地址
	
//	OLED_ShowNum(2,1,DataA[0],2);
//	OLED_ShowNum(2,4,DataA[1],2);
//	OLED_ShowNum(2,7,DataA[2],2);
//	OLED_ShowNum(2,10,DataA[3],2);
	
//	OLED_ShowNum(4,1,DataB[0],2);
//	OLED_ShowNum(4,4,DataB[1],2);
//	OLED_ShowNum(4,7,DataB[2],2);
//	OLED_ShowNum(4,10,DataB[3],2);
	while(1)
	{
		OLED_ShowNum(2,1,DataA[0],2);
		OLED_ShowNum(2,4,DataA[1],2);
		OLED_ShowNum(2,7,DataA[2],2);
		OLED_ShowNum(2,10,DataA[3],2);
		Delay_ms(1000);
		
		My_DMA_TransFer();//开始搬运
		
		OLED_ShowNum(4,1,DataB[0],2);
		OLED_ShowNum(4,4,DataB[1],2);
		OLED_ShowNum(4,7,DataB[2],2);
		OLED_ShowNum(4,10,DataB[3],2);
		
		DataA[0]++;
		DataA[1]++;
		DataA[2]++;
		DataA[3]++;
		
		Delay_ms(1000);
	}
}

3.2、ADC扫描模式+DMA

在这里插入图片描述
ADC单次扫描+DMA不自动重装模式
ADC.c文件的代码如下:
代码如下:

#include "stm32f10x.h"                  // Device header

uint16_t AD_Value[4];

void AD_Init(void)
{
	//1.开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	
	//2.对ADC时钟进行分频
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72MHZ/6 = 12MHz
	
	//3.对通道1(PA0)进行配置
	GPIO_InitTypeDef GPIOInitStruct;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入模式,ADC的专属模式
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;

	GPIO_Init(GPIOA,&GPIOInitStruct);
	
	//4.对ADC规则组进行配置
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//ADC几,通道,序列,采样时间
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
	
	//5.初始化ADC 单次扫描模式
	ADC_InitTypeDef ADC_InitStruct;
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//工作模式:独立模式/双ADC模式,这里的独立模式
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//ADC触发选择,选择软件触发
	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//连续/单次模式,这里选择单次
	ADC_InitStruct.ADC_ScanConvMode = ENABLE;//扫描/非扫描,这里选择扫描
	ADC_InitStruct.ADC_NbrOfChannel = 4;//在扫描模式下的盒子数目
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐,右对齐
	
	ADC_Init(ADC1,&ADC_InitStruct);
	
	//6.DMA1的通道1的初始化,硬件触发非自动重装
	DMA_InitTypeDef DMA_InitStruct;
	DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设站点的起始地址,这里选择DR寄存器
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度,16位
	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//是否自增,这里选择不自增,
														  //因为是将DR数据寄存器里面的数据挪出来,始终是DR寄存器
	
	DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)AD_Value;//存储器的起始地址
	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;//传输计数器
	DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//是否自动重装,这里选择不自动重装
	DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//是否软件触发,这里选择硬件触发
	DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//优先级
	DMA_Init(DMA1_Channel1,&DMA_InitStruct);//DMA1的通道1
	
	//6.开启ADC电源
	ADC_Cmd(ADC1,ENABLE);
	
	//7.校准
	ADC_ResetCalibration(ADC1);//将校准复位,给CR2_RSTCAL置1,进行复位
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//复位完成,硬件置0
	ADC_StartCalibration(ADC1);//开始校准,给CR2_CAL置1
	while(ADC_GetCalibrationStatus(ADC1) == SET);//校准完成,硬件置0
	
	//8.开启搬运
	ADC_DMACmd(ADC1 ,ENABLE);//开启ADC1硬件触发源,当一个通道转运完成后,就会自动请求DMA
	DMA_Cmd(DMA1_Channel1,ENABLE);
}

void AD_GetValue(void)//ADC触发函数并数据搬运
{
	DMA_Cmd(DMA1_Channel1,DISABLE);//关闭DMA
	DMA_SetCurrDataCounter(DMA1_Channel1,4);//写入传输计数器的值
	DMA_Cmd(DMA1_Channel1,ENABLE);//开启DMA
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发
	
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//等待搬运完成
	DMA_ClearFlag(DMA1_FLAG_TC1);//手动清除标志位
}

主程序文件的代码:

/*
	ADC+DMA的使用
*/

#include "stm32f10x.h"                 
#include "OLED.h"
#include "Delay.h"
#include "ADC.h"


int main(void)
{
	OLED_Init();
	OLED_Clear();
	AD_Init();

	OLED_ShowString(1,1,"AD0:");
	OLED_ShowString(2,1,"AD1:");
	OLED_ShowString(3,1,"AD2:");
	OLED_ShowString(4,1,"AD3:");
	
	while(1)
	{
		AD_GetValue();//转换并搬运,循环调用。
		
		OLED_ShowNum(1,5,AD_Value[0],4);//显示通道1采样到的数据
		OLED_ShowNum(2,5,AD_Value[1],4);
		OLED_ShowNum(3,5,AD_Value[2],4);
		OLED_ShowNum(4,5,AD_Value[3],4);
		Delay_ms(100);
	}
}

ADC连续扫描+DMA自动重装模式
ADC.c文件的代码如下:

#include "stm32f10x.h"                  // Device header

uint16_t AD_Value[4];

void AD_Init(void)
{
	//1.开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	
	//2.对ADC时钟进行分频
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72MHZ/6 = 12MHz
	
	//3.对通道1(PA0)进行配置
	GPIO_InitTypeDef GPIOInitStruct;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入模式,ADC的专属模式
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;

	GPIO_Init(GPIOA,&GPIOInitStruct);
	
	//4.对ADC规则组进行配置
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//ADC几,通道,序列,采样时间
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
	
	//5.初始化ADC,连续扫描模式
	ADC_InitTypeDef ADC_InitStruct;
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//工作模式:独立模式/双ADC模式,这里的独立模式
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//ADC触发选择,选择软件触发
	ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//连续/单次模式,这里选择连续
	ADC_InitStruct.ADC_ScanConvMode = ENABLE;//扫描/非扫描,这里选择非扫描
	ADC_InitStruct.ADC_NbrOfChannel = 4;//在扫描模式下的盒子数目
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐,右对齐
	
	ADC_Init(ADC1,&ADC_InitStruct);
	
	//6.DMA1的通道1的初始化,自动重装模式
	DMA_InitTypeDef DMA_InitStruct;
	DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设站点的起始地址,这里选择DR寄存器
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度,16位
	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//是否自增,这里选择不自增,
																																//因为是将DR数据寄存器里面的数据挪出来,始终是DR寄存器
	
	DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)AD_Value;//存储器的起始地址
	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;//传输计数器
	DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;//是否自动重装,这里选择自动重装
	DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//是否软件触发,这里选择硬件触发
	DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//优先级
	DMA_Init(DMA1_Channel1,&DMA_InitStruct);//DMA1的通道1
	
	//6.开启ADC电源
	ADC_Cmd(ADC1,ENABLE);
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发
	//7.校准
	ADC_ResetCalibration(ADC1);//将校准复位,给CR2_RSTCAL置1,进行复位
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//复位完成,硬件置0
	ADC_StartCalibration(ADC1);//开始校准,给CR2_CAL置1
	while(ADC_GetCalibrationStatus(ADC1) == SET);//校准完成,硬件置0
	
	//8.开启搬运
	ADC_DMACmd(ADC1 ,ENABLE);//开启ADC1硬件触发源
	DMA_Cmd(DMA1_Channel1,ENABLE);
}

void AD_GetValue(void)//ADC触发函数并数据搬运
{
//	DMA_Cmd(DMA1_Channel1,DISABLE);//关闭DMA
//	DMA_SetCurrDataCounter(DMA1_Channel1,4);//写入传输计数器的值
//	DMA_Cmd(DMA1_Channel1,ENABLE);//开启DMA
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//等待搬运完成
	DMA_ClearFlag(DMA1_FLAG_TC1);//手动清除标志位
}

主程序文件的代码:

/*
	ADC+DMA的使用
*/

#include "stm32f10x.h"                 
#include "OLED.h"
#include "Delay.h"
#include "ADC.h"


int main(void)
{
	OLED_Init();
	OLED_Clear();
	AD_Init();

	OLED_ShowString(1,1,"AD0:");
	OLED_ShowString(2,1,"AD1:");
	OLED_ShowString(3,1,"AD2:");
	OLED_ShowString(4,1,"AD3:");
	
	while(1)
	{
		AD_GetValue();//等待转运并搬运完成
		
		OLED_ShowNum(1,5,AD_Value[0],4);
		OLED_ShowNum(2,5,AD_Value[1],4);
		OLED_ShowNum(3,5,AD_Value[2],4);
		OLED_ShowNum(4,5,AD_Value[3],4);
		Delay_ms(100);
		
	}
}

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

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

相关文章

通配符证书的申请及配置教程

在当今高度互联的世界里,网站和应用程序需要确保其数据传输的安全性,以保护用户的隐私和敏感信息不被窃取。为此,HTTPS协议成为了标准配置,而SSL/TLS证书则是实现这一安全协议的重要组成部分。特别地,对于那些运营着多…

asp.net core web api项目添加自定义中间件

前言 在asp.net core web api项目中,默认提供了很多的中间件,比如访问静态文件中间件UseStaticFiles,跨域配置中间件UseCors,路由中间件UseRouting,身份验证中间件UseAuthentication。 那么如何添加一些自定义的中间件呢。 需求…

【数据结构】单链表功能的实现

目录 1.链表的概念及结构 2.单链表功能的实现 2.1打印单链表 2.2创建节点 2.3单链表尾插 2.3单链表头插 2.5单链表尾删 2.6单链表头删 2.7单链表的查找 2.8在指定位置之前插入数据 2.9在指定位置之后插入数据 2.10删除pos节点 2.11删除pos之后的节点 2.12销毁链表…

快专利与慢专利:速度与质量的天平

在当今快速发展的科技时代,专利成为了创新成果的重要保护手段。然而,不同的创新有着不同的节奏,由此也产生了“快专利”与“慢专利”之分。快专利以其迅速的申请和应用,为创新者抢占市场先机;慢专利则凭借深度的研发和…

Django Admin后台从一个页面同时编辑多个模型

要从Django Admin后台一个页面同时编辑多个对象,我们需要使用内联。 假设你有一个Category模型,并且需要在Admin后台Category编辑页面,同时编辑Villain模型。你可以在admin.py中使用内联: class VillainInline(admin.StackedInl…

EDIUS X 10.34.9631 视频剪辑软件 下载 包含安装说明

下载地址(资源制作整理不易,下载使用需付费,不能接受请勿浪费时间下载) 链接:https://pan.baidu.com/s/1P2wKxVcSx5WzAtHXCaAp5A?pwd227i 提取码:227i

自动控制:鲁棒控制的原理和设计

自动控制:鲁棒控制的原理和设计 引言 在实际控制系统中,由于模型不确定性、外部扰动、参数变化等因素,传统的控制方法难以保证系统在各种情况下的性能。这时,鲁棒控制(Robust Control)应运而生。鲁棒控制…

Vue(十一)默认插槽、具名插槽、作用域插槽

文章目录 一、需求二、插槽1. 默认插槽2. 具名插槽3. 作用域插槽 一、需求 有三个Category组件&#xff0c;展示不同的内容。 需求&#xff1a;美食模块需要展示图片&#xff0c;游戏模块还是文字&#xff0c;电影模块展示预告片。 <!--App组件--> <template>&l…

四款录音神器,你选对了吗?

在快节奏的现代生活中&#xff0c;我们经常需要处理大量的录音文件&#xff0c;如会议记录、采访、讲座等。为了更高效地处理这些信息&#xff0c;录音转文字工具变得越来越重要。本文将为大家介绍四款常用的录音转文字工具&#xff0c;并分享使用体验。 一、福昕PDF转换器 直…

Matlab 并联双振子声子晶体梁结构带隙特性研究

参考文献&#xff1a;吴旭东,左曙光,倪天心,等.并联双振子声子晶体梁结构带隙特性研究[J].振动工程学报,2017,30(01):79-85. 为使声子晶体结构实现范围更宽的多带隙特性&#xff0c;基于单振子型声子晶体结构弯曲振动带隙频率范围窄的局 限&#xff0c;提出了一种双侧振子布置…

电商智能分析:阿里巴巴商品详情API返回值的挖掘与利用

电商智能分析是利用大数据和机器学习技术来深入理解用户行为、商品趋势以及市场变化的过程。阿里巴巴商品详情API作为获取商品详细信息的重要工具&#xff0c;其返回值中蕴含了丰富的数据&#xff0c;可以通过挖掘和利用这些数据来进行智能分析。下面&#xff0c;我将提供一个基…

美畅物联丨科技赋能校车安全:智慧监控管理系统的创新应用

1、背景 1.1应用需求 孩子&#xff0c;作为国家未来的希望之星和民族发展的潜力所在&#xff0c;其安全与健康向来都是社会瞩目的核心要点。校车&#xff0c;作为孩子们日常出行的关键交通载体&#xff0c;其安全性更是时刻牵动着每一个家庭的敏感神经。然而&#xff0c;不可…

TensorFlow1和TensorFlow2介绍

目录 一.安装 二.TensorFlow结构分析 数据流图介绍 三.图与TensorBoard 1.图结构 2.图的相关操作 3.自定义图 4.开启会话Session中指定使用那个图 四.TensorBoard&#xff1a;可视化 1.数据序列化-events文件 2.启动TensorBoard 3.tensorflow2中使用tensorboard 1.…

【编程基础C++】素数判定、最小公倍数与最大公因数的实现方法

文章目录 素数法一法二 最大公因数辗转相除法另一写法 最小公倍数直接枚举法根据GCD算LCM 素数 素数 是指大于1的自然数&#xff0c;且只能被1和自身整除。例如&#xff0c;2、3、5和7都是素数。它们在数学中非常重要&#xff0c;因为任何大于1的自然数都可以唯一地表示为素数…

【类模板】成员函数模板

一、成员函数模板的基本含义 不管是普通的类&#xff0c;还是类模板&#xff0c;都可以为其定义成员函数模板&#xff0c;以下的情况就是类模板和成员函数模板都有各自独立的一套参数&#xff1a; template<typename T1> class A { public:T1 m_ic;static constexpr int…

电力104规约

对象性质十进制十六进制数量适用报文类型ASDU遥测1793~2304701H~900H512*9、11、21、34、35遥信1~10241H~400H1024*1、3、20、30、31遥控2817~2944B01H~B80H128*45、46遥调2945~3072B81H~C00 H128*47APCI 应用规约控制信息; ASDU 应用服务数据单元; APDU 应用规约数据单元;…

CountDownLatch的应用与原理

一、什么是CountDownLatch CountDownLatch是具有synchronized机制的一个工具&#xff0c;目的是让一个或者多个线程等待&#xff0c;直到其他线程的一系列操作完成。 CountDownLatch初始化的时候&#xff0c;需要提供一个整形数字&#xff0c;数字代表着线程需要调用countDow…

K8s系列之:解释Kubernetes Operators

K8s系列之&#xff1a;解释Kubernetes Operators 什么是控制器循环&#xff1f;Kubernetes Operator是如何工作的&#xff1f;如何添加自定义资源自定义资源定义Kubernetes Operators&#xff1a;案例研究 你是否曾想过&#xff0c;Site Reliability Engineering&#xff08;SR…

【优化】Nginx 配置页面请求不走缓存 浏览器页面禁用缓存

【优化】Nginx 配置页面请求不走缓存 禁用缓存 目录 【优化】Nginx 配置页面请求不走缓存 禁用缓存 对所有请求禁用缓存 对特定location禁用缓存 注意事项 全局禁用缓存 要配置Nginx使其不缓存内容&#xff0c;通常是指禁止浏览器缓存响应的内容&#xff0c;或者是在代理…

Qt 模仿企业微信图标实现按钮图片文字上下结构

简述 实现类似企业微信左侧导航栏的上下结构的按钮 效果图 可以用2种方案实现&#xff0c;2种最终效果图如下&#xff1a; 方案1 QToolButton 实现 ui.toolButton->setFixedSize(50, 50);ui.toolButton->setCheckable(true);ui.toolButton->setAutoExclusive(true);…