[其他ST产品] STM32爬坡寻迹小车(PID算法)

[复制链接]
9173|44
 楼主| 尽快回复过 发表于 2023-2-28 17:28 | 显示全部楼层
2 TIM2、TIM3

功能:TIM2和TIM3分别用于小车左后轮和右后轮编码器的正交解码,其中通道一连接编码器A相,通道二连接编码器B相,将定时器配置为编码器模式后,可根据A、B相的脉冲计数,即可获取电机的旋转情况。
 楼主| 尽快回复过 发表于 2023-2-28 17:29 | 显示全部楼层
2 TIM2、TIM3

功能:TIM2和TIM3分别用于小车左后轮和右后轮编码器的正交解码,其中通道一连接编码器A相,通道二连接编码器B相,将定时器配置为编码器模式后,可根据A、B相的脉冲计数,即可获取电机的旋转情况。
 楼主| 尽快回复过 发表于 2023-2-28 17:29 | 显示全部楼层
配置步骤:

使能定时器及端口时钟,配置对应引脚为浮空输入;
初始化定时器参数,包含自动重装值,分频系数,计数方式等;
选择时钟源,配置为编码器模式;
使能TIMX在CCRX上的预装载寄存器;
使能TIMX在ARR上的预装载寄存器允许位;
开启定时器。
 楼主| 尽快回复过 发表于 2023-2-28 17:29 | 显示全部楼层
定时器基本结构体中,将预分频值设置为0(不使用系统时钟,无需分频),重装载值设置为1040(一般为编码器线圈数 * 4,即电机转一圈所计的数,若编码器线圈数未知,可设为最大65535),计数方式为向上计数。
 楼主| 尽快回复过 发表于 2023-2-28 17:29 | 显示全部楼层
将编码器参数设置为通道一、二都计数(即A、B相的计数),可更加精确地获取脉冲,同时可获取方向。
 楼主| 尽快回复过 发表于 2023-2-28 17:29 | 显示全部楼层
3 TIM4

功能:TIM4仅用作一个基本的定时器,用于定时进入中断函数,获取TIM2、TIM3的脉冲数,并转换为对应的速度,调用PID算法,将转换得到的实际速度通过算法计算,改变PWM1的占空比,使其不断减小与期望速度的误差,稳定于期望速度。
 楼主| 尽快回复过 发表于 2023-2-28 17:29 | 显示全部楼层
配置步骤:

RCC开启定时器时钟;
初始化定时器参数,包含自动重装值,分频系数,计数方式等;
配置输出中断控制,使能更新中断;
配置NVIC,打开定时器通道;
使能定时器。
 楼主| 尽快回复过 发表于 2023-2-28 17:29 | 显示全部楼层
定时器基本结构体中,将预分频值设置为72,重装载值设置为5000,即每5ms触发一次中断,调用PID算法计算并调整速度,计数方式为向上计数。

中断配置结构体中,选择对应的中断通道(TIM4_IRQn)并使能,设置抢占优先级和响应优先级为1。
 楼主| 尽快回复过 发表于 2023-2-28 17:30 | 显示全部楼层
实物图 5311863fdc99b43097.png
 楼主| 尽快回复过 发表于 2023-2-28 17:30 | 显示全部楼层
 楼主| 尽快回复过 发表于 2023-2-28 17:30 | 显示全部楼层
