Diving into the STM32 HAL-----DAC笔记
根据所使用的系列和封装,STM32微控制器通常只提供一个具有一个或两个专用输出的DAC,除了STM32F3系列中的少数零件编号实现两个DAC,第一个具有两个输出,另一个只有一个输出。STM32G4 系列的一些较新的 MCU 甚至提供多达 5 个独立的 DAC 模块,但只有前两个具有输出 I/O:其他 MCU 可以馈送 OPAMP、比较器和 ADC 等内部外设(如果支持)。
DAC 通道可以配置为在 8/12 位模式下工作,两个通道的转换可以独立或同时执行:最后一种模式在必须生成两个独立但同步信号的应用(例如,在音频应用中)非常有用。与 ADC 外设一样,甚至 DAC 也可以由专用定时器触发,以产生给定频率的模拟信号。
本章简要介绍了该外设最相关的特性。像往常一样,我们现在将简要说明 DAC 控制器的工作原理。
1、DAC 外设简介
DAC 是一种将数字转换为模拟信号的器件,模拟信号与提供的参考电压 VREF 成正比(见下图)。
DAC 有很多类。其中一些包括脉宽调制器 (PWM)、插值、Σ-Δ DC 和高速 DAC。我们在前面分析了如何使用 STM32 定时器生成 PWM 信号,并在 RC 低通滤波器的帮助下使用此功能生成输出正弦波。
STM32微控制器中的DAC外设基于常见的R-2R梯形电阻网络。电阻梯是由电阻器的重复单元制成的电路,使用由高精度电阻器制成的重复电阻器网络进行数模转换是一种廉价且简单的方法。该网络充当参考电压和接地之间的可编程分压器。
上图显示了一个 8 位 R-2R 电阻梯形网络。DAC 的每个位都由数字逻辑门驱动。理想情况下,这些门在 V = 0 (逻辑 0)和 V = VREF (逻辑 1)之间切换输入位。R–2R 网络使这些数字位在它们对输出电压 VOUT 的贡献中进行加权。
对于具有 N 位和 0V /VREF 逻辑电平的 R–2R DAC 的给定数值 D,输出电压 VOUT 为:
例如,如果 N = 12(因此 2^N = 4096)和 VREF = 3.3 V(STM32 MCU 中的典型模拟电源电压),则 VOUT 将在 0V (VAL = 0 = 00000000) 和最大值 (VAL = 4095 = 11111111) 之间变化: VOUT = 3.3 × 4095 / 4096 ≈ 3.29V,步长(对应于 VAL = 1):∆VOUT = 3.3 × 1 / 4096 ≈ 0.0002V。
但是,请始终记住,DAC 输出的精度和稳定性在很大程度上受到 VDDA 电源域质量和 PCB 布局的影响。
在 STM32 微控制器中,DAC 模块的精度为 12 位,但也可以配置为在 8 位工作。在 12 位模式下,数据可以左对齐或右对齐。根据销售类型和使用的封装,DAC 有两个输出通道,每个通道都有自己的转换器。在双 DAC 通道模式下,当两个通道组合在一起进行同步更新操作时,可以独立或同时进行转换。输入参考引脚 VREF+ (与其他模拟外设共享)可用于更好的分辨率。与 ADC 外设一样,甚至 DAC 也可以与 DMA 控制器结合使用,以在给定的固定频率下产生可变输出电压。这在音频应用中非常有用,或者当我们想要生成在给定载波频率下工作的模拟信号时。正如我们将在本章后面看到的那样,STM32 DAC 能够产生噪声波和三角波。
最后,STM32 MCU中实现的DAC为每个通道集成了一个输出缓冲器(见上图),可用于降低输出阻抗并直接驱动外部负载,而无需添加外部运算放大器。每个 DAC 通道输出缓冲器都可以启用和禁用。
2、HAL_DAC 模块
为了操作 DAC 外设,HAL 定义了 C 结构体DAC_HandleTypeDef,其定义方式如下:
typedef struct {DAC_TypeDef *Instance; /* Pointer to DAC descriptor */__IO HAL_DAC_StateTypeDef State; /* DAC communication state */HAL_LockTypeDef Lock; /* DAC locking object */DMA_HandleTypeDef *DMA_Handle1; /* Pointer DMA handler for channel 1 */DMA_HandleTypeDef *DMA_Handle2; /* Pointer DMA handler for channel 2 */__IO uint32_t ErrorCode; /* DAC Error code */
} DAC_HandleTypeDef;
• Instance:是指向我们将要使用的 DAC 描述符的指针。例如,DAC1 是第一个 DAC 外设的描述符。
• DMA_Handle{1,2}:这是指向配置为在 DMA 模式下执行 D/A 转换的 DMA 处理程序的指针。在具有两个 output 通道的 DACs 中,存在两个独立的 DMA 处理程序,用于为每个通道执行转换。
DAC_HandleTypeDef 结构体与目前使用的其他处理程序描述符不同。事实上,它没有提供专用的 Init 参数,让HAL_DAC_Init() 函数使用它来配置 DAC。这是因为 DAC 的有效配置是在通道级别执行的,并且需要结构体DAC_ChannelConfTypeDef,其定义方式如下:
typedef struct {uint32_t DAC_Trigger; /* Specifies the external trigger for the selected DAC channel */uint32_t DAC_OutputBuffer;/* Specifies whether the DAC channel output buffer is enabled or disabled */
} DAC_ChannelConfTypeDef;
• DAC_Trigger:指定用于触发 DAC 转换的源。值DAC_TRIGGER_NONE 表示当使用 HAL_DAC_SetValue() 函数手动驱动 DAC;值DAC_TRIGGER_SOFTWARE表示当 DAC 在 DMA 模式下驱动而没有定时器来“计时”;值 DAC_TRIGGER_Tx_TRGO 表示由专用定时器驱动。
• DAC_OutputBuffer:启用专用输出缓冲区。
要配置 DAC 通道,我们使用函数:
HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel);
它接受指向 DAC_HandleTypeDef 结构体实例的指针,指向之前看到的 DAC_ChannelConfTypeDef 结构体实例的指针,以及宏DAC_CHANNEL_1来配置第一个通道并DAC_CHANNEL_2配置第二个通道。
在一些较新的 STM32 微控制器中,如 STM32L476 或 STM32G474,DAC 还提供额外的低功耗功能。例如,可以启用采样保持电路,即使 DAC 断电,也可以保持输出电压稳定。这在电池供电应用中非常有用。在这些 MCU 中, DAC_ChannelConfTypeDef 结构的结构不同,以允许配置这些附加功能。
2.1、手动驱动 DAC
外设可以手动驱动,也可以使用 DMA 和触发源(例如,专用定时器)驱动。我们现在要分析第一种方法,当我们不需要高频转换时使用。第一步包括通过调用函数
HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel);
该函数接受指向 DAC_HandleTypeDef 结构体实例的指针,以及要激活的通道(DAC_CHANNEL_1 或 DAC_CHANNEL_2)。
启用 DAC 通道后,我们可以通过调用函数来执行转换:
HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data);
其中,Alignment 参数可以假设DAC_ALIGN_8B_R以 8 位模式驱动 DAC 的值,DAC_ALIGN_12B_L 或 DAC_ALIGN_12B_R 以 12 位模式驱动 DAC,分别传递左对齐或右对齐的输出值。
以下示例设计展示了如何手动驱动 DAC 外设。该示例基于以下事实:板中DAC一个输出通道对应于连接到 LED 的 PA5 引脚。这允许我们使用 DAC 渐变 LED 的 ON/OFF。
代码很简单。配置 DAC,以便将通道 2 用作输出通道。因此,PA5 配置为模拟输出。请注意,由于我们将手动驱动 DAC 转换,因此通道触发源设置为 DAC_TRIGGER_NONE。最后,main() 只不过是一个无限循环,它增加/减少输出电压,使 LED 渐变开/关。
2.2、使用定时器在 DMA 模式下驱动 DAC
DAC 外设最常见的用途是生成具有给定频率的模拟波形(例如,在音频应用中)。如果是这种情况,那么驱动 DAC 的最佳方法是使用 DMA 和定时器来触发转换。
要启动 DAC 并在 DMA 模式下执行传输,我们需要配置相应的 DMA 通道/流对并使用以下功能:
HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment);
它接受指向 DAC_HandleTypeDef 结构实例的指针、要激活的通道(DAC_CHANNEL_1 或 DAC_CHANNEL_2)、指向要在 DMA 模式下传输的值数组的指针、其长度以及内存中输出值的对齐方式,它可以假设值DAC_ALIGN_8B_R以 8 位模式驱动 DAC, DAC_ALIGN_12B_L 或 DAC_ALIGN_12B_R 以 12 位模式驱动 DAC,分别将输出值左对齐或右对齐。
例如,我们可以使用 DAC 轻松生成正弦波。在以前,我们分析了如何使用定时器的 PWM 模式来产生正弦波。如果我们的 MCU 提供 DAC,那么同样的操作可以更容易地进行。此外,根据具体的应用,通过使能 output buffer,我们可以完全驱动外部元件。
为了生成以给定频率运行的正弦波,我们必须将整个周期分为多个步骤。通常,超过 200 步是输出波的良好近似值。这意味着,如果我们想生成 50Hz 的正弦波,那么我们执行一次转换的间隔为: fsinewave = 50Hz ∗ 200 = 10kHz。
由于 STM32 DAC 的分辨率为 12 位,我们必须使用以下公式将对应于最大输出电压的值 4095 除以 200 步:
其中 ns 是样本数,在我们的示例中为 200。
使用上述公式,我们可以生成一个初始化向量,以 DMA 模式馈送 DAC。与 ADC 外设一样,我们可以使用配置为以 10kHz 给出的频率触发 TRGO 线路的定时器。以下示例说明如何在 STM32F072 MCU 中使用 DAC 生成 50Hz 正弦波。
#define PI 3.14159
#define SAMPLES 200/* Private variables ---------------------------------------------------------*/
DAC_HandleTypeDef hdac;
TIM_HandleTypeDef htim6;
DMA_HandleTypeDef hdma_dac_ch1;/* Private function prototypes -----------------------------------------------*/
static void MX_DAC_Init(void);
static void MX_TIM6_Init(void);int main(void) {uint16_t IV[SAMPLES], value;HAL_Init();SystemClock_Config();/* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_DAC_Init();MX_TIM6_Init();for (uint16_t i = 0; i < SAMPLES; i++) {value = (uint16_t) rint((sinf(((2*PI)/SAMPLES)*i)+1)*2048);IV[i] = value < 4096 ? value : 4095;}HAL_DAC_Init(&hdac);HAL_TIM_Base_Start(&htim6);HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)IV, SAMPLES, DAC_ALIGN_12B_R);while(1);
}/* DAC init function */
void MX_DAC_Init(void) {DAC_ChannelConfTypeDef sConfig;GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_DAC1_CLK_ENABLE();/**DAC Initialization */hdac.Instance = DAC;HAL_DAC_Init(&hdac);/**DAC channel OUT1 config */sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1);/**DAC GPIO ConfigurationPA4 ------> DAC_OUT1*/GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* Peripheral DMA init*/hdma_dac_ch1.Instance = DMA1_Channel3;hdma_dac_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;hdma_dac_ch1.Init.PeriphInc = DMA_PINC_DISABLE;hdma_dac_ch1.Init.MemInc = DMA_MINC_ENABLE;hdma_dac_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;hdma_dac_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;hdma_dac_ch1.Init.Mode = DMA_CIRCULAR;hdma_dac_ch1.Init.Priority = DMA_PRIORITY_LOW;HAL_DMA_Init(&hdma_dac_ch1);__HAL_LINKDMA(&hdac,DMA_Handle1,hdma_dac_ch1);
}/* TIM6 init function */
void MX_TIM6_Init(void) {TIM_MasterConfigTypeDef sMasterConfig;__HAL_RCC_TIM6_CLK_ENABLE();htim6.Instance = TIM6;htim6.Init.Prescaler = 0;htim6.Init.CounterMode = TIM_COUNTERMODE_UP;htim6.Init.Period = 4799;HAL_TIM_Base_Init(&htim6);sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig);
}
函数 MX_DAC_Init() 配置 DAC,以便在生成 TIM6 TRGO 线路时,第一个通道执行转换。此外,DMA 也进行了相应的配置,将其设置为循环模式,以便它连续传输 DAC 数据寄存器中初始化向量的内容。MX_TIM6_Init() 函数设置 TIM6,使其以等于 10kHz 的频率溢出,从而触发内部连接到 DAC 的 TRGO 线。最后,根据上面公式生成初始化向量。然后,其内容用于馈送 DAC,在 TIM6 启用后,DAC 以 DMA 模式启动。
通过将示波器探头连接到板子的 PA4 引脚,我们可以看到 DAC 产生的输出正弦波(见上图)。如果我们想知道 DMA 模式下的 DAC 转换何时完成,我们可以实现回调函数:
void HAL_DACEx_ConvCpltCallbackChX(DAC_HandleTypeDef* hdac);
它由 HAL_DMA_IRQHandler() 例程自动调用,该例程从与 DAC 外设关联的 DMA 通道的 ISR 调用。函数名称中的最后一个 X 必须替换为 1 或 2,具体取决于所使用的通道。
请注意,在 STM32G4 系列中,DAC 外设寄存器必须通过字(32 位)访问。因此,上面的代码中 IV 数组和值变量应被定义为 unit32_t。
2.3、三角波生成
在一些音频应用程序中,生成三角波很有用。虽然使用前面的 DMA 技术完全可以生成三角波,但 STM32 DAC 允许在硬件中生成三角形的波。
上图显示了定义三角波形状的三个参数。让我们分析一下它们。
• Amplitude:这是一个介于 0 到 0xFFF 之间的值,它决定了波的最大高度。它与 offset 值直接相关。Amplitude 不能是任意值,但它是固定值列表的一部分。
• Offset:最小输出值,代表波浪的最低点。偏移量和振幅之和不能超过最大值 0xFFF。这意味着波的最大振幅将由amplitude - offset给出。
• Frequency:是波的频率,它由连接到 DAC 的定时器的更新频率决定。定时器的更新频率由下面的公式确定。
这意味着,如果我们想产生幅度等于 2047 的 50Hz 三角波,则需要将运行在 48MHz 的定时器的预分频器配置为 234。
为了生成三角波形,我们使用函数
HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude);
它接受要使用的 DAC 通道和所需的幅度。offset 是使用 HAL_DAC_SetValue() 例程配置的。生成三角波的完整过程如下:
• 配置用于生成波形的 DAC 通道。
• 配置与 DAC 关联的定时器,并根据上面公式配置其预分频器(应该是period才对)。
• 使用 HAL_DAC_Start() 函数启动 DAC。
• 使用 HAL_DAC_SetValue() 例程配置所需的偏移值。
• 通过调用 HAL_DACEx_TriangleWaveGenerate() 函数开始三角波生成。
int main(void) {HAL_Init();SystemClock_Config();/* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_DAC_Init();MX_TIM6_Init();while(1);
}/* DAC init function */
void MX_DAC_Init(void) {DAC_ChannelConfTypeDef sConfig;GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_DAC1_CLK_ENABLE();/**DAC Initialization */hdac.Instance = DAC;HAL_DAC_Init(&hdac);/**DAC channel OUT1 config */sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1);/**DAC GPIO ConfigurationPA4 ------> DAC_OUT1*/GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_DAC_Start(&hdac, DAC_CHANNEL_1);HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0);HAL_DACEx_TriangleWaveGenerate(&hdac, DAC_CHANNEL_1, DAC_TRIANGLEAMPLITUDE_2047);
}/* TIM6 init function */
void MX_TIM6_Init(void) {TIM_MasterConfigTypeDef sMasterConfig;__HAL_RCC_TIM6_CLK_ENABLE();htim6.Instance = TIM6;htim6.Init.Prescaler = 0;htim6.Init.CounterMode = TIM_COUNTERMODE_UP;htim6.Init.Period = 234;HAL_TIM_Base_Init(&htim6);sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig);HAL_TIM_Base_Start(&htim6);
}
2.4、噪声波生成
STM32 DAC还能够使用伪随机发生器产生噪声波(见下图)。
这在某些应用领域(如音频应用程序和 RF 系统)中非常有用。此外,它还可用于提高 ADC 外设的精度(https://bit.ly/25lJoqx)。
为了产生可变幅度的伪噪声,DAC 中提供了一个 LFSR (线性反馈移位寄存器)。这个 register 预加载了 0xAAA 值,它可以部分或全部屏蔽。然后将该值加到 DAC 数据寄存器内容中,而不会溢出,然后将该值用作输出值。
可以使用 HAL 例程
HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude);
它接受用于生成波的通道和振幅值,该值被添加到 LFSR 内容中以生成伪随机波。与三角波生成一样,定时器可用于触发转换:这意味着波的频率由定时器的溢出频率决定。
int main(void) {float tempV;uint32_t tempInt;char msg[30];HAL_Init();SystemClock_Config();/* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_DAC_Init();MX_TIM6_Init();MX_USART1_UART_Init();while (1){tempInt= HAL_DAC_GetValue(&hdac,DAC_CHANNEL_1);tempV=(float)tempInt*(3.3/4096); sprintf(msg, "ch1 = %.3f \r\n",tempV);HAL_UART_Transmit(&huart1, (uint8_t*) msg, strlen(msg), HAL_MAX_DELAY); HAL_Delay(100);}
}/* DAC init function */
void MX_DAC_Init(void) {DAC_ChannelConfTypeDef sConfig;GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_DAC1_CLK_ENABLE();/**DAC Initialization */hdac.Instance = DAC;HAL_DAC_Init(&hdac);/**DAC channel OUT1 config */sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1);/**DAC GPIO ConfigurationPA4 ------> DAC_OUT1*/GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_DAC_Start(&hdac, DAC_CHANNEL_1);HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0);HAL_DACEx_NoiseWaveGenerate(&hdac, DAC_CHANNEL_1, DAC_LFSRUNMASK_BITS7_0);
}/* TIM6 init function */
void MX_TIM6_Init(void) {TIM_MasterConfigTypeDef sMasterConfig;__HAL_RCC_TIM6_CLK_ENABLE();htim6.Instance = TIM6;htim6.Init.Prescaler = 0;htim6.Init.CounterMode = TIM_COUNTERMODE_UP;htim6.Init.Period = 234;HAL_TIM_Base_Init(&htim6);sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig);HAL_TIM_Base_Start(&htim6);
}
相关文章:
Diving into the STM32 HAL-----DAC笔记
根据所使用的系列和封装,STM32微控制器通常只提供一个具有一个或两个专用输出的DAC,除了STM32F3系列中的少数零件编号实现两个DAC,第一个具有两个输出,另一个只有一个输出。STM32G4 系列的一些较新的 MCU 甚至提供多达 5 个独立的…...
每日一题 LCR 078. 合并 K 个升序链表
LCR 078. 合并 K 个升序链表 使用二分法就可以解决 class Solution { public:ListNode* mergeKLists(vector<ListNode*>& lists) {int n lists.size();if(n 0){return nullptr;}ListNode* ans ;ans binMerge(lists,0,n-1);return ans;}ListNode* binMerge(vector…...
如何在分布式环境中实现高可靠性分布式锁
目录 一、简单了解分布式锁 (一)分布式锁:应对分布式环境的同步挑战 (二)分布式锁的实现方式 (三)分布式锁的使用场景 (四)分布式锁需满足的特点 二、Redis 实现分…...
如何利用java爬虫获得淘宝商品评论
在当今数字化时代,数据的价值日益凸显,尤其是对于电商平台而言,商品评论作为用户反馈的重要载体,蕴含着丰富的信息。本文将详细介绍如何利用Java爬虫技术获取淘宝商品评论,包括代码示例和关键步骤解析。 淘宝商品评论的…...
SQLAlchemy,ORM的Python标杆!
嗨,Python的小伙伴们!今天咱们来了解 SQLAlchemy,这可是对象关系映射(ORM)里的超级标杆哦!它就像一座神奇的桥梁,能让我们用 Python 代码轻松地和数据库打交道,不用写复杂的 SQL 语句…...
时序论文23|ICML24谷歌开源零样本时序大模型TimesFM
论文标题:A DECODER - ONLY FOUNDATION MODEL FOR TIME - SERIES FORECASTING 论文链接:https://arxiv.org/abs/2310.10688 论文链接:https://github.com/google-research/timesfm 前言 谷歌这篇时间序列大模型很早之前就在关注ÿ…...
java http body的格式 application/x-www-form-urlencoded不支持文件上传
在Java中,HTTP请求的body部分可以包含多种格式的数据,主要包括以下几种: application/x-www-form-urlencoded:这种格式将数据编码成键值对的形式,键和值都进行了URL编码,键值对之间用&符号连接。…...
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
头歌实训:利用kmp算法求子串在主串中不重叠出现的次数 文章目录 任务描述编程要求测试说明输入格式输出格式样例输入1样例输出1样例输入2样例输出2 源代码: 任务描述 本关任务:编写一个程序,利用kmp算法求子串在主串中不重叠出现…...
WPF动画
在 WPF(Windows Presentation Foundation)中,主要有两种类型的动画:属性动画(Property Animation)和关键帧动画(Key - Frame Animation)。属性动画用于简单地从一个起始值平滑地过渡…...
Kafka 分区分配及再平衡策略深度解析与消费者事务和数据积压的简单介绍
Kafka:分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析:从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析:…...
如何在 UniApp 中实现 iOS 版本更新检测
随着移动应用的不断发展,保持应用程序的更新是必不可少的,这样用户才能获得更好的体验。本文将帮助你在 UniApp 中实现 iOS 版的版本更新检测和提示,适合刚入行的小白。我们将分步骤进行说明,每一步所需的代码及其解释都会一一列出…...
Android 14.0 kenel中修改rom系统内部存储的大小
1. 前言 在14.0的系统rom产品开发定制中,在对一些产品开发中的配置需求方面,由于在产品后续订单中,有些产品是出口的,但是硬件方面已经定板,时间比较仓促,所以 就需要软件方面在rom内部存储的大小方面作假,修改rom真实的大小容量,所以就需要在kenel驱动部分来修改这部分…...
JavaScript 函数
JavaScript中也可以使用函数,但是使用的方法有些不同;需要使用function关键字定义一个函数(或者使用匿名函数或者箭头函数)。但是需要特别注意的是:在类中定义函数时,一定不可以使用箭头函数,因…...
js+new Date()+moment+时区
文章目录 概要一、Date对象基础知识1. 创建Date对象2. 获取日期和时间信息3. 设置日期和时间 二、Date对象的应用1. 日期格式化2. 时间差计算3. 倒计时功能 moment.jsmoment 常见场景应用时区差别亚洲欧洲美洲大洋洲 时区时间说明 概要 一、Date对象基础知识 1. 创建Date对象…...
OpenCV、YOLO、VOC、COCO之间的关系和区别
OpenCV、YOLO、COCO 和 VOC 是计算机视觉和深度学习领域常见的几个名词,它们分别代表不同的工具、算法和数据集,之间有一些联系和区别。下面分别说明它们的定义、用途以及相互关系。 1. OpenCV(Open Source Computer Vision Library…...
迁移学习理论与应用
迁移学习(Transfer Learning)是一种机器学习技术,旨在将一个任务(源任务)上学到的知识迁移到另一个相关但不完全相同的任务(目标任务)上,从而提高目标任务的学习效果。这种方法的核心…...
Python-简单病毒程序合集(一)
前言:简单又有趣的Python恶搞代码,往往能给我们枯燥无味的生活带来一点乐趣,激发我们对编程的最原始的热爱。那么话不多说,我们直接开始今天的编程之路。 编程思路:本次我们将会用到os,paltform,threading,ctypes,sys,…...
AI安全:从现实关切到未来展望
近年来,人工智能技术飞速发展,从简单的图像识别到生成对话,从自动驾驶到医疗诊断,AI技术正深刻改变着我们的生活。然而,伴随着这些进步,AI的安全性和可控性问题也日益凸显。这不仅涉及技术层面的挑战&#…...
集成金蝶云星空数据至MySQL的完整案例解析
金蝶云星空数据集成到MySQL的技术案例分享 在企业信息化系统中,数据的高效流动和准确同步是确保业务连续性和决策支持的重要环节。本文将聚焦于一个具体的系统对接集成案例——金蝶云星空的数据集成到MySQL,方案名称为“2金蝶物料同步到商城中间表”。 …...
C++格式化输入输出【练习版】
一、引言 在 C 编程中,准确地进行输入输出操作是构建功能强大且用户友好程序的关键。格式化输入输出允许我们以特定的格式展示数据,确保数据的可读性和准确性。本文将深入探讨 C 的格式化输入输出,通过丰富的练习例题和详细的答案解析&#x…...
aws服务(二)机密数据存储
在AWS(Amazon Web Services)中存储机密数据时,安全性和合规性是最重要的考虑因素。AWS 提供了多个服务和工具,帮助用户确保数据的安全性、机密性以及合规性。以下是一些推荐的存储机密数据的AWS服务和最佳实践: 一、A…...
CIO40: 回头再看ERP之“4问”
1、在数字化时代的今天,ERP现在的定位是? ERP软件财务化,我觉得是一个趋势,但是短期内(2-3年)ERP依然是企业的核心系统。这要看企业外部系统的建设情况,ERP系统的使用深度(特别是一些…...
数据库类型介绍
1. 关系型数据库(Relational Database, RDBMS): • 定义:基于关系模型(即表格)存储数据,数据之间通过外键等关系相互关联。 • 特点:支持复杂的SQL查询,数据一致性和完整…...
深入理解 Spring Boot 的 CommandLineRunner 原理及使用
引言 在开发 Spring Boot 应用程序时,我们经常需要在应用程序启动后执行一些初始化任务,比如加载初始数据、连接外部服务、执行健康检查等。Spring Boot 提供了 CommandLineRunner 接口,使得这些任务的实现变得非常简单和直观。本文将深入探…...
人工智能深度学习-Torch框架-数学运算
数学的基本操作 1.floor:向下取整 2.celi:向上取整 3.round:四舍五入,这里的四舍五入还要看前面整数的奇偶性,基进偶不进 4.trunc:只保留整数 5.frac:只保留小数部分 6.fix:向…...
操作系统的理解
目录 一、冯伊诺曼体系结构 二、操作系统的概念 三、如何理解“管理”? 四、系统调用和库调用的概念 一、冯伊诺曼体系结构 冯伊诺曼体系结构描述的是计算机硬件结构,相当于计算机的骨架。它大体可以分为4部分: 输入设备:键盘…...
SpringDataNeo4j使用详解
SDN快速入门 Spring Data Neo4j简称SDN,是Spring对Neo4j数据库操作的封装,其底层基于neo4j-java-driver实现。 我们使用的版本为:6.2.3,官方文档: 下面我们将基于项目中的运输路线业务进行学习,例如&#…...
undefined symbol: __nvJitLinkComplete_12_4, version libnvJitLink.so.12 问题解决
在部署运行opencompass项目时遇到了如下报错: ImportError: /data/conda/envs/opencompass/lib/python3.10/site-packages/torch/lib/../../nvidia/cusparse/lib/libcusparse.so.12: undefined symbol: __nvJitLinkComplete_12_4, version libnvJitLink.so.12…...
记一次:软著申请
前言:公司每年都有申请软著或者发明,可惜没有我的名字,没关系,我可以按个人的名义去申请一个,于是乎就有了这篇文章。话不多说,展示 之前还犹豫要不要发表一下,经过朋友的劝说,自己的…...
IntelliJ+SpringBoot项目实战(四)--快速上手数据库开发
对于新手学习SpringBoot开发,可能最急迫的事情就是尽快掌握数据库的开发。目前数据库开发主要流行使用Mybatis和Mybatis Plus,不过这2个框架对于新手而言需要一定的时间掌握,如果快速上手数据库开发,可以先按照本文介绍的方式使用JdbcTemplat…...
筑起数字堡垒:解析AWS高防盾(Shield)的全面防护能力
引言 在数字化时代,网络攻击的频率和复杂性持续增加。分布式拒绝服务(DDoS)攻击成为威胁在线业务的主要手段之一。AWS推出的高防盾(AWS Shield)是一项专注于DDoS防护的服务,帮助用户保护其应用程序和数据免…...
python语言基础
1. 基础语法 Q: Python 中的变量与数据类型有哪些? A: Python 支持多种数据类型,包括数字(整数 int、浮点数 float、复数 complex)、字符串 str、列表 list、元组 tuple、字典 dict 和集合 set。每种数据类型都有其特定的用途和…...
vue2 src_Todolist编辑($nextTick)
main.js //引入Vue import Vue from "vue"; //引入App import App from ./App;//关闭Vue的生产提示 Vue.config.productionTip false;new Vue({el: #app,render: h > h(App),beforeCreate() {//事件总线Vue.prototype.$bus this;} });App.vue <template>…...
复习!!!
前言: 今天好像没有复习什么,对了,老师让我们写作业来着 那个乌云漏洞网站真的好啊,虽然很老,但是有思路啊 乌云(WooYun.org)历史漏洞查询---http://WY.ZONE.CI 复习: 今天主要复习了nuclei工具的用法…...
面试题---深入源码理解MQ长轮询优化机制
引言 在分布式系统中,消息队列(MQ)作为一种重要的中间件,广泛应用于解耦、异步处理、流量削峰等场景。其中,延时消息和定时消息作为MQ的高级功能,能够进一步满足复杂的业务需求。为了实现这些功能…...
使用 PyTorch TunableOp 加速 ROCm 上的模型
Accelerating models on ROCm using PyTorch TunableOp — ROCm Blogs (amd.com) 在这篇博客中,我们将展示如何利用 PyTorch TunableOp 在 AMD GPU 上使用 ROCm 加速模型。我们将讨论通用矩阵乘法(GEMM)的基础知识,展示调优单个 G…...
配置Springboot+vue项目在ubuntu20.04
一、jdk1.8环境配置 (1) 安装jdk8: sudo apt-get install openjdk-8-jdk (2) 检查jdk是否安装成功: java -version(3) 设置JAVA_HOME: echo export JAVA_HOME/usr/lib/jvm/java-17-openjdk-amd64 >> ~/.bashrc echo export PATH$J…...
基于SpringBoot的在线教育系统【附源码】
基于SpringBoot的在线教育系统 效果如下: 系统登录页面 系统管理员主页面 课程管理页面 课程分类管理页面 用户主页面 系统主页面 研究背景 随着互联网技术的飞速发展,线上教育已成为现代教育的重要组成部分。在线教育系统以其灵活的学习时间和地点&a…...
国土安全部发布关键基础设施安全人工智能框架
美国国土安全部 (DHS) 发布建议,概述如何在关键基础设施中安全开发和部署人工智能 (AI)。 https://www.dhs.gov/news/2024/11/14/groundbreaking-framework-safe-and-secure-deployment-ai-critical-infrastructure 关键基础设施中人工智能的角色和职责框架 https:/…...
散户持股增厚工具:智能T0算法交易
最近市场很多都说牛市,但是大多数朋友怎么来的又怎么吐出去了。这会儿我们用T0的智能算法交易又可以增厚我们的持仓收益。简单来说,就是基于用户原有的股票持仓,针对同一标的,配合智能T0算法,每天全自动操作࿰…...
28、js基本数据类型
<!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title></title> </head> <body> </body> <script> //JS是弱语言类型,只有一种var,由隐藏类型 //基本数据类型…...
MacOS下的Opencv3.4.16的编译
前言 MacOS下编译opencv还是有点麻烦的。 1、Opencv3.4.16的下载 注意,我们使用的是Mac,所以ios pack并不能使用。 如何嫌官网上下载比较慢的话,可以考虑在csdn网站上下载,应该也是可以找到的。 2、cmake的下载 官网的链接&…...
[免费]SpringBoot+Vue毕业设计论文管理系统【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue毕业设计论文管理系统,分享下哈。 项目视频演示 【免费】SpringBootVue毕业设计论文管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 现代经济快节奏发展以及不断完善升级的信…...
科研深度学习:如何精选GPU以优化服务器性能
GPU在科研深度学习中的核心价值 在科研深度学习的范畴内,模型训练是核心环节。面对大规模参数的模型训练,这往往是科研过程中最具挑战性的部分。传统CPU的计算模式在处理复杂模型时,训练时间会随着模型复杂度的增加而急剧增长,这…...
嵌入式系统与OpenCV
目录 一、OpenCV 简介 二、嵌入式 OpenCV 的安装方法 1. Ubuntu 系统下的安装 2. 嵌入式 ARM 系统中的安装 3. Windows10 和树莓派系统下的安装 三、嵌入式 OpenCV 的性能优化 1. 介绍嵌入式平台上对 OpenCV 进行优化的必要性。 2. 利用嵌入式开发工具,如优…...
C++学习——编译的过程
编译的过程——预处理 引言预处理包含头文件宏定义指令条件编译 编译、链接 引言 C程序编译的过程:预处理 -> 编译(优化、汇编)-> 链接 编译和链接的内容可以查阅这篇文章(点击查看) 预处理 编译预处理是指&a…...
接口测试和单元测试
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 接口测试的本质:就是通过数据驱动,测试类里面的函数。 单元测试的本质:通过代码级别,测试函数。 单元测试的框架…...
redis工程实战介绍(含面试题)
文章目录 redis单线程VS多线程面试题**redis是多线程还是单线程,为什么是单线程****聊聊redis的多线程特性和IO多路复用****io多路复用模型****redis如此快的原因** BigKey大批量插入数据测试数据key面试题海量数据里查询某一固定前缀的key如果生产上限值keys * ,fl…...
深度学习:GPT-1的MindSpore实践
GPT-1简介 GPT-1(Generative Pre-trained Transformer)是2018年由Open AI提出的一个结合预训练和微调的用于解决文本理解和文本生成任务的模型。它的基础是Transformer架构,具有如下创新点: NLP领域的迁移学习:通过最…...
内嵌编辑器+AI助手,Wave Terminal打造终端新体验
作为新一代终端工具的佼佼者,Wave Terminal 突破性地将传统命令行与现代图形界面相结合,为开发者带来全新的操作体验。这款创新的开源终端工具跨越了操作系统的界限,完美支持 macOS、Windows 和 Linux 平台,特别适合需要频繁处理远…...