C++ STM32 F4xx USART LL库 DMA + IDLE ISR 驱动裸机 +FreeRTOS 任务通知
写的一般,大佬可以帮我看看
头文件
/********************************************************************************* @file : usart_driver.hpp* @brief : usart_driver program head******************************************************************************* @attention*******************************************************************************/
#ifndef __USART_DRIVER_H
#define __USART_DRIVER_H#include "stm32f4xx_hal.h"#define COM1 USART1
#define COM2 USART2
#define COM3 USART3
#define COM4 UART4
#define COM5 UART5
#define COM6 USART6#define USE_RTOS_FOR_USART
#ifdef USE_RTOS_FOR_USART
#include "FreeRTOS.h"
#include "task.h"
#endifclass serial_device {
public:explicit serial_device(USART_TypeDef* usartPort, uint32_t baudRate, uint16_t nvicPriority): m_serial_port(usartPort),m_baudrate(baudRate),m_nvic_priority(nvicPriority) {mp_buffer_for_dma_rx = mp_rx_bufferA;mp_buffer_for_user_rx = mp_buffer_for_dma_rx;m_is_rx_complete = 0;m_rx_data_size = 0;m_is_tx_complete = 0;#if USE_FREERTOSmp_task_handle = NULL; //接收任务通知#endif}void init(); // serial_init USARTvoid send(const uint8_t* data, uint16_t size); // Send datavoid handle_isr_recv(); // Interrupt receive processing function#ifdef USE_RTOS_FOR_USARTvoid set_notify_task(TaskHandle_t task_handle); //设置任务通知的task handleuint32_t task_notify_take();#endifvoid reset_rx_complete_flag();void reset_tx_complete_flag();const uint8_t* get_recv_data();uint16_t get_recv_data_size();uint8_t is_recv_ready();uint8_t is_send_ready();private:USART_TypeDef* m_serial_port;DMA_TypeDef* m_dma_port;uint32_t m_dma_rx_stream;uint32_t m_dma_tx_stream;#ifdef USE_RTOS_FOR_USARTTaskHandle_t mp_task_handle;BaseType_t mpx_task_woken;#endifuint32_t m_baudrate;uint16_t m_nvic_priority;uint16_t m_rx_data_size;static constexpr uint32_t RECEIVE_BUFFER_SIZE = 32; // Size of received data bufferuint8_t m_is_rx_complete;uint8_t m_is_tx_complete;uint8_t* mp_buffer_for_dma_rx; // Pointer to ready-to-receive bufferuint8_t* mp_buffer_for_user_rx; // Pointer to user-accessible receive bufferuint8_t mp_rx_bufferA[RECEIVE_BUFFER_SIZE * 2]; // Receive buffer Auint8_t mp_rx_bufferB[RECEIVE_BUFFER_SIZE * 2]; // Receive buffer Bserial_device(const serial_device&) = delete;serial_device& operator=(const serial_device&) = delete; // Disable copy and move constructorsserial_device(serial_device&&) = delete;serial_device& operator=(serial_device&&) = delete;
};#endif
源文件
/********************************************************************************* @file : usart_driver.c* @brief : usart program body******************************************************************************* @attention*******************************************************************************/
#include "usart_driver.h"
#include "string.h"
#include "stm32f4xx_ll_usart.h"
#include "stm32f4xx_ll_dma.h"
#include "stm32f4xx_ll_gpio.h"
#include "stm32f4xx_ll_rcc.h"
#include "stm32f4xx_ll_bus.h"/*** @brief 初始化串口** 此函数用于初始化指定的串口,包括GPIO配置、DMA配置、中断配置和串口配置。** @param 无** @return 无*/
void serial_device::init(){LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);LL_USART_InitTypeDef USART_InitStruct = {0};LL_GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;IRQn_Type COMIRQn;IRQn_Type DMARxIRQn;IRQn_Type DMATxIRQn;/* Peripheral clock enable */if(this->m_serial_port == COM1){LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);/**USART1 GPIO ConfigurationPA9 ------> USART1_TXPA10 ------> USART1_RX*/GPIO_InitStruct.Pin = LL_GPIO_PIN_9|LL_GPIO_PIN_10;GPIO_InitStruct.Alternate = LL_GPIO_AF_7;LL_GPIO_Init(GPIOA, &GPIO_InitStruct);m_dma_port = DMA2;m_dma_rx_stream = LL_DMA_STREAM_2;m_dma_tx_stream = LL_DMA_STREAM_7;COMIRQn = USART1_IRQn;DMARxIRQn = DMA2_Stream2_IRQn;DMATxIRQn = DMA2_Stream7_IRQn;} else if(this->m_serial_port == COM2){/* Peripheral clock enable */LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);/**USART2 GPIO ConfigurationPA2 ------> USART2_TXPA3 ------> USART2_RX*/GPIO_InitStruct.Pin = LL_GPIO_PIN_2|LL_GPIO_PIN_3;GPIO_InitStruct.Alternate = LL_GPIO_AF_7;LL_GPIO_Init(GPIOA, &GPIO_InitStruct);m_dma_port = DMA1;m_dma_rx_stream = LL_DMA_STREAM_5;m_dma_tx_stream = LL_DMA_STREAM_6;COMIRQn = USART2_IRQn;DMARxIRQn = DMA1_Stream5_IRQn;DMATxIRQn = DMA1_Stream6_IRQn;} else if(this->m_serial_port == COM3){/* Peripheral clock enable */LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);/**USART3 GPIO ConfigurationPB10 ------> USART3_TXPB11 ------> USART3_RX*/GPIO_InitStruct.Pin = LL_GPIO_PIN_10|LL_GPIO_PIN_11;GPIO_InitStruct.Alternate = LL_GPIO_AF_7;LL_GPIO_Init(GPIOB, &GPIO_InitStruct);m_dma_port = DMA1;m_dma_rx_stream = LL_DMA_STREAM_1;m_dma_tx_stream = LL_DMA_STREAM_3;COMIRQn = USART2_IRQn;DMARxIRQn = DMA1_Stream1_IRQn;DMATxIRQn = DMA1_Stream3_IRQn;} else if(this->m_serial_port == COM4){/* Peripheral clock enable */LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_UART4);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);/**UART4 GPIO ConfigurationPA0-WKUP ------> UART4_TXPA1 ------> UART4_RX*/GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1;GPIO_InitStruct.Alternate = LL_GPIO_AF_8;LL_GPIO_Init(GPIOA, &GPIO_InitStruct);m_dma_port = DMA1;m_dma_rx_stream = LL_DMA_STREAM_2;m_dma_tx_stream = LL_DMA_STREAM_4;COMIRQn = UART4_IRQn;DMARxIRQn = DMA1_Stream2_IRQn;DMATxIRQn = DMA1_Stream4_IRQn;}else if(this->m_serial_port == COM5){/* Peripheral clock enable */LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_UART5);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOD);/**UART5 GPIO ConfigurationPC12 ------> UART5_TXPD2 ------> UART5_RX*/GPIO_InitStruct.Pin = LL_GPIO_PIN_12;GPIO_InitStruct.Alternate = LL_GPIO_AF_8;LL_GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_InitStruct.Pin = LL_GPIO_PIN_2;GPIO_InitStruct.Alternate = LL_GPIO_AF_8;LL_GPIO_Init(GPIOD, &GPIO_InitStruct);m_dma_port = DMA1;m_dma_rx_stream = LL_DMA_STREAM_0;m_dma_tx_stream = LL_DMA_STREAM_7;COMIRQn = UART5_IRQn;DMARxIRQn = DMA1_Stream0_IRQn;DMATxIRQn = DMA1_Stream7_IRQn;}else if(this->m_serial_port == COM6){/* Peripheral clock enable */LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART6);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);/**USART6 GPIO ConfigurationPC6 ------> USART6_TXPC7 ------> USART6_RX*/GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7;GPIO_InitStruct.Alternate = LL_GPIO_AF_8;LL_GPIO_Init(GPIOC, &GPIO_InitStruct);this->m_dma_port = DMA2;this->m_dma_rx_stream = LL_DMA_STREAM_1;this->m_dma_tx_stream = LL_DMA_STREAM_6;COMIRQn = UART5_IRQn;DMARxIRQn = DMA2_Stream1_IRQn;DMATxIRQn = DMA2_Stream6_IRQn;}/* DMA Init *//* RX Init */LL_DMA_SetChannelSelection(this->m_dma_port, this->m_dma_rx_stream, LL_DMA_CHANNEL_4); LL_DMA_SetDataTransferDirection(this->m_dma_port, this->m_dma_rx_stream, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);LL_DMA_SetStreamPriorityLevel(this->m_dma_port, this->m_dma_rx_stream, LL_DMA_PRIORITY_LOW);LL_DMA_SetMode(this->m_dma_port, this->m_dma_rx_stream, LL_DMA_MODE_NORMAL);LL_DMA_SetPeriphIncMode(this->m_dma_port, this->m_dma_rx_stream, LL_DMA_PERIPH_NOINCREMENT);LL_DMA_SetMemoryIncMode(this->m_dma_port, this->m_dma_rx_stream, LL_DMA_MEMORY_INCREMENT);LL_DMA_SetPeriphSize(this->m_dma_port, this->m_dma_rx_stream, LL_DMA_PDATAALIGN_BYTE);LL_DMA_SetMemorySize(this->m_dma_port, this->m_dma_rx_stream, LL_DMA_MDATAALIGN_BYTE);LL_DMA_DisableFifoMode(this->m_dma_port, this->m_dma_rx_stream);/* TX Init */LL_DMA_SetChannelSelection(this->m_dma_port, this->m_dma_tx_stream, LL_DMA_CHANNEL_4);LL_DMA_SetDataTransferDirection(this->m_dma_port, this->m_dma_tx_stream, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);LL_DMA_SetStreamPriorityLevel(this->m_dma_port, this->m_dma_tx_stream, LL_DMA_PRIORITY_LOW);LL_DMA_SetMode(this->m_dma_port, this->m_dma_tx_stream, LL_DMA_MODE_NORMAL);LL_DMA_SetPeriphIncMode(this->m_dma_port, this->m_dma_tx_stream, LL_DMA_PERIPH_NOINCREMENT);LL_DMA_SetMemoryIncMode(this->m_dma_port, this->m_dma_tx_stream, LL_DMA_MEMORY_INCREMENT);LL_DMA_SetPeriphSize(this->m_dma_port, this->m_dma_tx_stream, LL_DMA_PDATAALIGN_BYTE);LL_DMA_SetMemorySize(this->m_dma_port, this->m_dma_tx_stream, LL_DMA_MDATAALIGN_BYTE);LL_DMA_DisableFifoMode(this->m_dma_port, this->m_dma_tx_stream);/* Interrupt Init */NVIC_SetPriority(COMIRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),this->m_nvic_priority, 0));NVIC_SetPriority(DMARxIRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),this->m_nvic_priority, 0));NVIC_SetPriority(DMATxIRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),this->m_nvic_priority, 0));NVIC_EnableIRQ(COMIRQn);NVIC_EnableIRQ(DMARxIRQn);NVIC_EnableIRQ(DMATxIRQn);/* UART init */USART_InitStruct.BaudRate = this->m_baudrate;USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;USART_InitStruct.StopBits = LL_USART_STOPBITS_1;USART_InitStruct.Parity = LL_USART_PARITY_NONE;USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;LL_USART_Init(this->m_serial_port, &USART_InitStruct);LL_USART_ConfigAsyncMode(this->m_serial_port);LL_USART_Enable(this->m_serial_port);LL_USART_EnableIT_IDLE(this->m_serial_port);//使用空闲中断,必须使能空闲中断LL_DMA_EnableIT_TC(this->m_dma_port,this->m_dma_tx_stream);LL_DMA_SetMemoryAddress(this->m_dma_port, m_dma_rx_stream,(uint32_t)(this->mp_buffer_for_dma_rx));LL_DMA_SetPeriphAddress(this->m_dma_port,this->m_dma_rx_stream, LL_USART_DMA_GetRegAddr(this->m_serial_port));LL_DMA_SetDataTransferDirection(this->m_dma_port,this->m_dma_rx_stream,LL_DMA_DIRECTION_PERIPH_TO_MEMORY);LL_DMA_SetDataLength(this->m_dma_port,this->m_dma_rx_stream, RECEIVE_BUFFER_SIZE); LL_DMA_EnableStream(this->m_dma_port,this->m_dma_rx_stream);//使能DMA流LL_USART_EnableDMAReq_RX(this->m_serial_port);LL_USART_EnableDMAReq_TX(this->m_serial_port);
}/*** @brief 发送数据到串口** 通过DMA(直接内存访问)方式将指定大小的数据发送到串口。** @param data 要发送的数据指针* @param size 要发送的数据大小(以字节为单位)*/
void serial_device::send(const uint8_t *data, uint16_t size) {// 重置传输完成标志reset_tx_complete_flag(); LL_DMA_SetMemoryAddress(this->m_dma_port, m_dma_tx_stream,(uint32_t)(data));LL_DMA_SetPeriphAddress(this->m_dma_port,this->m_dma_tx_stream, LL_USART_DMA_GetRegAddr(this->m_serial_port));LL_DMA_SetDataTransferDirection(this->m_dma_port,this->m_dma_tx_stream,LL_DMA_DIRECTION_MEMORY_TO_PERIPH);LL_DMA_SetDataLength(this->m_dma_port, m_dma_tx_stream, size); LL_DMA_EnableStream(this->m_dma_port, m_dma_tx_stream);//使能DMA流
}/*** @brief UART 中断处理函数** 该函数处理UART的中断,包括空闲中断和发送完成中断。** 当检测到空闲中断时,会清除空闲中断标志位,关闭DMA,清除DMA搬运完成标志,* 获取接收数据大小,更新接收缓冲区指针,并重新配置DMA以继续接收数据。** 当检测到发送完成中断时,会清除发送完成标志,清除DMA搬运完成中断,并禁用DMA流。*/
void serial_device::handle_isr_recv(){if((LL_USART_IsEnabledIT_IDLE(this->m_serial_port) != RESET) && (LL_USART_IsActiveFlag_IDLE(this->m_serial_port) != RESET))//空闲中断{ //清除空闲中断标志位 LL_USART_ClearFlag_IDLE(this->m_serial_port);//读取数据前将DMA关闭 LL_DMA_DisableStream(this->m_dma_port,this->m_dma_rx_stream);//清除DMA搬运完成标志if(this->m_dma_rx_stream == LL_DMA_STREAM_0){LL_DMA_ClearFlag_TC0(m_dma_port);}else if(this->m_dma_rx_stream == LL_DMA_STREAM_1){LL_DMA_ClearFlag_TC1(m_dma_port);}else if(this->m_dma_rx_stream == LL_DMA_STREAM_2){LL_DMA_ClearFlag_TC2(m_dma_port);}else if(this->m_dma_rx_stream == LL_DMA_STREAM_3){LL_DMA_ClearFlag_TC3(m_dma_port);}else if(this->m_dma_rx_stream == LL_DMA_STREAM_4){LL_DMA_ClearFlag_TC4(m_dma_port);}else if(this->m_dma_rx_stream == LL_DMA_STREAM_5){LL_DMA_ClearFlag_TC5(m_dma_port);}else if(this->m_dma_rx_stream == LL_DMA_STREAM_6){LL_DMA_ClearFlag_TC6(m_dma_port);}else if(this->m_dma_rx_stream == LL_DMA_STREAM_7){LL_DMA_ClearFlag_TC7(m_dma_port);}//获取接收数据大小m_rx_data_size = RECEIVE_BUFFER_SIZE - LL_DMA_GetDataLength(m_dma_port, m_dma_rx_stream);//得到串口收到的数据长度this->m_is_rx_complete = 1;#ifdef USE_RTOS_FOR_USARTthis->mpx_task_woken = pdFALSE;vTaskNotifyGiveFromISR(this->mp_task_handle,&mpx_task_woken); //发送通知#endifmp_buffer_for_user_rx = mp_buffer_for_dma_rx;//this->send(mp_buffer_for_user_rx,m_rx_data_size);if(this->mp_buffer_for_dma_rx == this->mp_rx_bufferA){ //切换缓冲区this->mp_buffer_for_dma_rx = this->mp_rx_bufferB;}else{this->mp_buffer_for_dma_rx = this->mp_rx_bufferA;}//重新开始接收,设置DMA的地址和数据大小LL_DMA_ConfigAddresses(this->m_dma_port,this->m_dma_rx_stream, LL_USART_DMA_GetRegAddr(this->m_serial_port), (uint32_t)(this->mp_buffer_for_dma_rx), LL_DMA_DIRECTION_PERIPH_TO_MEMORY);LL_DMA_SetDataLength(this->m_dma_port,this->m_dma_rx_stream, RECEIVE_BUFFER_SIZE); LL_DMA_EnableStream(this->m_dma_port,this->m_dma_rx_stream);//使能DMA流#ifdef USE_RTOS_FOR_USARTportYIELD_FROM_ISR(this->mpx_task_woken);#endif}
}#ifdef USE_RTOS_FOR_USART
void serial_device::set_notify_task(TaskHandle_t task_handle){this->mp_task_handle = task_handle;
}uint32_t serial_device::task_notify_take(){return ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
}
#endif/*** @brief 从接收缓冲区中读取数据指针** 获取接收缓冲区的数据指针,以便读取串口接收到的数据。** @return 返回接收缓冲区的指针*/
const uint8_t * serial_device::get_recv_data(){return this->mp_buffer_for_user_rx;
}/*** @brief 读取接收到的数据大小** 获取当前接收到的数据大小。** @return uint16_t 接收到的数据大小*/
uint16_t serial_device::get_recv_data_size(){return this->m_rx_data_size;
}
/*** @brief 检查串口接收是否准备好** 检查串口接收是否完成,如果完成则返回true,否则返回false。** @return 如果接收完成,返回true;否则返回false。*/
uint8_t serial_device::is_recv_ready(){return this->m_is_rx_complete;
}
/*** @brief 判断串口传输是否准备完成** 判断串口传输是否已经完成准备,可以开始传输数据。** @return 如果传输准备完成,返回非零值;否则返回0。*/
uint8_t serial_device::is_send_ready(){return this->m_is_tx_complete;
}
/*** @brief 重置接收完成标志位** 将接收完成标志位 `RecvCpltFlag` 重置为 0。*/
void serial_device::reset_rx_complete_flag(){this->m_is_rx_complete = 0;
}/*** @brief 重置传输完成标志** 该函数用于将传输完成标志重置为0。*/
void serial_device::reset_tx_complete_flag(){this->m_is_tx_complete = 0;
}
相关文章:
C++ STM32 F4xx USART LL库 DMA + IDLE ISR 驱动裸机 +FreeRTOS 任务通知
写的一般,大佬可以帮我看看 头文件 /********************************************************************************* file : usart_driver.hpp* brief : usart_driver program head**************************************************…...

RK3588在Android13/14如何查看GPU,NPU,DDR,RGA数据
由于Android13上selinux的权限管控加强,原来android12的方法已经无法获取到性能相关数据了,故单独介绍Android13上的性能数据获取 首先需要保障能过获取到root权限,adb root能够生效,adb shell进入shell命令行 mount -t debugfs…...

sentinel学习笔记6-限流降级(上)
本文属于sentinel学习笔记系列。网上看到吴就业老师的专栏,写的好值得推荐,我整理的有所删减,推荐看原文。 https://blog.csdn.net/baidu_28523317/category_10400605.html sentinel 实现限流降级、熔断降级、黑白名单限流降级、系统自适应…...
【Rust自学】6.4. 简单的控制流-if let
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 6.4.1. 什么是if let if let语法允许将if和let组合成一种不太冗长的方式来处理与一种模式匹配的值,同时忽略其余模式。 可以…...

【HarmonyOS】鸿蒙将资源文件夹Resource-RawFile下的文件存放到沙箱目录下
【HarmonyOS】鸿蒙将资源文件夹Resource-RawFile下的文件存放到沙箱目录下 一、问题背景 应用开发中,我们经常会遇到一些文件原先是放在资源文件夹 rawfile下,但是逻辑处理时,需要转移到本地沙箱才能操作。这种情况下,就需要将将…...

Vue项目中env文件的作用和配置
在实际项目的开发中,我们一般会经历项目的开发阶段、测试阶段和最终上线阶段,每一个阶段对于项目代码的要求可能都不尽相同,那么我们如何能够游刃有余的在不同阶段下使我们的项目呈现不同的效果,使用不同的功能呢?这里…...

在 Vue3 项目中实现计时器组件的使用(Vite+Vue3+Node+npm+Element-plus,附测试代码)
一、概述 记录时间 [2024-12-26] 本文讲述如何在 Vue3 项目中使用计时器组件。具体包括开发环境的配置,ViteVue 项目的创建,Element Plus 插件的使用,以及计时器组件的创建和使用。 想要直接实现计时器组件,查看文章的第四部分。…...

机器人C++开源库The Robotics Library (RL)使用手册(三)
进入VS工程,我们先看看这些功能函数及其依赖库的分布关系: rl命名空间下,主要有八大模块。 搞定VS后将逐个拆解。 1、编译运行 根据报错提示,配置相应错误的库(根据每个人安装位置不同而不同,我的路径如下:) 编译所有,Release版本耗时大约10分钟。 以rlPlan运动…...

Photoshop启动错误:找不到MSVCP140.dll的多步骤解决指南
在使用Adobe Photoshop(简称PS)进行创意设计或图像编辑时,有时会遇到软件启动报错的情况,其中“找不到MSVCP140.dll,无法继续执行代码”是一个常见的错误提示。这个错误通常意味着你的系统缺少了Microsoft Visual C Re…...

mac中idea菜单工具栏没有git图标了
1.右击菜单工具栏 2.选中VCS,点击添加 3.搜索你要的工具,选中点击确定就添加了 4.回到上面一个界面,选中你要放到工具栏的工具,点击应用就好了 5.修改图标,快捷键或者右击选中编辑图标 6.选择你要的图标就好了...

学习threejs,PerspectiveCamera透视相机和OrthographicCamera正交相机对比
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.PerspectiveCamera透…...
C#数学相关开发性能优化方法
本文Github地址:CSharp-MathOptimization.md 华为公司的C语言编程规范在开头就强调了: 一般情况下,代码的可阅读性高于性能,只有确定性能是瓶颈时,才应该主动优化。 本文讲述的方法没有经过大项目和大公司的检验&…...
【前沿 热点 顶会】AAAI 2025中与目标检测有关的论文
CP-DETR: Concept Prompt Guide DETR Toward Stronger Universal Object Detection(AAAI 2025) 最近关于通用物体检测的研究旨在将语言引入最先进的闭集检测器,然后通过构建大规模(文本区域)数据集进行训练࿰…...

APP投放的归因框架设计
一、归因相关概念回顾 在广告归因简介中我们介绍常见的归因模型和归因方法,我们先来回顾一下: 1. 背景 2. 设备标识 3. 归因模型 归因模型的多样性意味着每种模型都有其独特的优势和局限。关键在于选择一个与您的业务场景相匹配的模型,并且…...
职业生涯记录-1
机缘 普通人改命,要学会向上社交,能自然融入的圈子,多数是往下社交,没有多少价值,想要获取更多资源,但是有钱人只跟有钱人交朋友,不会带我们普通人玩,又错了,有钱人身边最不缺的就是有钱人,他们缺的是对他们有利用价值的朋友,往上社交的关键,你必须是个对他有利用价…...

江苏捷科云:可视化平台助力制造企业智能化管理
公司简介 江苏捷科云信息科技有限公司(以下简称“捷科”)是一家专注于云平台、云储存、云管理等产品领域的创新型企业,集研发、生产和销售于一体,致力于在网络技术领域打造尖端品牌。在推动制造业企业数字化转型的进程中…...
【ES6复习笔记】Promise对象详解(12)
1. 什么是 Promise? Promise 是 JavaScript 中处理异步操作的一种机制,它可以让异步操作更加容易管理和控制。Promise 对象代表一个异步操作的最终完成或失败,并提供了一种方式来处理操作的结果。 2. Promise 的基本语法 Promise 对象有三…...

01 Oracle 基本操作
Oracle 基本操作 初使用步骤 1.创建表空间 2.创建用户、设置密码、指定表空间 3.给用户授权 4.切换用户登录 5.创建表 注意点:oracle中管理表的基本单位是用户 文章目录 了解Oracle体系结构 1.创建表空间**2.删除表空间**3.创建用户4.给用户授权5.切换用户登录6.表操…...

C语言基础:指针(数组指针与指针数组)
数组指针与指针数组 数组指针 概念:数组指针是指向数组的指针,本质上还是指针 特点: 先有数组,后有指针 它指向的是一个完整的数组 一维数组指针: 语法: 数据类型 (*指针变量名)[行容量][列容量]; 案…...

本地部署 LLaMA-Factory
本地部署 LLaMA-Factory 1. 本地部署 LLaMA-Factory2. 下载模型3. 微调模型3-1. 下载数据集3-2. 配置参数3-3. 启动微调3-4. 模型评估3-5. 模型对话 1. 本地部署 LLaMA-Factory 下载代码, git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Facto…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...