找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8575|回复: 25
打印 上一主题 下一主题
收起左侧

ucosii+STM32 BLDC电机控制器设计 附源程序Proteus仿真

  [复制链接]
跳转到指定楼层
楼主
嵌入式,现在把我的程序和设计思路分享给大家。
软件所用版本如下
Proteus版本 SP 8.7
STM32CubeMX 版本 5.4.0
HAL固件库版本 1.8.0
Keil 版本 uVison5

一、设计思路:
使用STM32CubeMX软件进行资源初始化(Cube资源配置很方便),使用HAL库进行程序设计。
图1 资源配置图
二、系统功能介绍:
  • 可调转速
  • 可控转动方向
  • 显示转速和目标转速

三、软件设计说明:
  • 可调转速通过可调电阻和STM32的ADC功能,实现500-4596范围的速度调节。使用的是简单的比例控制,并未使用复杂的PID控制(太难了,一直调不好)。
  • 通过定时器1的PWM互补输出六路PWM控制电机的转动,驱动器使用L293D和IRF540 MOS管。
  • 换向使用的是外部中断,测速使用的是定时器2的三鹿输入捕获,这里有一个坑,proteus中三路输入捕获无法同时工作,本来打算三路都做测速逻辑,但是速度变化很大,所以最后只使用了一路作为测速通道。
  • 正反转使用的是外部中断。
  • 显示转速和目标转速使用的是lcd1602,在proteus仿真中,显示转速有一定的延时和误差(其实是proteus的仿真太慢了,多开一个任务就慢的要死)
6、使用ucosii进入分功能多任务处理。

四、调试及运行结果
图2 电机刚启动,速度未达到最小速度500

速度未达到最小速度时加载很快,大概加载到300rpm左右开始pid控制。

图3 仿真过程中
图4 仿真过程中

图5 反转时的调速过程

仿真过程中可以看到定时器PWM输出之间的切换以及脉宽的变化。
图6 接近稳定时

图7 反转时接近稳定

图8 稳定后增大转速

由于proteus中stm32 的定时器计时很坑,延时根本不对,需要修改芯片的时钟源频率,改大了仿真慢,改小了又不准,所以ADC采样值和转速之间只能近似转换,也造成了目标转速和实际转速的误差。
图9 整体电路图
五、心得体会
在这次设计过程中,期间遇到许许多多问题,对电机的控制不熟悉导致换向失败,仿真过程不收敛,定时器不起作用,引脚之间相互干扰,输入捕获无法同时进行,pwm模式设置错误导致pid控制越调速度越快等等问题,最后都比较好的解决了这些问题,当然程序和设计中还存在一些问题,由于时间关系无法全部解决,在以后的学习过程中,如果有机会会继续深入学习。

