物联网——TIM定时器、PWM驱动呼吸灯、舵机和直流电机
定时器概念(常用于输出PWM波形,驱动电机)

时间=脉冲数时钟周期; 这里的脉冲数=6553665536,支持定时器级联,从而延长定时
定时器类型

基本定时器原理图(UI:更新中断, U:更新事件,仅支持向上计时模式)

(stm32主模式)可以通过映射U(事件)至到触发器(TRGO)来控制DAC的输出,这样就不用CPU花费大量的中断时间输出DAC
通用定时器原理图(支持向上/下计时模式,中央对齐计时模式)
中央对齐计时模式(计数器的值和重装值相等时产生一次中断,计数器值再减为零再产生一次中断)

高级定时器

DTG(Dead Time Generate): 死区生成电路,用于防止直通
BKIN:刹车输入
定时中断基本结构

预分频器时序

计数器时序图


影子寄存器的作用:让值的更改与更新事件保持同步,防止在运行途中更改造成错误

MyClock.c
#include "stm32f10x.h"
extern uint16_t Num;
//定时器初始化
void Timer_Init(void){// Enables or disables the Low Speed APB (APB1) peripheral clock.(外部时钟)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//(内部时钟)TIM_InternalClockConfig(TIM2);//基本定时器配置TIM_TimeBaseInitTypeDef BaseTI;BaseTI.TIM_ClockDivision = TIM_CKD_DIV1;BaseTI.TIM_CounterMode = TIM_CounterMode_Up; //向上计数法BaseTI.TIM_Prescaler = 7200-1; //PSC,计数器(PSC大,ARR小,则定时器频率低,OV=C_PSC/PSC+1/ARR+1)BaseTI.TIM_Period = 1000-1; //ARR,重定位值 ,(PSC小,ARR大,则定时器频率高) BaseTI.TIM_RepetitionCounter = 0; //Specifies the repetition counter value. Each time the RCR downcounterreaches zero, an update event is generated and counting restarts from the RCR valueTIM_TimeBaseInit(TIM2,&BaseTI); //由于时钟在初始化的时候,触发了一次更新事件使预分频器的值有效,所以要清除掉更新事件,避免后续计时器数值从一开始TIM_ClearFlag(TIM2,TIM_FLAG_Update); //中断配置,由更新事件触发中断TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//中断控制器NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NI;NI.NVIC_IRQChannel = TIM2_IRQn;NI.NVIC_IRQChannelCmd = ENABLE;NI.NVIC_IRQChannelPreemptionPriority = 2;NI.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NI);//启动定时器TIM_Cmd(TIM2,ENABLE);
}
//对射式定时器初始化
void MappintTimer_Init(void){// Enables or disables the Low Speed APB (APB1) peripheral clock.(外部时钟)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //红外射线引脚GPIO_InitTypeDef GI;GI.GPIO_Mode = GPIO_Mode_IPU;GI.GPIO_Pin = GPIO_Pin_0;GI.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GI);//(外部时钟)TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00); //时钟模式,外部触发计数器,外部触发极性(这里是不反转,低电平有效),滤波器(采样n个点都相同,才输出滤波器)//基本定时器配置TIM_TimeBaseInitTypeDef BaseTI;BaseTI.TIM_ClockDivision = TIM_CKD_DIV1;BaseTI.TIM_CounterMode = TIM_CounterMode_Up; //向上计数法BaseTI.TIM_Prescaler = 1-1; //PSC,计数器(PSC大,ARR小,则定时器频率低,OV=C_PSC/PSC+1/ARR+1),这里从0~9BaseTI.TIM_Period = 10-1; //ARR,重定位值 ,(PSC小,ARR大,则定时器频率高),这里不需要分频 BaseTI.TIM_RepetitionCounter = 0; //Specifies the repetition counter value. Each time the RCR downcounterreaches zero, an update event is generated and counting restarts from the RCR valueTIM_TimeBaseInit(TIM2,&BaseTI); //由于时钟在初始化的时候,触发了一次更新事件使预分频器的值有效,所以要清除掉更新事件,避免后续计时器数值从一开始TIM_ClearFlag(TIM2,TIM_FLAG_Update); //中断配置,由更新事件触发中断TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//中断控制器NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NI;NI.NVIC_IRQChannel = TIM2_IRQn;NI.NVIC_IRQChannelCmd = ENABLE;NI.NVIC_IRQChannelPreemptionPriority = 2;NI.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NI);//启动定时器TIM_Cmd(TIM2,ENABLE);
}
//时钟中断控制,这个函数可以定义在主函数外面,这样就不用使用extern修饰变量
void TIM2_IRQHandler(void){if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}
PWM波形
PWM(Pulse Width Modulation)波形,即脉冲宽度调制波形,是一种通过调整一系列等幅脉冲的宽度来对输出进行编码和控制的技术。在PWM信号中,每个脉冲的幅度保持恒定,但是脉冲的持续时间(宽度)变化,从而改变脉冲的占空比,即高电平时间与整个脉冲周期的比例。这种调制方式使得PWM信号能够等效地模拟出不同强度的模拟信号,常用于控制电机转速、LED亮度调节、电源转换等领域。
PWM波形的关键特性包括:
-脉冲序列:PWM波由一系列矩形波(方波)组成。
-固定周期:每个PWM周期的时间长度是固定的。
-可变宽度:每个脉冲的高电平时间(即“开启时间”)可以改变,低电平时间相应调整以保持周期不变,这样就改变了占空比。
-占空比:占空比是指一个周期内高电平时间与整个周期时间的比例,通常以百分比表示,用于控制输出的有效功率或模拟信号的强度。
-等效模拟信号:通过调整占空比,PWM可以近似模拟连续的模拟信号,如正弦波,用于驱动如电机或LED等设备,实现平滑的控制效果。
在逆变电路和电源管理应用中,常用的PWM调制方法之一是SPWM(Sinusoidal PWM),它通过使脉冲宽度按照正弦波的形状变化,使得输出的PWM波形在一定意义上等效于期望的正弦波形,从而控制输出电压或电流的大小和频率。





