细说STM32F407单片机以DMA方式读写外部SRAM的方法
目录
一、工程配置
1、时钟、DEBUG、GPIO、CodeGenerator
2、USART3
3、NVIC
4、 FSMC
5、DMA 2
(1)创建MemToMem类型DMA流
(2)开启DMA流的中断
二、软件设计
1、KEYLED
2、fsmc.h、fsmc.c、dma.h、dma.c
3、main.h
4、main.c
三、运行与调试
本文作者旨在介绍如何使用DMA方式读写外部SRAM。继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。
参考文章:细说STM32F407单片机以轮询方式读写外部SRAM的方法-CSDN博客 https://wenchm.blog.csdn.net/article/details/144959391
原理图,详见参考文章。
一、工程配置
外部SRAM还可以通过DMA方式访问,HAL驱动程序中提供了HAL_SRAM_Write_DMA()和HAL_SRAM_Read_DMA()两个函数用于外部SRAM的DMA方式读写数据。但是在FSMC的参数设置界面并没有DMA设置界面,外部SRAM的DMA配置方法与一般的外设不同。在FSMC组件的配置界面没有DMA设置页面,为此需要在CubeMX里单独创建一个DMA流,然后在程序里编写少量代码将创建的DMA流与Bank 1子区3对象关联。
工程仍然引用KEYLED文件夹中的文件,使用方法详见参考文章。其按键的功能定义:
[S2]KeyUp = Write directly. LED1 ON
[S3]KeyDown = Write by DMA. LED2 ON
[S4]KeyLeft = Read by DMA. LED3 ON
1、时钟、DEBUG、GPIO、CodeGenerator
外部时钟,25MHz,设置到HCLK=168MHz,PCLK1=42MHz,PCLK2=84MHz,其它,都设置成168MHz。
DEBUG,选择serial wire,CodeGenerator的设置同参考文章1。
2、USART3
使用管脚PB10、PB11,不用USART6是因为IDE提示与FSMC有争执。
3、NVIC
开启DMA2全局中断,优先级=1,修改TIME BASE中断优先级=0。
4、 FSMC
设置与参考文章相同。
5、DMA 2
(1)创建MemToMem类型DMA流
在组件面板的System Core分组里有一个DMA组件,可以在这里管理已经为外设的DMA请求配置好的DMA流,也可以在这里直接创建DMA配置。DMA组件没有任何模式参数需要设置,界面如图所示:
访问外部SRAM的DMA传输方向是Memory To Memory(存储器到存储器),只有DMA2控制器支持这种类型的DMA传输,在Mem ToMem页面配置的DMA流会自动显示在DMA2页面。本示例创建的DMA配置,DMA请求只能选择为MEMTOMEM,选择一个流DMA2 Stream2(只能是DMA2控制器的DMA流),传输方向是Memory To Memory。
这个DMA流的属性参数设置需要注意以下事项:
- DMA流的工作模式(Mode)只能设置为正常(Normal)模式,不能设置为循环模式。
- DMA流会自动使用FIFO,且不能关闭。
- 源存储器和目标存储器的数据宽度(Data Width)设置为Word,这是因为函数HAL_SRAM_Write_DMA()和HAL_SRAM_Read_DMA()只支持uint32_t类型的数据缓冲区。
- 源存储器和目标存储器都应该开启地址自增功能。
CubeMX会为这样配置的一个DMA流生成初始化代码,也就是会定义DMA_HandleTypeDef类型的DMA流对象变量,并根据CubeMX里的设置生成赋值代码,用函数HAL_DMA_Init()进行DMA流的初始化,但是不会生成代码将DMA流对象与外设关联,也就是不会生成调用函数__HAL_LINKDMA()的代码,需要用户自己在程序中编写代码将DMA流对象与FSMC Bank 1子区3对象关联。这与前面介绍过的一些外设使用DMA的配置方法有差异。
(2)开启DMA流的中断
前面创建的DMA配置中用到DMA2 Stream2流,这个DMA流的中断并不会自动打开。不打开DMA流的中断,DMA传输完成中断事件的回调函数就不会被调用。所以,还需要在NVIC管理界面开启DMA2 Stream2的全局中断,将这个中断的抢占优先级设置为1,以防回调函数里直接或间接用到延时函数HAL Delay()。
二、软件设计
1、KEYLED
本例的项目中要使用KEYLED,其中的keyled.c和keyled.h的使用方法与参考文章相同。
2、fsmc.h、fsmc.c、dma.h、dma.c
由IDE自动生成,不需要修改。
3、main.h
/* USER CODE BEGIN Private defines */
void SRAM_WriteDirect();
void SRAM_WriteDMA();
void SRAM_ReadDMA();
/* USER CODE END Private defines */
4、main.c
/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PD */
// SRAM的容量不同,该处的定义就不同,更改SRAM就得修改此处的定义
#define SRAM_ADDR_BEGIN 0x68000000UL //Bank1子区3的SRAM起始地址
#define SRAM_ADDR_HALF 0x6801FFFFUL //SRAM容量256K*16bit,中间地址128K字节
#define SRAM_ADDR_END 0x6803FFFFUL //SRAM容量256K*16bit,结束地址512K字节
//#define SRAM_ADDR_HALF 0x68080000UL //SRAM容量512K*16bit,中间地址512K字节
//#define SRAM_ADDR_END 0x680FFFFFUL //SRAM容量512K*16bit,结束地址1024K字节
/* USER CODE END PD */
/* USER CODE BEGIN PV */
#define COUNT 5 //缓存区数据个数
uint32_t txBuffer[COUNT]; //DMA发送缓存区
uint32_t rxBuffer[COUNT]; //DMA接收缓存区uint8_t DMA_Direction=1; //DMA传输方向,1=write, 0=read
uint8_t DMA_Busy=0; //DMA工作状态,1=busy, 0=idle/* USER CODE END PV */
/* USER CODE BEGIN 2 */__HAL_LINKDMA(&hsram3,hdma,hdma_memtomem_dma2_stream0); //将DMA传输配置与外设hsram3关联printf("Demo19_2_FSMC_DMA: External SRAM\r\n");printf("Read/Write SRAM by DMA\r\n");//显示菜单printf("[S2]KeyUp = Write directly.\r\n");printf("[S3]KeyDown = Write by DMA.\r\n");printf("[S4]KeyLeft = Read by DMA.\r\n\r\n");// MCU output low level LED light is onLED1_OFF();LED2_OFF();LED3_OFF();/* USER CODE END 2 */
在main()函数里完成外设初始化后,执行了下面一行语句:
__HAL_LINKDMA(&hsram3,hdma,hdma_memtomem_dma2_stream0);
执行这行语句相当于执行了下面两行语句:
(&hsram3)->hdma =&(hdma_memtomem_dma2_stream0); //hsram3的hdma指向具体的DMA流对象
(hdma_memtomem_dma2_stream0).Parent=(&hsram3); //DMA流对象的Parent指向具体外设hsram3
所以,其功能就是将DMA流对象hdma_memtomem_dma2_stream0与外设hsram3互相关联。就是将初始化DMA流对象的代码放到了函数MX_DMA_Init()里,没有自动生成调用__HAL_LINKDMA()的代码实现DMA流与外设的互相关联。所以在main()函数里,需要调用函数__HAL_LINKDMA()将外设hsram3与DMA流对象hdma_memtomem_dma2_stream0关联起来。
/* USER CODE BEGIN 3 */KEYS curKey=ScanPressedKey(KEY_WAIT_ALWAYS);switch(curKey){case KEY_UP:{SRAM_WriteDirect();LED1_ON();LED2_OFF();LED3_OFF();break;}case KEY_DOWN:{SRAM_WriteDMA();LED1_OFF();LED2_ON();LED3_OFF();break;}case KEY_LEFT:{SRAM_ReadDMA();LED1_OFF();LED2_OFF();LED3_ON();break;}default:{LED1_OFF();LED2_OFF();LED3_OFF();}}HAL_Delay(500); //延时,消除按键抖动影��?}/* USER CODE END 3 */
文件main.c定义了几个全局变量用于DMA数据传输。
在外设初始化部分,MX_DMA_Init()用于DMA初始化,就是初始化CubeMX中定义的MemToMem类型的DMA流对象。MX_FSMC_Init()用于FSMC初始化,这个函数的代码与参考文章的示例的定义完全相同。
外设初始化完成后,要调用函数__HAL_LINKDMA()将DMA流对象hdma_memtomem_dma2_stream0与FSMC Bank 1子区3对象hsram3关联。(有时候,会用refactor方法将其更名为hdma_m2m_sram。但是重新生成式又会恢复到IDE自动生成的对象名。)
主程序里显示了一个菜单,while循环里通过检测按键对菜单做出响应,响应代码中用到3个自定义函数,USER CODE BEGIN 4数据对里介绍这几个函数的实现代码。
/* USER CODE BEGIN 4 */
//直接写入
void SRAM_WriteDirect()
{//准备数组数据printf("Writing 32bit array directly...\r\n");uint32_t Value=600;uint32_t *pAddr_32b=(uint32_t *)(SRAM_ADDR_BEGIN+256); //给指针赋值//准备数组,写数据for(uint8_t i=0; i<COUNT; i++){txBuffer[i]=Value;HAL_SRAM_Write_32b(&hsram3, pAddr_32b, &Value, 1);printf("The data writed at ADD %p = %ld\r\n",pAddr_32b,Value);Value += 5;pAddr_32b ++;}if (HAL_SRAM_Write_32b(&hsram3, pAddr_32b, txBuffer, COUNT) == HAL_OK)printf("Array is written directly successfully.\r\n\r\n");
}//DMA方式写入SRAM
void SRAM_WriteDMA()
{printf("Writing 32bit array by DMA...\r\n");uint32_t Value=800;uint32_t *pAddr_32b=(uint32_t *)(SRAM_ADDR_BEGIN+256);DMA_Direction=1; //DMA传输方向,1=write, 0=readDMA_Busy=1; //表示DMA正在传输状态,1=working, 0=idlefor(uint8_t i=0; i<COUNT; i++){txBuffer[i]=Value;Value += 6;}HAL_SRAM_Write_DMA(&hsram3, pAddr_32b, txBuffer, COUNT);
}//DMA方式读取SRAM
void SRAM_ReadDMA()
{printf("Reading 32bit array by DMA...\r\n");DMA_Direction=0; //DMA传输方向,1=write, 0=readDMA_Busy=1; //表示DMA正在传输状态,1=working, 0=idleuint32_t *pAddr_32b=(uint32_t *)(SRAM_ADDR_BEGIN+256);HAL_SRAM_Read_DMA(&hsram3, pAddr_32b, rxBuffer, COUNT); //以DMA方式读取SRAM
}//DMA传输完成中断回调函数
void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
{uint32_t *pAddr_32b=(uint32_t *)(SRAM_ADDR_BEGIN+256);if (DMA_Direction == 1){ //DMA传输方向,1=write, 0=readfor(uint8_t i=0; i<COUNT; i++){printf("The data writed at ADD %p = %ld\r\n",pAddr_32b,txBuffer[i]);pAddr_32b ++;}printf("Written by DMA complete.\r\n\r\n");}else if (DMA_Direction == 0){for(uint8_t i=0; i<COUNT; i++){printf("The data read at ADD %p = %ld\r\n",pAddr_32b,rxBuffer[i]);pAddr_32b ++;}printf("Read by DMA complete.\r\n\r\n");}elsereturn;DMA_Busy=0; //表示DMA结束了传输,1=working, 0=idle
}int __io_putchar(int ch)
{HAL_UART_Transmit(&huart3,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */
按下KeyUp键后,调用函数SRAM_WriteDirect(),其功能是调用函数HAL_SRAM_Write_32b()向外部SRAM写入一个数组的数据,主要是为了测试DMA方式读出的数据是否正确。hsram3关联的DMA流是MemToMem类型的,使用函数HAL_SRAM_Write_DMA()以DMA方式写入数据,或使用函数HAL_SRAM_Read_DMA()以DMA方式读取数据时,都使用这个DMA流,回调函数都是HAL_SRAM_DMA_XferCpltCallback()。所以,定义了两个全局变量表示DMA传输方向和DMA工作状态。
- 全局变量DMA_Direction表示DMA传输方向:DMA_Direction为1时,表示数据写入;为0时,表示数据读出。
- 全局变量DMA_Busy表示是否正在进行DMA传输:DMA_Busy为1时,表示正在进行DMA传输;为0时,表示空闲。
按下KeyDown键时,调用函数SRAM_WriteDMA(),其功能是调用HAL_SRAM_Write_DMA()以DMA方式向外部SRAM写入一个数组的数据。在开启DMA传输之前,将全局变量DMA_Direction设置为1,表示写入操作,将DMA_Busy设置为1。
按下KeyLeftt键时,调用函数SRAM_ReadDMA(),其功能是调用函数HAL_SRAM_Read_DMA(),以DMA方式从外部SRAM读取一批数据。在开启DMA传输之前,将全局变量DMA_Direction设置为0,表示读取操作,DMA_Busy设置为1。
函数HAL SRAM_Write_DMA()和HAL_SRAM_Read_DMA()启动的DMA传输完成后,会触发DMA流的传输完成事件中断,会调用相同的一个回调函数HAL_SRAM_DMA_XferCpltCallback(),所以需要在这个回调函数区分DMA传输方向。通过全局变量DMA_Direction可以判断DMA传输方向,从而做出相应的响应。回调函数处理完成后,将全局变量DMA_Busy的值设置为0,表示DMA传输完成。
在函数SRAM_WriteDMA()和SRAM_ReadDMA()中启动DMA传输之前,理论上还应该判断变量DMA_Busy的值。如果DMA_Busy为1,表示有未完成的DMA传输,需要等待DMA_Busy变为0之后再启动一次DMA传输。本示例中使用按键启动DMA传输,手动操作速度很慢,所以未做判断处理。
三、运行与调试
测试过程中仍然发现与参考文章一样的情况,等待作者解决后重新发布出来。
相关文章:
细说STM32F407单片机以DMA方式读写外部SRAM的方法
目录 一、工程配置 1、时钟、DEBUG、GPIO、CodeGenerator 2、USART3 3、NVIC 4、 FSMC 5、DMA 2 (1)创建MemToMem类型DMA流 (2)开启DMA流的中断 二、软件设计 1、KEYLED 2、fsmc.h、fsmc.c、dma.h、dma.c 3、main.h…...
Vue 3前端与Python(Django)后端接口简单示例
项目 后端(Django)前端(Vue 3) 后端(Django) 创建Django项目和应用: 确保你已经安装了Django。如果没有安装,可以使用以下命令安装: pip install django创建一个新的Dja…...
前端多语言
前端多语言目前常用i18n实现 一、react 1.安装依赖 npm install react-i18next i18next --save2.创建配置文件 src/i18n config.ts:对 i18n 进行初始化操作及插件配置 en.json:英文语言配置文件 zh.json:中文语言配置文件 config.ts im…...
单片机-直流电机实验
1、ULN2003芯片介绍 ULN2003, 该芯片是一个单片高电压、高电流的达林顿晶体管阵列集成电路。不仅可以用来 驱动直流电机,还可用来驱动五线四相步进电机。支持驱动大功率电器 因为 ULN2003 的输出是集电极开路,ULN2003 要输出高电平࿰…...
【Word_笔记】Word的修订模式内容改为颜色标记
需求如下:请把修改后的部分直接在原文标出来,不要采用修订模式 步骤1:打开需要转换的word后,同时按住alt和F11 进入(Microsoft Visual Basic for Appliations) 步骤2:插入 ---- 模块 步骤3&…...
计算机网络之---子网划分与IP地址
子网划分与IP地址的关系 在计算机网络中,子网划分(Subnetworking)是将一个网络划分为多个子网络的过程。通过子网划分,可以有效地管理和利用IP地址空间,提高网络的性能、安全性和管理效率。 子网划分的基本目的是通过…...
【LeetCode Hot100 贪心算法】 买卖股票的最佳时机、跳跃游戏、划分字母区间
贪心算法 买卖股票的最佳时机买卖股票的最佳时机II跳跃游戏跳跃游戏II划分字母区间 买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的…...
[ 第36次CCFCSP]梦境巡查
题目背景 传说每当月光遍布西西艾弗岛,总有一道身影默默守护着居民们的美梦。 题目描述 梦境中的西西艾弗岛由 n1 个区域组成。梦境巡查员顿顿每天都会从梦之源(0 号区域)出发,顺次巡查 1,2,⋯ ,n 号区域,最后从 n…...
使用PVE快速创建虚拟机集群并搭建docker环境
安装Linux系统 这里以安装龙蜥操作系统AnolisOS8.9为例加以说明。 通过PVE后台上传操作系统ISO镜像。 然后在PVE上【创建虚拟机】,选定上传的龙蜥操作系统镜像进行系统安装。 注意:在安装过程中,要设定语言、时区、超管用户root的密码、普…...
模型 断裂点理论(风险控制)
系列文章 分享模型,了解更多👉 模型_思维模型目录。设置小损失,防止大风险。 1 断裂点理论的应用 1.1 电路系统中的保险丝应用 背景介绍: 在工程学中,电路系统是现代科技中不可或缺的一部分,广泛应用于各…...
机器学习之贝叶斯分类器和混淆矩阵可视化
贝叶斯分类器 目录 贝叶斯分类器1 贝叶斯分类器1.1 概念1.2算法理解1.3 算法导入1.4 函数 2 混淆矩阵可视化2.1 概念2.2 理解2.3 函数导入2.4 函数及参数2.5 绘制函数 3 实际预测3.1 数据及理解3.2 代码测试 1 贝叶斯分类器 1.1 概念 贝叶斯分类器是基于贝叶斯定理构建的分类…...
nginx http反向代理
系统:Ubuntu_24.0.4 1、安装nginx sudo apt-get update sudo apt-get install nginx sudo systemctl start nginx 2、配置nginx.conf文件 /etc/nginx/nginx.conf,但可以在 /etc/nginx/sites-available/ 目录下创建一个新的配置文件,并在…...
【Python运维】利用Python实现高效的持续集成与部署(CI/CD)流程
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 持续集成与部署(CI/CD)是现代软件开发中不可或缺的实践,通过自动化测试、构建和部署流程,显著提高了开发效率与运维质量。本文详细介绍…...
markdown存储到faiss向量数据库
目录 一、faiss接收的数据接口二、Markdown文件切分并处理为document列表1.markdown分割器2.文本分割器3.添加文件名 三、整体流程源代码 一、faiss接收的数据接口 add_docunments接收的documents是一个document对象的列表。 Document 对象的列表(List of Document…...
开源cJson用法
cJSON cJSON是一个使用C语言编写的JSON数据解析器,具有超轻便,可移植,单文件的特点,使用MIT开源协议。 cJSON项目托管在Github上,仓库地址如下: https://github.com/DaveGamble/cJSON 使用Git命令将其拉…...
SSL,TLS协议分析
写在前面 工作中总是会接触到https协议,也知道其使用了ssl,tls协议。但对其细节并不是十分的清楚。所以,就希望通过这篇文章让自己和读者朋友们都能对这方面知识有更清晰的理解。 1:tls/ssl协议的工作原理 1.1:设计的…...
华为路由器、交换机、AC、新版本开局远程登录那些坑(Telnet、SSH/HTTP避坑指南)
关于华为设备远程登录配置开启的通用习惯1、HTTP/HTTPS相关服务 http secure-server enablehttp server enable 2、Telnet服务telnet server enable3、SSH服务stelnet server enablessh user admin authentication-type password 「模拟器、工具合集」复制整段内容 链接&…...
Redis的数据结构(基本)
安装完成后,在任意目录输入redis-server命令即可启动Redis: redis-server 我们可以进入redis命令行窗口 Redis安装完成后就自带了命令行客户端:redis-cli,使用方式如下: redis-cli [options] [commonds] 其中常见…...
分布式锁 Redis vs etcd
为什么要实现分布式锁?为什么需要分布式锁,分布式锁的作用是什么,哪些场景会使用到分布式锁?分布式锁的实现方式有哪些分布式锁的核心原理是什么 如何实现分布式锁redis(自旋锁版本)etcd 的分布式锁(互斥锁(信号控制)版本) 分布式锁对比redis vs etcd 总结 为什么要实现分布式…...
docker中jenkins流水线式部署GitLab中springboot项目
本质就是将java项目拉取下来,并自动打包成docker镜像,运行 首先启动一个docker的jenkins 如果没有镜像使用我的镜像 通过网盘分享的文件:jenkins.tar 链接: https://pan.baidu.com/s/1VJOMf6RSIQbvW_V1zFD7eQ?pwd6666 提取码: 6666 放入服…...
甘蔗叶片图像元素含量的回归预测多模型实现【含私人数据集】
完整源码项目包获取→点击文章末尾名片! 基于python的小样本学习,完成对甘蔗叶片图像元素含量的回归预测 数据集这边我提供,包含91个样本,共182个图像,要求全部数据集保密,不能对外公开或泄露;…...
uniapp:钉钉小程序需要录音权限及调用录音
{// ... 其他配置项"mp-dingtalk": {"permission": {"scope.userLocation" : {"desc" : "系统希望获得您的定位用于确认您周围的设施数据"},"scope.bluetooth" : {"desc" : "你的蓝牙权限将用于小…...
Qt仿音乐播放器:媒体类
一、铺垫 我暂时只会音频系列的操作,我只能演示音频部分;但是QMediaPlayer是一个可以播放视频、音频的类;请同学们细读官方文档; 二、头文件 #include<QMediaPlayer> 头文件 #include<QMediaPlaylist> 三、演…...
Flink-CDC 全面解析
Flink-CDC 全面解析 一、CDC 概述 (一)什么是 CDC CDC 即 Change Data Capture(变更数据获取),其核心要义在于严密监测并精准捕获数据库内发生的各种变动情况,像数据的插入、更新以及删除操作࿰…...
HarmonyOS中实现上拉加载下拉刷新
参考网址:Refresh-滚动与滑动-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者 1.数据基类 //根据自己的业务数据扩展此类 //注意:一定要继承Object export class PullToRefreshBean extends Object{name: string …...
【轻松学C:编程小白的大冒险】--- C语言简介 02
在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。 【轻松学C:编程小白的大冒险】…...
MySQL安装,配置教程
一、Linux在线yum仓库安装 打开MySQL官方首页,链接为:https://www.mysql.com/ 界面如下: 在该页面中找到【DOWNOADS】选项卡,点击进入下载页面。 在下载界面中,可以看到不同版本的下载链接,这里选择【My…...
项目实战——使用python脚本完成指定OTA或者其他功能的自动化断电上电测试
前言 在嵌入式设备的OTA场景测试和其他断电上电测试过程中,有的场景发生在夜晚或者随时可能发生,这个时候不可能24h人工盯着,需要自动化抓取串口日志处罚断电上电操作。 下面的python脚本可以实现自动抓取串口指定关键词,然后触发…...
多活架构的实现原理与应用场景解析
一、多活架构为何如此重要? 企业的业务运营与各类线上服务紧密相连,从日常的购物消费、社交娱乐,到金融交易、在线教育等关键领域,无一不依赖于稳定可靠的信息系统。多活架构的重要性愈发凸显,它宛如一位忠诚的卫士,为业务的平稳运行保驾护航。 回想那些因系统故障引发的…...
01-springclound
OpenFeign OpenFeign的日志级别 GateWay GateWay自定义过滤器 自定义过滤器,实现Order接口 数字小的先执行 GateWay传递用户信息 1、需要在网关搞定登录校验,将用户信息保存到请求头 2、网关到微服务 通过 springmvc的拦截器 来处理,将用户…...
Pandas-RFM会员价值度模型
文章目录 一. 会员价值度模型介绍二. RFM计算与显示1. 背景2. 技术点3. 数据4. 代码① 导入模块② 读取数据③ 数据预处理Ⅰ. 数据清洗, 即: 删除缺失值, 去掉异常值.Ⅱ. 查看清洗后的数据Ⅲ. 把前四年的数据, 拼接到一起 ④ 计算RFM的原始值⑤ 确定RFM划分区间⑥ RFM计算过程⑦…...
Java基础知识面试题
1.Java语言的特点? 1.一面向对象(封装,继承,多态); 2.平台无关性( Java 虚拟机实现平台无关性);(类是一种定义对象的蓝图或模板)3.支持多线程( C 语言没有内…...
WebSocket监听接口
在Vue.js中使用WebSocket来监听接口其实相对简单。WebSocket是一种在单个TCP连接上进行全双工通信的协议,通常用于需要实时数据更新的场景,比如聊天应用、实时通知等。 以下是一个在Vue.js中使用WebSocket的示例: 1. 创建Vue项目 如果你还…...
Kotlin语言的编程范式
Kotlin语言的编程范式 Kotlin是一种现代的编程语言,旨在提高开发效率,减少代码复杂度。在过去几年中,Kotlin在Android开发中获得了极大的普及,同时也逐渐被用在服务器端、Web开发、数据科学等多个领域。本文将深入探讨Kotlin的编…...
【权限管理】Apache Shiro学习教程
Apache Shiro 是一个功能强大且灵活的安全框架,主要用于身份认证(Authentication)、授权(Authorization)、会话管理(Session Management)和加密(Cryptography)。它旨在为…...
网络安全 信息收集入门
1.信息收集定义 信息收集是指收集有关目标应用程序和系统的相关信息。这些信息可以帮助攻击者了解目标系统的架构、技术实现细节、运行环境、网络拓扑结构、安全措施等方面的信息,以便我们在后续的渗透过程更好的进行。 2.收集方式-主动和被动收集 ①收集方式不同…...
Java Web开发进阶——RESTful API设计与开发
随着分布式系统和微服务架构的流行,RESTful API已成为现代Web应用中后端与前端、第三方系统交互的重要方式。本节将深入探讨RESTful API的设计原则、实现方式以及如何使用Spring Boot开发高效、可靠的RESTful服务。 1. 理解RESTful API的设计原则 1.1 什么是RESTfu…...
图片已经在windows上旋转了,但是在linux上仍然显示不正常
公司接了一个linux产品的售后工作,我们现在的产品都是android。linux设备如果要播放竖屏的图片在linux主板上。需要将图片旋转下才能正常播放。 我拿到图片以后,就用window图片编辑器打开了图片如下图左。选择逆时针选择了90 然后另存图片为如下图右。 …...
关于大数据的基础知识(二)——国内大数据产业链分布结构
成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于大数据的基础知识(二&a…...
Flutter鸿蒙化 在鸿蒙应用中添加Flutter页面
前言 今天这节课我们讲一下 在鸿蒙应用中添加Flutter页面。 作用: 之前有很多朋友和网友问我鸿蒙能不能使用Flutter开发,他们的项目已经用Flutter开发成熟了有什么好的方案呢,今天讲到这个就可以很好的解决他们的问题,例如我们正式项目中可能是一部分native 开发 一部分…...
【递归,搜索与回溯算法 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
优美的排列 题目解析 算法原理 解法 :暴搜 决策树 红色剪枝:用于剪去该节点的值在对应分支中,已经被使用的情况,可以定义一个 check[ ] 紫色剪枝:perm[i] 不能够被 i 整除,i 不能够被 per…...
Perl语言的语法
Perl语言概述及其应用 引言 Perl语言是一种通用的高级编程语言,由拉里沃尔(Larry Wall)于1987年首次发布。Perl语言的设计目标是简化文本处理和报告生成,同时也提供了强大的功能以用于系统管理、网络编程、数据库交互等多种场景…...
ELK+filebeat+kafka
ELKfilebeatkafka elkelk的架构数据流向ELK的部署 filebeatzookeeperkafkazopkeeprzookeeper的工作机制zookeeper的特点zookeeper的数据架构zookeeper的安装 kafka消息队列消息队列的应用场景消息队列的模式kafka组件的名称 elk elk的架构 elk:统一日志收集系统 …...
WPF系列九:图形控件EllipseGeometry
简介 EllipseGeometry用于绘制一个椭圆的形状。它通常与其他图形元素结合使用,比如 Path 或者作为剪切区域来定义其他元素的外形。 定义椭圆:EllipseGeometry 用来定义一个椭圆或者圆的几何形状。参与绘制:可以被用作 Path 元素的数据&…...
2025新年源码免费送
2025很开门很开门的源码免费传递。不需要馒头就能获取4套大开门源码。 听泉偷宝,又进来偷我源码啦👊👊👊。欢迎偷源码 🔥🔥🔥 获取免费源码以及更多源码,可以私信联系我 我们常常…...
离线录制激光雷达数据进行建图
目前有一个2D激光雷达,自己控制小车运行一段时间,离线获取到激光雷达数据后运行如下代码进行离线建图。 roslaunch cartographer_ros demo_revo_lds.launch bag_filename:/home/firefly/AutoCar/data/rplidar_s2/2025-01-08-02-08-33.bag实际效果如下 d…...
Scala分布式语言二(基础功能搭建、面向对象基础、面向对象高级、异常、集合)
章节3基础功能搭建 46.函数作为值三 package cn . itbaizhan . chapter03 // 函数作为值,函数也是个对象 object FunctionToTypeValue { def main ( args : Array [ String ]): Unit { //Student stu new Student() /*val a ()>{"GTJin"…...
AI中的神经元与权重矩阵之间的关系;神经元连接角度看行和列的意义
AI中的神经元与权重矩阵之间的关系 目录 AI中的神经元与权重矩阵之间的关系神经元连接角度看行和列的意义AI中的神经元概念 在人工智能领域,特别是神经网络中,神经元是基本的计算单元,它是对生物神经元的一种抽象模拟。就像生物神经元接收来自其他神经元的电信号,经过处理后…...
前端中常用的单位度量(px,rpx,rem,em,vw,vh)+图片自适应
文章目录 前端中常用的单位度量vw/vh 的场景应用px/rem/em 之间的转换关系项目中的rem 应用根元素 font-size 设置为16px 的应用惯例自适应之图片应用1. 使用 max-width 和 max-height2. 使用 object-fit 属性3. 使用 background-image 模拟图片展示 前端中常用的单位度量 px&…...
Attention计算中的各个矩阵的维度都是如何一步步变化的?
在Transformer模型中,各个矩阵的维度变化是一个关键的过程,涉及到输入、编码器、解码器和输出等多个阶段。以下是详细的维度变化过程: 输入阶段 输入序列:假设输入序列的长度为seq_len,每个单词或标记通过词嵌入&…...