电子设计竞赛(三)-SPWM与PID

2023-11-19

1  SPWM波调制技术

  逆变电路的控制方式主要是采用SPWM(正弦脉宽调制技术),IR2104控制开关管的通断来实现正弦调制,SPWM的基本思路是将一个正弦波按等宽间距分成N等份,对于每一个波形以一个等面积的脉冲来对应,使脉冲的中点与相应正弦波部分的中点重合,如下图所示,由于此脉冲序列的面积分布满足正弦规率,根据面积等效原理,将这个脉冲序列输出至负载时,将使负载得到相当接近正弦的输出电压和电流。

SPWM示意图

  由于采用该方式输出的电压波形很接近正弦波,所以电压中的谐波成分较少,同时也可以提高功率因数。通过改变SPWM脉冲的宽度可以改变输出电压的幅值,调节电路的调制周期则可以改变输出电压的频率,方便对负载进行控制。

1.1  单极性正弦脉宽调制

  单极性正弦脉宽调制是以一个宽度正弦规律变化的正弦脉冲序列对应交流输出波形的正半周,再以一个宽度按正弦规率变换的负脉冲序列对应交流输出波形的负半周,这两个脉冲序列交替作用,控制开关器件产生近似于正弦波的输出电压波形。
  正弦脉宽调制的基本方法是将正弦波性的调制波与三角波形的载波进行比较,通过比较正弦波形各点的瞬时值确定该点对应的脉冲宽度。单极性正弦脉宽调制使用的三角波是单极性的,在正弦调制波为正半周时三角载波是正极性的;在正弦波为负半周时三角波载波为负极性。如下图所示。

单相桥式逆变电路

单相桥式逆变电路

1.2  双极性正弦脉宽调制

  双极性正弦脉宽调制是以一个宽度按正弦规率变化的正负双向脉冲序列对应交流输出波形的整个周期,通过正向脉冲与负向脉冲宽度的差产生出按正弦规率变换的正半周波和负半周波。
  双极性正弦脉宽调制使用的三角波是双极性的,其波形的形式如下图,通过正弦调制波与三角波比较,当正弦调制波值大于三角波时,输出正脉冲;而当正弦调制波的值小于三角载波时,输出负脉冲。如此得到的脉冲序列是正负交替的双向脉冲序列。

双极性正弦脉宽调制

1.3  三相正弦脉宽调制

  三相正弦脉宽调制可以使用三个相角彼此相差120°的单相调制电路来合成,但是这样会使调制电路结构比较复杂。较简单的方法是采用一个双极性的三角载波对三相正弦调制波进行调制,其调制的波形如下图。
  调制过程中,双极性三角载波为三个正弦调制波共用,分别进行比较后获取脉宽调制信号,方式与双极性正弦脉宽调制方法相同。从而得到三个双向的脉冲序列,分别对应A、B、C三相,使用此三个脉冲序列控制逆变电路的A、B、C三相开关元件,可以将直流电压逆变为正弦波的三相交流输出电压。

三相正弦脉宽调制电路

三相正弦脉宽调制信号的产生

   三相脉宽调制波的三角载波只能是双极性的,因为单极性三角载波需要根据正弦调制波的正、负半周更换载波的极性。采用双极性正弦脉宽调制,H桥上同一相的上、下两个桥臂导通与截止都是互补的,为防止上下两个桥臂直通而造成的短路,需要在给一个桥臂施加关断信号后延迟一段时间,从而在波形中引入了死区时间,死区将会给输出的SPWM波形带来高次谐波。

1.4  SPWM控制信号的生成

  早期的SPWM采用模拟控制方式来实现,通过信号发生器产生所需的信号,由比较器进行信号之间的比较,随着数字技术和微处理器在SPWM逆变技术中的应用,采用一定算法产生SPWM的数字控制方式越来越广泛。

1.4.1  模拟控制方式

  波形比较法,其基本的方法是由正弦信号发生器件产生正弦调制波,由三角波信号发发生器产生的三角载波,将正弦调制波与三角载波比较,通过比较器的判断而产生出对应的脉冲信号序列,对逆变电路进行控制从而得到所需的交流电压。

1.4.2  数字控制方式

(1)等效面积法
  其原理就是按面积等效原理构成与正弦波等效的一系列等幅但宽度按正弦规律变化的矩形脉冲。等效面积法适用于单极性控制,算法中计算的是正弦波形到横轴间的面积,这与模拟控制方式中的单极性正弦脉冲调制的方式一致。