软件部分代码
pwm.c:使用高级定时器输出pwm波
  1. void TIM1_PWM_Init(u16 per,u16 psc)
  2. {
  3.         /*使能TIM4时钟*/
  4.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
  5.        
  6.         /*使能GPIO*/
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  8.        
  9.         /*使能AFIO*/
  10.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  11.        
  12.         /*配置GPIO*/
  13.         GPIO_InitTypeDef GPIO_InitStructure;
  14.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用
  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 |GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
  16.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  18.        
  19.         /*设置重映射*/
  20.         //GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//部分重映射       
  21.        
  22.         /*初始化定时器参数*/
  23.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  24.         TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频为1分频
  25.         TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择计数模式为向上计数
  26.         TIM_TimeBaseInitStructure.TIM_Period = per;//配置周期(ARR自动重装器的值)
  27.         TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//配置PSC预分频器的值
  28.         TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级计数器才需配置
  29.         TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);
  30.         //TIM_ClearFlag(TIM4,TIM_FLAG_Update);//先清除标志位,避免刚初始化就进入中断
  31.        
  32.         /*初始化PWM参数*/
  33.         TIM_OCInitTypeDef TIM_OCInitStructure;
  34.         TIM_OCInitStructure.TIM_Pulse = 0;
  35.         TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  36.         TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  37.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//选择PWM1模式
  38.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性:低电平有效
  39.         TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  40.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//使能
  41.         TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  42.         TIM_OC1Init(TIM1,&TIM_OCInitStructure);
  43.         TIM_OC2Init(TIM1,&TIM_OCInitStructure);
  44.         TIM_OC3Init(TIM1,&TIM_OCInitStructure);
  45.         TIM_OC4Init(TIM1,&TIM_OCInitStructure);
  46.        
  47.         /*使能TIMX在CCRX上的预装载寄存器*/
  48.         TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
  49.         TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);
  50.         TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);
  51.         TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);
  52.        
  53.         TIM_CtrlPWMOutputs(TIM1,ENABLE);
  54.        
  55.         /*使能TIMX在ARR上的预装载寄存器允许位*/
  56.         //TIM_ARRPreloadConfig(TIM4,ENABLE);
  57.        
  58.         /*开启定时器*/
  59.         TIM_Cmd(TIM1,ENABLE);
  60. }       
 楼主| 尽快回复过 发表于 2023-2-28 17:30 | 显示全部楼层
zjjm.c:使用定时器2、3
  1. #include "stm32f10x.h"                  // Device header

  2. /*
  3.         配置TIM2,TIM3的CH1、CH2作编码器的A、B相;
  4.         电机转速不同,机械几何位移量转换成的脉冲也不同,使得单位时间内TIM计数值不同,可由此判断电机速度的变化
  5. */

  6. void TIM2_Init(u16 per,u16 psc)
  7. {
  8.         /*开启通用定时器TIM2和GPIO时钟*/
  9.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  10.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  11.        
  12.         GPIO_InitTypeDef GPIO_InitStructure;
  13.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  14.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  15.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  17.        
  18.         /*配置时基单元*/
  19.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  20.         TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频为1分频
  21.         TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择计数模式为向上计数
  22.         /*
  23.         定时频率 = 72M / (PSC+1) / (ARR+1)
  24.         */
  25.         TIM_TimeBaseInitStructure.TIM_Period = per;//已知编码器线数:线数*4-1
  26.         TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  27.         TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级计数器才需配置
  28.         TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
  29.        
  30.         /*选择时钟源,配置正交解码*/
  31.         TIM_ICInitTypeDef TIM_ICInitStructure;  
  32.     TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge ,TIM_ICPolarity_BothEdge);//TI12:A、B项都计数
  33.     TIM_ICStructInit(&TIM_ICInitStructure);//缺省输入
  34.     TIM_ICInitStructure.TIM_ICFilter = 0;  //滤波器
  35.     TIM_ICInit(TIM2, &TIM_ICInitStructure);
  36.        
  37.         TIM_SetCounter(TIM2,0X7FFF); //TIM4->CNT=0X7FFF(65536的一半)
  38.         /*启动定时器*/
  39.         TIM_Cmd(TIM2,ENABLE);
  40. }

  41. void TIM3_Init(u16 per,u16 psc)
  42. {
  43.         /*开启通用定时器TIM2和GPIO时钟*/
  44.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  45.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  46.        
  47.         GPIO_InitTypeDef GPIO_InitStructure;
  48.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  49.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  50.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  51.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  52.        
  53.         /*配置时基单元*/
  54.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  55.         TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频为1分频
  56.         TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择计数模式为向上计数
  57.         /*
  58.         定时频率 = 72M / (PSC+1) / (ARR+1)
  59.         */
  60.         TIM_TimeBaseInitStructure.TIM_Period = per;//已知编码器线数:线数*4-1
  61.         TIM_TimeBaseInitStructure.TIM_Prescaler = psc;

  62.         TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级计数器才需配置
  63.         TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
  64.        
  65.         /*选择时钟源,配置正交解码*/
  66.         TIM_ICInitTypeDef TIM_ICInitStructure;  
  67.     TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge ,TIM_ICPolarity_BothEdge);//TI12:A、B项都计数
  68.     TIM_ICStructInit(&TIM_ICInitStructure);//缺省输入
  69.     TIM_ICInitStructure.TIM_ICFilter = 0;  //滤波器
  70.     TIM_ICInit(TIM3, &TIM_ICInitStructure);
  71.        
  72.         TIM_SetCounter(TIM3,0X7FFF); //TIM4->CNT=0X7FFF(65536的一半)
  73.         /*启动定时器*/
  74.         TIM_Cmd(TIM3,ENABLE);
  75. }

 楼主| 尽快回复过 发表于 2023-2-28 17:30 | 显示全部楼层