单片机源程序如下:
  1. /* USER CODE END Header */

  2. /* Includes ------------------------------------------------------------------*/
  3. #include "main.h"
  4. #include "adc.h"
  5. #include "tim.h"
  6. #include "gpio.h"

  7. /* Private includes ----------------------------------------------------------*/
  8. /* USER CODE BEGIN Includes */
  9. #include "includes.h"
  10. #include "lcd.h"
  11. /* USER CODE END Includes */

  12. /* Private typedef -----------------------------------------------------------*/
  13. /* USER CODE BEGIN PTD */

  14. /* USER CODE END PTD */

  15. /* Private define ------------------------------------------------------------*/
  16. /* USER CODE BEGIN PD */
  17. #define HALL_GPIO GPIOA
  18. //START 任务
  19. //设置任务优先级
  20. #define START_TASK_PRIO                              10 //开始任务的优先级设置为最低
  21. //设置任务堆栈大小
  22. #define START_STK_SIZE                                    64
  23. //任务堆栈        
  24. OS_STK START_TASK_STK[START_STK_SIZE];
  25. //任务函数
  26. void start_task(void *pdata);        
  27.                            
  28. //LED0任务
  29. //设置任务优先级
  30. #define LED0_TASK_PRIO                               2
  31. //设置任务堆栈大小
  32. #define LED0_STK_SIZE                                      64
  33. //任务堆栈        
  34. OS_STK LED0_TASK_STK[LED0_STK_SIZE];
  35. //任务函数
  36. void led0_task(void *pdata);

  37. //Speed_ADC 任务
  38. //设置任务优先级
  39. #define SPEED_ADC_TASK_PRIO                               1
  40. //设置任务堆栈大小
  41. #define SPEED_ADC_STK_SIZE                                      64
  42. //任务堆栈        
  43. OS_STK SPEED_ADC_TASK_STK[SPEED_ADC_STK_SIZE];
  44. //任务函数
  45. void speed_adc_task(void *pdata);

  46. /* USER CODE END PD */

  47. /* Private macro -------------------------------------------------------------*/
  48. /* USER CODE BEGIN PM */

  49. /* USER CODE END PM */

  50. /* Private variables ---------------------------------------------------------*/

  51. /* USER CODE BEGIN PV */

  52. //定时器2捕获通道参数
  53. /* Private variables ---------------------------------------------------------*/
  54. uint16_t         Channel1HighTime, Channel2HighTime, Channel3HighTime; //高电平时间
  55. uint16_t         Channel1Period, Channel2Period, Channel3Period; //周期
  56. uint8_t          Channel1Edge = 0, Channel2Edge = 0, Channel3Edge = 0; //上升沿
  57. uint16_t         Channel1Percent, Channel2Percent, Channel3Percent; //占空比
  58. uint16_t        Channel1PercentTemp[3] = {0, 0, 0};
  59. uint8_t         Channel1TempCount = 0;
  60. uint16_t         Channel1RisingTimeLast=0, Channel1RisingTimeNow, Channel1FallingTime;
  61. uint16_t         Channel2RisingTimeLast=0, Channel2RisingTimeNow, Channel2FallingTime;
  62. uint16_t         Channel3RisingTimeLast=0, Channel3RisingTimeNow, Channel3FallingTime;

  63. extern int motor_period;
  64. extern int motor_duty;
  65. extern int clock_wise;
  66. int current_speed = 0;
  67. int ADC_Speed = 500;  //555 / 90% = 500
  68. int ADC_Value = 555;  //
  69. BOOLEAN state = 0; // 0 关闭中 1 启动中
  70. /* USER CODE END PV */

  71. /* Private function prototypes -----------------------------------------------*/
  72. void SystemClock_Config(void);
  73. /* USER CODE BEGIN PFP */

  74. /* USER CODE END PFP */

  75. /* Private user code ---------------------------------------------------------*/
  76. /* USER CODE BEGIN 0 */

  77. /* USER CODE END 0 */

  78. /**
  79.   * @brief  The application entry point.
  80.   * @retval int
  81.   */
  82. int main(void)
  83. {
  84.   /* USER CODE BEGIN 1 */
  85.         HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  86.         OSInit();
  87.         OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
  88.   /* USER CODE END 1 */
  89.   

  90.   /* MCU Configuration--------------------------------------------------------*/

  91.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  92.   HAL_Init();

  93.   /* USER CODE BEGIN Init */

  94.   /* USER CODE END Init */

  95.   /* Configure the system clock */
  96.   SystemClock_Config();

  97.   /* USER CODE BEGIN SysInit */
  98.                
  99.   /* USER CODE END SysInit */

  100.   /* Initialize all configured peripherals */
  101.   MX_GPIO_Init();
  102.   MX_TIM1_Init();
  103.   MX_ADC1_Init();
  104.   MX_TIM2_Init();
  105.   /* USER CODE BEGIN 2 */
  106.         OSStart();
  107.   /* USER CODE END 2 */

  108.   /* Infinite loop */
  109.   /* USER CODE BEGIN WHILE */
  110.   while (1)
  111.   {
  112.     /* USER CODE END WHILE */

  113.     /* USER CODE BEGIN 3 */
  114.   }
  115.   /* USER CODE END 3 */
  116. }

  117. /**
  118.   * @brief System Clock Configuration
  119.   * @retval None
  120.   */
  121. void SystemClock_Config(void)
  122. {
  123.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  124.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  125.   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  126.   /** Initializes the CPU, AHB and APB busses clocks
  127.   */
  128.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  129.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  130.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  131.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  132.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  133.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  134.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;
  135.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  136.   {
  137.     Error_Handler();
  138.   }
  139.   /** Initializes the CPU, AHB and APB busses clocks
  140.   */
  141.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  142.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  143.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  144.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
  145.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  146.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  147.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  148.   {
  149.     Error_Handler();
  150.   }
  151.   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  152.   PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
  153.   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  154.   {
  155.     Error_Handler();
  156.   }
  157. }

  158. /* USER CODE BEGIN 4 */
  159. //开始任务
  160. void start_task(void *pdata)
  161. {

  162. //        //设置通道1的脉宽。  width = (1000 - 500) / 1000 = 50%
  163.         __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, motor_duty);
  164.         __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, motor_duty);
  165.         __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, motor_duty);
  166.         
  167.                 //打开定时器2通道 , 中断使能
  168.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
  169.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
  170.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_3);
  171.         HAL_Delay(100);
  172.                 //开启定时器1的通道1
  173.         HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
  174.         HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
  175.         HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);

  176.         //
  177.         HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  178.         HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
  179.         HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
  180.         
  181.         //
  182.         uint16_t hall_read = (HALL_GPIO->IDR)&0x0007; // 获取霍尔传感器状态 pin0 1 2__IO uint8_t uwStep = 0;
  183.         BLDC_PHASE_CHANGE(hall_read);   // 驱动换相
  184.         
  185.         //PID初始化
  186.         Speed_PIDInit();
  187.         
  188.   OS_CPU_SR cpu_sr=0;
  189.   OS_ENTER_CRITICAL();                        //进入临界区(无法被中断打断)   
  190.          OSTaskCreate(led0_task,(void *)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);        
  191.         OSTaskCreate(speed_adc_task,(void *)0,(OS_STK*)&SPEED_ADC_TASK_STK[SPEED_ADC_STK_SIZE-1],SPEED_ADC_TASK_PRIO);               
  192.   OSTaskSuspend(START_TASK_PRIO);        //挂起起始任务.
  193.         OS_EXIT_CRITICAL();                                //退出临界区(可以被中断打断)
  194. }

  195. //LED0任务
  196. void speed_adc_task(void *pdata)
  197. {                  
  198.         lcd_system_reset();
  199.         unsigned char temp_table[16] ={"Cur_Speed:"};
  200.         unsigned char temp_table1[16] ={"Tar_Speed:"};
  201.         for(uint8_t i=0;i<10;i++)
  202.         {
  203.                 lcd_char_write(i,0,temp_table[i]);
  204.                 lcd_char_write(i,1,temp_table1[i]);
  205.         }
  206.         HAL_ADC_Start(&hadc1);
  207.         while(1)
  208.         {
  209.                 HAL_ADC_PollForConversion(&hadc1,0); //等待转换完成,第二个参数代表最长等待时间ms
  210.                 if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
  211.                 {
  212.                         ADC_Value = HAL_ADC_GetValue(&hadc1); // 读取ADC数据 ,4096 -> 3.3V
  213.                         ADC_Speed = ADC_Value + 500;  //转换公式  0-4096  ->   500 - 4596
  214. //                        if(ADC_Speed > 100){
  215. //                                HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
  216. //                        }
  217.                 }
  218.                 //当前速度
  219.                 temp_table[10]=current_speed/1000+'0';
  220.                 temp_table[11]=current_speed/100%10+'0';
  221.                 temp_table[12]=current_speed/10%10+'0';
  222.                 temp_table[13]=current_speed%10+'0';
  223.           //目标速度
  224.                 temp_table1[10]=ADC_Speed/1000+'0';
  225.                 temp_table1[11]=ADC_Speed/100%10+'0';
  226.                 temp_table1[12]=ADC_Speed/10%10+'0';
  227.                 temp_table1[13]=ADC_Speed%10+'0';
  228.                 for(uint8_t i=10;i<14;i++)
  229.                 {
  230.                         lcd_char_write(i,0,temp_table[i]);
  231.                         lcd_char_write(i,1,temp_table1[i]);
  232.                 }
  233.         }
  234. }
  235. //speed adc 采样函数
  236. void led0_task(void *pdata)
  237. {                 
  238.         while(1)
  239.         {
  240.                 HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET);
  241.                 OSTimeDly(10);
  242.                 HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET);
  243.                 OSTimeDly(10);
  244.         }
  245. }
  246. //外部中断服务函数
  247. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  248. {        
  249.         if(!state)
  250.         {
  251.                 __IO uint8_t uwStep = 0;
  252.                 uint16_t hall_read=(HALL_GPIO->IDR)&0x0007; // 获取霍尔传感器状态 pin0 1 2
  253.                 uwStep = hall_read;
  254.                 BLDC_PHASE_CHANGE(uwStep);   // 驱动换相
  255.                         
  256.         }
  257.         uint16_t key_read =(Start_GPIO_Port->IDR)&0x00e0;
  258.         if(key_read == 0x00c0)
  259.         {
  260. //                state = !state;
  261. //                HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
  262. //                HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
  263. //                HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
  264. //               
  265. //                //BLDC_PHASE_CHANGE(7);
  266. //                HAL_TIM_Base_MspDeInit(&htim1);
  267. //               
  268. //                HAL_Delay(300);
  269. //                HAL_TIM_Base_MspDeInit(&htim1);
  270. //                HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  271. //                HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
  272. //                HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
  273. //                BLDC_PHASE_CHANGE(7);
  274.                         //HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
  275.         }else if(key_read == 0x00a0)
  276.         {
  277.                 clock_wise = 0;
  278.         }else if(key_read == 0x0060)
  279.         {
  280.                 clock_wise = 1;
  281.         }
  282. }
  283. //定时器2中断函数
  284. //溢出时间为1s
  285. //溢出值1000  每个点为1ms
  286. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  287. {
  288.         
  289.         if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) //捕获中断
  290.         {
  291.                 /*
  292.                 测速逻辑
  293.                 1、中断产生,先判断是否为第一次上升沿
  294.                 2、捕获到上升沿后,将时间点存入变量,切换捕获下降沿
  295.                 3、捕获到下降沿后,记下时间点,切换为捕获上升沿
  296.                 4、捕获到上升沿后,记下时间点
  297.                 5、计算周期和占空比
  298.                 6、问题如果经过多个周期才有一次上升沿和下降沿怎么办,需要记录溢出次数
  299.                     如果溢出的时候有上升沿标志位
  300.                
  301.                 问题:proteus三路输入捕获计算,测转速时,如果第一个上升沿和第二个上升沿不在一个定时器计数周期,会计算失败
  302.                 */
  303.                 if(Channel1Edge == 0)
  304.                 {
  305.                         //获取通道1上升沿时间点
  306.                         Channel1RisingTimeNow = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
  307.                         Channel1Edge = 1;//捕获上升沿置位
  308.                         Channel1RisingTimeLast = Channel1RisingTimeNow;
  309.                 }else if(Channel1Edge == 1)
  310.                 {
  311.                         Channel1RisingTimeNow = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
  312.                         if(Channel1RisingTimeNow > Channel1RisingTimeLast)
  313.                                 {
  314.                                         Channel1Period = Channel1RisingTimeNow - Channel1RisingTimeLast;
  315.                                 }
  316.                                 else
  317.                                 {
  318.                                         //Channel2Period = Channel2RisingTimeNow + 1000 - Channel2RisingTimeLast + 1;
  319.                                 }
  320.                         Channel1Edge = 0;
  321.                         //pid计算
  322. //                                current_speed = 60*1000 / Channel1Period; //转速计算
  323. //                                current_speed = current_speed * 5; //速度调整系数
  324. //                                motor_duty = Speed_PIDAdjust(current_speed);
  325.                 }
  326.         }else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
  327.         {
  328.                 if(Channel2Edge == 0)
  329.                 {
  330.                         Channel2RisingTimeNow = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2);
  331.                         Channel2Edge = 1;
  332.                         
  333.                         Channel2RisingTimeLast = Channel2RisingTimeNow;
  334.                 }
  335.                 else if(Channel2Edge == 1)
  336.                 {
  337.                         Channel2RisingTimeNow = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2);
  338.                         if(Channel2RisingTimeNow > Channel2RisingTimeLast)
  339.                                 {
  340.                                         Channel2Period = Channel2RisingTimeNow - Channel2RisingTimeLast;
  341.                                 }
  342.                                 else
  343.                                 {
  344.                                         //Channel2Period = Channel2RisingTimeNow + 1000 - Channel2RisingTimeLast + 1;
  345.                                 }
  346.                         current_speed = 60*1000 / Channel2Period;
  347.                         current_speed = current_speed * 5; //速度调整系数
  348.                         motor_duty = Speed_PIDAdjust(current_speed);
  349.                         Channel2Edge = 0;
  350.                 }
  351.         }
  352.         else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
  353.         {
  354.                 if(Channel3Edge == 0)
  355.                 {
  356.                         Channel3RisingTimeNow = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_3);
  357.                         Channel3Edge = 1;
  358.                         Channel3RisingTimeLast = Channel3RisingTimeNow;
  359.                 }
  360.                 else if(Channel3Edge == 1)
  361.                 {
  362.                         Channel3RisingTimeNow = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_3);
  363.                         if(Channel3RisingTimeNow > Channel3RisingTimeLast)
  364.                                 {
  365.                                         Channel3Period = Channel3RisingTimeNow - Channel3RisingTimeLast;
  366.                                 }
  367.                                 else
  368.                                 {
  369.                                         //Channel3Period = Channel3RisingTimeNow + 1000 - Channel3RisingTimeLast + 1;
  370.                                 }
  371. //                        current_speed = 60*1000 / Channel3Period;
  372. //                        current_speed = current_speed * 5; //速度调整系数
  373. //                        motor_duty = Speed_PIDAdjust(current_speed);
  374.                         Channel3Edge = 0;                        
  375.                 }
  376.         }
  377. }

  378. /* USER CODE END 4 */

  379. /**
  380.   * @brief  This function is executed in case of error occurrence.
  381.   * @retval None
  382.   */
  383. void Error_Handler(void)
  384. {
  385.   /* USER CODE BEGIN Error_Handler_Debug */
  386.   /* User can add his own implementation to report the HAL error return state */

  387.   /* USER CODE END Error_Handler_Debug */
  388. }

  389. #ifdef  USE_FULL_ASSERT
  390. /**
  391.   * @brief  Reports the name of the source file and the source line number
  392.   *         where the assert_param error has occurred.
  393.   * @param  file: pointer to the source file name
  394.   * @param  line: assert_param error line source number
  395.   * @retval None
  396.   */
  397. void assert_failed(uint8_t *file, uint32_t line)
  398. {
  399.   /* USER CODE BEGIN 6 */
  400.   /* User can add his own implementation to report the file name and line number,
  401.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  402.   /* USER CODE END 6 */
  403. }
  404. #endif /* USE_FULL_ASSERT */

  405. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码

