基于开源ATmega8 无感BLDC程序移植到ATmega328PB

基于开源ATmega8 无感BLDC程序移植到ATmega328PB


  • 🔖基于Atmel Studio 7.0开发环境。
  • 🥕开源原项目资源地址:https://svn.mikrokopter.de/websvn/listing.php?repname=BL-Ctrl&path=%2F&
  • 📍原理图和PCB资源 BL-Ctrl v2.0 in Eagle(MEGA168与本移植项目原理图差异较大):https://github.com/Janesak1977/BLCTRL20_HW
  • 🌿BL-Ctrl官网BL-Ctrl V3、BL-Ctrl V2.0、BL-Ctrl V1.2资料介绍:https://wiki.mikrokopter.de/en/BL-Ctrl?action=show&redirect=en%2FBrushlessCtrl
  • 📜BL-Ctrl历史版本查询:https://wiki.mikrokopter.de/Ctrl_History

ATmega8 单片机和ATmega328PB差异不大,大部分寄存器无需修改,少数寄存器存在差异,硬件资源上,ATmega328PB资源外设比ATmega8多,价格上差不多。虽然采用的是8位单片机,与当今主流单片机,在性能上无法比拟。不影响学习研究。

  • ✨同驱动类型,性价比更高的,国内开源公开资料的有:基于STC8和STC32单片机梁工的相关无刷电机驱动工程,可从STCAI论坛获取相关资料。原理实现方法相同,应该也算是借鉴过来的,后起之作。
  • 📍STC梁工开源的三相无刷直流电机驱动资料地址:https://www.stcaimcu.com/forum.php?mod=viewthread&tid=1822&highlight=%E6%97%A0%E5%88%B7%E7%94%B5%E6%9C%BA&page=1&extra=#pid11784
  • 🎉此项目开源,同类型驱动控制里面,在当时算得上最早被公开的了。里面的部分经典算法一直被同类型驱动上所采用。
  • 📜按照此开源资料,如果想移植到其它单片机上,按照此反电动势检测实现方法,硬件要求是需要有一个模拟比较器。和需要能产生3路PWM信号来驱动H桥,这最基本的电机转动的要求。如果还需要电流采集以及ADC调速,那就需要单片机要有ADC资源。
  • 🌿早期相关ATmega328P相关移植参考文章:https://www.amobbs.com/thread-4652868-1-1.html
  • 🌼移植后基于自制驱动板,驱动转动效果:
    🌼
  • 📌自制驱动板相关内容《自制无感无刷电机驱动板》
  • ✒自己亲手移植一遍工程,不是简单的照搬一次代码,起码对整个无感无刷电机运转实现,有一个认识和了解,同时硬件上学习了2个单片机的资源外设,进行熟悉了一遍。
  • 🌿ATmega8 原理图:https://wiki.mikrokopter.de/en/BL-Ctrl_V1.2
    在这里插入图片描述
  • 🌿通过上面的BL-Ctrl_V1.2版本原理图移植到ATmega328PB,个人使用参考的源码是:V0.42:https://svn.mikrokopter.de/websvn/listing.php?repname=BL-Ctrl&path=%2Ftags%2FV0.42%2F&#a4bfcc0886576e3118d94460220fa558a
    在这里插入图片描述
  • 🌿ATmega328PB引脚连接参考上面的图纸:BL-Ctrl_V1.2版本原理图。相关1.2版本程序:https://github.com/jankae/brushlessControl
  • 🔨代码移植编译平台:Atmel Studio 7.0

⛳移植难点和重点

✨整个工程,基本都是围绕着,电机转动时,反电动势检测过零点内容的实现。对于PWM发波,都是比较容易配置和实现的。
  • 🌟ATmega8 和ATmega328PB自带的模拟比较器功能又和ADC功能相关寄存器共生,不能同时启用,导致需要功能切换时,需要及时改变相关寄存器位的配置。
📑基于反电动势检测过零点有两种方式:
  • 🥕基于 ADC 采样的无感方波电机控制 ADC 采样检测过零点。

  • 🥕基于比较器检测的无感方波电机控制 比较器检测过零点。(本项目采用的方式)

    • 🍁比较器检测过零点电路部分:

在这里插入图片描述

  • 📐理论计算和推导部分:
    在这里插入图片描述

