久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11687|回復(fù): 29
收起左側(cè)

ucosii+STM32 BLDC電機(jī)控制器設(shè)計(jì) 附源程序Proteus仿真

  [復(fù)制鏈接]
ID:429971 發(fā)表于 2020-1-21 09:38 | 顯示全部樓層 |閱讀模式
嵌入式,現(xiàn)在把我的程序和設(shè)計(jì)思路分享給大家。
軟件所用版本如下
Proteus版本 SP 8.7
STM32CubeMX 版本 5.4.0
HAL固件庫版本 1.8.0
Keil 版本 uVison5

一、設(shè)計(jì)思路:
使用STM32CubeMX軟件進(jìn)行資源初始化(Cube資源配置很方便),使用HAL庫進(jìn)行程序設(shè)計(jì)。
圖1 資源配置圖
二、系統(tǒng)功能介紹:
  • 可調(diào)轉(zhuǎn)速
  • 可控轉(zhuǎn)動方向
  • 顯示轉(zhuǎn)速和目標(biāo)轉(zhuǎn)速

三、軟件設(shè)計(jì)說明:
  • 可調(diào)轉(zhuǎn)速通過可調(diào)電阻和STM32的ADC功能,實(shí)現(xiàn)500-4596范圍的速度調(diào)節(jié)。使用的是簡單的比例控制,并未使用復(fù)雜的PID控制(太難了,一直調(diào)不好)。
  • 通過定時(shí)器1的PWM互補(bǔ)輸出六路PWM控制電機(jī)的轉(zhuǎn)動,驅(qū)動器使用L293D和IRF540 MOS管。
  • 換向使用的是外部中斷,測速使用的是定時(shí)器2的三鹿輸入捕獲,這里有一個(gè)坑,proteus中三路輸入捕獲無法同時(shí)工作,本來打算三路都做測速邏輯,但是速度變化很大,所以最后只使用了一路作為測速通道。
  • 正反轉(zhuǎn)使用的是外部中斷。
  • 顯示轉(zhuǎn)速和目標(biāo)轉(zhuǎn)速使用的是lcd1602,在proteus仿真中,顯示轉(zhuǎn)速有一定的延時(shí)和誤差(其實(shí)是proteus的仿真太慢了,多開一個(gè)任務(wù)就慢的要死)
6、使用ucosii進(jìn)入分功能多任務(wù)處理。

四、調(diào)試及運(yùn)行結(jié)果
圖2 電機(jī)剛啟動,速度未達(dá)到最小速度500

速度未達(dá)到最小速度時(shí)加載很快,大概加載到300rpm左右開始pid控制。

圖3 仿真過程中
圖4 仿真過程中

圖5 反轉(zhuǎn)時(shí)的調(diào)速過程

仿真過程中可以看到定時(shí)器PWM輸出之間的切換以及脈寬的變化。
圖6 接近穩(wěn)定時(shí)

圖7 反轉(zhuǎn)時(shí)接近穩(wěn)定

圖8 穩(wěn)定后增大轉(zhuǎn)速

由于proteus中stm32 的定時(shí)器計(jì)時(shí)很坑,延時(shí)根本不對,需要修改芯片的時(shí)鐘源頻率,改大了仿真慢,改小了又不準(zhǔn),所以ADC采樣值和轉(zhuǎn)速之間只能近似轉(zhuǎn)換,也造成了目標(biāo)轉(zhuǎn)速和實(shí)際轉(zhuǎn)速的誤差。
圖9 整體電路圖
五、心得體會
在這次設(shè)計(jì)過程中,期間遇到許許多多問題,對電機(jī)的控制不熟悉導(dǎo)致?lián)Q向失敗,仿真過程不收斂,定時(shí)器不起作用,引腳之間相互干擾,輸入捕獲無法同時(shí)進(jìn)行,pwm模式設(shè)置錯(cuò)誤導(dǎo)致pid控制越調(diào)速度越快等等問題,最后都比較好的解決了這些問題,當(dāng)然程序和設(shè)計(jì)中還存在一些問題,由于時(shí)間關(guān)系無法全部解決,在以后的學(xué)習(xí)過程中,如果有機(jī)會會繼續(xù)深入學(xué)習(xí)。