PWM基本结构

PWM频率

CK_PSC
在PWM(Pulse Width Modulation,脉冲宽度调制)控制中,CK_PSC通常指的是时钟预分频系数(Prescaler value for Clock)。这是微控制器(如STM32系列)中的定时器模块中的一个配置参数,用于调整定时器的时钟频率。
具体来说,CK_PSC是定时器输入时钟(CK_INT,来自系统时钟或者外部时钟源)在进入定时器计数器之前经过的一个分频器。通过设置不同的CK_PSC值,可以减慢定时器的计数速度,使得计数器能以较低的频率进行计数,这对于生成各种不同频率的PWM信号非常关键。预分频的计算公式通常是 Timer Clock Frequency = (Input Clock Frequency) / (PSC + 1)。
例如,如果你有一个基于STM32的系统,其系统时钟频率为72MHz,而你需要一个较慢的PWM频率输出,你可以通过设置合适的CK_PSC值来实现这一点。增加PSC值会降低到达计数器的时钟频率,从而允许更精细地控制PWM信号的频率和占空比。
在编程时,通常会通过设置定时器的相关寄存器(如STM32中的TIMx_PSC寄存器)来配置CK_PSC的值,以满足特定应用的需求。
CCR 和 ARR
自动重装载寄存器(ARR)用于确定波形的频率(即周期)、捕获比较寄存器(CCRx)(用于确定占空比的)
PWM的工作过程如下:首先ARR寄存器里面的值确定了一个PWM周期(注意这个周期是在PWM系统初始化的时候写入ARR寄存器的,写入以后一般就不再改动了)。然后CCR寄存器里面的值是PWM工作过程中确定的,它可以为一个定值,也可以是一个变化的值。