📙移植到ATmega328PB,相关寄存器变更

  • 🌿外部时钟频率原来的8MHz换成16MHz。
  • 🌿TCCR2对应ATmega328PB相关寄存器TCCR0ATCCR0B
  • 🌿SFIOR对应ATmega328PB相关寄存器ADCSRB
  • 🌿参考电压差异,ATmega8 内部参考电压:2.56v,而ATmega328PB内部参考电压:1.1V。(个人移植使用的是AVCC作为参考电压即5V)
  • ✨在移植程序中需要处理的个别寄存器位差异,需要调整的地方比较多,如果自己移植,哪里报错有问题改哪里。

🛠3路PWM控制上桥臂说明

  • 🌿3路PWM控制上桥臂的信号频率个人采用的是15.625KHz.
  • 🌿引脚分别是:PB1、PB2、PB3
  • 🌿定时器通道选择和使用:
PB1  OC1A(定时器1,通道A)	 Mode: Normal top=0xFF
PB2  OC1B(定时器1,通道B)	 Mode: Normal top=0xFF
PB3  OC2A(定时器2,通道A)	 Mode: Normal top=0xFF
  • 🔧3路控制PWM信号核心代码:
#define PWM_A_ON  {TCCR1A=(1<<WGM10);TCCR1B=(1<<WGM12)| (1<<CS12) |(1<<CS10);TCCR2A=(1<<COM2A1)|(1<<WGM21) | (1<<WGM20);TCCR2B=(1<<CS22) | (1<<CS21) | (1<<CS20);  DDRB = 0x08;}//PB3#define PWM_B_ON  {	TCCR1A =  (1<<COM1B1) | (1<<WGM10);TCCR1B= (1<<WGM12)|(1<<CS12)|(1<<CS10);TCCR2A= (1<<WGM21) | (1<<WGM20) ;TCCR2B=(1<<CS22) | (1<<CS21) | (1<<CS20); DDRB = (1<<DDB2);}//PB2#define PWM_C_ON  {TCCR1A = (1<<COM1A1)|(1<<WGM10);TCCR1B=(1<<WGM12) |  (1<<CS12)|(1<<CS10);TCCR2A =(1<<WGM21)|(1<<WGM20);TCCR2B=  (1<<CS22) | (1<<CS21) | (1<<CS20); DDRB = (1<<DDB1);}//PB1
  • 🔑双路同时输出方式:
#define PWM_C_ON  {TCCR1A = (1<<COM1A1)|(1<<WGM10);TCCR1B=(1<<CS12);TCCR1C=(1<<FOC1A)|(1<<FOC1B);TCCR2A= (1<<WGM21)|(1<<WGM20);TCCR2B =(1<<FOC2A)|(1<<CS21);DDRB = 0x0A;}//PB3 ->OC2A	;PB1 ->OC1A	clkI/O/8
#define PWM_B_ON  {TCCR1A = (1<<COM1B1)|(1<<WGM10);TCCR1B=(1<<CS12);TCCR1C=(1<<FOC1A)|(1<<FOC1B); TCCR2A=(1<<COM2A1)|(1<<WGM21)|(1<<WGM20);TCCR2B =(1<<FOC2A)|(1<<CS21);DDRB = 0x0C;}//PB3 ->OC2A ; PB2 ->OC1B
#define PWM_A_ON  {TCCR1A =(1<<WGM10);TCCR1B=(1<<CS12);TCCR1C=(1<<FOC1A)|(1<<FOC1B);TCCR2A= (1<<COM2A1)|(1<<WGM21)|(1<<WGM20);TCCR2B = (1<<FOC2A)|(1<<CS21);DDRB = 0x08;}//PB3 ->OC2A
#define PWM_OFF   {TCCR1B &=~((1<<CS10)|(1<<CS11)|(1<<CS12));TCCR2B &=~((1<<CS20)|(1<<CS21)|(1<<CS22));PORTB &= ~0x0E;}

双路输出模式下,PWM_B_ON PWM_A_ON ,寄存器TCCR2A可以都配置定时器2的通道 A 的比较输出模式(1<<COM2A1),或者两者配置其一。推荐这两项控制,仅配置PWM_C_ON,其它参数不变的情况下,测试明显电流要小一些。