單片機(jī)源程序如下:
  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 任務(wù)
  19. //設(shè)置任務(wù)優(yōu)先級
  20. #define START_TASK_PRIO                              10 //開始任務(wù)的優(yōu)先級設(shè)置為最低
  21. //設(shè)置任務(wù)堆棧大小
  22. #define START_STK_SIZE                                    64
  23. //任務(wù)堆棧        
  24. OS_STK START_TASK_STK[START_STK_SIZE];
  25. //任務(wù)函數(shù)
  26. void start_task(void *pdata);        
  27.                            
  28. //LED0任務(wù)
  29. //設(shè)置任務(wù)優(yōu)先級
  30. #define LED0_TASK_PRIO                               2
  31. //設(shè)置任務(wù)堆棧大小
  32. #define LED0_STK_SIZE                                      64
  33. //任務(wù)堆棧        
  34. OS_STK LED0_TASK_STK[LED0_STK_SIZE];
  35. //任務(wù)函數(shù)
  36. void led0_task(void *pdata);

  37. //Speed_ADC 任務(wù)
  38. //設(shè)置任務(wù)優(yōu)先級
  39. #define SPEED_ADC_TASK_PRIO                               1
  40. //設(shè)置任務(wù)堆棧大小
  41. #define SPEED_ADC_STK_SIZE                                      64
  42. //任務(wù)堆棧        
  43. OS_STK SPEED_ADC_TASK_STK[SPEED_ADC_STK_SIZE];
  44. //任務(wù)函數(shù)
  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. //定時(shí)器2捕獲通道參數(shù)
  53. /* Private variables ---------------------------------------------------------*/
  54. uint16_t         Channel1HighTime, Channel2HighTime, Channel3HighTime; //高電平時(shí)間
  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 關(guān)閉中 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);//設(shè)置中斷優(yōu)先級分組為組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
  86.         OSInit();
  87.         OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//創(chuàng)建起始任務(wù)
  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. //開始任務(wù)
  160. void start_task(void *pdata)
  161. {

  162. //        //設(shè)置通道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.                 //打開定時(shí)器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.                 //開啟定時(shí)器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; // 獲取霍爾傳感器狀態(tài) pin0 1 2__IO uint8_t uwStep = 0;
  183.         BLDC_PHASE_CHANGE(hall_read);   // 驅(qū)動換相
  184.         
  185.         //PID初始化
  186.         Speed_PIDInit();
  187.         
  188.   OS_CPU_SR cpu_sr=0;
  189.   OS_ENTER_CRITICAL();                        //進(jìn)入臨界區(qū)(無法被中斷打斷)   
  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);        //掛起起始任務(wù).
  193.         OS_EXIT_CRITICAL();                                //退出臨界區(qū)(可以被中斷打斷)
  194. }

  195. //LED0任務(wù)
  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); //等待轉(zhuǎn)換完成,第二個(gè)參數(shù)代表最長等待時(shí)間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數(shù)據(jù) ,4096 -> 3.3V
  213.                         ADC_Speed = ADC_Value + 500;  //轉(zhuǎn)換公式  0-4096  ->   500 - 4596
  214. //                        if(ADC_Speed > 100){
  215. //                                HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
  216. //                        }
  217.                 }
  218.                 //當(dāng)前速度
  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.           //目標(biāo)速度
  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 采樣函數(shù)
  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. //外部中斷服務(wù)函數(shù)
  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; // 獲取霍爾傳感器狀態(tài) pin0 1 2
  253.                 uwStep = hall_read;
  254.                 BLDC_PHASE_CHANGE(uwStep);   // 驅(qū)動換相
  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. //定時(shí)器2中斷函數(shù)
  284. //溢出時(shí)間為1s
  285. //溢出值1000  每個(gè)點(diǎn)為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、中斷產(chǎn)生,先判斷是否為第一次上升沿
  294.                 2、捕獲到上升沿后,將時(shí)間點(diǎn)存入變量,切換捕獲下降沿
  295.                 3、捕獲到下降沿后,記下時(shí)間點(diǎn),切換為捕獲上升沿
  296.                 4、捕獲到上升沿后,記下時(shí)間點(diǎn)
  297.                 5、計(jì)算周期和占空比
  298.                 6、問題如果經(jīng)過多個(gè)周期才有一次上升沿和下降沿怎么辦,需要記錄溢出次數(shù)
  299.                     如果溢出的時(shí)候有上升沿標(biāo)志位
  300.                
  301.                 問題:proteus三路輸入捕獲計(jì)算,測轉(zhuǎn)速時(shí),如果第一個(gè)上升沿和第二個(gè)上升沿不在一個(gè)定時(shí)器計(jì)數(shù)周期,會計(jì)算失敗
  302.                 */
  303.                 if(Channel1Edge == 0)
  304.                 {
  305.                         //獲取通道1上升沿時(shí)間點(diǎn)
  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計(jì)算
  322. //                                current_speed = 60*1000 / Channel1Period; //轉(zhuǎn)速計(jì)算
  323. //                                current_speed = current_speed * 5; //速度調(diào)整系數(shù)
  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; //速度調(diào)整系數(shù)
  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; //速度調(diào)整系數(shù)
  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****/
復(fù)制代碼

所有資料51hei提供下載:
Proteus.zip (102.55 KB, 下載次數(shù): 554)

評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評分

回復(fù)

使用道具 舉報(bào)

ID:422933 發(fā)表于 2020-3-1 16:39 | 顯示全部樓層
這個(gè)是真的厲害
回復(fù)

使用道具 舉報(bào)

ID:526735 發(fā)表于 2020-3-11 16:48 | 顯示全部樓層
原來樓主另外開了一個(gè)帖,挺厲害的,這個(gè)仿真做到漂亮。
回復(fù)

使用道具 舉報(bào)

ID:693333 發(fā)表于 2020-3-12 08:48 | 顯示全部樓層
下來學(xué)習(xí)下,謝謝!
回復(fù)

使用道具 舉報(bào)

ID:705649 發(fā)表于 2020-3-13 09:17 | 顯示全部樓層
   挺厲害的  ,學(xué)習(xí)了,與大神共同學(xué)習(xí)。
回復(fù)

使用道具 舉報(bào)

ID:526735 發(fā)表于 2020-3-14 11:18 | 顯示全部樓層
看了樓主的仿真,有些地方我認(rèn)為有點(diǎn)問題,三相驅(qū)動橋的接法有問題,上下橋不能共用一個(gè)GND的。

2020-03-14_110615.png


還有程序上,一般單橋臂載波就行了。上橋臂輸出PWM,下橋臂恒通,換相時(shí)再一起關(guān)斷。比如某個(gè)時(shí)段,Q1、Q4作為對管驅(qū)動電機(jī)的U相、V相(U+、V-)。那么這段時(shí)間,Q4可以一直導(dǎo)通的,Q1發(fā)PWM就行了。
回復(fù)

使用道具 舉報(bào)

ID:700459 發(fā)表于 2020-3-14 20:29 | 顯示全部樓層
thank yu very much
回復(fù)

使用道具 舉報(bào)

ID:708548 發(fā)表于 2020-3-14 22:31 | 顯示全部樓層
剛?cè)腚娮涌拥男“浊皝韺W(xué)習(xí),給樓主點(diǎn)贊
回復(fù)