timer.c:使用定时器4产生溢出中断,通过cnt的值计算应输出的占空比大小(只使用后轮进行调速)
  1. #include "stm32f10x.h"                  // Device header
  2. #include "Timer.h"
  3. #include "stdlib.h"
  4. /*
  5.         配置定时中断流程:
  6.                 1.RCC开启时钟(定时器基准时钟和外设工作时钟)
  7.                 2.选择时基单元的时钟源(对于定时中断,选择内部时钟源)
  8.                 3.配置时基单元(包括PSC预分频器,ARR自动重装器,CNT计数器)
  9.                 4.配置输出中断控制,使能更新中断,允许更新中断输出到NVIC
  10.                 5.配置NVIC,打开定时器通道,并分配优先级
  11.                 6.运行控制,使能计数器
  12. */

  13. void TIM4_Init(u16 per,u16 psc)
  14. {
  15.         /*1、开启通用定时器TIM4时钟*/
  16.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
  17.        
  18.         /*2、选择时钟源为内部时钟*/
  19.         //TIM_InternalClockConfig(TIM4);//默认为内部时钟
  20.        
  21.         /*3、配置时基单元*/
  22.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  23.         TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频为1分频
  24.         TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择计数模式为向上计数
  25.         /*
  26.         定时频率 = 72M / (PSC+1) / (ARR+1)
  27.         */
  28.         TIM_TimeBaseInitStructure.TIM_Period = per;//配置周期(ARR自动重装器的值)
  29.         TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//配置PSC预分频器的值
  30.         TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
  31.        
  32.         /*4、使能更新中断*/
  33.         TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
  34.        
  35.         /*5、配置NVIC*/
  36.        
  37.         NVIC_InitTypeDef NVIC_InitStructure;
  38.         NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;//选择中断通道
  39.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//开启中断通道
  40.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
  41.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//响应优先级
  42.         NVIC_Init(&NVIC_InitStructure);       
  43.        
  44.         /*6、启动定时器*/
  45.         TIM_Cmd(TIM4,ENABLE);
  46. }

  47. float Kp=10;//
  48. float Ki=2;//
  49. float Kd= 0.2;
  50. int target_left=0;
  51. int target_right=0;

  52. int err_now1=0;
  53. int err_now2=0;
  54. int err_last1=0;
  55. int err_last2=0;
  56. int err_last_last1=0;
  57. int err_last_last2=0;
  58. int spd_now1=0;
  59. int spd_now2=0;
  60. int jisuan1=0;
  61. int jisuan2=0;
  62. int out_left=0;
  63. int out_right=0;

  64. void Change_Target(int t_l,int t_r)
  65. {
  66.         target_left = t_l;
  67.         target_right = t_r;
  68. }

  69. void TIM4_IRQHandler(void)
  70. {
  71.         if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
  72.         {
  73.                 int cnt_left,cnt_right;
  74.                 cnt_left = abs((TIM2->CNT)-0X7FFF);
  75.                 cnt_right = abs((TIM3->CNT)-0X7FFF);
  76.                
  77.                 TIM2->CNT = 0X7FFF;
  78.                 TIM3->CNT = 0X7FFF;
  79.                
  80.                 //左电机       
  81.                 spd_now1 = cnt_left;
  82.                 err_now1 = target_left - spd_now1;
  83.                 jisuan1 = Kp*(err_now1-err_last1) + Ki*err_now1 + Kd*(err_now1+err_last_last1-2*err_last1);
  84.                 out_left += jisuan1;
  85.                 if(out_left<0)
  86.                         out_left = 0;
  87.                 if(out_left>100)
  88.                         out_left = 100;
  89.                 TIM_SetCompare1(TIM1,out_left);       
  90.                 TIM_SetCompare2(TIM1,out_left);       
  91.                 err_last_last1 = err_last1;
  92.                 err_last1 = err_now1;
  93.                
  94.                 //右电机
  95.                 spd_now2 = cnt_right;
  96.                 err_now2 = target_right - spd_now2;
  97.                 jisuan2 = Kp*(err_now2-err_last2) + Ki*err_now2 + Kd*(err_now2+err_last_last2-2*err_last2);
  98.                 out_right += jisuan2;
  99.                 if(out_right<0)
  100.                         out_right = 0;
  101.                 if(out_right>100)
  102.                         out_right = 100;        
  103.                 TIM_SetCompare3(TIM1,out_right);       
  104.                 TIM_SetCompare4(TIM1,out_right);
  105.                 err_last_last2 = err_last2;
  106.                 err_last2 = err_now2;
  107.                
  108.                 TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
  109.         }

  110. }
 楼主| 尽快回复过 发表于 2023-2-28 17:31 | 显示全部楼层
