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

【STM32F103C8T6】DMA数据转运ADC多通道

前言

本节为代码部分,知识点在这【江协科技STM32】DMA直接存储器存储-学习笔记-CSDN博客

查看数据地址: 

uint8_t aa = 0x88;int main(void)
{OLED_Init();OLED_ShowHexNum(1,1,aa,4);		//显示十六进制数	OLED_ShowHexNum(2,1,(uint32_t)&aa,8);while(1){}
}

或者在变量前面加一个const,在C语言中,const关键字用来定义常量。通过在变量声明前加上const关键字,可以确保该变量的值在程序执行过程中只能读,不会被修改。这有助于提高代码的可读性和可维护性,同时也可以帮助编译器进行优化。常见的用法包括定义常量值、声明函数参数为常量、声明指针指向常量等。在STM32中,Flash存储器也是只能读不能写的,所以被const定义的变量时存储在Flash存储器中的。这个变量的值只能在定义的时候给。

 

如果把下面的const去掉,功能不会受到任何影响,只是SRAM存储器会被占用大片空间用来存储这些数据。这种数据比较多的、占用存储空间大的、一般不用修改的,一般用const定义变量,存储到Flash存储器中,为SRAM存储器节省内存。

 

查看外设寄存器ADC1的DR寄存器:

int main(void)
{OLED_Init();OLED_ShowHexNum(2,1,(uint32_t)&ADC1->DR,8);while(1){}
}

 ADC1的起始地址:4001 2400

 ADC_DR寄存器的地址偏移是4C

ADC1的起始地址为4001 2400,ADC_DR寄存器的地址偏移是4C,所以ADC1的DR地址就是4001 244C。想算某个寄存器的地址,先查一下寄存器所在外设的起始地址,然后再在外设寄存器的总表里查一下偏移, 起始地址+偏移就是外设地址。 

 用上面的代码就可查看对应的起始地址:

数据转运+DMA  

 接线图

 DMA初始化

DMA结构框图 

 

 具体步骤:

①RCC开启DMA时钟

②调用DMA_Init()函数初始化各个参数

③使能DMA

uint16_t HerDMA_Size;		//定义全局变量,用于记住Init函数的Size,供Transfer函数使用/*** 函    数:DMA初始化* 参    数:Addre1 原数组的首地址* 参    数:Addre2 目的数组的首地址* 参    数:Size 转运的数据大小(转运次数)* 返 回 值:无*/
void HerDMA_Init(uint32_t Addre1,uint32_t Addre2,uint16_t Size)
{HerDMA_Size = Size;		//将Size写入到全局变量,记住参数SizeRCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr =Addre1;					//外设基地址,给定形参Addre1DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Byte;//外设数据宽度,选择字节DMA_InitStructure.DMA_PeripheralInc =DMA_PeripheralInc_Enable;	//外设地址自增,选择使能DMA_InitStructure.DMA_MemoryBaseAddr =Addre2;					//存储器基地址,给定形参Addre2DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_Byte;  //存储器数据宽度,选择字节DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Enable;			//存储器地址自增,选择使能DMA_InitStructure.DMA_BufferSize =Size;							//转运的数据大小(转运次数)DMA_InitStructure.DMA_Priority =DMA_Priority_High;				//优先级选择DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralSRC;				//数据传输方向,选择由外设到存储器DMA_InitStructure.DMA_M2M =DMA_M2M_Enable;						//存储器到存储器,软件触发DMA_InitStructure.DMA_Mode =DMA_Mode_Normal;					//模式,选择正常模式,不循环DMA_Init(DMA1_Channel1,&DMA_InitStructure);DMA_Cmd(DMA1_Channel1,DISABLE);//这里先不给使能,初始化后不会立刻工作,等后续调用Transfer后,再开始
}

DMA转运三个条件: 

①传输计数器大于0

②触发源有触发信号

③DMA使能 

三个条件缺一不可 

函数解释:

void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) //启用或禁用AHB外设时钟,DMA是AHB总线的设备

void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)//初始化DMA 

参数说明
DMAy_Channelx其中y可以是1或2来选择DMA1或者DMA2,DMA1x取值为1 ~ 7,DMA2的x取值为1 ~ 5,表示选择DMA通道
DMA_InitStruct指向DMA_InitTypeDef结构体的指针包含指定DMA通道的配置信息。