PWM分辨率
PWM分辨率是指在PWM一个周期内能够实现的占空比调整的最小单位,它是衡量PWM信号精细程度的一个重要指标。PWM通过调整脉冲信号高电平时间的长短来模拟输出不同的平均电压值,而这个调整的细腻程度就是由分辨率决定的。
具体来说,PWM分辨率可以用比特数表示,常见的有8位、10位、12位等。一个8位的PWM控制器可以提供2^8=256个不同的占空比等级,这意味着在一个PWM周期内,高电平时间可以有256种不同的设置。相应地,10位分辨率则可以提供1024个不同的占空比等级,12位则有4096个等级,依此类推。分辨率越高,能够实现的控制精度就越高,输出的模拟信号就越接近真实连续的模拟信号。
PWM分辨率的计算也可以关联到具体的时钟频率上,比如一个PWM的时钟频率确定时,提高分辨率会导致每个脉冲宽度的可调步进减小,从而使得控制更为精确。反之,分辨率较低意味着调整的步长较大,占空比的变化相对粗糙。
呼吸灯电路图

注意事项

占空比为10%的PWM波形(示波器显示)

呼吸灯核心代码
//主函数
#include "stm32f10x.h" // Device header
#include "MyDelay.h" //自定义延时函数
#include "Delay.h" //官方延迟函数
#include "Button.h" //按键Led驱动
#include "stdio.h"
#include "PWM.h"
#include "OLED.h"int main(void){//环境配置OLED_Init();PWM_Init();while(1){for(int i=1;i<=100;i+=2){OLED_ShowNum(1,1,666,3);PWM_SetCompare1(i);Delay_ms(20);}for(int i=100;i>=1;i-=2){OLED_ShowNum(1,1,666,3);PWM_SetCompare1(i);Delay_ms(20);} }return 0;
}//PWM.h
#ifndef PWM_H
#define PWM_H
//初始化PWM
void PWM_Init(void);
//用于动态改变CCR,调节LED灯的亮度,PWM使用的PA0端口
void PWM_SetCompare1(uint16_t Compare);
#endif//PWM.c
#include "stm32f10x.h" // Device header
//初始化PWM
void PWM_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //时钟中断RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //为呼吸灯指定引脚PA0GPIO_InitTypeDef GI;GI.GPIO_Mode = GPIO_Mode_AF_PP; //定时器(外设)控制引脚,要用复用推挽输出GI.GPIO_Pin = GPIO_Pin_0;GI.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GI);TIM_InternalClockConfig(TIM2); //内部时钟TIM_TimeBaseInitTypeDef TI; //时钟中断配置TI.TIM_ClockDivision = TIM_CKD_DIV2 ;TI.TIM_CounterMode = TIM_CounterMode_Up;TI.TIM_Period = 100-1; // ARRTI.TIM_Prescaler = 720-1; // PSC ,CK_PSC=72MHZTI.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TI);TIM_Cmd(TIM2,ENABLE); //时钟中断使能//时钟中断的输出比较模块定义: PWM波形,频率1KHZ,占空比50%,分辨率为 1%,TIM_OCInitTypeDef OCI;TIM_OCStructInit(&OCI); //先初始化输出比较模块,后续修改某个属性OCI.TIM_OCMode = TIM_OCMode_PWM1;OCI.TIM_OCPolarity = TIM_OCPolarity_High; //极性,高电平有效电平OCI.TIM_OutputState = ENABLE;OCI.TIM_Pulse = 0; //CCR捕获寄存器,可以通过改变CCR的值,调制PWM波形的占空比,从而改变LED灯的亮度 TIM_OC1Init(TIM2,&OCI); //pwm波形初始化
}//用于动态改变CCR,调节LED灯的亮度,PWM使用的PA0端口
void PWM_SetCompare1(uint16_t Compare){TIM_SetCompare1(TIM2,Compare); //该函数用于设置CRR的值}//重映射端口PA15
#include "stm32f10x.h" // Device header//初始化PWM
void PWM_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //时钟中断RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //为呼吸灯指定引脚PA0//法二:为了提高引脚使用率,重映射端口,打开AFIO,重映射引脚,解除调试端口RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //禁用JTAG调试,这里用的是ST-LinkGPIO_InitTypeDef GI;GI.GPIO_Mode = GPIO_Mode_AF_PP; //定时器(外设)控制引脚,要用复用推挽输出GI.GPIO_Pin = GPIO_Pin_15;GI.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GI);TIM_InternalClockConfig(TIM2); //内部时钟TIM_TimeBaseInitTypeDef TI; //时钟中断配置TI.TIM_ClockDivision = TIM_CKD_DIV2 ;TI.TIM_CounterMode = TIM_CounterMode_Up;TI.TIM_Period = 100-1; // ARRTI.TIM_Prescaler = 720-1; // PSC ,CK_PSC=72MHZTI.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TI);TIM_Cmd(TIM2,ENABLE); //时钟中断使能//时钟中断的输出比较模块定义: PWM波形,频率1KHZ,占空比50%,分辨率为 1%,TIM_OCInitTypeDef OCI;TIM_OCStructInit(&OCI); //先初始化输出比较模块,后续修改某个属性OCI.TIM_OCMode = TIM_OCMode_PWM1;OCI.TIM_OCPolarity = TIM_OCPolarity_High; //极性,高电平有效电平OCI.TIM_OutputState = ENABLE;OCI.TIM_Pulse = 0; //CCR捕获寄存器,可以通过改变CCR的值,调制PWM波形的占空比,从而改变LED灯的亮度 TIM_OC1Init(TIM2,&OCI); //pwm波形初始化
}//用于动态改变CCR,调节LED灯的亮度,PWM使用的PA0端口
void PWM_SetCompare1(uint16_t Compare){TIM_SetCompare1(TIM2,Compare); //该函数用于设置CRR的值}
舵机


按键控制舵机旋转
#include "stm32f10x.h" // Device header
#include "MyDelay.h" //自定义延时函数
#include "Delay.h" //官方延迟函数
#include "Button.h" //按键Led驱动
#include "stdio.h"
#include "PWM.h"
#include "OLED.h"
#include "Servos.h"
float Angle;
int KeyNum;
int main(void){//环境配置OLED_Init();Servos_PWM_Init();Button_Init();//显示角度OLED_ShowString(1,1,"Angle:");while(1){KeyNum = Key_GetNum();if(KeyNum == 1){Angle += 25;if(Angle>=180) Angle = 180;OLED_ShowNum(1,7,Angle,5);Servos_SetAngle(Angle);} if(Angle>=180){Angle = 0; OLED_ShowNum(1,7,Angle,5);Servos_SetAngle(0);} }return 0;
}#ifndef Servos_h
#define Servos_h
//舵机PWM波形初始化
void Servos_PWM_Init(void);
//动态改变PWM通道2的波形
void PWM_SetCompare2(uint16_t Compare);
//设置舵机旋转角度
void Servos_SetAngle(float Angle);
#endif#include "stm32f10x.h"
//舵机PWM波形初始化
void Servos_PWM_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //时钟中断RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //为呼吸灯指定引脚PA0GPIO_InitTypeDef GI;GI.GPIO_Mode = GPIO_Mode_AF_PP; //定时器(外设)控制引脚,要用复用推挽输出GI.GPIO_Pin = GPIO_Pin_1;GI.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GI);TIM_InternalClockConfig(TIM2); //内部时钟TIM_TimeBaseInitTypeDef TI; //时钟中断配置TI.TIM_ClockDivision = TIM_CKD_DIV2;TI.TIM_CounterMode = TIM_CounterMode_Up;TI.TIM_Period = 20000; // ARRTI.TIM_Prescaler = 72; // PSC ,CK_PSC=72MHZTI.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TI);TIM_Cmd(TIM2,ENABLE); //时钟中断使能//时钟中断的输出比较模块定义: PWM波形,舵机要求时钟20ms,频率50HZ,占空比动态变化,分辨率动态变化,TIM_OCInitTypeDef OCI;TIM_OCStructInit(&OCI); //先初始化输出比较模块,后续修改某个属性OCI.TIM_OCMode = TIM_OCMode_PWM1;OCI.TIM_OCPolarity = TIM_OCPolarity_High; //极性,高电平有效电平OCI.TIM_OutputState = ENABLE;OCI.TIM_Pulse = 0; //调制PWM波形的占空比,从而控制舵机,舵机CCR取值范围:500 ~ 2500 TIM_OC1Init(TIM2,&OCI); //pwm通道1初始化 TIM_OC2Init(TIM2,&OCI); //pwm通道2}//动态改变PWM通道2的CCR
void PWM_SetCompare2(uint16_t Compare){TIM_SetCompare2(TIM2,Compare);
}//设置舵机旋转角度
void Servos_SetAngle(float Angle){float sum = 500 + (Angle/180*2000); //CCR:500~2500 与 角度:0~180 计算得出PWM_SetCompare2(sum);
}
直流电机



//电机驱动代码
#include "stm32f10x.h" // Device header
#include "MyDelay.h" //自定义延时函数
#include "Delay.h" //官方延迟函数
#include "Button.h" //按键Led驱动
#include "stdio.h"
#include "OLED.h"
#include "Servos.h"
#include "DCmotors.h"int Speed,KeyNum;
int main(void){//环境配置OLED_Init();DCmotors_Init();Button_Init();Motor_SetSpeed(-50);OLED_ShowString(1,1,"Circle Speed:");while(1){KeyNum = Key_GetNum(); //获取按键键码if (KeyNum == 1) //按键1按下{Speed += 20; //速度变量自增20if (Speed > 100) //速度变量超过100后{Speed = -100; //速度变量变为-100//此操作会让电机旋转方向突然改变,可能会因供电不足而导致单片机复位//若出现了此现象,则应避免使用这样的操作}}Motor_SetSpeed(Speed); //设置直流电机的速度为速度变量OLED_ShowSignedNum(2, 1, Speed, 3); //OLED显示速度变量}return 0;
}#ifndef DCmotors_h
#define DCmotors_h
//直流电机驱动
void DCmotors_Init(void);
//设置电机旋转速度以及旋转方向(电流方向决定旋转方向)
void Motor_SetSpeed(int8_t Speed);
#endif#include "stm32f10x.h"
#include "OLED.h"
#include "PWM.h"
//直流电机驱动
void DCmotors_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GI;GI.GPIO_Mode = GPIO_Mode_Out_PP; //要用推挽输出(不由片上外设控制,无需复用推挽输出)GI.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;GI.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GI);PWM_Init(); //PWM波形初始化
}
//设置电机旋转速度以及旋转方向(电流方向决定旋转方向)
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只能给正数}
}//封装好的PWM模块
#ifndef PWM_H
#define PWM_H
//初始化PWM
void PWM_Init(void);
//用于动态改变CCR,调节LED灯的亮度,PWM使用的PA0端口
void PWM_SetCompare3(uint16_t Compare);
#endif#include "stm32f10x.h" // Device header
//初始化PWM
void PWM_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //时钟中断RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //为呼吸灯指定引脚PA0//法二:为了提高引脚使用率,重映射端口,打开AFIO,重映射引脚,解除调试端口
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
// GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);
// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //禁用JTAG调试,这里用的是ST-LinkGPIO_InitTypeDef GI;GI.GPIO_Mode = GPIO_Mode_AF_PP; //(外设)控制引脚,PA2要用复用推挽输出GI.GPIO_Pin = GPIO_Pin_2;GI.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GI);TIM_InternalClockConfig(TIM2); //内部时钟TIM_TimeBaseInitTypeDef TI; //时钟中断配置TI.TIM_ClockDivision = TIM_CKD_DIV2 ;TI.TIM_CounterMode = TIM_CounterMode_Up;TI.TIM_Period = 100-1; // ARRTI.TIM_Prescaler = 36-1; // PSC ,CK_PSC=72MHZTI.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TI);TIM_Cmd(TIM2,ENABLE); //时钟中断使能//时钟中断的输出比较模块定义: PWM波形,频率1KHZ,占空比50%,分辨率为 1%,TIM_OCInitTypeDef OCI;TIM_OCStructInit(&OCI); //先初始化输出比较模块,后续修改某个属性OCI.TIM_OCMode = TIM_OCMode_PWM1;OCI.TIM_OCPolarity = TIM_OCPolarity_High; //极性,高电平有效电平OCI.TIM_OutputState = ENABLE;OCI.TIM_Pulse = 0; //CCR捕获寄存器,可以通过改变CCR的值,调制PWM波形的占空比,从而改变LED灯的亮度 TIM_OC3Init(TIM2,&OCI); //pwm波形初始化 }//用于动态改变CCR,调节LED灯的亮度,PWM使用的PA0端口
void PWM_SetCompare3(uint16_t Compare){TIM_SetCompare3(TIM2,Compare); //该函数用于设置CRR的值}相关文章:
物联网——TIM定时器、PWM驱动呼吸灯、舵机和直流电机
定时器概念(常用于输出PWM波形,驱动电机) 时间脉冲数时钟周期; 这里的脉冲数6553665536,支持定时器级联,从而延长定时 定时器类型 基本定时器原理图(UI:更新中断, U:更新事件&#…...
Elasticsearch 认证模拟题 -2
一、题目 有一个索引 task3,其中有 fielda,fieldb,fieldc,fielde 现要求对 task3 重建索引,重建后的索引新增一个字段 fieldg 其值是fielda,fieldb,fieldc,fielde 的值拼接而成。 …...
Java-----Comparable接口和Comparator接口
在Java中,我们会经常使用到自定义类,那我们如何进行自定义类的比较呢? 1.Comparable接口 普通数据的比较 int a10;int b91;System.out.println(a<b); 那自定义类型可不可以这样比较呢?看一下代码 我们发现会报错,因为自定义…...
通信技术体会
比如 pcie可以看成是全连接的ahb bus,但又不是。 因为pcie还是axi(神似split/cutthrough)。(axi更多是接口而不是bus)。 pcie虽然物理层和usb都是serdes,但transaction layer就是上面这样的,也就…...
Linux系统安全及其应用
文章目录 一、用户账号安全管理1.1 系统账号的清理1.2 对用户账号的操作1.2.1 锁定和解锁用户1.2.2 删除无用账号 1.3 对重要文件进行锁定1.4 密码安全控制1.4.1 新建用户1.4.2 已有用户 二、历史命令管理2.1 历史命令限制2.2 自动清空历史命令 三、设置终端登录的安全管理3.1 …...
JVM内存划分类加载的过程双亲委派模型的详解
JVM内存划分 JVM也就是java进程,这个进程一旦跑起来就会从操作系统这里申请一大块内存空间,JVM接下来就要进一步的对这个大的空间进行划分,划分成不同区域,从而每个区域都有不同的功能作用,一共分为如下几个区域 1.堆…...
Java异常详解
Java异常详解 前言一、异常类的定义Java异常异常类的构成Java常见运行错误异常示例除以 0数组下标越界访问 null 对象 防御式编程异常的好处LBYL 风格的代码EAFP 风格的代码 二、异常的基本用法捕获异常基本语法代码示例不处理异常使用 try catch 后的程序执行过程catch 只能处…...
C++入门3——类与对象2(类的6个默认成员函数)
目录 1.类的6个默认成员函数 2. 构造函数 2.1 构造函数的概念 2.2 构造函数的特性 3. 析构函数 3.1 析构函数的概念 3.2 析构函数的特性 4.拷贝构造函数 4.1 拷贝构造函数的概念 4.2 拷贝构造函数的特性 5.赋值运算符重载函数 5.1运算符重载函数 5.2 赋值运算符重…...
CobaltStrike基本渗透
目录 CobaltStrike简介 主要功能: 使用注意: 在使用CobaltStrike进行渗透测试时,务必遵守法律法规,并获得合法授权。 CobaltStrike安装 前提 安装 服务端安装 windows安装 CS基本使用 监听器配置 一些基本的攻击…...
【linux深入剖析】进程间通信
🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 1.进程间通信目的2. 什么…...
关系数据库:关系模式
文章目录 基本概述关系的相关名词术语笛卡儿积与关系关系的类型 关系模式总结 基本概述 关系的相关名词术语 关系:简单来说,就是一张二维表格。属性(Attribute):也称字段或列,在现实世界中,要描述一个事务常常取若干…...
医学图像处理质量的评价方法
评判处理后医学图像的质量是确保图像处理技术有效性和可靠性的关键。以下是一些常用的图像质量评估方法和指标: 1. 主观评估 主观评估是由专业人员(如放射科医生)通过视觉检查对图像质量进行评分。常用的主观评估方法包括: 视觉…...
Ehcache Java 缓存框架
详解 下图是 Ehcache 在应用程序中的位置: Ecache 是一个广泛使用的 Java 缓存框架,能够有效提升应用性能,并减少与后端数据库的交互次数。它采用了一系列高级缓存策略,包括内存缓存、磁盘缓存、分布式缓存等,并提供了…...
详解Spring IoCDI(二)
目录 承接上文:详解Spring IoC&DI (一) 1.IoC详解 1.1方法注解Bean 1.2方法注解要配合类注解使用 1.3定义多个对象 1.4重命名Bean 1.5扫描路径 2.DI详解 2.1DI与IoC的关系 2.2属性注入 2.3构造方法注入 2.4Setter注入 2.5 三…...
说明白计算机网络之TCP的流量控制与拥塞控制之慢开始算法与拥塞避免算法
TCP的流量控制 利用滑动窗口实现流量控制 设A向B发送数据,连接建立时候,B告诉A自身的接收窗口大小,A的发送窗口大小不能超过接收方B的窗口大小 流量控制:发送方发送速率不要太快,要让接收方来得及接收。窗口大小的单…...
这款信创FTP软件,可实现安全稳定的文件传输
信创,即信息技术应用创新,2018年以来,受“华为、中兴事件”影响,国家将信创产业纳入国家战略,并提出了“28n”发展体系。“8”具体指金融、石油、电力、电信、交通、航空航天、医院、教育等主要行业。目前企业使用比较…...
代码随想录算法训练营第十天|232.用栈实现队列、225. 用队列实现栈
232.用栈实现队列 题目链接:232. 用栈实现队列 文档讲解:代码随想录 状态:写出来 ,但差强人意 思路: 定义两个容器,可以是Stack,也可以是Deque,stackIn相当于临时容器,用来存放元素&…...
STM32 IIC协议
本文代码使用 HAL 库。 文章目录 前言一、什么是IIC协议二、IIC信号三、IIC协议的通讯时序1. 写操作2. 读操作 四、上拉电阻作用总结 前言 从这篇文章开始为大家介绍一些通信协议,包括 UART,SPI,IIC等。 UART串口通讯协议 SPI通信协议 一、…...
Java生成随机数的几种方式
随机数,在一些特殊场景下,是非常常用的。比如一些测试和验证场景、安全加密、随机抽样等都有随机数的‘身影’。 一、 使用java.util.Random类 java.util.Random类提供了更全面的随机数生成功能,包括随机整数、随机浮点数、随机布尔值等。 p…...
【面试】什么是Java虚拟机
目录 1. 说明2. 关键点 1. 说明 1.Java虚拟机(Java Virtual Machine,简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境。2.JVM是Java平台无关性的关键,它允许Java程序在任何支持JVM的硬件和操作系统上运…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
[拓扑优化] 1.概述
常见的拓扑优化方法有:均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有:有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...