所有资料51hei提供下载:
Proteus.zip (102.55 KB, 下载次数: 507)
文档.docx (758.47 KB, 下载次数: 351)
uCos_ii_Demo.7z (5.21 MB, 下载次数: 458)


评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏26 分享淘帖 顶4 踩
回复

使用道具 举报

沙发
ID:422933 发表于 2020-3-1 16:39 | 只看该作者
这个是真的厉害
回复

使用道具 举报

板凳
ID:526735 发表于 2020-3-11 16:48 | 只看该作者
原来楼主另外开了一个帖,挺厉害的,这个仿真做到漂亮。
回复

使用道具 举报

地板
ID:693333 发表于 2020-3-12 08:48 | 只看该作者
下来学习下,谢谢!
回复

使用道具 举报

5#
ID:705649 发表于 2020-3-13 09:17 | 只看该作者
   挺厉害的  ,学习了,与大神共同学习。
回复

使用道具 举报

6#
ID:526735 发表于 2020-3-14 11:18 | 只看该作者
看了楼主的仿真,有些地方我认为有点问题,三相驱动桥的接法有问题,上下桥不能共用一个GND的。




还有程序上,一般单桥臂载波就行了。上桥臂输出PWM,下桥臂恒通,换相时再一起关断。比如某个时段,Q1、Q4作为对管驱动电机的U相、V相(U+、V-)。那么这段时间,Q4可以一直导通的,Q1发PWM就行了。
回复

