找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

STM32閉環(huán)步進(jìn)電機(jī)驅(qū)動(dòng)程序以及Proteus仿真

  [復(fù)制鏈接]
ID:399339 發(fā)表于 2021-9-6 15:05 | 顯示全部樓層 |閱讀模式
(1) 掌握基于 PROTEUS 和 KEIL 的仿真調(diào)試方法。
(2) 掌握 uCOS-II 的移植,并采用多任務(wù)編程、調(diào)試。
(3) 熟悉電機(jī)的工作原理和功能,并掌握電機(jī)的應(yīng)用和驅(qū)動(dòng)方法。
1.2 內(nèi)容

(1) 基本功能:本任務(wù)通過(guò)輸出脈沖控制步進(jìn)電機(jī)的停止、運(yùn)動(dòng)、方向。使用 兩個(gè)按鍵分別控制步進(jìn)電機(jī)的正轉(zhuǎn)和反轉(zhuǎn),再次按下這兩個(gè)按鍵,步進(jìn)電機(jī)停止, 同時(shí) LCD 顯示電機(jī)狀態(tài)信息。
(2) 擴(kuò)展功能:加入一個(gè)轉(zhuǎn)速閾值設(shè)置功能,由電位器充當(dāng)閾值設(shè)置器,可設(shè) 置目標(biāo)轉(zhuǎn)速并使電機(jī)接近設(shè)置的轉(zhuǎn)速。

第 2 章 系統(tǒng)硬件設(shè)計(jì)

2.1 總體框架設(shè)計(jì)

51hei圖片編輯_20210906150340.jpg
圖 2-1 硬件框架圖


本次任務(wù)實(shí)踐的硬件架構(gòu)設(shè)計(jì)如圖 2-1 所示。按照設(shè)計(jì)任務(wù)的要求,本次設(shè) 計(jì)采用的主控芯片為 STM32F103,整體硬件設(shè)計(jì)以該芯片為中心,由按鍵輸入模 塊、LCD 顯示模塊、電機(jī)模塊等組成。
2.2 硬件電路設(shè)計(jì)

(1) 參考 LCD1602 液晶顯示屏的芯片資料,在 LCD 顯示屏的電路連接中,將 VDD 以及 VSS、VEE 接到電源以及地上。之后再將它的3 個(gè)信號(hào)控制引腳 RS、RW、 E 以及 8 個(gè)數(shù)據(jù)傳輸引腳 DO-D7 分別連接到 STM32 的相應(yīng)引腳上。
(2) 按鍵輸入模塊采用兩個(gè)獨(dú)立按鍵,分別連接 STM32 的 PB6、PB7 引腳,公 共端接地。
(3) 電機(jī)模塊使用直流無(wú)刷電機(jī),并采用 L293D 和 IRF540 MOS 管驅(qū)動(dòng)。
(4) 用所謂“六步換向法”,根據(jù)轉(zhuǎn)子當(dāng)前的位置,按照一定的順序給定子繞 組通電使 BLDC 電機(jī)轉(zhuǎn)動(dòng)。如圖 2-2 所示。
永磁體 N-S 交替交換,使位置傳感器產(chǎn)生相位差 120°的 H3、H2、H1 方波, 從而產(chǎn)生有效的六狀態(tài)編碼信號(hào):010、011、001、101、100、110,通過(guò)邏輯組 件處理產(chǎn)生 V6-V1 導(dǎo)通、V5-V6 導(dǎo)通、V4-V5 導(dǎo)通、V3-V4 導(dǎo)通、V2-V3 導(dǎo)通、V1-V2 導(dǎo)通,也就是說(shuō)將直流母線(xiàn)電壓依次加在 U ->V、w ->V、W ->U、V->U、V->W、
U ->W 上,這樣轉(zhuǎn)子每轉(zhuǎn)過(guò)一對(duì) N-S 極,V1、V2、V3、V4、V5、V6 各功率管即按 固定組合成六種狀態(tài)的依次導(dǎo)通。

圖 2-2 BLDC 控制框圖