(2)自然采样法与规则采样法
  自然采样法在算法上仿真模拟控制方式的双极性正弦脉冲调制,通过计算正弦调制波与三角载波的交点位置,确定调制的脉冲宽度。而规则采样法是对自然采样法的简化,其几何关系如下图。


  规则采样法适用于双极性控制,因为算法中采用的三角载波是双极性。等效面积法和规则采样法都是数字控制的算法,可以由微处理器实时计算SPWM脉冲的宽度和位置,实现对逆变电路的控制,也可以事先计算好每个脉冲中心位置和脉冲宽度存入微处理器中,以查表的方式实现对逆变电路的控制。
  此外除了使用微处理器生成SPWM以外, 目前还有专门产生SPWM波形的大规模集成芯片,有些微处理器也继承有SPWM波形发生器,如STM32微处理器,其内部有三相互补SPWM波形发生器,可以直接输出6路SPWM波形信号。

1.5.SPWM软件生成

利用单片机输出PWM波,然后让占空比正弦规律变化。
实现步骤可以简单分为三步,以stm32为例:
(1)生成载波。比如要生成一个10KHZ的三角波,将计数器设置加减计数、周期设为1/10K就ok啦。这样生成的三角波的幅值是多少呀,3.3V?其实在单片机里面都是数字信号,三角波最高点的时候可以用一个计数值来表示,比如8400,最低点是0。不用管他的电压是多少。
(2)生成正弦波。这一步用软件生成一个正弦表即可。比如将正弦波取200个点,即将一个正弦分割成200份,每个点代表一个幅值。用离散的数字量表达正弦模拟量。
(3)将正弦波和三角波进行比较。
a.什么时候进行比较。设置计数值达到比较值产生动作。
b.比较完之后,需要改变比较值,用于下一个周期进行比较(比较值可以理解为占空比),比较值查正弦表获得,这样就生成了占空比正弦规律变化的SPWM。
C.调制度m。m=正弦表最大值/三角波最大计数值。如正弦表最大值4200,三角波最大计数值8400,m=4200/8400=0.5,此时spwm最大占空比为50%,设置m=1,spwm最大占空比为100%。

    例如我们要生成一个开环的三相spwm。单相逆变需生成两组相差180度的spwm,三相即生成三组两两相差120度的spwm,且每组的spwm都是互补的。将生成的三组spwm分别加到1、2、3组桥臂,每组spwm互补防止了同一桥臂上下管同时导通会引起短路。

int const talab[250]=
{
 100 , 102 , 108 , 116 , 126 , 140 , 154 , 172 , 194 , 216 ,
 242 , 270 , 300 , 334 , 370 , 408 , 448 , 490 , 536 , 582 ,
 632 , 684 , 738 , 794 , 854 , 914 , 976 ,1040 ,1108 ,1176 ,
1246 ,1320 ,1394 ,1470 ,1548 ,1626 ,1708 ,1790 ,1874 ,1960 ,
2046 ,2136 ,2224 ,2316 ,2408 ,2502 ,2596 ,2690 ,2786 ,2884 ,
2982 ,3080 ,3180 ,3280 ,3382 ,3482 ,3584 ,3686 ,3788 ,3892 ,
3994 ,4096 ,4200 ,4304 ,4406 ,4508 ,4612 ,4714 ,4816 ,4918 ,
5018 ,5120 ,5220 ,5320 ,5418 ,5516 ,5614 ,5710 ,5804 ,5898 ,
5992 ,6084 ,6176 ,6264 ,6354 ,6440 ,6526 ,6610 ,6692 ,6774 ,
6852 ,6930 ,7006 ,7080 ,7154 ,7224 ,7292 ,7360 ,7424 ,7486 ,
7546 ,7606 ,7662 ,7716 ,7768 ,7818 ,7864 ,7910 ,7952 ,7992 ,
8030 ,8066 ,8100 ,8130 ,8158 ,8184 ,8206 ,8228 ,8246 ,8260 ,
8274 ,8284 ,8292 ,8298 ,8300 ,8300 ,8298 ,8292 ,8284 ,8274 ,
8260 ,8246 ,8228 ,8206 ,8184 ,8158 ,8130 ,8100 ,8066 ,8030 ,
7992 ,7952 ,7910 ,7864 ,7818 ,7768 ,7716 ,7662 ,7606 ,7546 ,
7486 ,7424 ,7360 ,7292 ,7224 ,7154 ,7080 ,7006 ,6930 ,6852 ,
6774 ,6692 ,6610 ,6526 ,6440 ,6354 ,6264 ,6176 ,6084 ,5992 ,
5898 ,5804 ,5710 ,5614 ,5516 ,5418 ,5320 ,5220 ,5120 ,5018 ,
4918 ,4816 ,4714 ,4612 ,4508 ,4406 ,4304 ,4200 ,4096 ,3994 ,
3892 ,3788 ,3686 ,3584 ,3482 ,3382 ,3280 ,3180 ,3080 ,2982 ,
2884 ,2786 ,2690 ,2596 ,2502 ,2408 ,2316 ,2224 ,2136 ,2046 ,
1960 ,1874 ,1790 ,1708 ,1626 ,1548 ,1470 ,1394 ,1320 ,1246 ,
1176 ,1108 ,1040 , 976 , 914 , 854 , 794 , 738 , 684 , 632 ,
 582 , 536 , 490 , 448 , 408 , 370 , 334 , 300 , 270 , 242 ,
 216 , 194 , 172 , 154 , 140 , 126 , 116 , 108 , 102 , 100 
};    