使用道具 举报

7#
ID:700459 发表于 2020-3-14 20:29 | 只看该作者
thank yu very much
回复

使用道具 举报

8#
ID:708548 发表于 2020-3-14 22:31 | 只看该作者
刚入电子坑的小白前来学习,给楼主点赞
回复

使用道具 举报

9#
ID:429971 发表于 2020-5-3 23:15 | 只看该作者
zcllom 发表于 2020-3-14 11:18
看了楼主的仿真,有些地方我认为有点问题,三相驱动桥的接法有问题,上下桥不能共用一个GND的。

仿真里面是可以的
回复

使用道具 举报

10#
ID:778569 发表于 2020-6-21 16:50 | 只看该作者
楼主,我有问题想问一下,代码里面的include里面main.h我为什么报错啊?是不是写错着呢?
这四个头文件都是怎么来的?楼主能发一下吗?
回复

使用道具 举报

11#
ID:429971 发表于 2020-8-9 10:20 | 只看该作者
永不开的城南花 发表于 2020-6-21 16:50
楼主,我有问题想问一下,代码里面的include里面main.h我为什么报错啊?是不是写错着呢?
这四个头文件都 ...

这个是cube生成的时候我勾选生成了头文件,程序里应该有,没找到报错可能是你的keil没有设置头文件路径
回复