圖 2-3 120°HAll 換相控制圖
對(duì)于典型的三相帶傳感器的 BLDC 電機(jī),有 6 個(gè)不同的工作區(qū)間,每個(gè)區(qū)間 中有特定的兩相繞組通電。通過(guò)檢測(cè)霍爾傳感器,可以得到一個(gè) 3 位編碼,編碼 值的范圍從 1 到 6。每個(gè)編碼值代表轉(zhuǎn)子當(dāng)前所處的區(qū)間。從而提供了需要對(duì)哪 些繞組通電的信息。因此程序可以使用簡(jiǎn)單的查表操作來(lái)確定要對(duì)哪兩對(duì)特定的 繞組通電以使轉(zhuǎn)子轉(zhuǎn)動(dòng)。注意狀態(tài)"0 和 7"對(duì)于霍爾效應(yīng)傳感器而言是無(wú)效狀態(tài)。 軟件應(yīng)該檢查出這些值并相應(yīng)地禁止 PWM。
(5) Proteus 的無(wú)刷直流電機(jī)模型帶有 3 個(gè)霍爾傳感器,霍爾傳感器的輸出信 號(hào)兩相間相差 120 度。與此對(duì)應(yīng)的是電機(jī)轉(zhuǎn)子每旋轉(zhuǎn)一周霍爾傳感器就能輸出
6 種編碼狀態(tài),如圖 2-4 所示。 從圖可見(jiàn),霍爾傳感器輸 出狀態(tài)變化一次,就 意味著電機(jī)轉(zhuǎn)子轉(zhuǎn)過(guò)了 60 度。 據(jù)此,可以根據(jù)單位時(shí)間 T 內(nèi)捕獲的霍爾傳感 器輸出變化的個(gè)數(shù) n 計(jì)算出電機(jī)的轉(zhuǎn)速 V=60n/T。 根據(jù)這一原理,通過(guò)控制器 的輸入捕獲功能 IC 獲取到其中 一相霍爾傳感器輸出信號(hào)的周期,就可以比較準(zhǔn) 精確地測(cè)量到電機(jī)的轉(zhuǎn)速。


圖 2-4 霍爾位置傳感器輸出信號(hào)波形


圖 2-5 硬件原理圖

第 3 章 系統(tǒng)軟件設(shè)計(jì)


為了方便編程并使代碼美觀,需要?jiǎng)?chuàng)建一個(gè)開(kāi)始任務(wù)。該任務(wù)可以用來(lái)創(chuàng)建 其他任務(wù)以及一些信號(hào)量、消息郵箱、事件標(biāo)志組等。而根據(jù)設(shè)計(jì)要求,需要在 本地 LCD 顯示電機(jī)運(yùn)轉(zhuǎn)狀態(tài),因此需要一個(gè)信息顯示任務(wù)。該控制系統(tǒng)最終所實(shí) 現(xiàn)的功能是控制直流無(wú)刷電機(jī),故還需要一個(gè)步進(jìn)電機(jī)驅(qū)動(dòng)任務(wù)。根據(jù)上述分析, 一共劃分為兩個(gè)任務(wù)。

圖 3-1 主函數(shù)流程圖
開(kāi)始任務(wù)主要用來(lái)對(duì)一些驅(qū)動(dòng)電機(jī)的寄存器進(jìn)行初始化并啟動(dòng)電機(jī)以及創(chuàng) 建后面所需要的任務(wù)以及一些信號(hào)量、事件標(biāo)志組和消息郵箱,任務(wù)優(yōu)先級(jí)設(shè)置 為 10。

圖 3-2 開(kāi)始任務(wù)流程圖
速度任務(wù)主要將霍爾傳感器的數(shù)據(jù)進(jìn)行讀取并將讀到的速度參數(shù)進(jìn)行轉(zhuǎn)換, 之后顯示在顯示屏上,任務(wù)優(yōu)先級(jí)設(shè)置為 1。


圖 3-3 速度讀取任務(wù)流程圖
速度讀取主要是在中斷服務(wù)函數(shù)里進(jìn)行,通過(guò)對(duì)捕獲霍爾傳感器的上升沿以 及下降沿,讀的其信號(hào)周期,再將其轉(zhuǎn)換為頻率得到速度值。

圖 3-4 轉(zhuǎn)速讀取計(jì)算流程圖

第 4 章 調(diào)試過(guò)程及結(jié)果

圖 4-1 仿真過(guò)程中
圖 4-2 反轉(zhuǎn)時(shí)的調(diào)速過(guò)程 仿真過(guò)程中可以看到定時(shí)器 PWM 輸出之間的切換以及脈寬的變化。


圖 4-3 接近穩(wěn)定時(shí)

