WS2812B彩灯 STM32库函数开发:PWM+DMA(stm32f407VET6)

这里写目录标题

  • 1、概述
  • 2、芯片级联方法
  • 3、数据传输特性
  • 4、程序实例
    • 4.1、硬件电路
    • 4.2、定时器初始化
    • 4.3、DMA初始化
    • 4.4、RGB数据驱动
  • 5、完整代码
    • 5.1、WS2812B.c
    • 5.2、WS2812B.h
    • 5.3、main.c

1、概述

WS2812B是一种常见的RGB LED灯带,每个灯珠内部都有一个芯片控制,通过发送特定的时序数据来控制其亮灭。发送数据时,需要按照一定的时序发送24位RGB数据,其中高位在前低位在后,格式为GRB。发送数据时,需要注意不仅仅是发送高电平或低电平,而是要发送占空比不同的PWM波,比如给予一定的高电平和低电平时间。重置码是发送一个持续280us的低电平信号。可以先发送一组24位的数据,然后接一个重置信号表示一组结束。数据采用单总线,归零码的通讯方式, 每个像素点接收24bit数据,溢出的数据传输给下一个像素点。

WS2812B作为一种常见的RGB LED(三色LED)驱动芯片,具有以下优点和缺点:
优点:

  • 集成度高:WS2812B芯片将RGB LED和控制电路集成在一个小型封装中,简化了设计和布线过程。
  • 控制灵活:每个WS2812B芯片都具有独立的控制电路,可以通过单线串联多个LED,并根据需要独立控制每个LED的颜色和亮度。
  • 易于编程:WS2812B芯片与微控制器通信采用简单的串行通信协议,使得编程和控制相对容易。
  • 色彩丰富:每个WS2812B芯片都能够显示256级亮度的红、绿、蓝三个颜色通道,通过调整三个颜色的亮度可以实现丰富多彩的效果。

缺点:

  • 电源需求高:WS2812B芯片对电源的要求较高,供电电源需要稳定而强大,以保证每个芯片的正常工作。
  • 刷新频率限制:由于通信协议的限制,WS2812B的刷新频率相对较低,控制大量LED时可能会出现刷新延迟。
  • 单点故障影响范围大:因为WS2812B芯片串联连接,当某个芯片发生故障时,可能会影响整个串联链路的正常工作。

2、芯片级联方法

典型应用电路:其硬件电路仅需要三根线(5V电源线、GND、DI信号线)。其仅需要一个具有定时器PWM输出功能的GPIO口,即可对多个灯进行控制。
在这里插入图片描述

数据传输示意图:下图中 D1 为 MCU 端发送的数据,D2、D3、D4 为级联电路自动整形转发的数据。
在这里插入图片描述

3、数据传输特性

在这里插入图片描述
如上图所示,当数据线传入灯带后,第一个灯珠截取第一个24位数据自己使用,而后会将其余的数据进行整形后发送给第二颗灯珠,第二颗灯珠会依次截取24位数据并对剩余数据进行整形发送,以此类推。直到最后一组数据被显示为止。每一组24位数根据数据的不同显示不同的颜色和亮度(每个像素点的三基色颜色可实现256级亮度显示, 完成16777216种颜色的全真色彩显示)。
在这里插入图片描述

4、程序实例

根据其电位控制要求,通过软件实现IO控制模拟0码和1码并进行数据传输在理论上是可以实现的,但是在实际过程中,会过于占用CPU资源,所以我们这里采用TIM1+PWM+DMA的控制方式。
通过控制PWM占空比发送0码和1码,额定周期为1.25us,则频率为800Khz
0码PWM占空比:
(0码高电平时间)/(周期)—> 0.4 / 1.25 = 0.32
用占空比乘以定时器重装值加一就是0码的CCR值(代表PWM高电平计数个数)—>
0.32 * (209+1) = 67.2(我实际使用的60,左右相差不太大都可正常使用)
1码PWM占空比:
(1码高电平时间)/(周期)—> 0.8 / 1.25 = 0.64
用占空比乘以定时器重装值加一就是1码的CCR值(代表PWM高电平计数个数)—>
0.64 * (209+1) = 134.4(我实际使用的130,左右相差不太大都可正常使用)

4.1、硬件电路