使用道具 举报

12#
ID:772986 发表于 2020-8-11 20:47 | 只看该作者
这是PID控制吗
回复

使用道具 举报

13#
ID:429971 发表于 2020-8-24 20:12 | 只看该作者

只用了比例控制
回复

使用道具 举报

14#
ID:243702 发表于 2021-2-21 16:20 | 只看该作者
zcllom 发表于 2020-3-14 11:18
看了楼主的仿真,有些地方我认为有点问题,三相驱动桥的接法有问题,上下桥不能共用一个GND的。

仿真并不是非常真
回复

使用道具 举报

15#
ID:319011 发表于 2021-4-18 18:17 | 只看该作者
您好,xuhe:
    keil工程可以下载吗,按照你贴出来的代码不能运行,不知道是不是我工程配置有问题呢,谢谢
回复

使用道具 举报

16#
ID:945182 发表于 2021-6-26 23:00 | 只看该作者
优秀!
回复

使用道具 举报

17#
ID:144093 发表于 2021-7-2 16:56 | 只看该作者
楼主,太好了,又玩操作系统,还带电机的,感谢分享
回复

使用道具 举报

18#
ID:478238 发表于 2021-7-22 09:40 | 只看该作者
多谢老大,一直莫不着头脑
回复

使用道具 举报