DMA初始化结构定义: 

参数说明
DMA_PeripheralBaseAddr指定DMAy通道的外设基址
DMA_PeripheralDataSize指定外设数据宽度
DMA_PeripheralInc指定外设地址寄存器是否递增
DMA_MemoryBaseAddr指定DMAy通道的内存基址
DMA_MemoryDataSize内存数据宽度
DMA_MemoryInc指定内存地址寄存器是否递增
DMA_DIR指定外设是源还是目标,源就是外设站点到存储器,目标就是存储器到外设
DMA_BufferSize传输计数器,指定传输几次,直接赋值给传输计数器的寄存器
DMA_Mode指定DMAy通道的工作模式,循环模式还是正常模式
DMA_Priority指定DMAy通道的软件优先级,紧急转运就给高优先级
DMA_M2M指定是否在存储器到存储器的传输中使用DMAy通道,就是是否使用软件触发

DMA传输函数:

调用一次这个函数,DMA再次启动转运一次

给DMA赋值,必须先让DMA失能,在写入传输计数器之前,需要DMA暂停工作

void HerDMA_Transfer(void)
{DMA_Cmd(DMA1_Channel1,DISABLE);		//DMA失能,在写入传输计数器之前,需要DMA暂停工作DMA_SetCurrDataCounter(DMA1_Channel1,HerDMA_Size);//写入传输计数器,指定将要转运的次数DMA_Cmd(DMA1_Channel1,ENABLE);		//DMA使能,开始工作while (DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);	//等待DMA工作完成DMA_ClearFlag(DMA1_FLAG_TC1);						//清除工作完成标志位
}

void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber)//给我i传输计数器写数据 

参数说明
DMAy_Channelx其中y可以是1或2来选择DMA1或者DMA2,DMA1x取值为1 ~ 7,DMA2的x取值为1 ~ 5,表示选择DMA通道
DataNumber当前DMAy通道中的数据单元数转移

注意:该功能只能在禁用DMAy_Channelx时使用 

uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)//返回传输计数器的值,查看还剩多少数据没有转运 

参数说明
DMAy_Channelx其中y可以是1或2来选择DMA1或者DMA2,DMA1x取值为1 ~ 7,DMA2的x取值为1 ~ 5,表示选择DMA通道

返回值:当前DMAy通道中剩余数据单元的数量转移 

FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)//检查是否设置了指定的DMAy通道标志

参数说明
DMAy_FLAG指定要检查的标志。

返回值:DMAy_FLAG的新状态(SET或RESET) 

 

 转换完成后不要忘了清除标志位,这里需要手动清除标志位。

void DMA_ClearFlag(uint32_t DMAy_FLAG) //清除DMAy通道的挂起标志

参数说明
DMAy_FLAG指定要清除的标志

Main函数 

uint8_t DataA[] = {0x00,0x01,0x02,0x03};
uint8_t DataB[] = {0,0,0,0};int main(void)
{/*模块初始化*/OLED_Init();HerDMA_Init((uint32_t)DataA,(uint32_t)DataB,4);	//DMA初始化,把源数组和目的数组的地址传入/*显示静态字符串*/OLED_ShowString(1,1,"DataA:");OLED_ShowString(3,1,"DataB:");/*显示数组的首地址*/OLED_ShowHexNum(1,8,(uint32_t)DataA,8);OLED_ShowHexNum(3,8,(uint32_t)DataB,8);while(1){DataA[0]++;DataA[1]++;DataA[2]++;DataA[3]++;OLED_ShowHexNum(2,1,DataA[0],2);OLED_ShowHexNum(2,4,DataA[1],2);OLED_ShowHexNum(2,7,DataA[2],2);OLED_ShowHexNum(2,10,DataA[3],2);OLED_ShowHexNum(4,1,DataB[0],2);OLED_ShowHexNum(4,4,DataB[1],2);OLED_ShowHexNum(4,7,DataB[2],2);OLED_ShowHexNum(4,10,DataB[3],2);Delay_ms(1000);		//延时1s,观察转运前的现象HerDMA_Transfer();	//使用DMA转运数组,从DataA转运到DataBOLED_ShowHexNum(2,1,DataA[0],2);OLED_ShowHexNum(2,4,DataA[1],2);OLED_ShowHexNum(2,7,DataA[2],2);OLED_ShowHexNum(2,10,DataA[3],2);OLED_ShowHexNum(4,1,DataB[0],2);OLED_ShowHexNum(4,4,DataB[1],2);OLED_ShowHexNum(4,7,DataB[2],2);OLED_ShowHexNum(4,10,DataB[3],2);Delay_ms(1000);		//延时1s,观察转运后的现象}
}