uint16_t Counter_sine1 = 0; //A相
uint16_t Counter_sine2 = 83; //滞后A相120度
uint16_t Counter_sine3 = 166;//超前A相120度
/*TIM1GPIO初始化  CH1--A8   CH2--A9   CH3--A10
CH1N-B13  CH2N-B14  CH3N-B15 
*/
void TIM1_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8 | GPIO_Pin_9| GPIO_Pin_10;  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       //复用推挽输出              
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13| GPIO_Pin_14 | GPIO_Pin_15;  
  GPIO_Init(GPIOB, &GPIO_InitStructure);                                                  
}
#define CKTIM       ((u32)72000000uL)  //主频
#define PWM_PRSC    ((u8)0)            //TIM1分频系数
#define PWM_FREQ    ((u16) 10000)      //PWM频率(Hz)
#define PWM_PERIOD  ((u16) (CKTIM / (u32)(2 * PWM_FREQ *(PWM_PRSC+1))))
#define MODULAT     (float)0.7           //调制度
void TIM1_Mode_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    TIM_BDTRInitTypeDef TIM1_BDTRInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD; //计数周期
    TIM_TimeBaseStructure.TIM_Prescaler = PWM_PRSC;//分频系数
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;       
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; 
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //使能CHx的PWM输出
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//互补输出使能,使能CHxN的PWM输出
    TIM_OCInitStructure.TIM_Pulse = 0;                          
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;   
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;   
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;  
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; 
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);//配置CH1
    TIM_OCInitStructure.TIM_Pulse = 0;                         
    TIM_OC2Init(TIM1, &TIM_OCInitStructure); //配置CH2
    TIM_OCInitStructure.TIM_Pulse = 0;                         
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);//配置CH3

    //死区时间
    TIM1_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; 
    TIM1_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
    TIM1_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;   
    TIM1_BDTRInitStructure.TIM_DeadTime = 360; //设置死区时间
    TIM1_BDTRInitStructure.TIM_Break = TIM_Break_Disable;        
    TIM1_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;         
    TIM1_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;  
    TIM_BDTRConfig(TIM1, &TIM1_BDTRInitStructure);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //4个抢先级、4个子优先级    
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    TIM_ITConfig(TIM1,TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3,ENABLE);  //使能中断

    TIM_CtrlPWMOutputs(TIM1, ENABLE);  //PWM输出使能    
    TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
void TIM1_PWM_Init(void)
{
    TIM1_GPIO_Config();
    TIM1_Mode_Config();
}