使用道具 舉報(bào)

ID:429971 發(fā)表于 2020-5-3 23:15 | 顯示全部樓層
zcllom 發(fā)表于 2020-3-14 11:18
看了樓主的仿真,有些地方我認(rèn)為有點(diǎn)問題,三相驅(qū)動橋的接法有問題,上下橋不能共用一個(gè)GND的。

仿真里面是可以的
回復(fù)

使用道具 舉報(bào)

ID:778569 發(fā)表于 2020-6-21 16:50 | 顯示全部樓層
樓主,我有問題想問一下,代碼里面的include里面main.h我為什么報(bào)錯(cuò)啊?是不是寫錯(cuò)著呢?
這四個(gè)頭文件都是怎么來的?樓主能發(fā)一下嗎?
回復(fù)

使用道具 舉報(bào)

ID:429971 發(fā)表于 2020-8-9 10:20 | 顯示全部樓層
永不開的城南花 發(fā)表于 2020-6-21 16:50
樓主,我有問題想問一下,代碼里面的include里面main.h我為什么報(bào)錯(cuò)啊?是不是寫錯(cuò)著呢?
這四個(gè)頭文件都 ...

這個(gè)是cube生成的時(shí)候我勾選生成了頭文件,程序里應(yīng)該有,沒找到報(bào)錯(cuò)可能是你的keil沒有設(shè)置頭文件路徑
回復(fù)

使用道具 舉報(bào)

ID:772986 發(fā)表于 2020-8-11 20:47 | 顯示全部樓層
這是PID控制嗎
回復(fù)

使用道具 舉報(bào)

ID:429971 發(fā)表于 2020-8-24 20:12 | 顯示全部樓層

只用了比例控制
回復(fù)

使用道具 舉報(bào)

ID:243702 發(fā)表于 2021-2-21 16:20 | 顯示全部樓層
zcllom 發(fā)表于 2020-3-14 11:18
看了樓主的仿真,有些地方我認(rèn)為有點(diǎn)問題,三相驅(qū)動橋的接法有問題,上下橋不能共用一個(gè)GND的。