圖 4-4 穩(wěn)定后增大轉(zhuǎn)速
STM32單片機(jī)源程序如下:
  1. include "main.h"
  2. #include "adc.h"
  3. #include "tim.h"
  4. #include "gpio.h"
  5. /* Private includes ----------------------------------------------------------*/
  6. /* USER CODE BEGIN Includes */
  7. #include "includes.h"
  8. #include "lcd.h"
  9. /* USER CODE END Includes */
  10. /* Private typedef -----------------------------------------------------------*/
  11. /* USER CODE BEGIN PTD */
  12. /* USER CODE END PTD */
  13. /* Private define ------------------------------------------------------------*/
  14. /* USER CODE BEGIN PD */
  15. #define HALL_GPIO GPIOA
  16. //START 任務(wù)
  17. //設(shè)置任務(wù)優(yōu)先級(jí)
  18. #define START_TASK_PRIO                              10 //開(kāi)始任務(wù)的優(yōu)先級(jí)設(shè)置為最低
  19. //設(shè)置任務(wù)堆棧大小
  20. #define START_STK_SIZE                                    64
  21. //任務(wù)堆棧        
  22. OS_STK START_TASK_STK[START_STK_SIZE];
  23. //任務(wù)函數(shù)
  24. void start_task(void *pdata);        
  25.                            
  26. //LED0任務(wù)
  27. //設(shè)置任務(wù)優(yōu)先級(jí)
  28. #define LED0_TASK_PRIO                               2
  29. //設(shè)置任務(wù)堆棧大小
  30. #define LED0_STK_SIZE                                      64
  31. //任務(wù)堆棧        
  32. OS_STK LED0_TASK_STK[LED0_STK_SIZE];
  33. //任務(wù)函數(shù)
  34. void led0_task(void *pdata);
  35. //Speed_ADC 任務(wù)
  36. //設(shè)置任務(wù)優(yōu)先級(jí)
  37. #define SPEED_ADC_TASK_PRIO                               1
  38. //設(shè)置任務(wù)堆棧大小
  39. #define SPEED_ADC_STK_SIZE                                      64
  40. //任務(wù)堆棧        
  41. OS_STK SPEED_ADC_TASK_STK[SPEED_ADC_STK_SIZE];
  42. //任務(wù)函數(shù)
  43. void speed_adc_task(void *pdata);
  44. /* USER CODE END PD */
  45. /* Private macro -------------------------------------------------------------*/
  46. /* USER CODE BEGIN PM */
  47. /* USER CODE END PM */
  48. /* Private variables ---------------------------------------------------------*/
  49. /* USER CODE BEGIN PV */
  50. //定時(shí)器2捕獲通道參數(shù)
  51. /* Private variables ---------------------------------------------------------*/
  52. uint16_t         Channel1HighTime, Channel2HighTime, Channel3HighTime; //高電平時(shí)間
  53. uint16_t         Channel1Period, Channel2Period, Channel3Period; //周期
  54. uint8_t          Channel1Edge = 0, Channel2Edge = 0, Channel3Edge = 0; //上升沿
  55. uint16_t         Channel1Percent, Channel2Percent, Channel3Percent; //占空比
  56. uint16_t        Channel1PercentTemp[3] = {0, 0, 0};
  57. uint8_t         Channel1TempCount = 0;
  58. uint16_t         Channel1RisingTimeLast=0, Channel1RisingTimeNow, Channel1FallingTime;
  59. uint16_t         Channel2RisingTimeLast=0, Channel2RisingTimeNow, Channel2FallingTime;
  60. uint16_t         Channel3RisingTimeLast=0, Channel3RisingTimeNow, Channel3FallingTime;
  61. extern int motor_period;
  62. extern int motor_duty;
  63. extern int clock_wise;
  64. int current_speed = 0;
  65. int ADC_Speed = 500;  //555 / 90% = 500
  66. int ADC_Value = 555;  //
  67. BOOLEAN state = 0; // 0 關(guān)閉中 1 啟動(dòng)中
  68. /* USER CODE END PV */
  69. /* Private function prototypes -----------------------------------------------*/
  70. void SystemClock_Config(void);
  71. /* USER CODE BEGIN PFP */
  72. /* USER CODE END PFP */
  73. /* Private user code ---------------------------------------------------------*/
  74. /* USER CODE BEGIN 0 */
  75. /* USER CODE END 0 */
  76. /**
  77.   * @brief  The application entry point.
  78.   * @retval int
  79.   */
  80. int main(void)
  81. {
  82.   /* USER CODE BEGIN 1 */
  83.         HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);//設(shè)置中斷優(yōu)先級(jí)分組為組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
  84.         OSInit();
  85.         OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//創(chuàng)建起始任務(wù)
  86.   /* USER CODE END 1 */
  87.   
  88.   /* MCU Configuration--------------------------------------------------------*/
  89.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  90.   HAL_Init();
  91.   /* USER CODE BEGIN Init */
  92.   /* USER CODE END Init */
  93.   /* Configure the system clock */
  94.   SystemClock_Config();
  95.   /* USER CODE BEGIN SysInit */
  96.                
  97.   /* USER CODE END SysInit */
  98.   /* Initialize all configured peripherals */
  99.   MX_GPIO_Init();
  100.   MX_TIM1_Init();
  101.   MX_ADC1_Init();
  102.   MX_TIM2_Init();
  103.   /* USER CODE BEGIN 2 */
  104.         OSStart();
  105.   /* USER CODE END 2 */
  106.   /* Infinite loop */
  107.   /* USER CODE BEGIN WHILE */
  108.   while (1)
  109.   {
  110.     /* USER CODE END WHILE */
  111.     /* USER CODE BEGIN 3 */
  112.   }
  113.   /* USER CODE END 3 */
  114. }
  115. /**
  116.   * @brief System Clock Configuration
  117.   * @retval None
  118.   */
  119. void SystemClock_Config(void)
  120. {
  121.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  122.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  123.   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  124.   /** Initializes the CPU, AHB and APB busses clocks
  125.   */
  126.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  127.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  128.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  129.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  130.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  131.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  132.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;
  133.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  134.   {
  135.     Error_Handler();
  136.   }
  137.   /** Initializes the CPU, AHB and APB busses clocks
  138.   */
  139.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  140.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  141.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  142.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
  143.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  144.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  145.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  146.   {
  147.     Error_Handler();
  148.   }
  149.   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  150.   PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
  151.   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  152.   {
  153.     Error_Handler();
  154.   }
  155. }
  156. /* USER CODE BEGIN 4 */
  157. //開(kāi)始任務(wù)
  158. void start_task(void *pdata)
  159. {
  160. //        //設(shè)置通道1的脈寬。  width = (1000 - 500) / 1000 = 50%
  161.         __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, motor_duty);
  162.         __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, motor_duty);
  163.         __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, motor_duty);
  164.         
  165.                 //打開(kāi)定時(shí)器2通道 , 中斷使能
  166.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
  167.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
  168.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_3);
  169.         HAL_Delay(100);
  170.                 //開(kāi)啟定時(shí)器1的通道1
  171.         HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
  172.         HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
  173.         HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
  174.         //
  175.         HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  176.         HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
  177.         HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
  178.         
  179.         //
  180.         uint16_t hall_read = (HALL_GPIO->IDR)&0x0007; // 獲取霍爾傳感器狀態(tài) pin0 1 2__IO uint8_t uwStep = 0;
  181.         BLDC_PHASE_CHANGE(hall_read);   // 驅(qū)動(dòng)換相
  182.         
  183.         //PID初始化
  184.         Speed_PIDInit();
  185.         
  186.   OS_CPU_SR cpu_sr=0;
  187.   OS_ENTER_CRITICAL();                        //進(jìn)入臨界區(qū)(無(wú)法被中斷打斷)   
  188.          OSTaskCreate(led0_task,(void *)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);        
  189.         OSTaskCreate(speed_adc_task,(void *)0,(OS_STK*)&SPEED_ADC_TASK_STK[SPEED_ADC_STK_SIZE-1],SPEED_ADC_TASK_PRIO);               
  190.   OSTaskSuspend(START_TASK_PRIO);        //掛起起始任務(wù).
  191.         OS_EXIT_CRITICAL();                                //退出臨界區(qū)(可以被中斷打斷)
  192. }
  193. //LED0任務(wù)
  194. void speed_adc_task(void *pdata)
  195. {                  
  196.         lcd_system_reset();
  197.         unsigned char temp_table[16] ={"Cur_Speed:"};
  198.         unsigned char temp_table1[16] ={"Tar_Speed:"};
  199.         for(uint8_t i=0;i<10;i++)
  200.         {
  201.                 lcd_char_write(i,0,temp_table[i]);
  202.                 lcd_char_write(i,1,temp_table1[i]);
  203.         }
  204.         HAL_ADC_Start(&hadc1);
  205.         while(1)
  206.         {
  207.                 HAL_ADC_PollForConversion(&hadc1,0); //等待轉(zhuǎn)換完成,第二個(gè)參數(shù)代表最長(zhǎng)等待時(shí)間ms
  208.                 if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
  209.                 {
  210.                         ADC_Value = HAL_ADC_GetValue(&hadc1); // 讀取ADC數(shù)據(jù) ,4096 -> 3.3V
  211.                         ADC_Speed = ADC_Value + 500;  //轉(zhuǎn)換公式  0-4096  ->   500 - 4596
  212. //                        if(ADC_Speed > 100){
  213. //                                HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
  214. //                        }
  215.                 }
  216.                 //當(dāng)前速度
  217.                 temp_table[10]=current_speed/1000+'0';
  218.                 temp_table[11]=current_speed/100%10+'0';
  219.                 temp_table[12]=current_speed/10%10+'0';
  220.                 temp_table[13]=current_speed%10+'0';
  221.           //目標(biāo)速度
  222.                 temp_table1[10]=ADC_Speed/1000+'0';
  223.                 temp_table1[11]=ADC_Speed/100%10+'0';
  224.                 temp_table1[12]=ADC_Speed/10%10+'0';
  225.                 temp_table1[13]=ADC_Speed%10+'0';
  226.                 for(uint8_t i=10;i<14;i++)
  227.                 {
  228.                         lcd_char_write(i,0,temp_table[i]);
  229.                         lcd_char_write(i,1,temp_table1[i]);
  230.                 }
  231.         }
  232. }
  233. //speed adc 采樣函數(shù)
  234. void led0_task(void *pdata)
  235. {                 
  236.         while(1)
  237.         {
  238.                 HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET);
  239.                 OSTimeDly(10);
  240.                 HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET);
  241.                 OSTimeDly(10);
  242.         }
  243. }
  244. //外部中斷服務(wù)函數(shù)
  245. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  246. {        
  247.         if(!state)
  248.         {
  249.                 __IO uint8_t uwStep = 0;
  250.                 uint16_t hall_read=(HALL_GPIO->IDR)&0x0007; // 獲取霍爾傳感器狀態(tài) pin0 1 2
  251.                 uwStep = hall_read;
  252.                 BLDC_PHASE_CHANGE(uwStep);   // 驅(qū)動(dòng)換相
  253.                         
  254.         }
  255.         uint16_t key_read =(Start_GPIO_Port->IDR)&0x00e0;
  256.         if(key_read == 0x00c0)
  257.         {
  258. //                state = !state;
  259. //                HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
  260. //                HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
  261. //                HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
  262. //               
  263. //                //BLDC_PHASE_CHANGE(7);
  264. //                HAL_TIM_Base_MspDeInit(&htim1);
  265. //               
  266. //                HAL_Delay(300);
  267. //                HAL_TIM_Base_MspDeInit(&htim1);
  268. //                HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  269. //                HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
  270. //                HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
  271. //                BLDC_PHASE_CHANGE(7);
  272.                         //HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
  273.         }else if(key_read == 0x00a0)
  274.         {
  275.                 clock_wise = 0;
  276.         }else if(key_read == 0x0060)
  277.         {
  278.                 clock_wise = 1;
  279.         }
  280. }
  281. //定時(shí)器2中斷函數(shù)
  282. //溢出時(shí)間為1s
  283. //溢出值1000  每個(gè)點(diǎn)為1ms
  284. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  285. {
  286.         
  287.         if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) //捕獲中斷
  288.         {
  289.                 /*
  290.                 測(cè)速邏輯
  291.                 1、中斷產(chǎn)生,先判斷是否為第一次上升沿
  292.                 2、捕獲到上升沿后,將時(shí)間點(diǎn)存入變量,切換捕獲下降沿
  293.                 3、捕獲到下降沿后,記下時(shí)間點(diǎn),切換為捕獲上升沿
  294.                 4、捕獲到上升沿后,記下時(shí)間點(diǎn)
  295.                 5、計(jì)算周期和占空比
  296.                 6、問(wèn)題如果經(jīng)過(guò)多個(gè)周期才有一次上升沿和下降沿怎么辦,需要記錄溢出次數(shù)
  297.                     如果溢出的時(shí)候有上升沿標(biāo)志位
  298.                
  299.                 問(wèn)題:proteus三路輸入捕獲計(jì)算,測(cè)轉(zhuǎn)速時(shí),如果第一個(gè)上升沿和第二個(gè)上升沿不在一個(gè)定時(shí)器計(jì)數(shù)周期,會(huì)計(jì)算失敗
  300.                 */
  301.                 if(Channel1Edge == 0)
  302.                 {
  303.                         //獲取通道1上升沿時(shí)間點(diǎn)
  304.                         Channel1RisingTimeNow = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
  305.                         Channel1Edge = 1;//捕獲上升沿置位
  306.                         Channel1RisingTimeLast = Channel1RisingTimeNow;
  307.                 }else if(Channel1Edge == 1)
  308.                 {
  309.                         Channel1RisingTimeNow = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
  310.                         if(Channel1RisingTimeNow > Channel1RisingTimeLast)
  311.                                 {
  312.                                         Channel1Period = Channel1RisingTimeNow - Channel1RisingTimeLast;
  313.                                 }
  314.                                 else
  315.                                 {
  316.                                         //Channel2Period = Channel2RisingTimeNow + 1000 - Channel2RisingTimeLast + 1;
  317.                                 }
  318.                         Channel1Edge = 0;
  319.                         //pid計(jì)算
  320. //                                current_speed = 60*1000 / Channel1Period; //轉(zhuǎn)速計(jì)算
  321. //                                current_speed = current_speed * 5; //速度調(diào)整系數(shù)
  322. //                                motor_duty = Speed_PIDAdjust(current_speed);
  323. ……………………
  324. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

51hei.png
全部資料51hei下載地址:
代碼: uCos_ii_Demo.7z (5.21 MB, 下載次數(shù): 297)
仿真: Proteus.zip (102.55 KB, 下載次數(shù): 310)
以上圖文: 電機(jī)轉(zhuǎn)速檢測(cè)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)v2.0.pdf (1.3 MB, 下載次數(shù): 195)

評(píng)分

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

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:262 發(fā)表于 2021-12-9 02:14 | 顯示全部樓層

代碼工程在MDK-ARM 這個(gè)目錄里面,仿真用Proteus8.8 如下圖
51hei.gif
51hei.png
回復(fù)

使用道具 舉報(bào)

ID:989153 發(fā)表于 2021-12-8 19:03 | 顯示全部樓層
誰(shuí)能教下我要如何才能打開(kāi)?
回復(fù)

使用道具 舉報(bào)

ID:907200 發(fā)表于 2021-12-14 00:11 | 顯示全部樓層
請(qǐng)問(wèn)Proteus7.8是不是打不開(kāi)qaq
回復(fù)

使用道具 舉報(bào)

ID:349102 發(fā)表于 2021-12-18 09:14 | 顯示全部樓層
可以研究一下
回復(fù)

使用道具 舉報(bào)

ID:920508 發(fā)表于 2022-4-24 16:18 | 顯示全部樓層
代碼的文件在MDK-ARM目錄的uCos_ii_Demo.uvprojx,用Keil5打開(kāi) 找了一圈才找到
回復(fù)

使用道具 舉報(bào)

ID:1046504 發(fā)表于 2022-10-8 12:01 | 顯示全部樓層
請(qǐng)問(wèn)一下,使用proteus8.9 老是閃退是什么原因
回復(fù)

使用道具 舉報(bào)

ID:1044173 發(fā)表于 2022-10-16 10:35 | 顯示全部樓層
步進(jìn)電機(jī)頭文件是哪個(gè)?Proteus1602不顯示
回復(fù)

使用道具 舉報(bào)

ID:1069757 發(fā)表于 2023-6-30 01:46 來(lái)自手機(jī) | 顯示全部樓層
不行啊轉(zhuǎn)速顯示0
回復(fù)

使用道具 舉報(bào)

ID:97349 發(fā)表于 2024-3-25 23:05 | 顯示全部樓層
這是直流無(wú)刷電機(jī) 不是步進(jìn)電機(jī)
回復(fù)

使用道具 舉報(bào)

ID:97349 發(fā)表于 2024-3-25 23:06 | 顯示全部樓層
直流無(wú)刷電機(jī)啊
回復(fù)

使用道具 舉報(bào)

ID:923738 發(fā)表于 2024-4-23 17:03 | 顯示全部樓層
是步進(jìn)電機(jī)嗎
回復(fù)

使用道具 舉報(bào)

ID:1123630 發(fā)表于 2024-6-4 00:43 | 顯示全部樓層

可以研究一下
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表