//定时器1中断服务函数
void TIM1_CC_IRQHandler(void) 
{    
    if(Counter_sine1>=250)  { Counter_sine1 = 0; }
    if(Counter_sine2>=250)  { Counter_sine2 = 0; }
    if(Counter_sine3>=250)  { Counter_sine3 = 0; }
    if (TIM_GetITStatus(TIM1, TIM_IT_CC1)!=RESET)
    {
        TIM_SetCompare1(TIM1,(uint32_t)(talab[Counter_sine1])*MODULAT); //A相    
        Counter_sine1++;
        TIM_ClearITPendingBit(TIM1 , TIM_IT_CC1);
     }
    if (TIM_GetITStatus(TIM1, TIM_IT_CC2) !=RESET)
    {
        TIM_SetCompare2(TIM1,((uint32_t)talab[Counter_sine2])*MODULAT); //B相
        Counter_sine2++;
        TIM_ClearITPendingBit(TIM1 , TIM_IT_CC2);   
    }
    if (TIM_GetITStatus(TIM1, TIM_IT_CC3) !=RESET)
    {
        TIM_SetCompare3(TIM1,(uint32_t)(talab[Counter_sine3])*MODULAT); //C相
        Counter_sine3++;
        TIM_ClearITPendingBit(TIM1 , TIM_IT_CC3);   
    }
}

        TIM1设置为中央计数模式,开启互补通道,设置死区时间,死区时间是多少个时钟计数周期,比如TIM1计数周期是72M,设置为72就是1000ns。spwm频率设置为10k,然后TIM1每个通道的比较值达到时更新比较值。调制度m范围为0~1,设为0.7。正弦调制波的频率是自己设置的,方法是f=载波频率/表中点数,这里设置的是载波频率10K,取250个点得到的正弦频率就是40HZ,改变载波频率为50*250就得到了50hz的正弦波输出。正弦表可以用取点工具。

2  PID算法

  在连续时间控制系统中,PID控制器应用非常广泛,其设计技术成熟,长期以来形成了典型的结构,参数整定方便,结构更改灵活。由于计算机程序的灵活性,数字PID控制比连续PID控制更为优越。

2.1  PID控制系统简介

  连续时间PID控制系统如下图所示,D(s)完成PID控制规律,称为PID控制器。PID控制器是一种线性控制器,用输出量y(t)和给定量r(t)之间的误差的时间函数e(t)=r(t)-y(t)的比例、积分和微分的线性组合构成控制量u(t),称为比例、积分、微分控制,简称PID控制。

连续时间PID控制系统

  PID控制组合了比例控制、积分控制和微分控制这三种基本控制规律,通过改变调节器参数来实现控制,其基本输入输出关系为:

2.2  PID参数控制效果分析

  PID控制的三基本参数为KP、KI、KD,分别对应比例,积分,微分三个模,经实验测试,可总结出这三项参数的实际控制作用为:
  比例调节参数(KP):按比例反映系统的偏差,系统一旦出现偏差,比例调节立即进行。比例调节是主要的控制部分,但过大的比例会使系统的稳定性下降。增大KP,系统的反应变灵敏、速度加快、稳态误差减小,但振荡次数也会加多、调节时间加长。
  积分调节参数(KI):消除系统静态(稳态)误差 ,提高系统的控制精度。积分调节会使系统的稳定性下降,动态响应变慢,超调加大。积分控制一般不单独作用,而是与P或者PD结合作用。
  微分调节参数(KD):反映系统偏差信号的变化率,可以预见偏差的变化趋势,产生超前控制作用,使偏差在未形成前已被消除。因此,微分控制可以提高系统的动态跟踪性能,减小超调量,但对噪声干扰有放大作用,过强的微分调节会使系统剧烈震荡,对抗干扰不利。
  常规的PID控制系统中,减少超调和提高控制精度难以两全其美。主要是积分作用有缺陷造成的。如果减少积分作用,静差不易消除,有扰动时,消除误差速度变慢;而加强积分作用时又难以避免超调,这也是常规PID控制中经常遇到的难题。

PID