19#
ID:247623 发表于 2021-10-11 16:53 | 只看该作者
请教一下,源程序是在哪个文件夹里
回复

使用道具 举报

20#
ID:1070647 发表于 2023-4-20 10:37 | 只看该作者
为什么还是闪退
回复

使用道具 举报

21#
ID:1081973 发表于 2023-6-4 16:25 | 只看该作者
楼主还是6的
回复

使用道具 举报

22#
ID:1087429 发表于 2023-7-6 17:49 | 只看该作者
hello sir im student in Master 2 mecatronics and i work on this project can you provide me this simulations files please
回复

使用道具 举报

23#
ID:1087429 发表于 2023-7-6 17:51 | 只看该作者
Hello sir im student in master 2 and i work on the same project please i can't download the files because i m not from c im Moroccan  can you help me ..?  thanks
回复

使用道具 举报

24#
ID:1087429 发表于 2023-7-13 22:01 | 只看该作者
Hello dear friends if some one might help me i download the files but the simulation didn't work with me where is the error please if you can help me I'm studen.  

erreur simulation.png (112.01 KB, 下载次数: 28)

erreur simulation.png
回复

使用道具 举报

25#
ID:228452 发表于 2023-7-14 04:48 | 只看该作者
Hello
same problem with proteus simulation
LCD screen is empty
Speed regulation not possible
Proteus 8.16 SP0
Any advice ?
Thank you



回复

使用道具 举报

26#
ID:1087429 发表于 2023-7-17 16:12 | 只看该作者
Hello Friends
please if some one can help me fix this error LCD screen is empty speed regulation :0
proteus 8
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表