袁胜富 发表于 2023-2-6 13:33

基于CH32V208的无刷有感电机驱动

本帖最后由 袁胜富 于 2023-2-6 16:24 编辑

https://www.bilibili.com/video/BV1R24y1i7ZX?t=0.8#技术资源# #申请原创# 1.项目简介:
       基于CH32V208WBU6芯片,预驱芯片用的是EG2133,最大支持输入电压75V,功率1000W,支持USB下载程序,板载一路485,引出USART1接口,板载蓝牙天线,板载旋转电位器。实现了电机的按键启停,按键切换旋转方向,速度环PID,测量母线电压,电机运行电流以及基于硬石上位机协议的PID调参。
static/image/hrline/1.gif
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.最小系统电路static/image/hrline/1.gif
3.软件说明:
static/image/hrline/1.gif

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_Value;            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));            VBUS = (VBUS /4096.00f);            BLDC1.Vbus_Voltage = VBUS;            //Rs485_Printf("VBUS=%.3f\r\n",VBUS);            BFB = (float)Get_ConversionVal(ADC_Value)/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_Value;            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));            VBUS = (VBUS /4096.00f);            BLDC1.Vbus_Voltage = VBUS;            //printf("VBUS=%.3f\r\n",VBUS);            BFB = (float)Get_ConversionVal(ADC_Value)/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
https://www.bilibili.com/video/BV1R24y1i7ZX?t=0.8

LOVEEVER 发表于 2023-2-8 09:29

CH32V208有双USB 支持

klbyf 发表于 2023-2-9 08:56

leeyouhon 发表于 2023-2-9 09:25

感谢楼主大大的无私分享

yuchl 发表于 2023-2-9 14:52

感谢分享

huazi2008 发表于 2023-2-15 11:57

WoodData 发表于 2023-2-20 17:55

感谢分享

Innercourage 发表于 2023-2-27 09:02

不错不错,学到了

qbwww 发表于 2023-2-28 12:41

基于CH32V208WBU6芯片,预驱芯片用的是EG2133,最大支持输入电压75V,功率1000W,支持USB下载程序,板载一路485,引出USART1接口,板载蓝牙天线,板载旋转电位器。实现了电机的按键启停,按键切换旋转方向,速度环PID,测量母线电压,电机运行电流以及基于硬石上位机协议的PID调参。

小夏天的大西瓜 发表于 2023-3-1 13:28

CH32V208 支持2个USB 接口,可以独立工作,其中一个可以作为Host和Device(USB2),另外一个只能作为Device 使用(USB1)。

LOVEEVER 发表于 2023-3-2 16:53

CH32V208系列是基于32位RISC-V设计的无线型微控制器,配备了硬件堆栈区、快速中断入口,在标准RISC-V基础上大大提高了中断响应速度

tpgf 发表于 2023-3-6 16:19

请问楼主什么叫做无刷有感电机呀

木木guainv 发表于 2023-3-6 16:58

有感无刷电机中的感是指“霍尔传感器”。

磨砂 发表于 2023-3-6 17:07

无刷电机的转速是靠交流电频率决定的,那么电调要想方设法弄明白目前电机的转速以及当前电机的状态

晓伍 发表于 2023-3-6 17:19

无感无刷电机会在低速时线性不好甚至可能会颤抖,而起步的扭力也难以强过同等级有刷电机

八层楼 发表于 2023-3-7 08:08

在运行的过程中 电容有没有稍微发热的现象啊

观海 发表于 2023-3-7 08:55

LOVEEVER 发表于 2023-2-8 09:29
CH32V208有双USB 支持

请问它带的双USB都可以工作在什么usb模式下啊

WoodData 发表于 2023-3-20 09:22

看一看
页: [1]
查看完整版本: 基于CH32V208的无刷有感电机驱动