2.3 通俗易懂的理解PID

  P就是比例的意思。它的作用最明显,原理也最简单。
  需要控制的量,比如水温,有它现在的『当前值』,也有我们期望的『目标值』。当两者差距不大时,就让加热器“轻轻地”加热一下。要是因为某些原因,温度降低了很多,就让加热器“稍稍用力”加热一下。要是当前温度比目标温度低得多,就让加热器“开足马力”加热,尽快让水温到达目标附近。
  这就是P的作用,跟开关控制方法相比,是不是“温文尔雅”了很多.实际写程序时,就让偏差(目标减去当前)与调节装置的“调节力度”,建立一个一次函数的关系,就可以实现最基本的“比例”控制了~
  KP越大,调节作用越激进,KP调小会让调节作用更保守。
  要是你正在制作一个平衡车,有了KP的作用,你会发现,平衡车在平衡角度附近来回“狂抖”,比较难稳住。如果已经到了这一步——恭喜你!离成功只差一小步了~

  D的作用更好理解一些,所以先说说D,最后说i。
  刚才我们有了P的作用。你不难发现,只有P好像不能让平衡车站起来,水温也控制得晃晃悠悠,好像整个系统不是特别稳定,总是在“抖动”。


  你心里设想一个弹簧:现在在平衡位置上。拉它一下,然后松手。这时它会震荡起来。因为阻力很小,它可能会震荡很长时间,才会重新停在平衡位置。
  请想象一下:要是把上图所示的系统浸没在水里,同样拉它一下 :这种情况下,重新停在平衡位置的时间就短得多。我们需要一个控制作用,让被控制的物理量的“变化速度”趋于0,即类似于“阻尼”的作用。
  因为,当比较接近目标时,P的控制作用就比较小了。越接近目标,P的作用越温柔。有很多内在的或者外部的因素,使控制量发生小范围的摆动。D的作用就是让物理量的速度趋于0,只要什么时候,这个量具有了速度,D就向相反的方向用力,尽力刹住这个变化。kD参数越大,向速度相反方向刹车的力道就越强。
  如果是平衡小车,加上P和D两种控制作用,如果参数调节合适,它应该可以站起来了~欢呼吧
  等等,PID三兄弟好想还有一位。看起来PD就可以让物理量保持稳定,那还要I干嘛?

  因为我们忽视了一种重要的情况:
  还是以热水为例。假如有个人把我们的加热装置带到了非常冷的地方,开始烧水了。需要烧到50℃。
  在P的作用下,水温慢慢升高。直到升高到45℃时,他发现了一个不好的事情:天气太冷,水散热的速度,和P控制的加热的速度相等了。这可怎么办?
  P兄这样想:我和目标已经很近了,只需要轻轻加热就可以了。
  D兄这样想:加热和散热相等,温度没有波动,我好像不用调整什么。
  于是,水温永远地停留在45℃,永远到不了50℃。
  作为一个人,根据常识,我们知道,应该进一步增加加热的功率。可是增加多少该如何计算呢?
  前辈科学家们想到的方法是真的巧妙。设置一个积分量。只要偏差存在,就不断地对偏差进行积分(累加),并反应在调节力度上。这样一来,即使45℃和50℃相差不太大,但是随着时间的推移,只要没达到目标温度,这个积分量就不断增加。
  系统就会慢慢意识到:还没有到达目标温度,该增加功率啦!到了目标温度后,假设温度没有波动,积分值就不会再变动。这时,加热功率仍然等于散热功率。但是,温度是稳稳的50℃。
  Ki的值越大,积分时乘的系数就越大,积分效果越明显。所以,I的作用就是,减小静态情况下的误差,让受控物理量尽可能接近目标值。
  I在使用时还有个问题:需要设定积分限制。防止在刚开始加热时,就把积分量积得太大,难以控制。

2.4  数字PID控制的实现

  数字PID控制是通过算法程序实现PID控制的。数字控制系统大多数是采样数据控制系统,进入系统的连续时间信号必须经过采样和量化后转换为数字量,方能进行相应的计算和处理,不论是积分还是微分,只能用数值计算去逼近。当采样周期相当短时,用求和代替积分,用差商代替微商,将描述连续时间PID算法的微分方程变为描述离散时间PID算法的差分方程。数字PID控制通常有以下两种实现:

2.4.1  位置式PID控制算法

  此式是数字PID算法的非递推形式,称全量算法,其中uo为控制量基值(n=0时的控制量);un为第n个采样时刻的控制量;Ts为采样周期。算法中为实现求和,必须存储系统偏差的全部值ei,得出的全量输出un是控制量的绝对数值,这种控制量确定了执行机构在控制系统中的位置(如阀门控制中,输出对应阀门的位置),因此将这种算法称为“位置算法”。
位置式PID控制算法实现框图
2.4.2  增量式PID控制算法

  当执行机构需要的不是控制量的绝对值,而是控制量的增量(例如驱动步进电动机)时,需要用PID的“增量算法”,其简化示意图如下图所示。

增量式PID控制算法简化示意图

  增量式PID算法的差分方程为

  此时已看不出P、I、D作用的直接关系,只能体现各次误差量对控制作用的影响,但处理时只需要贮存最近的三个误差采样值en en-1 en-2 。

-END-


关于比赛的帖子,之前写过很多篇:

「第一弹」电子设计大赛应该准备什么?

「第一篇」大学生电子设计竞赛,等你来提问。

「第二篇」全国一等奖,经验帖。

「第三篇」电赛,这些你必须知道的比赛细节,文末附上近十年电赛题目下载

「第四篇」电赛控制题可以准备一些什么?

「第五篇」全国电子设计竞赛-电源题设计方案总结

「第六篇」对于电赛,我们应该看重什么?

电子设计竞赛电源题(1)-电源题简介

电子设计竞赛电源题(2)-检波与采样