我在电路设计中,是使用的PE13作为WS2812B的控制引脚,
根据芯片手册可知,PE13是TIM1的CH3通道

在这里插入图片描述

4.2、定时器初始化

下面是定时器1的CH3(PE13)输出PWM的初始化代码
我这里使用的是STM32F407VET6,配置的系统时钟为168MHZ,可根据时钟更改TIM_TimeBaseStructure.TIM_Period的值来修改定时器周期(168MHZ / 210 = 800KHZ)

/*
*函数名称:Timer1_Init
*功能描述:配置TIM1_CH3输出PWM
*传入参数:无
*返回值  :无
*/
void Timer1_Init(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);      /*使能GPIOE时钟*/
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);       /*使能TIM1时钟*/

  GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1);   /*将GPIOE13重映射到TIM1的输出通道上*/
	
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;               /*将引脚功能配置为复用*/
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;               /*推挽输出*/
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;                 /*上拉*/
  GPIO_Init(GPIOE, &GPIO_InitStructure);
   
	/* 定时器周期 : T =(arr + 1) * (PSC + 1) / Tck.   arr:周期值 PSC:预分频值  Tck: 系统时钟频率 */
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_TimeBaseStructure.TIM_Period = 210 - 1;                     /* T = (TIM_Period + 1)*(0+1)/168M,此时800kHz*/
  TIM_TimeBaseStructure.TIM_Prescaler = 0;                        /* 0:不预分频 */
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;         /* 0:时钟分频因子设为1,不分频*/
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     /*向上计数*/
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;                /*重复计数值为0,不使用重复计数*/
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                /*PWM1模式,计数值小于比较值输出高电平,大于输出低电平*/
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    /*使能输出通道*/
  TIM_OCInitStructure.TIM_Pulse = 0;                               /*设置占空比为0, 1 ~ TIM_TimeBaseStructure.TIM_Period */
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;        /*设置输出极性高电平有效*/
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /*禁用互补输出通道*/
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;      /*设置互补输出通道极性高电平有效*/
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCNIdleState_Set;      /*设置空闲时输出高电平*/
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;   /*设置互补通道空闲时输出低电平*/ 
  TIM_OC3Init(TIM1, &TIM_OCInitStructure);                         /*将上述配置应用到定时器一的通道三上*/
  TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);                /*使能通道三的输出比较寄存器的预装载功能*/

  TIM_Cmd(TIM1, ENABLE);                                           /*使能TIM1定时器*/
  TIM_CtrlPWMOutputs(TIM1,ENABLE);                                 /*使能TIM1的PWM输出*/
}

4.3、DMA初始化

在这里插入图片描述
在这里插入图片描述

下面是DMA初始化代码:

/*
*函数名称:dma2_Init
*功能描述:配置从源地址到TIM1_CCR3的DMA数据传输
*传入参数:无
*返回值  :无
*/
uint16_t g_ledDataBuffer[24];
void dma2_Init(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);                        /*使能DMA2时钟*/
  DMA_DeInit(DMA2_Stream6);                                                   /*对DMA2_Stream6进行默认值初始化*/
  /* DMA2 Stream6 Config for PWM1 by TIM1_CH1*/
	DMA_InitTypeDef DMA_InitStructure;
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;                              /*配置DMA通道,通道0*/
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM1->CCR3);         /*配置外设基地址:TIM1的CCR3寄存器*/
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)g_ledDataBuffer;          /*配置源数据的基地址*/
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                     /*设置搬运方向:存储器到外设*/
  DMA_InitStructure.DMA_BufferSize = 42;                                      /*设置传输数据的大小*/
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            /*外设基地址不自增*/
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                     /*源数据基地址自增*/
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; /*设置外设数据大小为半字(16bit)*/
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         /*设置存储器数据大小为半字(16bit)*/
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                               /*设置DMA为普通模式*/
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;                         /*DMA优先级为高*/
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                      /*禁用DMA的FIFO模式*/
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;               /*设置DMA的FIFO阈值为满*/
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                 /*设置内存突发传输模式为单次传输*/
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;         /*设置外设突发传输模式为单次传输*/

  DMA_Init(DMA2_Stream6, &DMA_InitStructure);                                 /*将上述配置应用到 DMA2_Stream6*/

  TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE);                                      /*将TIM1的DMA请求映射到通道三并使能*/
}