仿真并不是非常真
回復(fù)

使用道具 舉報(bào)

ID:319011 發(fā)表于 2021-4-18 18:17 | 顯示全部樓層
您好,xuhe:
    keil工程可以下載嗎,按照你貼出來的代碼不能運(yùn)行,不知道是不是我工程配置有問題呢,謝謝
回復(fù)

使用道具 舉報(bào)

ID:945182 發(fā)表于 2021-6-26 23:00 | 顯示全部樓層
優(yōu)秀!
回復(fù)

使用道具 舉報(bào)

ID:144093 發(fā)表于 2021-7-2 16:56 | 顯示全部樓層
樓主,太好了,又玩操作系統(tǒng),還帶電機(jī)的,感謝分享
回復(fù)

使用道具 舉報(bào)

ID:478238 發(fā)表于 2021-7-22 09:40 | 顯示全部樓層
多謝老大,一直莫不著頭腦
回復(fù)

使用道具 舉報(bào)

ID:247623 發(fā)表于 2021-10-11 16:53 | 顯示全部樓層
請教一下,源程序是在哪個(gè)文件夾里
回復(fù)

使用道具 舉報(bào)

ID:1070647 發(fā)表于 2023-4-20 10:37 | 顯示全部樓層
為什么還是閃退
回復(fù)

使用道具 舉報(bào)

ID:1081973 發(fā)表于 2023-6-4 16:25 | 顯示全部樓層
樓主還是6的
回復(fù)

使用道具 舉報(bào)

ID:1087429 發(fā)表于 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
回復(fù)

使用道具 舉報(bào)

ID:1087429 發(fā)表于 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
回復(fù)

使用道具 舉報(bào)

ID:1087429 發(fā)表于 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
回復(fù)

使用道具 舉報(bào)

ID:228452 發(fā)表于 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



回復(fù)

使用道具 舉報(bào)

ID:1087429 發(fā)表于 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
回復(fù)

使用道具 舉報(bào)

ID:1121358 發(fā)表于 2024-5-19 12:10 來自手機(jī) | 顯示全部樓層
Kara-kala-10 發(fā)表于 2023-7-17 16:12
Hello Friends
please if some one can help me fix this error LCD screen is empty speed regulation : ...

use proteus 8.7 would fix this problem
回復(fù)

使用道具 舉報(bào)

ID:1121358 發(fā)表于 2024-5-19 12:13 來自手機(jī) | 顯示全部樓層
mick32 發(fā)表于 2023-7-14 04:48
Hello
same problem with proteus simulation
LCD screen is empty

i tried to use proteus 8.15 to simulate this project but it just doesnt work. then i checked the version of the original project, its 8.7, so i use proteus 8.7 and everything runs correctly.
回復(fù)

使用道具 舉報(bào)

ID:344848 發(fā)表于 2024-5-19 13:41 | 顯示全部樓層
沒有畫MOS管的體二極管,R1~R6通常不畫。
回復(fù)

使用道具 舉報(bào)

ID:670730 發(fā)表于 2024-7-4 23:50 | 顯示全部樓層
學(xué)習(xí)一下謝謝!!
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 综合久久99 | 日韩欧美一级精品久久 | 国产精品影视在线观看 | 日韩在线精品视频 | 日韩成人免费视频 | 日韩精品久久久久久 | 91精品久久久久久久久久入口 | 黄色欧美视频 | 久久久久久久久久久爱 | 夜夜爽99久久国产综合精品女不卡 | 久久综合伊人 | 在线观看www高清视频 | 黄色成人免费在线观看 | 精品国产乱码久久久久久果冻传媒 | 超碰免费在 | 亚洲精品视频播放 | 韩日一区二区 | 永久精品 | 久久久91 | 久久久久国产精品一区 | 成在线人视频免费视频 | 亚洲精品女优 | av在线天天 | 欧美一区二区三区视频在线观看 | 91在线精品视频 | 亚洲一区中文 | 毛片免费看 | 国产电影一区二区 | 懂色av一区二区三区在线播放 | 精品久久一区二区三区 | 日本中文字幕在线视频 | av一二三四 | 伊人精品视频 | 久久婷婷麻豆国产91天堂 | 精品成人一区二区 | 午夜视频免费在线 | 免费在线色| 91av小视频 | 久久99精品视频 | 久久久久久久久毛片 | 免费艹逼视频 |