也有一些大神的经验贴,其实不乏国奖获得者:

全国一等奖,他的学习之路。

从0开始,三个月,获全国一等奖。

奖状是怎么炼成的—我的电赛狂魔之旅

全国一等奖的获得者,如今去当了人民教师。


也有一些关于比赛项目的文章:

参加智能车大赛还是电赛?在做电磁炮中我找到了答案

2019年电赛综合测评题详解

「权威发布」2019年电赛最全各类题目细节问题解答汇总

奖状是怎么炼成的—我的电赛狂魔之旅

【大学生电子设计竞赛分享经验贴】风力循迹小车


去年还做过几期猜题的文章,貌似有点接近了,今年还可以继续给大家猜猜。

「猜题第一篇」2019年大学生电子设计竞赛

「重磅猜题之第二篇」2019年大学生电子设计竞赛

 最 后   若觉得文章不错,转发分享,也是我们继续更新的动力。5T资源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,PCB、FPGA、DSP、labview、单片机、等等!在公众号内回复「更多资源」,即可免费获取,期待你的关注~长按识别图中二维码关注
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

电子设计竞赛(三)-SPWM与PID 的相关文章

  • PythonML-Day02: k-近邻、朴素贝叶斯、决策树、随机森林、交叉验证、网格搜索

    ML Day02 k 近邻 朴素贝叶斯 决策树 随机森林 交叉验证 网格搜索 1 数据分类 离散型数据 可以列举出 连续型数据 在区间内可任意划分 不可一一列举 2 机器学习算法分类 监督学习 预测 有特征值和目标值 有标准答案 分类 离散
  • BeanUtils.copyProperties的使用(浅拷贝)

    BeanUtils copyProperties的使用场景 将一个 Java 对象的属性值复制到另一个对象中 解决方法通常有2种方法 一个一个set 用BeanUtils copyProperties 很显然BeanUtils更加方便 代码
  • python中permute_PyTorch中permute的用法详解

    permute dims 将tensor的维度换位 参数 参数是一系列的整数 代表原来张量的维度 比如三维就有0 1 2这些dimension 例 import torch import numpy as np a np array 1 2
  • js-ajax

    一 ajax Asynchronous Javasript And Xml 通过Ajax向服务器请求数据 在不刷新整个页面的情况下 更新页面的内容 二 Ajax的创建 三步走 1 创建XMLHttpRequest对象 用来和服务器进行数据交
  • hdu1827Summer Holiday【tarjan强连通分量解决最小联系费用】

    1A 撒花 这比买买买开心多了 思路 既然是强连通分量的题 很容易想到形成的东西是一坨一坨的 哈哈 然后如果某一坨入度为0 那么很不幸 这一坨只能直接被威士忌通知 至于具体通知这一坨中的哪一个 枚举一遍就知道了 最后把话费求和 感觉强连通分
  • python程序运行提示Process finished with exit code -1073741819 (0xC0000005),程序终止运行...

    这个错误代码是表示程序运行时发生了访问冲突 通常是由于程序尝试访问不属于它的内存空间导致的 这可能是由于程序代码本身存在 bug 也可能是因为计算机环境问题造成的 为了解决这个问题 需要调查程序的代码 找出导致访问冲突的原因 然后修改代码以
  • 笔试题目收集(3)

    笔试题目搜集系列推荐 1 笔试题目搜集1 2 笔试题目收集2 3 笔试题目搜集3 4 笔试题目搜集4 5 笔试题目搜集5 1 下列程序输出结果 typedef union long i int k 5 char c DATE struct
  • 使用R语言进行数据对象获取的mget函数实战

    使用R语言进行数据对象获取的mget函数实战 在R语言中 我们经常需要获取由多个数据对象组成的列表 为了高效地获取这些对象 R提供了一个非常方便的函数 即mget函数 mget函数可以根据给定的对象名称 在当前环境中查找并返回相应的数据对象
  • 多类别属性预测深度架构GlideNet

    将属性 如颜色 形状 状态 动作 附加到对象类别是一个重要的计算机视觉问题 属性预测最近取得了令人振奋的进展 通常被表述为一个多标签分类问题 然而 在以下方面仍然存在重大挑战 1 预测多个对象类别上的大量属性 2 建模属性的类别依赖性 3
  • java pager,Pager 分页设计

    分页是非常基础又重复度高的功能 不论是前台 后台 或是手机版都有分页的需求 这里介绍Pager及相关代码 Pager是分页数据的封装 必要时需要与其他分页对象适配 PageObject Pageable等 详见PagerUtil publi
  • IO输入溢出(转载+整理)

    gets 防止缓冲区溢出 描述了高水平的缓冲区溢出攻击 以及讨论了为什么缓冲区溢出是如此严重的安全性问题 本专栏文章的主题是 通过防御性编程保护代码不受缓冲区溢出攻击 我们将论及 C编程语言中的主要安全性陷阱 显示应该避免特殊构造的原因 以
  • Bad owner or permissions on /root/.ssh/config

    vmware centos 部署 hadoop集群 启动hadoop节点 报错Bad owner or permissions on root ssh config 原因 SSH关于公钥认证Permission denied的问题 不能直接
  • 安装好后如何查看mysql/apache/nginx/php安装参数

    查看mysql编译参数 cat usr local mysql bin mysqlbug grep CONFIGURE LINE 查看apache编译参数 cat apachehome build config nice 查看php编译参数
  • 《机器学习》二刷超详细笔记

    博主在4月学完西瓜书时 一头雾水 觉得还是一知半解 9月开学后上完了必修的 machine learning 课程 并且自己编程实现了多种机器学习算法和论文复现后 才对机器学习有一点了解 现在再次翻阅西瓜书 很多知识点看到都豁然开朗 所以出
  • Debian 某些程序无法使用中文输入法设置方法

    debian系统下发现某些程序不能写入中文 下面是我解决的方法 sudo apt get install fcitx frontend qt5 1 我们可以通过在命令行下输入 dpkg L fcitx frontend qt5 1 修改配置
  • 如何解决apt-get中Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify的问题

    在Ubuntu中用apt get安装软件 系统报出Unmet dependencies错误 Unmet dependencies Try apt fix broken install with no packages or specify
  • 【Python-Anaconda】在anaconda中创建、激活虚拟环境;在anaconda中所创建的虚拟环境中安装OpenCv;如何在jupter notebook中使用所创建的虚拟环境

    一 在anaconda中创建虚拟环境 1 为什么要创建虚拟环境 答 为了避免库依赖冲突 所以在安装pytorch tensflow等时最好创建虚拟环境进行安装 2 创建虚拟环境步骤 1 打开anaconda prompt 输入如下代码 co
  • 基于AJAX技术提高搜索引擎排名

    描述 嵌入在你的web页面中的导航元素能够降低你的搜索引擎评价排名并且降低你的网站的响应性能 本文作者想同你一起探讨如何使用AJAX技术来解决这两个问题 许多设计良好的web站点都包含大量的与实际内容相联系的可导航信息 用于导航的HTML标
  • 【C++】抽象类

    2023年8月25日 周五上午 目录 声明抽象类 抽象类的特点 举例说明 声明抽象类 要在C 中声明一个抽象类 要求类中至少有一个纯虚函数 在C 中 一个类如果包含至少一个纯虚函数 那么这个类就被称为抽象类 总结起来 抽象类是一个包含至少一
  • 了解如何在20分钟内创建您的第一个Angular应用

    Angular is a JavaScript framework created my Misko Hevery and maintained by Google It s an MVC Model View Vontroller You

