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

               找回密碼
               立即注冊

              QQ登錄

              只需一步,快速開始

              搜索
              查看: 4266|回復: 3
              收起左側

              基于stm32f103rct6的PID算法控制四驅車程序—基于HAL庫的

              [復制鏈接]
              ID:507807 發表于 2019-7-30 20:41 | 顯示全部樓層 |閱讀模式
              STM32F103RCT6PID算法控制四個電機,基于HAL,希望可以給各位一些幫助,僅供參考,請勿他用

              單片機源程序如下:
              1. /* USER CODE END Header */

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

              8. /* Private includes ----------------------------------------------------------*/
              9. /* USER CODE BEGIN Includes */
              10. #include "string.h"
              11. #include "Motr_conter.h"
              12. #include "pid.h"
              13. /* USER CODE END Includes */

              14. /* Private typedef -----------------------------------------------------------*/
              15. /* USER CODE BEGIN PTD */

              16. /* USER CODE END PTD */

              17. /* Private define ------------------------------------------------------------*/
              18. /* USER CODE BEGIN PD */

              19. /* USER CODE END PD */

              20. /* Private macro -------------------------------------------------------------*/
              21. /* USER CODE BEGIN PM */

              22. /* USER CODE END PM */

              23. /* Private variables ---------------------------------------------------------*/

              24. /* USER CODE BEGIN PV */

              25. /* USER CODE END PV */

              26. /* Private function prototypes -----------------------------------------------*/
              27. void SystemClock_Config(void);
              28. /* USER CODE BEGIN PFP */

              29. /* USER CODE END PFP */

              30. /* Private user code ---------------------------------------------------------*/
              31. /* USER CODE BEGIN 0 */
              32.                                                
              33. uint8_t Left_Front_or_Right_rear;                        //用于保存電機行駛方向的變量
              34. uint8_t RX_buff[100],Start_Flag=0;                //接收緩沖區,和電機運行開始的標志位
              35. int16_t pwm_duth_A=0,pwm_duth_B=0,pwm_duth_C=0,pwm_duth_D=0;//四個電機的pwm變量
              36. uint16_t save_Ecoder_A=0,save_Ecoder_B=0,save_Ecoder_C=0,save_Ecoder_D=0;        //保存四個電機的編碼值

              37. extern PID sPID;                        //PID結構體變量,用于改變目標值
              38. /* USER CODE END 0 */

              39. /**
              40.   * @brief  The application entry point.
              41.   * @retval int
              42.   */
              43. int main(void)
              44. {
              45.   /* USER CODE BEGIN 1 */
              46. uint8_t TX_buff[500]={"今天是個好日子,天氣有點涼快!!\n"};

              47.   /* USER CODE END 1 */
              48.   

              49.   /* MCU Configuration--------------------------------------------------------*/

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

              52.   /* USER CODE BEGIN Init */

              53.   /* USER CODE END Init */

              54.   /* Configure the system clock */
              55.   SystemClock_Config();

              56.   /* USER CODE BEGIN SysInit */

              57.   /* USER CODE END SysInit */

              58.   /* Initialize all configured peripherals */
              59.   MX_GPIO_Init();                                                //GPIO的初始化
              60.   MX_DMA_Init();                                                //DMA的初始化
              61.   MX_TIM2_Init();                                                //定時器2的初始化
              62.   MX_USART1_UART_Init();                //串口1的初始化
              63.   MX_TIM1_Init();                                                //定時器1的初始化
              64.   MX_TIM6_Init();                                                //定時器6的初始化
              65. MX_USART2_UART_Init();                        //串口2的初始化
              66.   MX_TIM3_Init();                                                //定時器3的初始化
              67.   MX_TIM4_Init();                                                //定時器4的初始化
              68.   MX_TIM5_Init();                                                //定時器5的初始化
              69.   MX_TIM8_Init();                                                //定時器8的初始化
              70.   /* USER CODE BEGIN 2 */
              71.         Motor_Stop;                                                                //電機初始化狀態位停止的
              72.         HAL_TIM_Base_Start_IT(&htim6);                                                                                                                                        //啟動定時器
              73.         HAL_UART_Transmit(&huart2,TX_buff,strlen((char*)TX_buff),1000);        //串口2發送一串數據,表示串口2工作正常
              74.         HAL_UART_Transmit(&huart1,TX_buff,strlen((char*)TX_buff),100);        //串口發送數據測試        ,表示串口1工作正常
              75.         printf("電機編碼器測試,測試通過\n");                                                                                                                //發送實驗測試名稱
              76.         IncPIDInit();                                                                                                                                                                                                                //pPID參數初始化
              77.         HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_ALL);                                                                //開始電機D編碼器接口計數
              78.         HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_ALL);                                                                //開啟電機C的編碼器接口計數
              79.         HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_ALL);                                                                //開啟電機B的編碼器接口計數
              80.         HAL_TIM_Encoder_Start(&htim5,TIM_CHANNEL_ALL);                                                                //開啟電機C的編碼器接口計數
              81.         HAL_UART_Receive_DMA(&huart2,RX_buff,5);                                                                                        //開啟串口2的DMA接收數據
              82.   /* USER CODE END 2 */

              83.   /* Infinite loop */
              84.   /* USER CODE BEGIN WHILE */
              85.   while (1)
              86.   {
              87.     /* USER CODE END WHILE */

              88.     /* USER CODE BEGIN 3 */
              89.                 if(RX_buff[0]==0x31)
              90.                 {
              91.                         if(RX_buff[1]==0x31&&RX_buff[2]==0x31&&RX_buff[3]==0x31)        Derection_Control(1,3,1,3);                                //左前行駛
              92.                 }
              93.                 if(RX_buff[0]==0x32)
              94.                 {
              95.                         if(RX_buff[1]==0x32&&RX_buff[2]==0x32&&RX_buff[3]==0x32)        Derection_Control(1,1,1,1);                                //向前行駛
              96.                 }
              97.                 if(RX_buff[0]==0x33)
              98.                 {
              99.                         if(RX_buff[1]==0x33&&RX_buff[2]==0x33&&RX_buff[3]==0x33)        Derection_Control(3,1,3,1);                                //右前行駛
              100.                 }
              101.                 if(RX_buff[0]==0x34)
              102.                 {
              103.                         if(RX_buff[1]==0x34&&RX_buff[2]==0x34&&RX_buff[3]==0x34)        Derection_Control(1,2,1,2);                                //向左平行行駛
              104.                 }
              105.                 if(RX_buff[0]==0x35)
              106.                 {
              107.                         if(RX_buff[1]==0x35&&RX_buff[2]==0x35&&RX_buff[3]==0x35)        Derection_Control(1,2,2,1);                                //順時針旋轉
              108.                 }
              109.                 if(RX_buff[0]==0x36)
              110.                 {
              111.                         if(RX_buff[1]==0x36&&RX_buff[2]==0x36&&RX_buff[3]==0x36)        Derection_Control(2,1,2,1);                                //向右平行行駛
              112.                 }
              113.                 if(RX_buff[0]==0x37)
              114.                 {
              115.                         if(RX_buff[1]==0x37&&RX_buff[2]==0x37&&RX_buff[3]==0x37)        Derection_Control(3,2,3,2);                                //左后行駛
              116.                 }
              117.                 if(RX_buff[0]==0x38)
              118.                 {
              119.                         if(RX_buff[1]==0x38&&RX_buff[2]==0x38&&RX_buff[3]==0x38)        Derection_Control(2,2,2,2);                                //向后行駛
              120.                 }
              121.                 if(RX_buff[0]==0x39)
              122.                 {
              123.                         if(RX_buff[1]==0x39&&RX_buff[2]==0x39&&RX_buff[3]==0x39)        Derection_Control(2,3,2,3);                                //右后行駛
              124.                 }
              125.                 if(RX_buff[0]==0x30)
              126.                 {
              127.                         if(RX_buff[1]==0x30&&RX_buff[2]==0x30&&RX_buff[3]==0x30)        Derection_Control(2,1,1,2);                                //逆時針旋轉
              128.                 }
              129.                 if(RX_buff[0]==0x2E)
              130.                 {
              131.                         if(RX_buff[1]==0x31&&RX_buff[2]==0x32&&RX_buff[3]==0x33)        {Derection_Control(3,3,3,3);        }                //停止
              132.                 }
              133.                 if(RX_buff[0]==0x2B)
              134.                 {
              135.                         sPID.SetPoint_A=sPID.SetPoint_B=sPID.SetPoint_C=sPID.SetPoint_D=(RX_buff[1]-0x30)*1000+(RX_buff[2]-0x30)*100+(RX_buff[3]-0x30)*10+(RX_buff[4]-0x30);                //設置行駛的速度
              136.                 }                       
              137.   }
              138.   /* USER CODE END 3 */
              139. }

              140. /**
              141.   * @brief System Clock Configuration
              142.   * @retval None
              143.   */
              144. void SystemClock_Config(void)
              145. {
              146.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
              147.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

              148.   /** Initializes the CPU, AHB and APB busses clocks
              149.   */
              150.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
              151.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
              152.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
              153.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
              154.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
              155.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
              156.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
              157.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
              158.   {
              159.     Error_Handler();
              160.   }
              161.   /** Initializes the CPU, AHB and APB busses clocks
              162.   */
              163.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
              164.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
              165.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
              166.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
              167.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
              168.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

              169.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
              170.   {
              171.     Error_Handler();
              172.   }
              173.   /** Enables the Clock Security System
              174.   */
              175.   HAL_RCC_EnableCSS();
              176. }

              177. /* USER CODE BEGIN 4 */
              178.         uint8_t direction_A,direction_B,direction_C,direction_D;                                        //保存四個電機方向的變量
              179.         uint32_t Code_val_A=0,Code_val_B=0,Code_val_C=0,Code_val_D=0;                        //保存四個編碼器計數器的的值
              180.         uint16_t last_Code_val_A=0,last_Code_val_B=0,last_Code_val_C=0,last_Code_val_D=0;//保存上一秒計數器的值,與下一秒的相比較到底計數了多少次
              181. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
              182. {                                                                        
              183.        
              184.         if(htim->Instance==TIM6)                                                                                                        //判斷是不是定時器6達到更新事件
              185.         {
              186.                 if(Start_Flag==1)                                                                                                                                //判斷電機的行駛標志位
              187.                 {
              188.                 direction_A=__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim5);//獲取電機A轉動的方向
              189.                 direction_B=__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim4);//獲取電機B 的旋轉方向
              190.                 direction_C=__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);//獲取電機C 的旋轉方向
              191.                 direction_D=__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim2);//獲取電機D的旋轉方向
              192.                 Code_val_A=__HAL_TIM_GET_COUNTER(&htim5);                                                //讀取電機A的計數器的值
              193.                 Code_val_B=__HAL_TIM_GET_COUNTER(&htim4);                                                //讀取電機B的計數器的值
              194.                 Code_val_C=__HAL_TIM_GET_COUNTER(&htim3);                                                //讀取電機C的計數器的值
              195.                 Code_val_D=__HAL_TIM_GET_COUNTER(&htim2);                                                //讀取電機D的計數器的值
              196.                 if(direction_A==0)  save_Ecoder_A=(Code_val_A>=last_Code_val_A?Code_val_A-last_Code_val_A:Code_val_A+65535-last_Code_val_A);                                                                                                 //方向為正定時器向上計數
              197.                 if(direction_A==1)        save_Ecoder_A=(Code_val_A>last_Code_val_A?last_Code_val_A+65535-Code_val_A:last_Code_val_A-Code_val_A);                                                                                                        //方向為反轉代表計數器是向下計數                       
              198.                 if(direction_B==0)  save_Ecoder_B=(Code_val_B>=last_Code_val_B?Code_val_B-last_Code_val_B:Code_val_B+65535-last_Code_val_B);                                                                                                 //方向為正定時器向上計數
              199.                 if(direction_B==1)        save_Ecoder_B=(Code_val_B>last_Code_val_B?last_Code_val_B+65535-Code_val_B:last_Code_val_B-Code_val_B);                                                                                                        //方向為反轉代表計數器是向下計數
              200.                 if(direction_C==0)  save_Ecoder_C=(Code_val_C>=last_Code_val_C?Code_val_C-last_Code_val_C:Code_val_C+65535-last_Code_val_C);                                                                                                 //方向為正定時器向上計數
              201.                 if(direction_C==1)        save_Ecoder_C=(Code_val_C>last_Code_val_C?last_Code_val_C+65535-Code_val_C:last_Code_val_C-Code_val_C);                                                                                                        //方向為反轉代表計數器是向下計數
              202.                 if(direction_D==0)  save_Ecoder_D=(Code_val_D>=last_Code_val_D?Code_val_D-last_Code_val_D:Code_val_D+65535-last_Code_val_D);                                                                                                 //方向為正定時器向上計數
              203.                 if(direction_D==1)        save_Ecoder_D=(Code_val_D>last_Code_val_D?last_Code_val_D+65535-Code_val_D:last_Code_val_D-Code_val_D);                                                                                                        //方向為反轉代表計數器是向下計數
              204.                 if(Left_Front_or_Right_rear==0)                                                        //如果小車是按照前后左右的某一個方向行駛,將ABCD四個電機進行PID控制
              205.                 {
              206.                 pwm_duth_A+=(IncPIDCalc_C(save_Ecoder_A));        //電機A的PID算法值返回
              207.                 pwm_duth_B+=(IncPIDCalc_B(save_Ecoder_B));        //電機B的PID算法值返回
              208.                 pwm_duth_C+=(IncPIDCalc_C(save_Ecoder_C));        //電機C的PID算法值返回
              209.                 pwm_duth_D+=(IncPIDCalc_D(save_Ecoder_D));        //電機D的PID算法值返回
              210.                 }
              211.                 if(Left_Front_or_Right_rear==1)                                                                        //電機向左前或者右后行駛
              212.                 {
              213.                         pwm_duth_A+=(IncPIDCalc_C(save_Ecoder_A));                //就只進行電機AC的PID算法,不進行電機BD的算法
              214.                         pwm_duth_C+=(IncPIDCalc_C(save_Ecoder_C));                //就只進行電機AC的PID算法,不進行電機BD的算法
              215.                 }                       
              216.                 if(Left_Front_or_Right_rear==2)                                                                        //電機向右前或者左后行駛
              217.                 {
              218.                         pwm_duth_B+=(IncPIDCalc_B(save_Ecoder_B));                //就只進行電機BD的PID算法,不進行電機AC的PID算法
              219.                         pwm_duth_D+=(IncPIDCalc_D(save_Ecoder_D));                //就只進行電機BD的PID算法,不進行電機AC的PID算法
              220.                 }
              221.                 if(pwm_duth_A<0) pwm_duth_A=-pwm_duth_A;                                //處理電機A,當PWM值為負時變為正
              222.                 if(pwm_duth_B<0) pwm_duth_B=-pwm_duth_B;                                //處理電機B,當PWM值為負時變為正
              223.                 if(pwm_duth_C<0) pwm_duth_C=-pwm_duth_C;                                //處理電機C,當PWM值為負時變為正       
              224.                 if(pwm_duth_D<0) pwm_duth_D=-pwm_duth_D;                                //處理電機D,當PWM值為負時變為正
              225.                 if(pwm_duth_A>=7199)        pwm_duth_A=7200*4/6;                        //限制電機A的速度為最大占空比的百分之六十六
              226.                 if(pwm_duth_B>=7199)        pwm_duth_B=7200*4/6;                        //限制電機B的速度為最大占空比的百分之六十六                               
              227.                 if(pwm_duth_C>=7199)        pwm_duth_C=7200*4/6;                        //限制電機C的速度為最大占空比的百分之六十六
              228.                 if(pwm_duth_D>=7199)        pwm_duth_D=7200*4/6;                        //限制電機D的速度為最大占空比的百分之六十六
              229.                 Set_compare(motor_A,pwm_duth_A);                                                                //將電機A經過PID算法之后得到的PWM賦給電機,讓電機真正的按照目標運行起來
              230.                 Set_compare(motor_B,pwm_duth_B);                                                                //將電機B經過PID算法之后得到的PWM賦給電機,讓電機真正的按照目標運行起來
              231.                 Set_compare(motor_C,pwm_duth_C);                                                                //將電機C經過PID算法之后得到的PWM賦給電機,讓電機真正的按照目標運行起來
              232.                 Set_compare(motor_D,pwm_duth_D);                                                                //將電機D經過PID算法之后得到的PWM賦給電機,讓電機真正的按照目標運行起來
              233.                 last_Code_val_A=Code_val_A;                                                                                        //保存電機A的編碼值,便于進行脈沖值的計算
              234.                 last_Code_val_B=Code_val_B;                                                                                        //保存電機B的編碼值,便于進行脈沖值的計算
              235.                 last_Code_val_C=Code_val_C;                                                                                        //保存電機C的編碼值,便于進行脈沖值的計算
              236.                 last_Code_val_D=Code_val_D;                                                                                        //保存電機D的編碼值,便于進行脈沖值的計算

              237.                 }
              238.         }
              239. }




              240. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
              241. {
              242.         if(huart->Instance==USART1)                                                                                                                        //判斷是不是串口1接收完成
              243.         {
              244. //                        HAL_UART_Receive_IT(&huart1,RX_buff,8);
              245.         }
              246.         if(huart->Instance==USART2)                                                                                                                        //判斷是否是串口2接收完成
              247.         {

              248.                 HAL_UART_Transmit_DMA(&huart2,RX_buff,5);                                                //DMA發送數據
              249.         }
              250. }
              251. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)                        //發送完成回調函數
              252. {
              253.         if(huart->Instance==USART2)
              254.         {
              255.                 HAL_UART_Receive_DMA(&huart2,RX_buff,5);                                                                //使能DMA接收數據
              256.         }
              257. }
              258. /* USER CODE END 4 */

              259. /**
              260.   * @brief  This function is executed in case of error occurrence.
              261.   * @retval None
              262.   */
              263. void Error_Handler(void)
              264. {
              265.   /* USER CODE BEGIN Error_Handler_Debug */
              266.   /* User can add his own implementation to report the HAL error return state */

              267.   /* USER CODE END Error_Handler_Debug */
              268. }

              269. #ifdef  USE_FULL_ASSERT
              270. /**
              271.   * @brief  Reports the name of the source file and the source line number
              272.   *         where the assert_param error has occurred.
              273.   * @param  file: pointer to the source file name
              274.   * @param  line: assert_param error line source number
              275.   * @retval None
              276.   */
              277. void assert_failed(uint8_t *file, uint32_t line)
              278. {
              279.   /* USER CODE BEGIN 6 */
              280.   /* User can add his own implementation to report the file name and line number,
              281.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
              282.   /* USER CODE END 6 */
              283. }
              284. #endif /* USE_FULL_ASSERT */

              285. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
              復制代碼

              所有資料51hei提供下載:
              藍牙+PID控制的小車.7z (264.82 KB, 下載次數: 91)

              回復

              使用道具 舉報

              ID:1 發表于 2019-7-30 23:28 | 顯示全部樓層
              本帖需要重新編輯補全電路原理圖,源碼,詳細說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
              回復

              使用道具 舉報

              ID:584531 發表于 2019-8-17 14:45 | 顯示全部樓層
              膜拜大佬
              回復

              使用道具 舉報

              ID:80689 發表于 2019-9-28 20:37 | 顯示全部樓層
              資料注釋很詳細!贊!!
              回復

              使用道具 舉報

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

              本版積分規則

              小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

              Powered by 單片機教程網

              快速回復 返回頂部 返回列表
              主站蜘蛛池模板: 午夜精品 | 亚洲欧美综合精品久久成人 | 亚洲欧美一区二区三区国产精品 | 天天干干| 国产大片黄色 | 欧美精品一区二区三区四区五区 | caoporn视频在线 | 成人国产精品久久 | 成人精品久久日伦片大全免费 | 精品久久久一区二区 | 免费看欧美一级片 | 成人在线中文字幕 | 久久夜夜 | 久久91av| 激情欧美日韩一区二区 | 国产激情一区二区三区 | 91国内精精品久久久久久婷婷 | 国产一区二区三区四区在线观看 | 91在线视频播放 | 色婷婷综合久久久中字幕精品久久 | 日韩男人天堂 | 精品av| 四虎影 | 能看的av | 亚洲一区二区在线播放 | 美国十次成人欧美色导视频 | 毛片片 | 亚洲一区中文字幕在线观看 | 男女啪啪高潮无遮挡免费动态 | 久久69精品久久久久久国产越南 | 日韩国产一区二区三区 | 欧美1区2区| 天天色影视综合 | 国产日韩欧美一区 | 国产精品一区二区视频 | 日韩在线免费电影 | 久久久久久久久久久久久久国产 | 欧美一区二区三区高清视频 | 精品久久久久一区二区国产 | 日韩欧美久久精品 | 亚洲欧美成人在线 |