训练营PLSR题目
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

618 righe
17 KiB

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2025 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "dma.h"
  22. #include "tim.h"
  23. #include "usart.h"
  24. #include "gpio.h"
  25. /* Private includes ----------------------------------------------------------*/
  26. /* USER CODE BEGIN Includes */
  27. #include "PLSR.h"
  28. #include "includes.h"
  29. #include "modbus.h"
  30. #include "bitset.h"
  31. /* USER CODE END Includes */
  32. /* Private typedef -----------------------------------------------------------*/
  33. /* USER CODE BEGIN PTD */
  34. uint8_t ArrFlag = 0; /* 加速度Flag */
  35. float Acc; /* 加速度 */
  36. int32_t AllPulseCNT = 0;
  37. int32_t BaseCNT = 0;
  38. int32_t CNT_Only[10] = {0};
  39. uint8_t EXT_Flag = 0;
  40. uint8_t PulseStartFlag = 0;
  41. uint8_t ArrTimes = 0;
  42. extern uint8_t Register_H[16384]; ///<寄存器的高字节
  43. extern uint8_t Register_L[16384]; ///<寄存器的低字节
  44. /* USER CODE END PTD */
  45. /* Private define ------------------------------------------------------------*/
  46. /* USER CODE BEGIN PD */
  47. /* USER CODE END PD */
  48. /* Private macro -------------------------------------------------------------*/
  49. /* USER CODE BEGIN PM */
  50. /* USER CODE END PM */
  51. /* Private variables ---------------------------------------------------------*/
  52. /* USER CODE BEGIN PV */
  53. /* USER CODE END PV */
  54. /* Private function prototypes -----------------------------------------------*/
  55. void SystemClock_Config(void);
  56. /* USER CODE BEGIN PFP */
  57. /* USER CODE END PFP */
  58. /* Private user code ---------------------------------------------------------*/
  59. /* USER CODE BEGIN 0 */
  60. /* 任务优先级 */
  61. #define TASK_Y1Direction 6
  62. #define TASK_PulseStart 5
  63. #define TASK_DirOutput 6
  64. #define TASK_PulseGetCount 5
  65. #define TASK_EXTSet 6
  66. /* 任务堆栈大小 */
  67. #define Task_Y1Direction_SIZE 256
  68. #define Task_PulseStart_SIZE 512
  69. #define Task_DirOutput_SIZE 256
  70. #define Task_PulseGetCount_SIZE 256
  71. #define Task_EXTSet_SIZE 256
  72. /* 任务控制块 */
  73. OS_TCB Y1Direction_Tsk;
  74. OS_TCB PulseStart_Tsk;
  75. OS_TCB DirOutput_Tsk;
  76. OS_TCB PulseGetCount_Tsk;
  77. OS_TCB EXTSet_Tsk;
  78. /* 任务栈 */
  79. CPU_STK Task_Y1Direction_STK[Task_Y1Direction_SIZE];
  80. CPU_STK Task_PulseStart_STK[Task_PulseStart_SIZE];
  81. CPU_STK Task_DirOutput_STK[Task_DirOutput_SIZE];
  82. CPU_STK Task_PulseGetCount_STK[Task_PulseGetCount_SIZE];
  83. CPU_STK Task_EXTSet_STK[Task_EXTSet_SIZE];
  84. /* 任务函数 */
  85. void Y1Direction(void *p_arg);
  86. void PulseStartTsk(void *p_arg);
  87. void DirOutput(void *p_arg);
  88. void PulseGetCount(void *p_arg);
  89. void EXTSet(void *p_arg);
  90. /* USER CODE END 0 */
  91. /**
  92. * @brief The application entry point.
  93. * @retval int
  94. */
  95. int main(void)
  96. {
  97. /* USER CODE BEGIN 1 */
  98. OS_ERR err;
  99. /* USER CODE END 1 */
  100. /* MCU Configuration--------------------------------------------------------*/
  101. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  102. HAL_Init();
  103. /* USER CODE BEGIN Init */
  104. /* USER CODE END Init */
  105. /* Configure the system clock */
  106. SystemClock_Config();
  107. /* USER CODE BEGIN SysInit */
  108. HAL_PWR_EnableBkUpAccess();/* 使能备份域访问 */
  109. __HAL_RCC_BKPSRAM_CLK_ENABLE();/* 使能备份SRAM时钟 */
  110. HAL_PWREx_EnableBkUpReg();/* 使能备份SRAM */
  111. /* USER CODE END SysInit */
  112. /* Initialize all configured peripherals */
  113. MX_GPIO_Init();
  114. MX_DMA_Init();
  115. MX_USART1_UART_Init();
  116. MX_TIM10_Init();
  117. MX_TIM2_Init();
  118. MX_TIM11_Init();
  119. MX_TIM13_Init();
  120. MX_TIM14_Init();
  121. MX_TIM3_Init();
  122. /* USER CODE BEGIN 2 */
  123. BSP_Init();
  124. OSInit(&err);
  125. CPU_SR_ALLOC();
  126. CPU_CRITICAL_ENTER();///进入临界区
  127. /* 任务1 */
  128. OSTaskCreate((OS_TCB * )&Y1Direction_Tsk, /* 任务控制块 */
  129. (CPU_CHAR* )"Y1Direction", /* 任务名字 */
  130. (OS_TASK_PTR)Y1Direction, /* 任务函数 */
  131. (void * )0, /* 传递给任务函数的参数 */
  132. (OS_PRIO )TASK_Y1Direction, /* 任务优先级 */
  133. (CPU_STK * )&Task_Y1Direction_STK[0], /* 任务堆栈基地址 */
  134. (CPU_STK_SIZE)Task_Y1Direction_SIZE/10, /* 任务堆栈深度限位 */
  135. (CPU_STK_SIZE)Task_Y1Direction_SIZE, /* 任务堆栈大小 */
  136. (OS_MSG_QTY)0, /* 任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息 */
  137. (OS_TICK )0, /* 当使能时间片轮转时的时间片长度,为0时为默认长度 */
  138. (void * )0, /* 用户补充的存储区 */
  139. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, /* 任务选项 */
  140. (OS_ERR * )&err); /* 存放该函数错误时的返回值 */
  141. /* 任务2 */
  142. OSTaskCreate((OS_TCB * )&PulseStart_Tsk,
  143. (CPU_CHAR* )"PulseStartTsk",
  144. (OS_TASK_PTR)PulseStartTsk,
  145. (void * )0,
  146. (OS_PRIO )TASK_PulseStart,
  147. (CPU_STK * )&Task_PulseStart_STK[0],
  148. (CPU_STK_SIZE)Task_PulseStart_SIZE/10,
  149. (CPU_STK_SIZE)Task_PulseStart_SIZE,
  150. (OS_MSG_QTY)0,
  151. (OS_TICK )0,
  152. (void * )0,
  153. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  154. (OS_ERR * )&err);
  155. /* 任务3 */
  156. OSTaskCreate((OS_TCB * )&DirOutput_Tsk,
  157. (CPU_CHAR* )"DirOutput_Tsk",
  158. (OS_TASK_PTR)DirOutput,
  159. (void * )0,
  160. (OS_PRIO )TASK_DirOutput,
  161. (CPU_STK * )&Task_DirOutput_STK[0],
  162. (CPU_STK_SIZE)Task_DirOutput_SIZE/10,
  163. (CPU_STK_SIZE)Task_DirOutput_SIZE,
  164. (OS_MSG_QTY)0,
  165. (OS_TICK )0,
  166. (void * )0,
  167. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  168. (OS_ERR * )&err);
  169. /* 任务4 */
  170. OSTaskCreate((OS_TCB * )&PulseGetCount_Tsk,
  171. (CPU_CHAR* )"PulseGetCount_Tsk",
  172. (OS_TASK_PTR)PulseGetCount,
  173. (void * )0,
  174. (OS_PRIO )TASK_PulseGetCount,
  175. (CPU_STK * )&Task_PulseGetCount_STK[0],
  176. (CPU_STK_SIZE)Task_PulseGetCount_SIZE/10,
  177. (CPU_STK_SIZE)Task_PulseGetCount_SIZE,
  178. (OS_MSG_QTY)0,
  179. (OS_TICK )0,
  180. (void * )0,
  181. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  182. (OS_ERR * )&err);
  183. /* 任务5 */
  184. OSTaskCreate((OS_TCB * )&EXTSet_Tsk,
  185. (CPU_CHAR* )"EXTSet_Tsk",
  186. (OS_TASK_PTR)EXTSet,
  187. (void * )0,
  188. (OS_PRIO )TASK_EXTSet,
  189. (CPU_STK * )&Task_EXTSet_STK[0],
  190. (CPU_STK_SIZE)Task_EXTSet_SIZE/10,
  191. (CPU_STK_SIZE)Task_EXTSet_SIZE,
  192. (OS_MSG_QTY)0,
  193. (OS_TICK )0,
  194. (void * )0,
  195. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  196. (OS_ERR * )&err);
  197. /* 掉电数据读取 */
  198. ModbusLoadSRAM();
  199. CPU_CRITICAL_EXIT() ; ///退出临界区
  200. OSStart(&err);
  201. /* USER CODE END 2 */
  202. /* Infinite loop */
  203. /* USER CODE BEGIN WHILE */
  204. while (1)
  205. {
  206. /* USER CODE END WHILE */
  207. /* USER CODE BEGIN 3 */
  208. }
  209. /* USER CODE END 3 */
  210. }
  211. /**
  212. * @brief System Clock Configuration
  213. * @retval None
  214. */
  215. void SystemClock_Config(void)
  216. {
  217. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  218. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  219. /** Configure the main internal regulator output voltage
  220. */
  221. __HAL_RCC_PWR_CLK_ENABLE();
  222. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  223. /** Initializes the RCC Oscillators according to the specified parameters
  224. * in the RCC_OscInitTypeDef structure.
  225. */
  226. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  227. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  228. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  229. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  230. RCC_OscInitStruct.PLL.PLLM = 6;
  231. RCC_OscInitStruct.PLL.PLLN = 72;
  232. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  233. RCC_OscInitStruct.PLL.PLLQ = 4;
  234. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  235. {
  236. Error_Handler();
  237. }
  238. /** Initializes the CPU, AHB and APB buses clocks
  239. */
  240. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  241. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  242. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  243. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  244. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  245. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  246. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  247. {
  248. Error_Handler();
  249. }
  250. }
  251. /* USER CODE BEGIN 4 */
  252. /**
  253. * @brief 任务1, 脉冲加减速
  254. * @return 无
  255. */
  256. void Y1Direction(void *p_arg)
  257. {
  258. p_arg = p_arg;
  259. OS_ERR err;
  260. while(1)
  261. {
  262. OSTimeDly(100, OS_OPT_TIME_DLY, &err); // 延时 100 个节拍
  263. }
  264. }
  265. /**
  266. * @brief 任务2,脉冲开始,数据处理
  267. * @return 无
  268. */
  269. void PulseStartTsk(void *p_arg)
  270. {
  271. p_arg = p_arg;
  272. OS_ERR err;
  273. uint8_t EN = 1;
  274. while(1)
  275. {
  276. PLSRPluseLoad(); //读取脉冲设置
  277. PLSROptionLoad(); //读取脉冲基础设置
  278. if (Register_L[0x3000] == 0x01 && EN == 1)
  279. {
  280. EN = 0;
  281. PulseStartFlag = 1;
  282. //NowFrequeny = PulseOutput[NowPulse].Frequency; /* 保存当前脉冲的频率 */
  283. PulseStart();
  284. HAL_TIM_Base_Start_IT(&htim3); /* 启动定时器3和中断 */
  285. }
  286. else if (Register_L[0x3000] == 0x02 && EN == 0)
  287. {
  288. EN = 1;
  289. }
  290. ModbusSaveSRAM();
  291. OSTimeDly(10, OS_OPT_TIME_DLY, &err); // 延时 10 个节拍
  292. }
  293. }
  294. /**
  295. * @brief 任务3,脉冲方向输出
  296. * @return 无
  297. */
  298. void DirOutput(void *p_arg)
  299. {
  300. p_arg = p_arg;
  301. OS_ERR err;
  302. while(1)
  303. {
  304. /* 根据当前的方向和输出的方向的端口进行输出的配置 */
  305. if (Options.DirPost == 0)
  306. {
  307. if (Options.Dir == 1)
  308. {
  309. HAL_GPIO_WritePin(GPIOH, Y12_Pin, GPIO_PIN_SET);
  310. }
  311. else
  312. {
  313. HAL_GPIO_WritePin(GPIOH, Y12_Pin, GPIO_PIN_RESET);
  314. }
  315. }
  316. if (Options.DirPost == 1)
  317. {
  318. if (Options.Dir == 1)
  319. {
  320. HAL_GPIO_WritePin(GPIOH, Y13_Pin, GPIO_PIN_SET);
  321. }
  322. else
  323. {
  324. HAL_GPIO_WritePin(GPIOH, Y13_Pin, GPIO_PIN_RESET);
  325. }
  326. }
  327. if (Options.DirPost == 2)
  328. {
  329. if (Options.Dir == 1)
  330. {
  331. HAL_GPIO_WritePin(GPIOH, Y14_Pin, GPIO_PIN_SET);
  332. }
  333. else
  334. {
  335. HAL_GPIO_WritePin(GPIOH, Y14_Pin, GPIO_PIN_RESET);
  336. }
  337. }
  338. if (Options.DirPost == 3)
  339. {
  340. if (Options.Dir == 1)
  341. {
  342. HAL_GPIO_WritePin(GPIOH, Y15_Pin, GPIO_PIN_SET);
  343. }
  344. else
  345. {
  346. HAL_GPIO_WritePin(GPIOH, Y15_Pin, GPIO_PIN_RESET);
  347. }
  348. }
  349. /* 预留时间给其他任务 */
  350. OSTimeDly(100, OS_OPT_TIME_DLY, &err); // 延时 100 个节拍
  351. }
  352. }
  353. /**
  354. * @brief 任务4,脉冲计数
  355. * @return 无
  356. */
  357. void PulseGetCount(void *p_arg)
  358. {
  359. p_arg = p_arg;
  360. OS_ERR err;
  361. while(1)
  362. {
  363. /* 根据当前脉冲的方向设置输出的方向 */
  364. if(PulseOutput[NowPulse].PulseCount < 0)
  365. {
  366. Options.Dir = 1;
  367. }
  368. else
  369. {
  370. Options.Dir = 0;
  371. }
  372. if (TIM2->CNT != 0) CNT_Only[NowPulse] = TIM2->CNT;
  373. AllPulseCNT = CNT_Only[0] + CNT_Only[1] + CNT_Only[2] + CNT_Only[3] +
  374. CNT_Only[4] + CNT_Only[5] + CNT_Only[6] + CNT_Only[7] +
  375. CNT_Only[8] + CNT_Only[9];
  376. CountSave();
  377. OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  378. }
  379. }
  380. /**
  381. * @brief 任务5,EXT
  382. * @return 无
  383. */
  384. void EXTSet(void *p_arg)
  385. {
  386. p_arg = p_arg;
  387. OS_ERR err;
  388. uint8_t X4_Sta, X5_Sta;
  389. while(1)
  390. {
  391. if(HAL_GPIO_ReadPin(GPIOB, X4_Pin) == GPIO_PIN_SET)
  392. {
  393. OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  394. if(HAL_GPIO_ReadPin(GPIOB, X4_Pin) == GPIO_PIN_SET)
  395. {
  396. X4_Sta = 1;
  397. while(HAL_GPIO_ReadPin(GPIOB, X4_Pin) == GPIO_PIN_SET);
  398. }
  399. }
  400. if(HAL_GPIO_ReadPin(GPIOG, X5_Pin) == GPIO_PIN_SET)
  401. {
  402. OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  403. if(HAL_GPIO_ReadPin(GPIOG, X5_Pin) == GPIO_PIN_SET)
  404. {
  405. X5_Sta = 1;
  406. while(HAL_GPIO_ReadPin(GPIOG, X5_Pin) == GPIO_PIN_SET);
  407. }
  408. }
  409. /* X4引脚的EXT信号 */
  410. if(X4_Sta == 1 && Options.EXT == 0 && PulseOutput[NowPulse].EXT == 1)
  411. {
  412. if (TIM2->CNT != 0) CNT_Only[NowPulse] = TIM2->CNT; /* 保存当前的脉冲计数 */
  413. TIM2->CNT = TIM2->ARR - 1;
  414. EXT_Flag = 1;
  415. X4_Sta = 0;
  416. }
  417. else
  418. {
  419. X4_Sta = 0;
  420. }
  421. /* X5引脚的EXT信号 */
  422. if(X5_Sta == 1 && Options.EXT == 1 && PulseOutput[NowPulse].EXT == 1)
  423. {
  424. if (TIM2->CNT != 0) CNT_Only[NowPulse] = TIM2->CNT; /* 保存当前的脉冲计数 */
  425. TIM2->CNT = TIM2->ARR - 1;
  426. EXT_Flag = 1;
  427. X5_Sta = 0;
  428. }
  429. else
  430. {
  431. X5_Sta = 0;
  432. }
  433. if(EXT_Flag == 1)
  434. {
  435. EXT_Flag = 0;
  436. HAL_TIM_GenerateEvent(&htim2, TIM_EVENTSOURCE_UPDATE);
  437. }
  438. OSTimeDly(100, OS_OPT_TIME_DLY, &err);
  439. }
  440. }
  441. /**
  442. * @brief 定时器中断回调函数,用来实现脉冲加减速(定时时间1ms)
  443. * @return 无
  444. */
  445. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  446. {
  447. //OSIntEnter(); /* 进入中断 */
  448. if (htim == (&htim3))
  449. {
  450. if (ArrFlag == 1)
  451. {
  452. /* 脉冲加速 */
  453. if (Acc > 0)
  454. {
  455. if (ArrTimes <= Options.AccUpTime)
  456. {
  457. SetFrequency(Options.SentPost, PulseOutput[PrePulse].Frequency + ArrTimes * Acc);
  458. if(ArrTimes == 0) PulseStart(); /* 开始产生脉冲 */
  459. ArrTimes++;
  460. }
  461. else
  462. {
  463. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  464. ArrTimes = 0;
  465. ArrFlag = 0;
  466. HAL_TIM_Base_Stop_IT(&htim3); // 停止定时器并禁用中断
  467. }
  468. }
  469. /* 脉冲减速 */
  470. else if (Acc <= 0)
  471. {
  472. if (ArrTimes <= Options.AccDownTime)
  473. {
  474. SetFrequency(Options.SentPost, PulseOutput[PrePulse].Frequency + ArrTimes * Acc);
  475. if (ArrTimes == 0) PulseStart(); /* 开始产生脉冲 */
  476. ArrTimes++;
  477. }
  478. else
  479. {
  480. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  481. ArrTimes = 0;
  482. ArrFlag = 0;
  483. HAL_TIM_Base_Stop_IT(&htim3); // 停止定时器并禁用中断
  484. }
  485. }
  486. }
  487. /* 第一段脉冲的加速 */
  488. if (NowPulse == Options.StartPulse && PulseStartFlag == 1)
  489. {
  490. Acc = PulseOutput[NowPulse].Frequency / Options.AccUpTime;/* 计算加速度 */
  491. if(ArrTimes <= Options.AccUpTime)
  492. {
  493. ArrTimes++;
  494. SetFrequency(Options.SentPost, ArrTimes * Acc);
  495. if (ArrTimes == 1) PulseStart(); /* 开始产生脉冲 */
  496. }
  497. else
  498. {
  499. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  500. HAL_TIM_Base_Stop_IT(&htim3); // 停止定时器并禁用中断
  501. PulseStartFlag = 0;
  502. ArrTimes = 0;
  503. }
  504. }
  505. /* 最后一段脉冲的减速 */
  506. if(Options.AllPulse == PulseNum)
  507. {
  508. Acc = - PulseOutput[NowPulse].Frequency / Options.AccUpTime;/* 计算加速度 */
  509. /* 思路: 在中断内计算正常情况下减速时间对应多少脉冲,在给最后一段脉冲赋值时减去对应的值,同时使能减速标志位
  510. 在此函数内实现最后一段脉冲的减速过程。 */
  511. }
  512. }
  513. //OSIntExit(); /* 退出中断 */
  514. }
  515. /* USER CODE END 4 */
  516. /**
  517. * @brief This function is executed in case of error occurrence.
  518. * @retval None
  519. */
  520. void Error_Handler(void)
  521. {
  522. /* USER CODE BEGIN Error_Handler_Debug */
  523. /* User can add his own implementation to report the HAL error return state */
  524. __disable_irq();
  525. while (1)
  526. {
  527. }
  528. /* USER CODE END Error_Handler_Debug */
  529. }
  530. #ifdef USE_FULL_ASSERT
  531. /**
  532. * @brief Reports the name of the source file and the source line number
  533. * where the assert_param error has occurred.
  534. * @param file: pointer to the source file name
  535. * @param line: assert_param error line source number
  536. * @retval None
  537. */
  538. void assert_failed(uint8_t *file, uint32_t line)
  539. {
  540. /* USER CODE BEGIN 6 */
  541. /* User can add his own implementation to report the file name and line number,
  542. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  543. /* USER CODE END 6 */
  544. }
  545. #endif /* USE_FULL_ASSERT */