随机推荐

  • Verilog实现两路组相联cache

    cache代码 timescale 1ns 1ps cache共32块 分为16组 每组2块 即两路组相联 1块 4字 1字 4字节 主存共1024块 4096个字 主存地址共12位 1 0 为块内偏移 5 2 为组地址 11 6 为Tag
  • 【MATLAB第43期】基于MATLAB的BO-NAR贝叶斯优化动态神经网络NAR时间序列股票预测模型

    MATLAB第43期 基于MATLAB的BO NAR贝叶斯优化动态神经网络NAR时间序列股票预测模型 一 效果展示 二 模型介绍 1 数据情况 一列数据 499个值 ratio 0 9 训练集比例 MaxEpochs 600 最大训练次数
  • Fatal error in gc GetThreadContext failed bug 异常。

    Fatal error in gc GetThreadContext failed PC unity5 3 4 c exe windows 废话不说 网上各种回答是杀毒软件关闭 但是需求不允许关闭其他 只能从代码出发 发现 开个一个线程 这
  • 13 openEuler用户组管理

    文章目录 13 1 创建用户组 13 1 1 groupadd命令 13 1 2 用户组信息文件 13 1 3 创建用户组实例 13 2 修改用户组 13 2 1 修改GID 13 2 2 修改用户组名 13 3 删除用户组 13 4 将用
  • DSS部署-11、Spark on Yarn部署

    文章目录 第七部分 Spark on Yarn部署 相关配置 操作记录如下 spark sql e show databases 第七部分 Spark on Yarn部署 相关配置 tar xf spark 2 3 2 bin hadoop
  • 数学表达式: 从恐惧到单挑 (7. min 与 argmin)

    7 min 与 argmin min 和 argmin 在机器学习中常用 max 和 argmax 同理 7 1 min min 是 minimal 的缩写 用于获得集合中的最小值 如 min 3 1
  • 螺旋矩阵,python实现

    螺旋矩阵问题 给定一个n阶正方形矩阵 生成一个包含 1 到 n2 所有元素 且元素按顺时针顺序螺旋排列的正方形矩阵 力扣原题 这个问题不涉及什么算法问题 考察的就是个人对于代码的掌控和抽象 螺旋矩阵长的是这个样子 处理这个问题就得提到二分法
  • 各操作系统下安装docker

    1 查看服务器软硬件信息 1 1 判断操作系统类型 操作系统 基于发行版 统信UOS Debian 银河麒麟 StartOS Debian openEuler CentOS 优麒麟 Ubuntu Kylin Ubuntu 中标麒麟 Kyli
  • Java算法题:两数之和

    LeetCode原题 给你一个下标从 1 开始的整数数组 numbers 该数组已按 非递减顺序排列 请你从数组中找出满足相加之和等于目标数 target 的两个数 示例 1 输入 numbers 2 7 11 15 target 9 输出
  • STM32F103VG使用RTT实现发送DMX512调光数据

    DMX512调光协议和DALI一样属于数字调光协议 一个完整的DMX512数据包格式 1break 1mab 1startcode 512个调光数据 DMX512发送是基于485串口的基础上实现的特殊的数据协议 使用RTT需要把串口打开并且
  • 大话数据结构:线性表(顺序存储结构)

    线性表 零个或多个数据元素的有限序列 直接前驱元素 直接后继元素 线性表的长度 线性表元素的个数n 线性表的抽象数据类型 ADT线性表 list Data 线性表的数据对象集合为 a1 a2 an 每个元素的类型均为Datatype 其中
  • 微软服务器的主要功能,数据库服务器主要功能

    数据库服务器主要功能 内容精选 换一换 HANA全称High performanceAnalyticAppliance是由SAP开发的基于内存的面向行 列存储的关系型数据库管理系统 其作为数据库服务器的主要功能是根据应用程序的要求存储和检索
  • jdk17下载

    官网下载 https download oracle com java 17 latest jdk 17 windows x64 bin zip
  • 也想做一个绝地求生版的汽车控制移动,进来瞧瞧?(干货满满)

    控制车子移动 效果图附上 1 首先4个车轮复制一遍为车轮2备用 2 给车轮2全部添加wheel collider 只剩下车轮碰撞器和transform组件 3 给原版4个车轮添加脚本wheel 变量共有 面板赋值 依次添加车轮2里面的车轮c
  • c#图解教程和c#高级编程电子书链接

    链接 https pan baidu com s 1y TM08JvyBh8kQ0v7uT5hg 提取码 b0cq
  • Python的多维空数组赋值

    Python里面的list tuple默认都是一维的 创建二维数组或者多维数组也是比较简单 可以这样 list1 1 2 list1 append 3 4 可以这样 list2 1 2 3 4 还可以这样 list3 1 2 list3 i
  • android界面监控,防劫持

    1 首先要对自己应用的activity建立一个白名单 2 权限
  • http协议从客户端提交数据给服务器并返回数据

    老罗视频学习 本例从客户端提交数据给服务器 服务器接收到数据之后 看是否匹配 匹配返回字符串 login is success 失败返回 login is error 一 客户端 初始化url地址 private static String
  • Git如何比较不同分支的差异

    前两天 良许在做集成的时候碰到了一件闹心事 事情是这样的 良许的一位同事不小心把一个错误的 dev 分支 merge 到了 master 分支上 导致了良许编译不通过 于是 我们需要将版本回退到 merge 之前的状态 如果是下面这个状态
  • 电子设计竞赛(三)-SPWM与PID

    1 SPWM波调制技术 逆变电路的控制方式主要是采用SPWM 正弦脉宽调制技术 IR2104控制开关管的通断来实现正弦调制 SPWM的基本思路是将一个正弦波按等宽间距分成N等份 对于每一个波形以一个等面积的脉冲来对应 使脉冲的中点与相应正弦