结果图,DataA的数据会跳变转运到DataB ,这里地址相同 

main小细节: 

这里为什么强转为uint32_t, 是因为初始化函数的参数定义的是uint32_t,而初始化函数的参数定义的为什么是uint32_t,因为DMA初始化结构定义里面的参数也是uint32_t

 

拓展: 

如果想把Flash存储器里的数据转到SRAM存储器里面来,就可以在定义变量前加const

 

下面可以看到DataA的地址发生了改变,Flash存储器DataA的数据成功转到SRAM DataB的数据里

 

 第一个实验完成。

ADC扫描模式+DMA  

接线图 

 执行流程:

 ADC初始化

#include "stm32f10x.h"                  // Device headeruint16_t AD_Value[4];					//定义用于存放AD转换结果的全局数组/*** 函    数:AD初始化* 参    数:无* 返 回 值:无*/
void AD_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);		//开启DMA1的时钟/*设置ADC时钟*/RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA0、PA1、PA2和PA3引脚初始化为模拟输入/*规则组通道配置*/ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);	//规则组序列1的位置,配置为通道0ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);	//规则组序列2的位置,配置为通道1ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);	//规则组序列3的位置,配置为通道2ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);	//规则组序列4的位置,配置为通道3/*ADC初始化*/ADC_InitTypeDef ADC_InitStructure;											//定义结构体变量ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;							//模式,选择独立模式,即单独使用ADC1ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;						//数据对齐,选择右对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;			//外部触发,使用软件触发,不需要外部触发ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;							//连续转换,使能,每转换一次规则组序列后立刻开始下一次转换ADC_InitStructure.ADC_ScanConvMode = ENABLE;								//扫描模式,使能,扫描规则组的序列,扫描数量由ADC_NbrOfChannel确定ADC_InitStructure.ADC_NbrOfChannel = 4;										//通道数,为4,扫描规则组的前4个通道ADC_Init(ADC1, &ADC_InitStructure);											//将结构体变量交给ADC_Init,配置ADC1/*DMA初始化*/DMA_InitTypeDef DMA_InitStructure;											//定义结构体变量DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;				//外设基地址(uint32_t)&ADC1->DR=4001244CDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;	//外设数据宽度,选择半字,对应16为的ADC数据寄存器DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;			//外设地址自增,选择失能,始终以ADC数据寄存器为源DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;					//存储器基地址,给定存放AD转换结果的全局数组AD_ValueDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;			//存储器数据宽度,选择半字,与源数据宽度对应DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;						//存储器地址自增,选择使能,每次转运后,数组移到下一个位置DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;							//数据传输方向,选择由外设到存储器,ADC数据寄存器转到数组DMA_InitStructure.DMA_BufferSize = 4;										//转运的数据大小(转运次数),与ADC通道数一致DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;								//模式,选择循环模式,与ADC的连续转换一致DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;								//存储器到存储器,选择失能,数据由ADC外设触发转运到存储器DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;						//优先级,选择中等DMA_Init(DMA1_Channel1, &DMA_InitStructure);								//将结构体变量交给DMA_Init,配置DMA1的通道1/*DMA和ADC使能*/DMA_Cmd(DMA1_Channel1, ENABLE);							//DMA1的通道1使能ADC_DMACmd(ADC1, ENABLE);								//ADC1触发DMA1的信号使能ADC_Cmd(ADC1, ENABLE);									//ADC1使能/*ADC校准*/ADC_ResetCalibration(ADC1);								//固定流程,内部有电路会自动执行校准while (ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1) == SET);/*ADC触发*/ADC_SoftwareStartConvCmd(ADC1, ENABLE);	//软件触发ADC开始工作,由于ADC处于连续转换模式,故触发一次后ADC就可以一直连续不断地工作
}

下两图对应序列 

 

 

 DMA_Init(DMA1_Channel1, &DMA_InitStructure)只能填DMA1_Channel1

 

void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) //启用或禁用指定的ADC DMA请求