4.4、RGB数据驱动

#define TIMING_ONE          (130)
#define TIMING_ZERO         (60)
/*
*函数名称:RGB_Show
*功能描述:通过DMA控制器从内存中读取数据,然后将数据传输到TIM1的CC3通道,以驱动RGB灯。
*传入参数:
*返回值  :无
*/
void RGB_Show(uint8_t (*color)[3], uint16_t len)
{
  uint8_t i = 0;
  uint16_t memaddr = 0;
  uint16_t buffersize = 0;
  buffersize = (len * 24) + 1;       // 缓冲区字节数 = len(RGB灯个数)*24+1
  while (len)
  {
    for(i = 0; i < 8; i++)/*  green data */
    {
       g_ledDataBuffer[memaddr] = ((color[0][1] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
       memaddr++;
     } 
    for(i = 0; i < 8; i++)/*  red data */
    {   
      g_ledDataBuffer[memaddr] = ((color[0][0] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
			memaddr++;
     }
    for(i = 0; i < 8; i++)/*  blue data */
    {
      g_ledDataBuffer[memaddr] = ((color[0][2] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
      memaddr++;
    }
    len--;
   }
   DMA_SetCurrDataCounter(DMA2_Stream6, buffersize);         /*指定要传输的数据量*/
   TIM_Cmd(TIM1, ENABLE);                                    /*启用TIM1定时器*/
   TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE);                    /*将TIM1的DMA请求映射到通道三并使能*/
   DMA_Cmd(DMA2_Stream6, ENABLE);                            /*启用DMA2_Stream6,开始数据传输*/
   while(!DMA_GetFlagStatus(DMA2_Stream6, DMA_FLAG_TCIF6));  /*等待DMA传输完成,使用循环检查DMA传输完成标志*/
   DMA_Cmd(DMA2_Stream6, DISABLE);                           /*禁用DMA2流6,停止数据传输*/
   DMA_ClearFlag(DMA2_Stream6, DMA_FLAG_TCIF6);              /*清除DMA传输完成标志*/
   TIM_Cmd(TIM1, DISABLE);                                   /*禁用TIM1定时器,停止计时*/
}

5、完整代码

5.1、WS2812B.c


#include "WS2812B.h"
#include "DWT_Delay.h"
#include "string.h"

#define TIMING_ONE          (130)
#define TIMING_ZERO         (60)


/*
*函数名称:Timer1_Init
*功能描述:配置TIM1_CH3输出PWM
*传入参数:无
*返回值  :无
*/
void Timer1_Init(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);      /*使能GPIOE时钟*/
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);       /*使能TIM1时钟*/

  GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1);   /*将GPIOE13重映射到TIM1的输出通道上*/
	
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;               /*将引脚功能配置为复用*/
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;               /*推挽输出*/
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;                 /*上拉*/
  GPIO_Init(GPIOE, &GPIO_InitStructure);
   
	/* 定时器周期 : T =(arr + 1) * (PSC + 1) / Tck.   arr:周期值 PSC:预分频值  Tck: 系统时钟频率 */
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_TimeBaseStructure.TIM_Period = 210 - 1;                     /* T = (TIM_Period + 1)*(0+1)/168M  = 800kHz*/
  TIM_TimeBaseStructure.TIM_Prescaler = 0;                        /* 0:不预分频 */
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;         /* 0:时钟分频因子设为1,不分频*/
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     /*向上计数*/
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;                /*重复计数值为0,不使用重复计数*/
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                /*PWM1模式,计数值小于比较值输出高电平,大于输出低电平*/
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    /*使能输出通道*/
  TIM_OCInitStructure.TIM_Pulse = 0;                               /*设置占空比为0, 1 ~ TIM_TimeBaseStructure.TIM_Period */
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;        /*设置输出极性高电平有效*/
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /*禁用互补输出通道*/
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;      /*设置互补输出通道极性高电平有效*/
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCNIdleState_Set;      /*设置空闲时输出高电平*/
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;   /*设置互补通道空闲时输出低电平*/ 
  TIM_OC3Init(TIM1, &TIM_OCInitStructure);                         /*将上述配置应用到定时器一的通道三上*/
  TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);                /*使能通道三的输出比较寄存器的预装载功能*/

  TIM_Cmd(TIM1, ENABLE);                                           /*使能TIM1定时器*/
  TIM_CtrlPWMOutputs(TIM1,ENABLE);                                 /*使能TIM1的PWM输出*/
}


uint16_t g_ledDataBuffer[24];
/*
*函数名称:dma2_Init
*功能描述:配置从源地址到TIM1_CCR3的DMA数据传输
*传入参数:无
*返回值  :无
*/
void dma2_Init(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);                        /*使能DMA2时钟*/

  DMA_DeInit(DMA2_Stream6);                                                   /*对DMA2_Stream6进行默认值初始化*/

  /* DMA2 Stream6 Config for PWM1 by TIM1_CH1*/
	DMA_InitTypeDef DMA_InitStructure;
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;                              /*配置DMA通道,通道0*/
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM1->CCR3);         /*配置外设基地址:TIM1的CCR3寄存器*/
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)g_ledDataBuffer;          /*配置源数据的基地址*/
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                     /*设置搬运方向:存储器到外设*/
  DMA_InitStructure.DMA_BufferSize = 42;                                      /*设置传输数据的大小*/
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            /*外设基地址不自增*/
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                     /*源数据基地址自增*/
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; /*设置外设数据大小为半字(16bit)*/
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         /*设置存储器数据大小为半字(16bit)*/
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                               /*设置DMA为普通模式*/
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;                         /*DMA优先级为高*/
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                      /*禁用DMA的FIFO模式*/
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;               /*设置DMA的FIFO阈值为满*/
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                 /*设置内存突发传输模式为单次传输*/
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;         /*设置外设突发传输模式为单次传输*/

  DMA_Init(DMA2_Stream6, &DMA_InitStructure);                                 /*将上述配置应用到 DMA2_Stream6*/

  TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE);                                      /*将TIM1的DMA请求映射到通道三并使能*/
}