car.c
  1. #include "stm32f10x.h"                  // Device header
  2. #include "pwm.h"
  3. #include "Timer.h"
  4. /*

  5. TIM1(高级定时器):CH1-CH4: PWM输出控制四个电机  
  6.                 PA8    左前
  7.                 PA9    左后
  8.                 PA10   右前
  9.                 PA11   右后
  10. TIM2:CH1-CH2: 左后轮编码器A、B相   PA0,PA1
  11. TIM3:CH1-CH2: 右后轮编码器A、B相   PA6,PA7
  12. TIM4:定时测速调速
  13.        
  14.         红外:PB12,PB13,PB14

  15. TB6612N逻辑输入:(1 0正转,0 1反转)
  16.         PB0,PB1:左前         通道1
  17.         PB5,PB8:右前     通道3
  18.         PA3,PA2:左后         通道2
  19.         PB10,PB11:右后   通道4
  20. */

  21. void GPIOB_Init(void)
  22. {
  23.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  24.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  25.        
  26.         GPIO_InitTypeDef GPIO_InitStructure;
  27.         /*红外out引脚:PB12,PB13,PB14*/
  28.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
  30.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  31.         GPIO_Init(GPIOB,&GPIO_InitStructure);
  32.        
  33.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
  34.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
  35.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  36.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  37.        
  38.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
  39.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11;
  40.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  41.         GPIO_Init(GPIOB,&GPIO_InitStructure);
  42.         /*初始为低电平*/
  43.         GPIO_ResetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11);
  44.         GPIO_ResetBits(GPIOA,GPIO_Pin_2 | GPIO_Pin_3);
  45. }


  46. void forward(u16 speed)
  47. {
  48.         TIM_SetCompare1(TIM1,speed);
  49.         TIM_SetCompare2(TIM1,speed);
  50.         TIM_SetCompare3(TIM1,speed);
  51.         TIM_SetCompare4(TIM1,speed);
  52.         GPIO_SetBits(GPIOB,GPIO_Pin_0| GPIO_Pin_5 | GPIO_Pin_10);
  53.         GPIO_SetBits(GPIOA,GPIO_Pin_3);
  54.         GPIO_ResetBits(GPIOB,GPIO_Pin_1| GPIO_Pin_8 | GPIO_Pin_11);
  55.         GPIO_ResetBits(GPIOA,GPIO_Pin_2);
  56. }

  57. void back(u16 speed)
  58. {
  59.         TIM_SetCompare1(TIM1,speed);
  60.         TIM_SetCompare2(TIM1,speed);
  61.         TIM_SetCompare3(TIM1,speed);
  62.         TIM_SetCompare4(TIM1,speed);
  63.         GPIO_SetBits(GPIOB,GPIO_Pin_1| GPIO_Pin_8 | GPIO_Pin_11);
  64.         GPIO_SetBits(GPIOA,GPIO_Pin_2);
  65.         GPIO_ResetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_5 | GPIO_Pin_10);
  66.         GPIO_ResetBits(GPIOA,GPIO_Pin_3);
  67. }

  68. void turn_left(u16 speed1,u16 speed2)
  69. {
  70.         TIM_SetCompare1(TIM1,speed1);
  71.         TIM_SetCompare2(TIM1,speed1);
  72.         TIM_SetCompare3(TIM1,speed2);
  73.         TIM_SetCompare4(TIM1,speed2);
  74.         GPIO_SetBits(GPIOB,GPIO_Pin_0| GPIO_Pin_5 | GPIO_Pin_10);
  75.         GPIO_SetBits(GPIOA,GPIO_Pin_3);
  76.         GPIO_ResetBits(GPIOB,GPIO_Pin_1| GPIO_Pin_8 | GPIO_Pin_11);
  77.         GPIO_ResetBits(GPIOA,GPIO_Pin_2);
  78. }

  79. void turn_right(u16 speed1,u16 speed2)
  80. {
  81.         TIM_SetCompare1(TIM1,speed1);
  82.         TIM_SetCompare2(TIM1,speed1);
  83.         TIM_SetCompare3(TIM1,speed2);
  84.         TIM_SetCompare4(TIM1,speed2);
  85.         GPIO_SetBits(GPIOB,GPIO_Pin_0| GPIO_Pin_5 | GPIO_Pin_10);
  86.         GPIO_SetBits(GPIOA,GPIO_Pin_3);
  87.         GPIO_ResetBits(GPIOB,GPIO_Pin_1| GPIO_Pin_8 | GPIO_Pin_11);
  88.         GPIO_ResetBits(GPIOA,GPIO_Pin_2);
  89. }
  90. void stop(void)
  91. {
  92.         GPIO_ResetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11);
  93.         GPIO_ResetBits(GPIOA,GPIO_Pin_2 | GPIO_Pin_3);
  94. }



周半梅 发表于 2024-5-6 08:03 | 显示全部楼层

整流器或功率开关管与每个电容端的连线长度和宽度都要一样
Pulitzer 发表于 2024-5-6 09:06 | 显示全部楼层

不要根据不同的参数类型走不同的代码逻辑
童雨竹 发表于 2024-5-6 11:02 | 显示全部楼层

其他的信号和地要与这些高压引线和它的散热部分隔开
Wordsworth 发表于 2024-5-6 12:05 | 显示全部楼层

对于没有else的场景,使用ifPresent即可
Clyde011 发表于 2024-5-6 13:08 | 显示全部楼层

每个Strategy交由Spring管理,并在构造后注册
公羊子丹 发表于 2024-5-6 14:01 | 显示全部楼层

变压器隔离拓扑中,变压器有多少个绕组
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部