📘3路下桥臂采用IO开关控制

#define  STEUER_A_L {PORTD &= ~0x30; PORTD |= 0x08;}//U- ->PD3
#define  STEUER_B_L {PORTD &= ~0x28; PORTD |= 0x10;}//V- ->PD4
#define  STEUER_C_L {PORTD &= ~0x18; PORTD |= 0x20;}//W- ->PD5
  • 🔖以下内容待写……

📙ADC检测

  • 🔖ADC采集电流,是通过硬件蛇形布线实现的。具体看开源资料中的PCB文件。
    在这里插入图片描述
  • 📑ADC采集代码实现,进行ADC功能前,需要关闭模拟比较器,采集完ADC数据后,需要打开模拟比较器。两个不能同时启用。
//############################################################################
//Strom Analogwerte lesen
unsigned int MessAD(unsigned char channel)
//############################################################################
{unsigned char sense;sense = ADMUX;   // Sense-Kanal merkenchannel |= IntRef;ADMUX  =  channel;  // 开启对应ADC通道//SFIOR  =  0x00;  // Analog Comperator ausADCSRB &= ~(1<<ACME);//关闭模拟比较器
//    GTCCR &=~((1<<PSRSYNC)|(1<<PSRASY));//将定时器2,0,1,3,4分频系数reset
//    MCUCR  &=~(1<<PUD);//禁用上拉电阻
//  ADC is enabledPRR0&= ~(1<<PRADC);ADMUX  =  channel;  ///** initialize ADC:* Prescaler = 16 -> 1MHz,* Enable + Start*/ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADPS2);
//等待转换完成while(ADCSRA & (0x01 << ADIF));    /* check if ADC conversion complete */
//   while (ADCSRA & (1 << ADSC));// wait for ADC to finishADCSRA = 0x00;ADMUX = sense;   // zurück auf den Sense-Kanal
//   SFIOR = 0x08;  // Analog Comperator einADCSRB |= (1<<ACME);//打开模拟比较器
// ADC is disabled to preserve power
//    PRR0|= 1<<PRADC;ADCSRB |= (1<<ACME);//当ACME为1,且ADEN为0时可以选择ADC相关引脚为负输入ADCSRA &= ~_BV(ADEN);/*Bit 3 – ACIE Analog Comparator Interrupt EnableBit 6 – ACBG Analog Comparator Bandgap Select*/ACSR |= _BV(ACIE);ACSR &= ~_BV(ACBG);//当该位被清除时,AIN0被应用于模拟比较器的正输入。
//    GTCCR &=~((1<<PSRSYNC)|(1<<PSRASY));//将定时器2,0,1,3,4分频系数resetMCUCR  &=~(1<<PUD);//禁用上拉电阻return (ADCW);
}

📗三相反电动势检测比较器实现。

  • 📄三相反电动势检测,对应电机转动过程就的:消磁事件,过零事件,换相事件。(下面参考图来源于网络)
    在这里插入图片描述

🧲电机启动实现方式

  • 📝强制启动,代码实现:
//############################################################################
//电机启动
char Anwerfen(unsigned char pwm)
//############################################################################
{unsigned long timer = 200, i;//timer = 300DISABLE_SENSE_INT;//关闭模拟比较器中断PWM = 16;SetPWM();//T1和T2定时计数器赋值,设置pwm占空比/*补充注释:开环顺序换向算法,注意换向时必须同步修改比较器端口及触发沿以便在反相感生电动势到达切换条件时,自动切换到闭环运转状态*/Manuell();//换相操作Delay_ms(200);/*MinUpmPulse = SetDelay(300);while (!CheckDelay(MinUpmPulse)){FastADConvert();if (Strom > 120){STEUER_OFF; // 因短路而关闭RotBlink(10);printf("ADC7 Strom STOP\r\n");return (0);}}*/PWM = pwm;while (1){/*for (i = 0; i < timer; i++){if (!UebertragungAbgeschlossen)  SendUart();else DatenUebertragung();//  Wait(100);  // warten 8/8Wait(25);//328p 16/64}DebugAusgaben();FastADConvert();if (Strom > 60){STEUER_OFF; // Abschalten wegen KurzschlussRotBlink(10);return (0);}*/timer -= timer / 15 + 1;if (timer < 25){if (TEST_MANUELL) timer = 25;else return (1);}Manuell();//BLDC换相Phase++;Phase %= 6;AdConvert();PWM = pwm;SetPWM();if (SENSE){PORTD ^= GRUEN;}}
}//############################################################################
/*
开环顺序换向算法,注意换向时必须同步修改比较器端口及触发沿
以便在反相感生电动势到达切换条件时,自动切换到闭环运转状态
*/
void Manuell(void)//BLDC换相
//############################################################################
{switch (Phase){case 0:STEUER_A_H;//U+STEUER_B_L;//V-SENSE_C;//比较器选择,通道 ADC2(PC2)作为负输入端SENSE_RISING_INT;//模拟比较器输出的上升沿产生中断break;case 1:STEUER_A_H;STEUER_C_L;SENSE_B;//比较器选择,通道 ADC1(PC1)作为负输入端SENSE_FALLING_INT;break;case 2:STEUER_B_H;STEUER_C_L;SENSE_A;//比较器选择,通道 ADC1(PC0)作为负输入端SENSE_RISING_INT;break;case 3:STEUER_B_H;STEUER_A_L;SENSE_C;SENSE_FALLING_INT;break;case 4:STEUER_C_H;STEUER_A_L;SENSE_B;SENSE_RISING_INT;break;case 5:STEUER_C_H;STEUER_B_L;SENSE_A;SENSE_FALLING_INT;break;}
}
  • 🌾在STC 无感BLDC代码中也有类似的启动代码:
/******************* 强制电机启动函数 ***************************/
void StartMotor(void)
{u16 timer,i;PIE = 0; NIE = 0;	// 关比较器中断,	PIE=1: 允许比较器上升沿中断, PIE=0: 禁止上升沿中断.	NIE=1: 允许比较器下降沿中断, NIE=0: 禁止下降沿中断.PWM_Value  = D_START_PWM;	// 初始占空比, 根据电机特性设置PWMA_CCR1H = (u8)(PWM_Value/256);PWMA_CCR1L = (u8)(PWM_Value%256);PWMA_CCR2H = (u8)(PWM_Value/256);PWMA_CCR2L = (u8)(PWM_Value%256);PWMA_CCR3H = (u8)(PWM_Value/256);PWMA_CCR3L = (u8)(PWM_Value%256);step = 0;	StepMotor();	Delay_n_ms(30);	// 初始位置step = 1;	StepMotor();	Delay_n_ms(20);	// 初始位置timer = 232;	//200电机启动while(1){for(i=0; i<timer; i++)	delay_us(18);  //20根据电机加速特性, 最高转速等等调整启动加速速度timer -= timer /16;if(++step >= 6)	step = 0;StepMotor();if(timer < 40)	return;}
}void StepMotor(void) // 换相序列函数
{switch(step){case 0:  // AB  PWM1, PWM2_L=1PWMA_ENO = 0x00;	PWM1_L=0;	PWM3_L=0;Delay_500ns();PWMA_ENO = 0x01;		// 打开A相的高端PWMPWM2_L = 1;				// 打开B相的低端CMPEXCFG = 0;			// 比较器选择C相反电动势,  CMP+输入选择,0->P3.7(EMFC),1->P5.0(EMFA),2->P5.1(EMFB),3->ADCINPIE = 0; NIE = 1;		// 比较器下降沿中断,	PIE=1: 允许比较器上升沿中断, PIE=0: 禁止上升沿中断.	NIE=1: 允许比较器下降沿中断, NIE=0: 禁止下降沿中断.break;case 1:  // AC  PWM1, PWM3_L=1PWMA_ENO = 0x01;	PWM1_L=0;	PWM2_L=0;	// 打开A相的高端PWMDelay_500ns();PWM3_L = 1;				// 打开C相的低端CMPEXCFG = 2;			// 比较器选择B相反电动势,  CMP+输入选择,0->P3.7(EMFC),1->P5.0(EMFA),2->P5.1(EMFB),3->ADCINPIE = 1; NIE = 0;		// 比较器上升沿中断,	PIE=1: 允许比较器上升沿中断, PIE=0: 禁止上升沿中断.	NIE=1: 允许比较器下降沿中断, NIE=0: 禁止下降沿中断.break;case 2:  // BC  PWM2, PWM3_L=1PWMA_ENO = 0x00;	PWM1_L=0;	PWM2_L=0;Delay_500ns();PWMA_ENO = 0x04;		// 打开B相的高端PWMPWM3_L = 1;				// 打开C相的低端CMPEXCFG = 1;			// 比较器选择A相反电动势,  CMP+输入选择,0->P3.7(EMFC),1->P5.0(EMFA),2->P5.1(EMFB),3->ADCINPIE = 0; NIE = 1;		// 比较器下降沿中断,	PIE=1: 允许比较器上升沿中断, PIE=0: 禁止上升沿中断.	NIE=1: 允许比较器下降沿中断, NIE=0: 禁止下降沿中断.break;case 3:  // BA  PWM2, PWM1_L=1PWMA_ENO = 0x04;	PWM2_L=0;	PWM3_L=0;	// 打开B相的高端PWMDelay_500ns();PWM1_L = 1;				// 打开C相的低端CMPEXCFG = 0;			// 比较器选择C相反电动势,  CMP+输入选择,0->P3.7(EMFC),1->P5.0(EMFA),2->P5.1(EMFB),3->ADCINPIE = 1; NIE = 0;		// 比较器上升沿中断,	PIE=1: 允许比较器上升沿中断, PIE=0: 禁止上升沿中断.	NIE=1: 允许比较器下降沿中断, NIE=0: 禁止下降沿中断.break;case 4:  // CA  PWM3, PWM1_L=1PWMA_ENO = 0x00;	PWM2_L=0;	PWM3_L=0;Delay_500ns();PWMA_ENO = 0x10;		// 打开C相的高端PWMPWM1_L = 1;				// 打开A相的低端CMPEXCFG = 2;			// 比较器选择B相反电动势,  CMP+输入选择,0->P3.7(EMFC),1->P5.0(EMFA),2->P5.1(EMFB),3->ADCINPIE = 0; NIE = 1;		// 比较器下降沿中断,	PIE=1: 允许比较器上升沿中断, PIE=0: 禁止上升沿中断.	NIE=1: 允许比较器下降沿中断, NIE=0: 禁止下降沿中断.break;case 5:  // CB  PWM3, PWM2_L=1PWMA_ENO = 0x10;	PWM1_L=0;	PWM3_L=0;	// 打开C相的高端PWMDelay_500ns();PWM2_L = 1;				// 打开B相的低端CMPEXCFG = 1;			// 比较器选择A相反电动势,  CMP+输入选择,0->P3.7(EMFC),1->P5.0(EMFA),2->P5.1(EMFB),3->ADCINPIE = 1; NIE = 0;		// 比较器上升沿中断,	PIE=1: 允许比较器上升沿中断, PIE=0: 禁止上升沿中断.	NIE=1: 允许比较器下降沿中断, NIE=0: 禁止下降沿中断.break;default:break;}if(B_start)	// 启动时禁止下降沿和上升沿中断{CMPIF = 0;		//清除比较器中断标志PIE = 0; NIE = 0;		// 比较器上升沿中断,	PIE=1: 允许比较器上升沿中断, PIE=0: 禁止上升沿中断.	NIE=1: 允许比较器下降沿中断, NIE=0: 禁止下降沿中断.}
}

📓比较器中断代码

✨用于确定下一刻,应该换哪一相;以及设定下一次比较器触发电平模式。

//############################################################################
//
SIGNAL(TIMER2_COMPB_vect)	//SIG_OVERFLOW2 定时器2溢出
//############################################################################
{
}//############################################################################
//SIG_COMPARATOR模拟比较器
// + Wird durch den Analogkomperator ausgelöst
// + Dadurch wird das Kommutieren erzeugt
SIGNAL(ANALOG_COMP_vect)
//############################################################################
{unsigned char sense = 0;do{if (SENSE_H) sense = 1;else sense = 0;switch (Phase){case 0:STEUER_A_H;if (sense){STEUER_C_L;if (ZeitZumAdWandeln) AdConvert();SENSE_FALLING_INT;SENSE_B;Phase++;CntKommutierungen++;}else{STEUER_B_L;}break;case 1:STEUER_C_L;if (!sense){STEUER_B_H;if (ZeitZumAdWandeln) AdConvert();SENSE_A;SENSE_RISING_INT;Phase++;CntKommutierungen++;}else{STEUER_A_H;}break;case 2:STEUER_B_H;if (sense){STEUER_A_L;if (ZeitZumAdWandeln) AdConvert();SENSE_C;SENSE_FALLING_INT;Phase++;CntKommutierungen++;}else{STEUER_C_L;}break;case 3:STEUER_A_L;if (!sense){STEUER_C_H;if (ZeitZumAdWandeln) AdConvert();SENSE_B;SENSE_RISING_INT;Phase++;CntKommutierungen++;}else{STEUER_B_H;}break;case 4:STEUER_C_H;if (sense){STEUER_B_L;if (ZeitZumAdWandeln) AdConvert();SENSE_A;SENSE_FALLING_INT;Phase++;CntKommutierungen++;}else{STEUER_A_L;}break;case 5:STEUER_B_L;if (!sense){STEUER_A_H;if (ZeitZumAdWandeln) AdConvert();SENSE_C;SENSE_RISING_INT;Phase = 0;CntKommutierungen++;}else{STEUER_C_H;}break;}}while ((SENSE_L && sense) || (SENSE_H && !sense));ZeitZumAdWandeln = 0;
}

🔬移植初版工程源码

链接:https://pan.baidu.com/s/1kCNJCOLu4gqsP1KXwm9d3Q?pwd=6z15 
提取码:6z15

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Win32 API

个人主页&#xff1a;星纭-CSDN博客 系列文章专栏 : C语言 踏上取经路&#xff0c;比抵达灵山更重要&#xff01;一起努力一起进步&#xff01; 一.Win32 API 1.Win32 API介绍 Windows这个多作业系统除了协调应⽤程序的执⾏、分配内存、管理资源之外&#xff0c;它同时也是…

Redis内存回收-内存淘汰策略

LFU的访问次数之所以叫做逻辑访问次数&#xff0c;是因为并不是每次key被访问都计数&#xff0c;而是通过运算&#xff1a; 生成0~1之间的随机数R计算 (旧次数 * lfu_log_factor 1)&#xff0c;记录为P如果 R < P &#xff0c;则计数器 1&#xff0c;且最大不超过255访问…

9.任务调度

一、开启任务调度器 1.函数 vTaskStartScheduler() 函数 vTaskStartScheduler()用于启动任务调度器&#xff0c;任务调度器启动后&#xff0c;FreeRTOS 便会开始 进行任务调度&#xff0c;除非调用函数 xTaskEndScheduler()停止任务调度器&#xff0c;否则不会再返回。函数 vTa…

Centos修改系統語言

一、使用命令行修系统语言 1、显示系统当前语言环 [rootkvm-suma ~]# localectl System Locale: LANGen_US.utf8 VC Keymap: cn X11 Layout: cn 2、查看系统支持字符集 [rootkvm-suma ~]# locale -a 2、设置系统语言环境 [rootkvm-suma ~]# localectl set-locale LANGz…

【GESP试卷】2024年03月Scratch四级试卷

2024年GESP03月认证Scratch四级试卷 分数&#xff1a;100 题数&#xff1a;27 一、单选题(共15题&#xff0c;每题2分&#xff0c;共30分) 010203040506070809101112131415CDBBACBCDCDADBA 1、小杨的父母最近刚刚给他买了一块华为手表&#xff0c;他说手表上跑的是鸿蒙&…

【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【00】补充

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【00】补充 插件IDEAVsCode MavenvagrantDocker解决MySQL连接慢问题启动&#xff08;自动&#xff09;Docker注意切换到root用户远程访问MySQL MyBatisPlus代码地址参考 插件 IDEA Mybati…

【数据挖掘】四分位数识别数据中的异常值(附代码)

写在前面&#xff1a; 首先感谢兄弟们的订阅&#xff0c;让我有创作的动力&#xff0c;在创作过程我会尽最大能力&#xff0c;保证作品的质量&#xff0c;如果有问题&#xff0c;可以私信我&#xff0c;让我们携手共进&#xff0c;共创辉煌。 路虽远&#xff0c;行则将至&#…

STM32F1之OV7725摄像头

目录 1. 摄像头简介 2. OV7725 摄像头简介 3. OV7725 引脚 4. OV7725 功能框架图 5. SCCB时序 5.1 SCCB 的起始、停止信号及数据有效性 5.2 SCCB 数据读写过程 1. 摄像头简介 在各类信息中&#xff0c;图像含有最丰富的信息&#xff0c;作为机…

SVM原问题与对偶问题

目的&#xff1a;求出我们的f(X)&#xff0c;它代表着我们X映射到多维的情况&#xff0c;能够帮我们在多维中招到超平面进行分类。 1.优化问题&#xff1a; 1.1推荐好书&#xff1a; 1.2 优化理论中的原问题&#xff1a; 原问题和限制条件如下&#xff1a; 这是一个泛化性…

【漏洞复现】英飞达医学影像存档与通信系统 WebJobUpload 任意文件上传漏洞

0x01 产品简介 英飞达医学影像存档与通信系统 Picture Archiving and Communicaton System&#xff0c;它是应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像(包括核磁&#xff0c;CT&#xff0c;超声&#xff0c;各种X光机&#xff0c;各种红外仪…

LeetCode - 数组 - 四数之和

题目地址 描述 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#x…

cs与msf权限传递以及mimikatz抓取win2012明文密码

简单的介绍 cs与msf的简单介绍 我查找过资料得出&#xff0c;Cobalt Strike 的前身是 Armitage&#xff0c;而 Armitage 又可以理解为 Metasploit Framework 的图形界面版&#xff0c;因此 Cobalt Strike 与 Metasploit Framework 在很多地方都是兼容的&#xff0c;所以我们便…

人工智能 框架 paddlepaddle 飞桨 使用指南 使用例子 线性回归模型demo 详解

安装过程&使用指南&线性回归模型 使用例子 本来预想 是安装 到 conda 版本的 11.7的 但是电脑没有gpu 所以 安装过程稍有变动,下面简单讲下 conda create -n paddle_env117 python=3.9 由于想安装11.7版本 py 是3.9 所以虚拟环境名称也是 paddle_env117 activa…

下载和安装AD19 - Altium Designer 19.1.9 Build 167

虽然有AD24 的安装资源&#xff0c;但是我比较喜欢19 这个数字[doge] 下载 仍然是从毛子网站源头进货&#xff1a;https://rutracker.net/forum/viewtopic.php?t5754276&#xff0c;网盘: https://pan.baidu.com/s/1ic31N4h7HS2FBu7JFll0YQ?pwdvjum 提取码: vjum 安装 压…

【DevOps】深入了解RabbitMQ:AMQP协议基础、消息队列工作原理和应用场景

目录 一、核心功能 二、优势 三、核心概念 四、工作原理 五、交换机类型 六、消息确认 七、持久性和可靠性 八、插件和扩展 九、集群和镜像队列 十、客户端库 十一、管理界面 十二、应用场景 RabbitMQ是一个基于AMQP协议的消息队列中间件&#xff0c;提供高可用、可…

[MRCTF2020]Xor

32位程序 主要逻辑 flagMSAWB~FXZ:J:tQJ"N bpdd}8g for i in range(len(flag)):print(chr(ord(flag[i])^i),end)

react 权限树形结构实现

项目背景 react ant design 实现效果 1 将后台返回的平铺数据 , 转成树形结构 const [roleId, setRoleId] useState() //存储角色id// 弹权限弹窗const empowerHandle async record > {setRoleId(record.roleId)//获取单独的权限const res1 await getPermission({ role…

力扣96. 不同的二叉搜索树

Problem: 96. 不同的二叉搜索树 文章目录 题目描述思路复杂度Code 题目描述 思路 一个数字做根节点的话可能的结果为&#xff1a;其左边数字做子树的组合数字乘以其右边数字做子树的个数之积 1.创建备忘录memo&#xff1b; 2.递归分别求取当前数字左边和右边数字做子树的数量&…

Vue 中 diff 算法原理

1. Diff 概念 vue 基于虚拟 DOM 做更新 。diff 的核心就是比较两个虚拟节点的差异 。Vue 的 diff 算法是平级比较,不考虑跨级比较的情况。内部采用深度递归的方式 + 双指针的方式进行比较。 2. Vue2 Diff 比较流程. 1.1先比较是否是相同节点 key tag 1.2相同节点比较属性,并…