/*
*函数名称:RGB_Show
*功能描述:通过DMA控制器从内存中读取数据,然后将数据传输到TIM1的CC3通道,以驱动RGB灯。
*传入参数:
*返回值  :无
*/
void RGB_Show(uint8_t (*color)[3], uint16_t len)
{
  uint8_t i = 0;
  uint16_t memaddr = 0;
  uint16_t buffersize = 0;
  buffersize = (len * 24) + 1;       // 缓冲区字节数 = len(RGB灯个数)*24+1
  while (len)
  {
    for(i = 0; i < 8; i++)/*  green data */
    {
       g_ledDataBuffer[memaddr] = ((color[0][1] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
       memaddr++;
     } 
    for(i = 0; i < 8; i++)/*  red data */
    {   
      g_ledDataBuffer[memaddr] = ((color[0][0] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
			memaddr++;
     }
    for(i = 0; i < 8; i++)/*  blue data */
    {
      g_ledDataBuffer[memaddr] = ((color[0][2] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
      memaddr++;
    }
    len--;
   }
   DMA_SetCurrDataCounter(DMA2_Stream6, buffersize);         /*指定要传输的数据量*/
   TIM_Cmd(TIM1, ENABLE);                                    /*启用TIM1定时器*/
   TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE);                    /*将TIM1的DMA请求映射到通道三并使能*/
   DMA_Cmd(DMA2_Stream6, ENABLE);                            /*启用DMA2_Stream6,开始数据传输*/
   while(!DMA_GetFlagStatus(DMA2_Stream6, DMA_FLAG_TCIF6));  /*等待DMA传输完成,使用循环检查DMA传输完成标志*/
   DMA_Cmd(DMA2_Stream6, DISABLE);                           /*禁用DMA2流6,停止数据传输*/
   DMA_ClearFlag(DMA2_Stream6, DMA_FLAG_TCIF6);              /*清除DMA传输完成标志*/
   TIM_Cmd(TIM1, DISABLE);                                   /*禁用TIM1定时器,停止计时*/
}

5.2、WS2812B.h

#ifndef __WS2818B_H
#define __WS2812B_H
#include "stm32f4xx.h"                  // Device header
void Timer1_Init(void);
void dma2_Init(void);
void RGB_Show(uint8_t (*color)[3], uint16_t len);
#endif

5.3、main.c

#include "stm32f4xx.h"                  // Device header
#include "DWT_Delay.h"
#include "WS2812B.h"

uint8_t rgbRed[][3] = {{0xff, 0xff, 0x99}};
uint8_t rgbRed1[][3] = {{0x20, 0x20, 0x20}};
uint8_t rgbRed2[][3] = {{0x33, 0x00, 0x33}};
uint8_t rgbRed3[][3] = {{0xFF, 0x33, 0xff}};
int main(void)
{
	DWT_Init();
	Timer1_Init();
	dma2_Init();
	while(1)
	{
	RGB_Show(rgbRed,1);DWT_DelayMS(1000);
	RGB_Show(rgbRed1,1);DWT_DelayMS(1000);
	RGB_Show(rgbRed2,1);DWT_DelayMS(1000);
	RGB_Show(rgbRed3,1);DWT_DelayMS(1000);
	RGB_Show(rgbRed,1);DWT_DelayMS(1000);
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB进行特征选择

特征选择是机器学习和统计建模中的重要步骤,它涉及选择最相关、最有信息价值的特征,以提高模型性能、降低过拟合风险,并加速训练过程。以下是一些常见的特征选择方法: (1)方差选择法 计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征作为筛选出来的特…

恒流模块与常用电容

户外电源电芯&#xff1a;DJ采用无热中心设计&#xff1a;每个电芯都有一部分裸露在外面&#xff0c;保证良好散热上 固态电容相较于普通电解电容具有更高的电气性能、更长的使用寿命和更稳定的温度特性&#xff0c;但成本也相对较高。固态电容在1块左右&#xff0c;电解电容在…

点亮代码之灯,程序员的夜与电脑

在科技的海洋里&#xff0c;程序员是那些驾驶着代码船只&#xff0c;穿梭于虚拟世界的探险家。他们手中的键盘是航行的舵&#xff0c;而那台始终不愿关闭的电脑&#xff0c;便是他们眼中永不熄灭的灯塔。有人说&#xff0c;程序员不喜欢关电脑&#xff0c;这究竟是为什么呢&…

vue3之setup的基本使用

setup是一个全新的配置项&#xff0c;值是一个函数&#xff0c;既然是配置项&#xff0c;是否与data、methods是兄弟&#xff1f; 没错&#xff0c;确实是兄弟关系&#xff0c;只不过到了vue3&#xff0c;就不怎么使用data这些配置项&#xff0c;会使用setup&#xff0c;让我为…

牛客网SQL进阶128:未完成试卷数大于1的有效用户

官网链接&#xff1a; 未完成试卷数大于1的有效用户_牛客题霸_牛客网现有试卷作答记录表exam_record&#xff08;uid用户ID, exam_id试卷ID, st。题目来自【牛客题霸】https://www.nowcoder.com/practice/46cb7a33f7204f3ba7f6536d2fc04286?tpId240&tqId2183007&ru%2…

2024 年合并 PDF 文件的免费 PDF 合并软件榜单

合并 PDF 是当今人们寻找的最重要的功能之一。在本文中&#xff0c;您将了解前五名的 PDF 合并软件以及详细的介绍&#xff0c;以便您选择最佳的。如果您想将所有重要信息都放在一个文件中&#xff0c;而不是在不同的文件中查找&#xff0c;那么合并 PDF 文件是必要的。通过这种…

Windows11系统下对jar文件解压修改后在压缩为jar文件

一、准备内容 安装JAVA环境——若已安装则忽略 我这里以在Windows11中安装JAVA 的JDK8环境为例进行安装配置说明: 1.1、下载JDK安装包 Java Downloads | Oraclehttps://www.oracle.com/java/technologies/downloads/#java8-windows 1.2、安装JDK

订餐|网上订餐系统|基于springboot的网上订餐系统设计与实现(源码+数据库+文档)

网上订餐系统目录 目录 基于springboot的网上订餐系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户功能模块的实现 &#xff08;1&#xff09;用户注册界面 &#xff08;2&#xff09;用户登录界面 &#xff08;3&#xff09;菜品详情界面 &#xff08…

阿里云ECS香港服务器性能强大、cn2高速网络租用价格表

阿里云香港服务器中国香港数据中心网络线路类型BGP多线精品&#xff0c;中国电信CN2高速网络高质量、大规格BGP带宽&#xff0c;运营商精品公网直连中国内地&#xff0c;时延更低&#xff0c;优化海外回中国内地流量的公网线路&#xff0c;可以提高国际业务访问质量。阿里云服务…

Flex布局简介及微信小程序视图层View详解

目录 一、Flex布局简介 什么是flex布局&#xff1f; flex属性 基本语法和常用属性 Flex 布局技巧 二、视图层View View简介 微信小程序View视图层 WXML 数据绑定 列表渲染 条件渲染 模板 WXSS 样式导入 内联样式 选择器 全局样式与局部样式 WXS 示例 注意事项…

h5和微信小程序实现拍照功能(其中h5暂时无法调用闪光灯)

代码如下 <template><view class"camera"><!-- #ifdef MP --><camera ref"myCamera" id"myCamera" device-position"back" :flash"flash" error"error" style"display: block;"&…

shell编程:求稀疏数组中元素的和(下标不连续)

#!/bin/basharr([2]3 [5]2 [6]2 [9]1)for i in "${!arr[]}" dosum$((sumarr[i])) doneecho $sumBash 脚本中&#xff0c;* 和 符号在数组上下文中有不同的用途。当使用它们来遍历数组时&#xff0c;必须了解它们之间的区别。 * (无前置感叹号 !)&#xff1a; 在索引…

数据库第五次实验

目录 1 创建数据表 2 创建多个用户 ​​​​​​​3 用户的授权 ​​​​​​​4 用户权限的回收 ​​​​​​​5 角色的创建与授权 ​​​​​​​6 回收角色的权利 ​​​​​​​7 审计的设置 1 创建数据表 SQL语句&#xff1a; use experimentfive; create table…

MySQL 基础知识(九)之视图

目录 1 视图的介绍 2 视图算法 3 创建视图 4 查看视图结构 5 修改视图 6 删除视图 7 参考文档 1 视图的介绍 视图是一张并不存储数据的虚拟表&#xff0c;其本质是根据 SQL 语句动态查询数据库中的数据。数据库中只存放了视图的定义&#xff0c;通过 SQL 语句使用视图时…

HarmonyOS—@State装饰器:组件内状态

State装饰的变量&#xff0c;或称为状态变量&#xff0c;一旦变量拥有了状态属性&#xff0c;就和自定义组件的渲染绑定起来。当状态改变时&#xff0c;UI会发生对应的渲染改变。 在状态变量相关装饰器中&#xff0c;State是最基础的&#xff0c;使变量拥有状态属性的装饰器&a…

C#学习(十三)——多线程与异步

一、什么是线程 程序执行的最小单元 一次页面的渲染、一次点击事件的触发、一次数据库的访问、一次登录操作都可以看作是一个一个的进程 在一个进程中同时启用多个线程并行操作&#xff0c;就叫做多线程 由CPU来自动处理 线程有运行、阻塞、就绪三态 代码示例&#xff1a; cl…

AI:131- 法律文件图像中的隐含信息挖掘与敲诈勒索检测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

[AIGC ~ coze] Kafka 消费者——从源码角度深入理解

Kafka 消费者——从源码角度深入理解 一、引言 Kafka 是一个分布式的流处理平台&#xff0c;广泛应用于大规模数据处理和实时数据管道。在 Kafka 生态系统中&#xff0c;消费者扮演着至关重要的角色&#xff0c;它们从 Kafka 主题中读取数据并进行处理。本文将深入探讨 Kafka …

七天入门大模型 :大模型LLM 训练理论和实战最强总结!

本文对于想入门大模型、面试大模型岗位、大模型实具有很强的指导意义。喜欢记得收藏、关注、点赞 文章目录 技术交流群用通俗易懂方式讲解系列总览介绍预训练范式如何确定自己的模型需要做什么训练&#xff1f;模型推理的一般过程PyTorch 框架设备PyTorch基本训练代码范例Trans…

自动化测试:电商管理系统元素定位练习​

本次专题我们来说一下 Python中Unittest 框架的使用及如何通过HTMLTestRunner实现自动化测试报告的自动生成。案例中的代码我们仍旧使用课堂学习中部署的“电商管理系统”来实现。本次练习包括以下几个操作&#xff1a; l 测试用例整体结构设计 l 测试用例的实现 l 测试套的…