定时器Tim输出比较(output compare)
输出比较OC(Output Compare)
输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
每个高级定时器和通用定时器都拥有4个输出比较通道,高级定时器的前3个通道额外拥有死区生成和互补输出的功能
在通用定时器的这个位置:
PWM(Pulse Width Modulation)脉冲宽度调制波形
PWM呼吸灯
PWM呼吸灯是通过调节LED的亮度来实现呼吸效果的一种应用。通过改变PWM信号的占空比,可以控制LED的亮度,从而实现从亮到暗再到亮的循环变化。例如,在STM32中,可以通过设置定时器的捕获/比较寄存器(CCR)的值来改变占空比,从而实现呼吸灯效果。通过在运行中更改CCR的值,可以使LED的亮度发生变化,从而实现呼吸灯效果
驱动电机原理
电机驱动的基本原理是利用电流通过电机的线圈产生磁场,与永磁体或其他磁场互相作用,从而产生转矩和旋转运动。常见的电机驱动方式包括直流电机驱动和交流电机驱动。直流电机驱动器通过调节直流电机的输入电流,从而控制电机的转速和转矩。它主要由电源、控制器、驱动器和电机组成。控制器根据输入信号发出控制指令,驱动器根据指令调节电机的电流,进而控制电机的运动
Ton表示高电平时间,Toff表示低电平时间,Ts是一个周期的时间
占空比决定了PWM等效出来的模拟电压的大小,占空比越大,那等效的模拟电压就越趋近于高电平,反之。
-
输入信号:
-
ETRF:外部触发输入,用于同步定时器。
-
TIMx_CCR1 和 TIMx_CCR1:捕获/比较寄存器,用于存储比较值。
-
-
输出模式控制器:
-
该模块负责根据捕获/比较寄存器的值和定时器的计数值来控制输出信号。
-
OC1ref:输出比较参考信号,这是最终输出到外部引脚的信号。
-
-
至主模式控制器:
-
该部分负责将输出比较信号传递给主模式控制器,用于进一步处理。
-
-
输出使能电路:
-
CC1P 和 CC1E:这些是控制输出极性和输出使能的位。
-
CC1P:控制输出极性。当该位为1时,输出为反相;为0时,输出为正相。
-
CC1E:控制输出使能。当该位为1时,输出使能;为0时,输出禁用。
-
-
-
输出引脚(OC1):
-
最终的输出信号通过OC1引脚输出到外部设备。
-
-
TIMx_CCER寄存器:
-
该寄存器用于配置输出极性和输出使能。
-
CC1P 和 CC1E:如上所述,分别控制输出极性和输出使能。
-
-
TIMx_CCMR1寄存器:
-
该寄存器用于配置输出模式。
-
OC1M[2:0]:输出模式选择位,用于选择不同的输出模式(如模式1、模式2等)。
-
输出模式
STM32定时器提供多种输出模式,常见的有:
-
模式1(Toggle):当定时器计数值等于捕获/比较寄存器的值时,输出引脚状态翻转。
-
模式2(Inverted):当定时器计数值等于捕获/比较寄存器的值时,输出引脚状态取反。
-
模式3(Set):当定时器计数值等于捕获/比较寄存器的值时,输出引脚置高。
-
模式4(Reset):当定时器计数值等于捕获/比较寄存器的值时,输出引脚置低。
应用示例
-
PWM输出:
-
通过配置捕获/比较寄存器的值和定时器的自动重装载值,可以生成PWM信号,用于控制LED亮度或电机速度。
-
-
单稳态输出:
-
通过配置输出模式和捕获/比较寄存器的值,可以生成单稳态信号,用于定时控制。
-
-
边缘触发输出:
-
通过配置输出模式和捕获/比较寄存器的值,可以生成边缘触发信号,用于同步外部设备。
-
输出控制器的逻辑
一般使用PWN模式1向上计数
用这个公式,要求输出频率为1khz,占空比可任意调节,分辨率为百分之一的pwm波形怎么计算呢?
-
输出频率(Freq)为1kHz
-
占空比(Duty)可任意调节
-
分辨率(Reso)为百分之一,即0.01
根据图中的公式:
-
PWM频率(Freq)= CK_PSC / (PSC + 1) / (ARR + 1)
-
PWM占空比(Duty)= CCR / (ARR + 1)
-
PWM分辨率(Reso)= 1 / (ARR + 1)
步骤1:计算ARR值
首先,我们需要根据分辨率要求计算ARR的值。分辨率为百分之一,即0.01,这意味着: Reso=ARR+11=0.01 ARR+1=100 ARR=99
步骤2:计算PWM频率
接下来,我们需要计算PWM频率。假设CK_PSC(定时器时钟频率)为72MHz(一个常见的STM32时钟频率),我们希望频率为1kHz。72MHz=72×10^6Hz=72,000,000Hz
步骤3:配置CCR
由于占空比需要可任意调节,CCR的值可以在0到ARR的范围内变化。在本例中,ARR为99,所以CCR可以从0变化到99,以实现从0%到100%的占空比。
总结
-
PSC(预分频器):719
-
ARR(自动重装载值):99
-
CCR(捕获/比较值):0到99(根据需要调节占空比)
这样配置后,你将得到一个频率为1kHz,分辨率为0.01,占空比可调的PWM波形。确保在实际应用中,定时器的时钟源配置正确,以匹配CK_PSC的假设值。
舵机、直流电机以及驱动
反转:IN1低电平,IN2高电平,PWN高反转低不转
正转:IN1高电平,IN2低电平,PWN高正转低不转
如果PWM频率足够快,点击就是连续稳定的转了,速度取决于PWM信号的占空比。
实验:
实验1:呼吸灯
led正极接PA0引脚,负极接在GND的驱动方法,高电平点亮,这样的话就是占空比越大,led越亮,反之。
第一步:RCC开启时钟,把我们要用的TIM外设和GPIO外设打开
第二步:配置时基单元,时钟源选择
第三步:配置输出比较单元,CCR的值,输出比较模式,极性选择,输出使能
第四部:配置GPIO,初始化为复用推挽模式
第五步:运行控制,启用计数器,这样就能输出PWM了
#include "stm32f10x.h" // Device header/*** 函 数:PWM初始化* 参 数:无* 返 回 值:无*/
void PWM_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO重映射*/
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启AFIO的时钟,重映射必须先开启AFIO的时钟
// GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE); //将TIM2的引脚部分重映射,具体的映射方案需查看参考手册
// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //将JTAG引脚失能,作为普通GPIO引脚使用/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA0引脚初始化为复用推挽输出 //受外设控制的引脚,均需要配置为复用模式 /*配置时钟源*/TIM_InternalClockConfig(TIM2); //选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; //预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元/*输出比较初始化*/TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体变量TIM_OCStructInit(&TIM_OCInitStructure); //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较模式,选择PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性,选择为高,若选择极性为低,则输出高低电平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值TIM_OC1Init(TIM2, &TIM_OCInitStructure); //将结构体变量交给TIM_OC1Init,配置TIM2的输出比较通道1/*TIM使能*/TIM_Cmd(TIM2, ENABLE); //使能TIM2,定时器开始运行
}/*** 函 数:PWM设置CCR* 参 数:Compare 要写入的CCR的值,范围:0~100* 返 回 值:无* 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比* 占空比Duty = CCR / (ARR + 1)*/
void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2, Compare); //设置CCR1的值
}
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"uint8_t i; //定义for循环的变量int main(void)
{/*模块初始化*/OLED_Init(); //OLED初始化PWM_Init(); //PWM初始化while (1){for (i = 0; i <= 100; i++){PWM_SetCompare1(i); //依次将定时器的CCR寄存器设置为0~100,PWM占空比逐渐增大,LED逐渐变亮Delay_ms(10); //延时10ms}for (i = 0; i <= 100; i++){PWM_SetCompare1(100 - i); //依次将定时器的CCR寄存器设置为100~0,PWM占空比逐渐减小,LED逐渐变暗Delay_ms(10); //延时10ms}}
}
实验二:驱动舵机
#include "stm32f10x.h" // Device header/*** 函 数:PWM初始化* 参 数:无* 返 回 值:无*/
void PWM_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA1引脚初始化为复用推挽输出 //受外设控制的引脚,均需要配置为复用模式/*配置时钟源*/TIM_InternalClockConfig(TIM2); //选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1; //计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元/*输出比较初始化*/ TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体变量TIM_OCStructInit(&TIM_OCInitStructure); //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较模式,选择PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性,选择为高,若选择极性为低,则输出高低电平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值TIM_OC2Init(TIM2, &TIM_OCInitStructure); //将结构体变量交给TIM_OC2Init,配置TIM2的输出比较通道2/*TIM使能*/TIM_Cmd(TIM2, ENABLE); //使能TIM2,定时器开始运行
}/*** 函 数:PWM设置CCR* 参 数:Compare 要写入的CCR的值,范围:0~100* 返 回 值:无* 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比* 占空比Duty = CCR / (ARR + 1)*/
void PWM_SetCompare2(uint16_t Compare)
{TIM_SetCompare2(TIM2, Compare); //设置CCR2的值
}
#include "stm32f10x.h" // Device header
#include "PWM.h"/*** 函 数:舵机初始化* 参 数:无* 返 回 值:无*/
void Servo_Init(void)
{PWM_Init(); //初始化舵机的底层PWM
}/*** 函 数:舵机设置角度* 参 数:Angle 要设置的舵机角度,范围:0~180* 返 回 值:无*/
void Servo_SetAngle(float Angle)
{PWM_SetCompare2(Angle / 180 * 2000 + 500); //设置占空比//将角度线性变换,对应到舵机要求的占空比范围上
}
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Servo.h"
#include "Key.h"uint8_t KeyNum; //定义用于接收键码的变量
float Angle; //定义角度变量int main(void)
{/*模块初始化*/OLED_Init(); //OLED初始化Servo_Init(); //舵机初始化Key_Init(); //按键初始化/*显示静态字符串*/OLED_ShowString(1, 1, "Angle:"); //1行1列显示字符串Angle:while (1){KeyNum = Key_GetNum(); //获取按键键码if (KeyNum == 1) //按键1按下{Angle += 30; //角度变量自增30if (Angle > 180) //角度变量超过180后{Angle = 0; //角度变量归零}}Servo_SetAngle(Angle); //设置舵机的角度为角度变量OLED_ShowNum(1, 7, Angle, 3); //OLED显示角度变量}
}
有人知道为什么下面的跟图不一样嘛??
常见的舵机控制参数
在许多舵机中,常见的控制参数如下:
-
0.5ms(500微秒)的高电平对应 0°
-
1.5ms(1500微秒)的高电平对应 90°
-
2.5ms(2500微秒)的高电平对应 180°
舵机的控制通常依赖于PWM信号,其中0°对应500微秒的高电平时长,180°对应2500微秒的高电平时长。这种对应关系是舵机控制的一种行业标准,用于在0°到180°之间精确控制舵机的角度
至于setcompare()
函数,它通常用于设置定时器的比较寄存器值,即设定一个时间基准,当计数器达到该值时,就会引发一个定时器溢出中断或者定时事件。在STM32系列微控制器中,这个函数可以用来精确地控制设备的工作周期,比如定时器超时、延时操作或者是脉冲宽度调制(PWM)的占空比设置。例如,在舵机控制中,通过调用setcompare()
函数并传入相应的参数,可以生成对应角度的PWM信号,从而控制舵机转动到指定的角度
舵机要求周期20ms,PWM频率就是1/20ms =50hz
输出高电平的时间:
高电平时间=周期×占空比
duty = ccr/(arr+1)=50/20000= 0.025
高电平时间 = 20ms ×0.025 = 0.5ms
ccr设置500就是0.5ms,设置2500就是2.5ms
0° -500,180° -2500
实验三:PWM驱动直流电机
#include "stm32f10x.h" // Device header/*** 函 数:PWM初始化* 参 数:无* 返 回 值:无*/
void PWM_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA2引脚初始化为复用推挽输出 //受外设控制的引脚,均需要配置为复用模式/*配置时钟源*/TIM_InternalClockConfig(TIM2); //选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1; //预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元/*输出比较初始化*/ TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体变量TIM_OCStructInit(&TIM_OCInitStructure); //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较模式,选择PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性,选择为高,若选择极性为低,则输出高低电平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值TIM_OC3Init(TIM2, &TIM_OCInitStructure); //将结构体变量交给TIM_OC3Init,配置TIM2的输出比较通道3/*TIM使能*/TIM_Cmd(TIM2, ENABLE); //使能TIM2,定时器开始运行
}/*** 函 数:PWM设置CCR* 参 数:Compare 要写入的CCR的值,范围:0~100* 返 回 值:无* 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比* 占空比Duty = CCR / (ARR + 1)*/
void PWM_SetCompare3(uint16_t Compare)
{TIM_SetCompare3(TIM2, Compare); //设置CCR3的值
}
#include "stm32f10x.h" // Device header
#include "PWM.h"/*** 函 数:直流电机初始化* 参 数:无* 返 回 值:无*/
void Motor_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA4和PA5引脚初始化为推挽输出 PWM_Init(); //初始化直流电机的底层PWM
}/*** 函 数:直流电机设置速度* 参 数:Speed 要设置的速度,范围:-100~100* 返 回 值:无*/
void Motor_SetSpeed(int8_t Speed)
{if (Speed >= 0) //如果设置正转的速度值{GPIO_SetBits(GPIOA, GPIO_Pin_4); //PA4置高电平GPIO_ResetBits(GPIOA, GPIO_Pin_5); //PA5置低电平,设置方向为正转PWM_SetCompare3(Speed); //PWM设置为速度值}else //否则,即设置反转的速度值{GPIO_ResetBits(GPIOA, GPIO_Pin_4); //PA4置低电平GPIO_SetBits(GPIOA, GPIO_Pin_5); //PA5置高电平,设置方向为反转PWM_SetCompare3(-Speed); //PWM设置为负的速度值,因为此时速度值为负数,而PWM只能给正数}
}
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Motor.h"
#include "Key.h"uint8_t KeyNum; //定义用于接收按键键码的变量
int8_t Speed; //定义速度变量int main(void)
{/*模块初始化*/OLED_Init(); //OLED初始化Motor_Init(); //直流电机初始化Key_Init(); //按键初始化/*显示静态字符串*/OLED_ShowString(1, 1, "Speed:"); //1行1列显示字符串Speed:while (1){KeyNum = Key_GetNum(); //获取按键键码if (KeyNum == 1) //按键1按下{Speed += 20; //速度变量自增20if (Speed > 100) //速度变量超过100后{Speed = -100; //速度变量变为-100//此操作会让电机旋转方向突然改变,可能会因供电不足而导致单片机复位//若出现了此现象,则应避免使用这样的操作}}Motor_SetSpeed(Speed); //设置直流电机的速度为速度变量OLED_ShowSignedNum(1, 7, Speed, 3); //OLED显示速度变量}
}
相关文章:
定时器Tim输出比较(output compare)
输出比较OC(Output Compare) 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形 每个高级定时器和通用定时器都拥有4个输出比较通道,高级定时器的前3个通道额外拥有死区生…...
Linux Shell 脚本编程极简入门指南
一、学习前提准备 ✅ 环境要求: Linux系统(Ubuntu/CentOS等)或 WSL (Windows用户) 任意文本编辑器(推荐VSCode/Vim) 基础命令行操作能力 🔍 验证环境: # 查看系统默认Shell echo $SHELL #…...
C++:二分习题
1. 借教室 503. 借教室 - AcWing题库 在大学期间,经常需要租借教室。 大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。 教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。 面对海…...
【AIGC】计算机视觉-YOLO系列家族
YOLO系列家族 (1)YOLO发展史(2) YOLOX(3) YOLOv6(4) YOLOv7(5) YOLOv8(6) YOLOv9(7)YOLOv10(8&…...
浅谈SSE爬虫
什么是SSE SSE(Server-Sent Events,服务器推送事件)是一种用于在Web应用程序中实现单向实时数据传输的技术。它允许服务器通过HTTP连接向客户端(通常是浏览器)推送更新的数据,而无需客户端主动请求。 目前主流的大模型 就是采用的 SSE,想deepseek、chatgpt、通以千问。…...
Goland如何玩依赖注入——基于gone@v2创建一个service
经过多天的工作,终于把gone2的beta版本发布出去了。在v2版本中,做了很多更新,最大的改进是将一些不必要的概念给隐藏起来了,提供了Provider机制…… 文章目录 1. 安装**gonectr**2.创建项目2.1 项目结构 2.2 简单说明3. 启动项目…...
rpmlib(SetVersions) is needed by can-uilts-v2019.00.0-alt1.aarch64
在我在Linux中安装离线CAN工具时,出现了一个问题, rootwanghuo:~# rpm -ivh can-uilts-v2019.00.0-alt1.aarch64.rpm error: Failed dependencies:rpmlib(SetVersions) is needed by can-uilts-v2019.00.0-alt1.aarch64 意思是尝试安装 can-uilts-v20…...
处理Java中的异常
处理Java中的异常 在 Java 中,异常处理是通过 try-catch-finally 语句来实现的。Java 提供了一种强大的机制,用于捕捉和处理程序运行中的各种错误和异常。通过这种方式,你可以有效地捕捉到可能导致程序崩溃的错误,并做出相应的处…...
mac 苍穹外卖 前端环境配置
博主的 mac 是 m2。 结合以下两篇,成功配置前端环境。 macOS 配置苍穹外卖前端环境_macbook怎么nginx下载外卖-CSDN博客 苍穹外卖-Mac配置前端开发环境_sudo 启动 nginx 有什么区别-CSDN博客 一、安装nginx 我使用的是 homebrew,homebrew 的安装请自…...
前端系统测试(单元、集成、数据|性能|回归)
有关前端测试的面试题 系统测试 首先,功能测试部分。根据资料,单元测试是验证最小可测试单元的正确性,比如函数或组件。都提到了单元测试的重要性,强调其在开发早期发现问题,并通过自动化提高效率。需要整合我搜索到的资料中的观点,比如单元测试的方法(接口测试、路径覆…...
Python:函数式编程
函数式编程(Functional Programming, FP)是一种编程范式,强调通过纯函数、不可变数据和声明式风格来构建程序。Python 虽然不是纯函数式语言,但提供了丰富的函数式编程工具。(简单来说是,函数约等于模块功能࿰…...
Spring Boot中@Valid 与 @Validated 注解的详解
Spring Boot中Valid 与 Validated 注解的详解 引言 在Spring Boot应用中,参数校验是确保数据完整性和一致性的重要手段。Valid和Validated注解是Spring Boot中用于参数校验的两个核心注解。本文将详细介绍这两个注解的用法、区别以及代码样例。 Valid注解 功能介…...
[动手学习深度学习]12.权重衰退
1.介绍 权重衰退是常见的处理过拟合的方法 控制模型容量方法 把模型控制的比较小,即里面参数比较少使参数选择范围小 约束就是正则项 每个特征的权重都大会导致模型复杂,从而导致过拟合。 控制权重矩阵范数可以使得减少一些特征的权重,甚至…...
JVM内存结构笔记04-字符串常量池
文章目录 定义字符串常量池的位置JDK 1.7 为什么要将字符串常量池移动到堆中? StringTable案例1案例2案例3 String.intern()案例4案例5案例6总结 StringTable 垃圾回收案例1.创建100个字符串(不会触发垃圾回收)2.创建10000个字符串(触发垃圾回收) StringTable 性能调…...
STM32 HAL库实战:高效整合DMA与ADC开发指南
STM32 HAL库实战:高效整合DMA与ADC开发指南 一、DMA与ADC基础介绍 1. DMA:解放CPU的“数据搬运工” DMA(Direct Memory Access) 是STM32中用于在外设与内存之间直接传输数据的硬件模块。其核心优势在于无需CPU干预,…...
c语言闯算法--常用技巧
双指针 类别: 同向快慢指针 异常情况,慢指针才动 双向指针 视情况,左右指针动 最长无重复子串 int max(int a, int b){if(a < b){return b;}else{return a;} } int lengthOfLongestSubstring(char* s) {int count[300];for(int i 0; i …...
docker启动jenkins,jenkins中调用docker
在jenkins中执行docker 思路 jenkins中安装docker客户端,使用第三方的docker(需要付费)。jenkins中安装docker客户端,另一个容器中安装docker服务, docker-in-docker,需要特权模式,或者第三方的工具。jenkins中什么都…...
【设计模式】设计模式介绍
一、设计模式概述 设计模式分很多种,每种一般都用于解决某个软件开发过程中的问题。许多人认为设 计模式有23种,其实,对于这个数字也没必要那么教条,当然还有更多的设计模式种类,只 不过是这23种比较经典而已。甚至可…...
图形学面试题总结
图形学面试题总结 文章目录 图形学面试题总结Opengl 与 Vulkan1、OpenGL的渲染管线有哪些主要阶段?分别做什么?2、OpenGL中的VAO、VBO和EBO分别是什么?为什么需要它们?3、细分着色器与几何着色器是什么4、Vulkan与Opengl的区别是什…...
Spring Cloud Alibaba 实战:Sentinel 保障微服务的高可用性与流量防护
1.1 Sentinel 作用 Sentinel 是阿里巴巴开源的一款 流量控制和熔断降级 框架,主要用于: 流量控制:限制 QPS,防止流量暴增导致系统崩溃熔断降级:当某个服务不可用时自动降级,避免故障扩散热点参数限流&…...
Comfyui 与 SDwebui
ComfyUI和SD WebUI是基于Stable Diffusion模型的两种不同用户界面工具,它们在功能、用户体验和适用场景上各有优劣。 1. 功能与灵活性 ComfyUI:ComfyUI以其节点式工作流设计为核心,强调用户自定义和灵活性。用户可以通过连接不同的模块&…...
面试之《前端常见的设计模式》
前端开发中运用多种设计模式可以提高代码的可维护性、可扩展性和可复用性。以下是一些常见的前端设计模式: 创建型模式 1. 单例模式 定义:确保一个类只有一个实例,并提供一个全局访问点。应用场景:在前端中,像全局状…...
PostgreSQL异常:An IO error occurred while sending to the backend
在使用PostgreSQL数据库批量写入数据的时候,遇到了一个问题,异常内容如下: Cause: org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.报错内容 报错提示1 Caused by: org.postgresql.util.PSQLExc…...
嵌入式八股C语言---面向对象篇
面向对象与面向过程 面向过程 就是把整个业务逻辑分成多个步骤,每步或每一个功能都可以使用一个函数来实现面向对象 对象是类的实例化,此时一个类就内部有属性和相应的方法 封装 在C语言里实现封装就是实现一个结构体,里面包括的成员变量和函数指针,然后在构造函数中,为结构体…...
一周学会Flask3 Python Web开发-使用SQLAlchemy动态创建数据库表
锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 前面我们定义了模型,我们可以通过sqlalchemy对象提供的create_all()方法来映射和动态创建数据库表。 因为我们用到…...
【spring】springAOP
1.基本概念 AOP即面向切面编程,它利用的是一种横切技术,解剖开封装的对象内部,并将那些影响多个类的公共行为封装到一个可重 用模块,这就是所谓的Aspect方面/切面。所谓的切面,简单点所说,就是将哪些与业务…...
解决VMware虚拟机CentOS 7 忘记登陆密码问题
1. 重启虚拟机,在重启时不停按E键进入初始化脚本编辑界面 2.在初始化脚本编辑界面,按↓键向下拉到最后,找到LANG/zh_CN.UTF-8那里,输入空格,接着添加 "init/bin/sh" 。然后按ctrlX键进入下一步。 3. 在界面中…...
如何在 Windows 10 启用卓越性能模式及不同电源计划对比
在使用 powercfg -duplicatescheme 命令启用 “卓越性能模式”(即 Ultimate Performance 模式)之前,有几个前提条件需要注意: 前提条件: 系统版本要求:卓越性能模式 仅在 Windows 10 专业版 或更高版本&a…...
基于 GEE 利用 Sentinel-2 数据反演叶绿素与冠层水分含量
目录 1 数据加载与预处理 2 叶绿素含量反演 3 冠层水分反演 4 数据可视化与导出 5 完整代码 6 运行结果 在生态学和环境科学领域,植被的健康状况是评估生态系统稳定性和功能的关键指标之一。而叶绿素含量和冠层水分含量作为反映植被生理状态的重要参数&#x…...
《鸿蒙系统下AI模型训练加速:时间成本的深度剖析与优化策略》
在当今数字化浪潮中,鸿蒙系统凭借其独特的分布式架构与强大的生态潜力,为人工智能的发展注入了新的活力。随着AI应用在鸿蒙系统上的日益普及,如何有效降低模型训练的时间成本,成为了开发者与研究者们亟待攻克的关键课题。这不仅关…...
PyTorch分布式训练
本文结构: 分布式训练概述环境设置数据并行(DDP)模型并行启动训练性能优化建议示例代码参考资料和相关问题 以下是为您整理的PyTorch分布式训练教程指南: 一、PyTorch分布式训练核心概念 数据并行:通过分割数据集实…...
ubuntu22.04 关于挂在设备为nfts文件格式无法创建软连接的问题
最近遇到情况,解压工程报错,无法创建软连接 但是盘内还有130G空间,明显不是空间问题,查找之后发现是移动硬盘的文件格式是NTFS,在ubuntu上不好兼容,于是报错。 开贴记录解决方案。 1.确定文件格式 使用命…...
C++编程:进阶阶段—4.2对象
目录 4.2 对象特征 4.2.1 构造函数和析构函数 4.2.2 构造函数的分类 4.2.3 拷贝函数调用时机 4.2.4 构造函数调用规则 4.2.5 深拷贝与浅拷贝 4.2.6 初始化列表 4.2.7 类对象作为类成员 4.2.8 静态成员 4.2.9 成员变量和成员函数的存储 4.2.10 this指针 4.2.11 空指针…...
C++跨平台开发环境搭建全指南:工具链选型与性能优化实战
C跨平台开发环境搭建全指南:工具链选型与性能优化实战 目录 开发环境搭建工具链选型性能优化实战常见问题排查 开发环境搭建 操作系统环境准备 Windows# 安装Visual Studio Build Tools choco install visualstudio2022buildtools choco install cmake --instal…...
常见JVM命令
1. java -XX:PrintCommandLineFlags HelloGC 作用:打印 JVM 启动时的命令行参数,包括用户显式设置的参数和 JVM 自动默认设置的参数。用于确认 JVM 实际使用的配置。 2. java -Xmn10M -Xms40M -Xmx60M -XX:PrintCommandLineFlags -XX:PrintGC -XX:Prin…...
C语言实现队列数据结构:思路与代码详解
目录 一、引言 二、整体思路 三、代码模块分析 (一)头文件包含与宏定义 (二)数据类型定义 (三)队列操作函数 1. 队列初始化 2. 队列销毁 3. 入队操作 4. 出队操作 5. 获取队头元素 6…...
【Docker项目实战】使用Docker与Caddy部署BanBan任务管理工具
【Docker项目实战】使用Docker部署BanBan任务管理工具 一、BanBan介绍1.1 BanBan简介1.2 主要特点1.3 使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、下载BanBan镜像五、…...
AI重构私域增长:从流量收割到终身价值运营的三阶跃迁
私域运营的AI进化论:内容即服务的三个阶段 随着企业微信生态的成熟,私域运营正经历从"流量收割"到"关系养成"的本质转变。在AIGC技术的推动下,2024年私域场景正式进入**"内容即服务"**的价值共创期࿱…...
es扩容节点以后写入数据量增加1倍
背景: es扩容一倍的数据节点以后 写入数据量增加1倍 业务反馈业务访问量没增加。 最后定位是监控数据: PUT _cluster/settings {"persistent": {"xpack.monitoring.collection.enabled" : "false"} }这个索引记录的是 节…...
Go本地缓存设计与实现
本地缓存是一个项目中很常见的组件。在很多人的眼中就是一个简单的key-value的map存储即可实现,但实际上,设计一个本地缓存需要考虑的问题远比你想象的多,比如说,本地缓存是将数据存储在内存,若数据量激增突破了内存限…...
04 | 初始化 fastgo 项目仓库
提示: 所有体系课见专栏:Go 项目开发极速入门实战课;欢迎加入 云原生 AI 实战 星球,12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力(聚焦于 Go、云原生、AI Infra);本节课最终…...
Spring中复杂对象的创建方式:FactoryBean、实例工厂与静态工厂全解析
1.反转控制与依赖注入 控制:对于成员变量赋值的控制权 反转控制:把对于成员变量赋值的控制权,从代码中反转(转移)到Spring工厂和配置文件中完成 好处:解耦合 底层实现:工厂设计模式 依赖注入: 注入…...
异或和之和 第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 A 组
异或和之和 题目来源 第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 A 组 原题链接 蓝桥杯 异或和之和 https://www.lanqiao.cn/problems/3507/learning/ 问题描述 问题分析 要点1:异或运算 概念 异或(Exclusive OR,简称 XOR)是一种数学运算符,常用于逻辑运算与计算机…...
设计模式 一、软件设计原则
一、理解设计原则 1、单一原则 1.1 如何理解单一职责原则(SRP) 单一职责原则(Single Responsibility Principle,简称SRP),他要求一个类或模块应该只负责一个特定的功能,这有助于降低类之间的耦合度…...
修复Electron项目Insecure Content-Security-Policy(内容安全策略CSP)警告的问题
将以下代码粘贴进html的<header>标签内 <metahttp-equiv"Content-Security-Policy"content"default-src self; style-src self unsafe-inline; img-src self data:; "> 解释一下上面代码中的属性含义 default-src self:配置加载策…...
机器人交互系统 部署构建
环境要求 Ubuntu 20.04 或更高版本ROS Noetic 或兼容版本Python 3.8 安装步骤 1. 安装ROS环境(如未安装) sudo apt update sudo apt install ros-noetic-desktop-full source /opt/ros/noetic/setup.bash2. 创建工作空间并克隆代码 mkdir -p ~/code…...
当AI回答问题时,它的“大脑”里在炒什么菜?
文章目录 1. 拆解订单:AI如何听懂你的“暗号”?2. 调用工具:AI的“万能工具箱”里有什么?3. 知识不够?去“图书馆”现学现卖!4. 人类的秘密武器:给AI戴上“镣铐”5. 为什么AI会“胡言乱语”&…...
linux 软件扩展GPU显存
概述 共享内存可以通过 Unified Memory(统一内存)来实现,它允许 CPU 和 GPU 共享相同的内存地址空间,从而方便数据的传输和访问。 利用该技术可解决家用GPU 机器学习时显存不足的问题 (注: 虽然解决了爆显…...
【RabbitMQ】Spring Boot 结合 RabbitMQ 完成应用间的通信
🔥个人主页: 中草药 🔥专栏:【中间件】企业级中间件剖析 Spring 框架与 RabbitMQ 的整合主要通过 Spring AMQP(Advanced Message Queuing Protocol)模块实现,提供了便捷的消息队列开发能力。 引…...
DeepSeek本地化部署(DeepSeek+olloma+Dify)
文章目录 概要需要准备的工具Ollama准备内容Docker准备内容Dify准备内容本地访问Dify 概要 提示:本篇文章主要讲述如何部署本地Deepseek私有大模型,使用Windows无显卡环境进行部署 需要准备的工具 Ollama、Docker Desktop 下载地址: Ollama…...