| 本帖最后由 袁胜富 于 2023-2-6 16:24 编辑 
 #技术资源# #申请原创# 1.项目简介:
 基于CH32V208WBU6芯片,预驱芯片用的是EG2133,最大支持输入电压75V,功率1000W,支持USB下载程序,板载一路485,引出USART1接口,板载蓝牙天线,板载旋转电位器。实现了电机的按键启停,按键切换旋转方向,速度环PID,测量母线电压,电机运行电流以及基于硬石上位机协议的PID调参。
 
  2.硬件说明:1.电源电路
     电源电路使用XDS(芯鼎盛)的TX4139,宽电压输入4.5V-75V,TX4139将输入电压降压至12V,LM317AG-TN3-R将12V降压至5V,AMS1117-3.3将5V降压至3.3V供给CH32V208WBU6,12V电压供给预取芯片EG2133. 2.霍尔电路 3.预驱电路 4.三相桥电路 5.电流采集电路 6.RS485电路 7.按键电路 8.USB下载电路 9.最小系统电路  3.软件说明:
 
  
 
 1.开发平台使用MounRiver Studio,使用六路互补PWM配置,PWM方波频率为4KHZ,使用外部高速晶振(HSE).PLL系统时钟频率为96MHZ。 2.系统软件框架图 3.电机状态机代码     if(!GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_4))     {         delay_ms(1);         if(!GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_4))         {             if(BLDC1.Motor_Status == M_IDLE)             {                 BLDC1.Motor_Status = M_Start;                 if(Get_Motor_Dir() == 1)                 {                     BLDC1.Motor_Dir = M_CCW;                 }                 else {                     BLDC1.Motor_Dir = M_CW;               }             }         }         while(!GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_4));     }     if(!GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_5))     {         delay_ms(1);         if(!GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_5))         {             if(BLDC1.Motor_Status == M_Running)//只有电机运行状态下才能停止电机             {                 BLDC1.Motor_Status = M_Stop;             }         }         while(!GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_5));     }     if(BLDC1.Motor_Status == M_Start)     {         BLDC_Motor_Start();         BLDC1.MotorStopFalg = 0;         BLDC1.Motor_Status = M_Accelerate;     }     if(BLDC1.Motor_Status == M_Accelerate)     {     if(BLDC1.Motor_Dir == M_CCW)     {         if((Result<50) && (Result>0))         {             Motor_AccleleRate(8000);         }         else {             Motor_AccleleRate(6000);         }     }     else {         if((Result<50) && (Result>0))         {             Motor_AccleleRate(10000);         }         else {             Motor_AccleleRate(6000);         }     }         //delay_ms(5);         BLDC1.Motor_Status = M_Running;     }     if((BLDC1.Motor_Status == M_Stop) && (BLDC1.MotorStopFalg == 0))     {         BLDC1.MotorStopFalg = 1;         BLDC_Stop_Motor();         BLDC1.Motor_Status = M_IDLE;     }     if(BLDC1.Motor_Status == M_IDLE)     {         BLDC_Motor_Brake();         BLDCStopCounter++;         if(BLDCStopCounter == 1500)         {             TIM_ITConfig(TIM2, TIM_IT_Trigger, DISABLE);             TIM_ClearITPendingBit(TIM2, TIM_IT_Trigger);             BLDC1.Motor_Speed = 0;             PID_Result = 0;             BLDCStopCounter = 0;         }     }     if(BLDC1.Motor_Status == M_Running)     {         //Monitor_Speed();//监控电机速度状态         NoDelaySystickTaskStart(&BLDC1.PIDTimeFlag, PIDTask);//每隔30ms执行一次PID     }     if(RData.RXfinished == 1)     {         if(CommandCheck(RData.RXBuffer) == 1)         {         }         RData.RXfinished = 0;         memset((char*)RData.RXBuffer, 0,RXMaxSize);     } 4.电压电流采集代码         if(ADC_EOF)         {             int sum = 0;             ADC_AMPBuffer[ADC_AMPCounter++] = ADC_Value[3];             if(ADC_AMPCounter == 512)             {                 ADC_AMPCounter = 0;                 for(int i =0;i<512;i++)                 {                     sum += ADC_AMPBuffer;                 }                 sum = sum/512;                 //Rs485_Printf("SUM=%d\r\n",sum);                 BLDC1.Motor_Current = (((float)sum)*3.3f)/4096;                 BLDC1.Motor_Current = BLDC1.Motor_Current/34.0f;                 BLDC1.Motor_Current = (BLDC1.Motor_Current/0.002)/2.0;                 //Rs485_Printf("Motor_Current=%.3f\r\n",BLDC1.Motor_Current);                 sum = 0;             }             counter ++;             VBUS = 20.61 * 3.3 *((float)Get_ConversionVal(ADC_Value[0]));             VBUS = (VBUS /4096.00f);             BLDC1.Vbus_Voltage = VBUS;             //Rs485_Printf("VBUS=%.3f\r\n",VBUS);             BFB = (float)Get_ConversionVal(ADC_Value[1])/4096.00;             Result = ceil(BFB * 100.0);             if(!(temp == Result))             {                 //PWM_Value_Set(BFB*15800);                 if(BLDC1.Motor_Status == M_Stop)                 {                     //PwmDutyUpdate(pwm_value);                 }             }             temp = Result;             if(counter == 10)             {                 counter = 0;                 //Rs485_Printf("%.0f%s\r\n",Result,"%");             }             ADC_EOF = 0;         } 4.霍尔信号换相和转速测量代码
 void TIM2_IRQHandler(void) {     uint8_t Hall_status;     if(TIM_GetITStatus(TIM2, TIM_IT_Trigger) != RESET)     {         /** Clear interrupt flag */         TIM_ClearITPendingBit(TIM2, TIM_IT_Trigger);         Hall_status = Get_Hall_Value();         //printf("Hall_status=%d\r\n",Hall_status);         BLDC_Phase_Change(Hall_status);//换相操作         /* 每换向360°读取TIM3,从而得到360°的换向周期 */         if(Hall_status == 2)         {             /* 计算2次换向周期的平均值 */             CommutateTime = (CommutateTime + TIM4->CNT) >> 1;             TIM4->CNT = 0;             /* 计算电机转速 */             Get_MotorSpeed();         }     } 
 } 5.main函数代码 int main(void)
 {     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //    Delay_Init();     Systick_Init();     DMA_Channel1_Init();     DMA_Channel2_Init(u8UartTx3Buffer);     DMA_Channel3_Init(u8UartRx3Buffer);     DMA_Channel4_Init(u8UartTxBuffer);     DMA_Channel5_Init(u8UartRxBuffer);     Bsp_Gpio_Init();     OPA2_Init();     Drv_Uart_Init(115200);     Drv_Rs485_Init(115200);     Drv_Hall_Init();     Drv_Adc_Init();     Drv_Tim4_Init();     Drv_Pwm_Init();     Speed_PIDInit();     SystickStart(1000, BLDC_ParInit);     BLDC_ParInit();//电机参数初始化     IWDG_Feed_Init(IWDG_Prescaler_32,3200);   // 3.2s IWDG reset     while(1)     {         IWDG_ReloadCounter();   //Feed dog         if(ADC_EOF)         {             int sum = 0;             ADC_AMPBuffer[ADC_AMPCounter++] = ADC_Value[3];             if(ADC_AMPCounter == 512)             {                 ADC_AMPCounter = 0;                 for(int i =0;i<512;i++)                 {                     sum += ADC_AMPBuffer;                 }                 sum = sum/512; //                printf("SUM=%d\r\n",sum);                 BLDC1.Motor_Current = (((float)sum)*3.3f)/4096;                 BLDC1.Motor_Current = BLDC1.Motor_Current/34.0f;                 BLDC1.Motor_Current = (BLDC1.Motor_Current/0.002)*1.223f;                 //printf("Motor_Current=%.3f\r\n",BLDC1.Motor_Current);                 sum = 0;             }             counter ++;             VBUS = 20.61 * 3.3 *((float)Get_ConversionVal(ADC_Value[0]));             VBUS = (VBUS /4096.00f);             BLDC1.Vbus_Voltage = VBUS;             //printf("VBUS=%.3f\r\n",VBUS);             BFB = (float)Get_ConversionVal(ADC_Value[1])/4096.00;             Result = ceil(BFB * 100.0);             if(!(temp == Result))             {                 PWM_Value_Set(BFB*15800);                 if(BLDC1.Motor_Status == M_Stop)                 {                     PwmDutyUpdate(pwm_value);                 }             }             temp = Result;             if(counter == 10)             {                 counter = 0;                 //printf("%.0f%s\r\n",Result,"%");             }             ADC_EOF = 0;         }         NoDelaySystickTaskStart(&BLDC1.MotorTaskSchFlag, MotorTask);//每隔1ms调度一次电机任务         NoDelaySystickTaskStart(&BLDC1.LEDToggleTimeFlag, Led1_Toggle);//每隔500MSLED翻转一次         NoDelaySystickTaskStart(&BLDC1.CommunicationFlag, CommunicationTask);//每隔500MSLED翻转一次         if((BLDC1.Motor_Status == M_Running) || (BLDC1.Motor_Status == M_Accelerate))         {             NoDelaySystickTaskStart(&BLDC1.Motor_StalledFlag, BLDC_Motor_Stalled);//检测电机是否堵转         }     } }   4.演示效果:
 
   关于例程代码和设计文件(生产文件已经打包至附件),本例程只能作为学习使用,严禁商用。
 1.演示照片
 
   2.演示视频
 
 https://b23.tv/fhW6Zkp
 
 
 
 |