参数说明
ADCx其中x可以是1或3来选择ADC外设。注意:ADC2没有DMA功能。
NewState

所选ADC DMA传输的新状态,取值包括:ENABLE或DISABLE

 main函数

int main(void)
{/*模块初始化*/OLED_Init();				//OLED初始化AD_Init();					//AD初始化/*显示静态字符串*/OLED_ShowString(1, 1, "AD0:");OLED_ShowString(2, 1, "AD1:");OLED_ShowString(3, 1, "AD2:");OLED_ShowString(4, 1, "AD3:");while (1){OLED_ShowNum(1, 5, AD_Value[0], 4);		//显示转换结果第0个数据OLED_ShowNum(2, 5, AD_Value[1], 4);		//显示转换结果第1个数据OLED_ShowNum(3, 5, AD_Value[2], 4);		//显示转换结果第2个数据OLED_ShowNum(4, 5, AD_Value[3], 4);		//显示转换结果第3个数据Delay_ms(100);							//延时100ms,手动增加一些转换的间隔时间}
}

相关文章:

【STM32F103C8T6】DMA数据转运ADC多通道

前言 本节为代码部分,知识点在这【江协科技STM32】DMA直接存储器存储-学习笔记-CSDN博客 查看数据地址: uint8_t aa 0x88;int main(void) {OLED_Init();OLED_ShowHexNum(1,1,aa,4); //显示十六进制数 OLED_ShowHexNum(2,1,(uint32_t)&aa,8);wh…...

[Web]ServletContext域(Application)

简介 Web应用的Application域的实现是通过ServletContext对象实现的。整个Web应用程序的所有资源共享这个域。生命周期与Web应用程序相同,即当前Web应用程序启动时(以服务器视角而非访客视角)出生,Web应用服务程序关闭时停止。 通…...

计算机网络--访问一个网页的全过程

文章目录 访问一个网页的全过程应用层在浏览器输入URL网址http://www.aspxfans.com:8080/news/index.aspboardID5&ID24618&page1#r_70732423通过DNS获取IP地址生成HTTP请求报文应用层最后 传输层传输层处理应用层报文建立TCP连接传输层最后 网络层网络层对TCP报文进行处…...

JVM G1垃圾回收器详细解析

G1内存布局 Garbage First(简称G1)收集器摒弃了传统垃圾收集器的严格的内存划分,而是采用了基于Region的内存布局形式和局部回收的设计思路。 G1垃圾收集器把Java堆划分为2048个大小相等的独立的Region,每个Region大小取值范围为1-32MB,且必…...

OpenGL中绘制图形元素的实现(使用visual studio(C++)绘制一个矩形)

目标&#xff1a;使用OpenGL提供的函数绘制矩形、线段、三角形等基本图形元素 所需效果 实验步骤 1、配置OpenGL&#xff08;详情参见OpenGL的配置&#xff09; 2、头文件引入 #include <gl/glut.h> 3、编写方法体 1>矩形实现 //绘制矩形 void DisplayRectangl…...

datax-coud部署

centos7系统环境安装 jdk1.8安装 cd /usr/local 上传jdk文件到/usr/local目录下解压缩 tar -zxvf jdk-8u261-linux-x64.tar.gz# 配置环境变量 vim /etc/profileexport JAVA_HOME=/usr/local/jdk1.8.0_261 export CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/lib export PATH=$JAVA_…...

数据库---sqlite3

数据库&#xff1a; 数据库文件与普通文件区别: 1.普通文件对数据管理(增删改查)效率低 2.数据库对数据管理效率高,使用方便 常用数据库: 1.关系型数据库: 将复杂的数据结构简化为二维表格形式 大型:Oracle、DB2 中型:MySql、SQLServer …...

Android StrictMode 使用与原理深度解析

Android StrictMode 是 Android 系统提供的一种开发者工具&#xff0c;用于检测应用主线程中不合理的耗时操作&#xff08;如磁盘 I/O、网络请求等&#xff09;和内存泄漏问题。通过配置策略和惩罚机制&#xff0c;它帮助开发者在早期发现潜在性能问题&#xff0c;提升应用流畅…...

js和java中方法重载(js本身是不支持方法重载,方便对比学习)

js如果需要实现方法重载 示例 1&#xff1a;根据参数数量实现重载 function overloadExample() {if (arguments.length 1) {console.log(一个参数:, arguments[0]);} else if (arguments.length 2) {console.log(两个参数:, arguments[0], arguments[1]);} else {console.l…...

代理模式的C++实现示例

核心思想 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;其核心思想是为其他对象提供一个代理或占位符&#xff0c;以控制对这个对象的访问。代理对象通常会在客户端和目标对象之间起到中介作用&#xff0c;可以在不改变目标对象的情况下&am…...

【阿里云】控制台使用指南:从创建ECS到系统诊断测评

前言 随着云计算技术的快速发展&#xff0c;越来越多的企业和开发者开始使用云服务来部署和管理应用程序。在众多云服务提供商中&#xff0c;阿里云&#xff08;Alibaba Cloud&#xff09;凭借其强大的基础设施和丰富的服务&#xff0c;成为了众多用户的首选。本文旨在介绍如何…...

简易的微信聊天网页版【项目测试报告】

文章目录 一、项目背景二、项目简介登录功能好友列表页面好友会话页面 三、测试工具和环境四、测试计划测试用例部分人工手动测试截图web自动化测试测试用例代码框架配置内容代码文件&#xff08;Utils.py&#xff09;登录页面代码文件&#xff08;WeChatLogin.py&#xff09;好…...

显示篇(2)- DRM A733 多显主副显绑定

通过hal层根据优先级绑定&#xff0c;优先级越高送显越靠前。&#xff08;sdk默认mipi优先级最高为主显&#xff09; 1.双显 如edp主mipi副&#xff0c;edp优先级搞。 更改如下 diff --git a/hwc-hal/drm/drmConnector.cpp b/hwc-hal/drm/drmConnector.cpp --- a/hwc-hal/d…...

基于腾讯云高性能HAI-CPU的跨境电商客服助手全链路解析

跨境电商的背景以及痛点 根据Statista数据&#xff0c;2025年全球跨境电商市场规模预计达6.57万亿美元&#xff0c;年增长率保持在12.5% 。随着平台规则趋严&#xff08;如亚马逊封店潮&#xff09;&#xff0c;更多卖家选择自建独立站&#xff0c;2024年独立站占比已达35%。A…...

北京迅为RK3568开发板OpenHarmony系统南向驱动开发内核HDF驱动框架架构

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…...

从0到1入门Docker

一、快速入门 Docker run命令中的常见参数 -d&#xff1a;让容器后台运行--name&#xff1a;给容器命名&#xff08;唯一&#xff09;-e&#xff1a;环境变量-p&#xff1a;宿主机端口映射到容器内端口镜像名称结构&#xff1a;Repository &#xff1a;TAG&#xff08;镜像名&…...

应用篇| 抓包工具-charles的使用

上文说到,我们app爬虫要借助一些抓包工具,本节课就教大家如何使用抓包工具分析app的流量。抓包工具的使用是app爬虫的必修课。相比 Fiddler 来说,Charles 的功能更强大,而且跨平台支持更好。 charles安装 官方网站:https://www.charlesproxy.com 下载链接:Download a F…...

Docker搭建Redis哨兵模式【一主两从三哨兵】

Docker搭建Redis哨兵模式 系统: CentOS 7 Dockder 版本: VMware虚拟机 网络适配器 网络连接 桥接模式:直接连接物理网络查看IP命令 ip addr一、哨兵模式概述 1. 官方文档与关联博客 官方文档:https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel关联博…...

labview实现大小端交换移位

在解码时遇到了大小端交换的问题&#xff0c;需要把高低字节的16进制值进行互换&#xff0c;这里一时间不知道怎么操作&#xff0c;本来打算先把16进制转字节数组&#xff0c;算出字节数组的大小&#xff0c;然后通过模2得到0&#xff0c;1&#xff0c;来判断是否为奇数位和偶数…...

Three.js 进阶(灯光阴影关系和设置、平行光、阴影相机)

本篇主要学习内容 : 灯光与阴影聚光灯点光源平行光阴影相机和阴影计算投射阴影接受阴影 点赞 关注 收藏 学会了 1.灯光与阴影 1、材质要满足能够对光有反应 2、设置渲染器开启阴影计算 renderer.shadowMap.enabledtrue 3、设置光照投射阴影 directionalLight.castShadow …...

FastAPI 分页模块实现详解

1. 简介 本文详细介绍了一个基于 FastAPI 框架的通用分页处理模块的实现。该模块提供了标准的分页参数处理、数据切片和响应格式化功能&#xff0c;可以轻松地集成到任何 FastAPI 项目中。 2. 代码实现 2.1 导入必要的模块 首先&#xff0c;我们需要导入所需的模块&#xf…...

RK3588部署YOLOv8(2):OpenCV和RGA实现模型前处理对比

目录 前言 1. 结果对比 1.1 时间对比 1.2 CPU和NPU占用对比 2. RGA实现YOLO前处理 2.1 实现思路 2.2 处理类的声明 2.3 处理类的实现 总结 前言 RK平台上有RGA (Raster Graphic Acceleration Unit) 加速&#xff0c;使用RGA可以减少资源占用、加速图片处理速度。因此…...

打造智能钉钉机器人:借助智谱GLM-4-Flash实现高效智能回复(文末附源码)

文章目录 前言一、准备工作&#xff08;一&#xff09;钉钉机器人&#xff08;二&#xff09;智谱 GLM-4-Flash&#xff08;三&#xff09;内网穿透工具 cpolar&#xff08;四&#xff09;需要准备的工具和环境 二、钉钉机器人的创建与配置步骤1&#xff1a;创建钉钉机器人步骤…...

使用Mermaid语法绘制的C语言程序从Linux移植到Windows的流程图

以下是使用Mermaid语法绘制的C语言程序从Linux移植到Windows的流程图&#xff1a; graph TDA[开始移植] --> B[代码兼容性检查]B --> C[检查系统调用差异\nfork/exec -> CreateProcess]B --> D[检查文件路径格式\n/ vs \\]B --> E[检查依赖库兼容性\nPOSIX vs …...

入门到入土,Java学习 day16(算法1)

利用循环遍历来判断是否相等 二分查找/折半查找 前提条件&#xff1a;数组中的数据有序 每次排除一般的查找范围 用min,max,mid来处理&#xff0c;最大加最小除2&#xff0c;比较&#xff0c;然后得到在中间左边还是右边然后更新最大最小 public class Two {// 二分查找方法…...

Vulnhub 靶机 VulnOSv2 write up opendocman cms 32075 sql注入 账号密码 ssh连接 37292.c 脏牛提权

Vulnhub 靶机 VulnOSv2 write up opendocman cms 32075 sql注入 账号密码 ssh连接 37292.c 脏牛提权 一、信息收集 1、首先拿到靶场先扫一下ip arp-scan -l 3、 2、指纹扫描 nmap -sS -sV 192.168.66.178nmap -p- -sV -A 192.168.66.253 PORT STATE SERVICE VERSION 22…...

Unity辅助工具_头部与svn

Unity调用者按钮增加PlaySideButton using QQu; using UnityEditor; using UnityEngine; [InitializeOnLoad] public class PlaySideButton {static PlaySideButton(){UnityEditorToolbar.RightToolbarGUI.Add(OnRightToolbarGUI);UnityEditorToolbar.LeftToolbarGUI.Add(OnLe…...

2025最新Postman、Apipost和Apifox API 协议与工具选择方案解析

作为一个一个每天和 API“打交道”的全栈开发者&#xff0c;我的日常就是在一堆请求回应之间探寻系统间的“沟通艺术”。熟悉 API 的各种协议和工具&#xff0c;几乎成了我的谋生技能。今天&#xff0c;我就把自己积累多年的“血泪教训”和经验打包成一篇文章&#xff0c;献给和…...

ARM SVC指令

在 ARM 汇编中&#xff0c;SVC&#xff08;Supervisor Call&#xff09;指令用于从用户模式切换到特权模式&#xff08;如 Supervisor 模式&#xff09;&#xff0c;以便执行操作系统内核提供的服务。它通常用于系统调用。 具体作用 触发异常&#xff1a;执行 SVC 指令时&…...

MicroPython 智能硬件开发完整指南

第一部分&#xff1a;MicroPython 基础 1. MicroPython简介 定义&#xff1a;专为微控制器设计的精简Python 3实现&#xff0c;支持硬件直接操作。特点&#xff1a; 语法兼容Python 3&#xff0c;但移除复杂功能&#xff08;如多线程&#xff09;。支持GPIO、PWM、I2C、SPI等…...