训练营PLSR题目
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

604 行
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. PulseStart();
  283. HAL_TIM_Base_Start_IT(&htim3); /* 启动定时器3和中断 */
  284. }
  285. else if (Register_L[0x3000] == 0x02 && EN == 0)
  286. {
  287. EN = 1;
  288. }
  289. ModbusSaveSRAM();
  290. OSTimeDly(10, OS_OPT_TIME_DLY, &err); // 延时 10 个节拍
  291. }
  292. }
  293. /**
  294. * @brief 任务3,脉冲方向输出
  295. * @return 无
  296. */
  297. void DirOutput(void *p_arg)
  298. {
  299. p_arg = p_arg;
  300. OS_ERR err;
  301. while(1)
  302. {
  303. /* 根据当前的方向和输出的方向的端口进行输出的配置 */
  304. if (Options.DirPost == 0)
  305. {
  306. if (Options.Dir == 1)
  307. {
  308. HAL_GPIO_WritePin(GPIOH, Y12_Pin, GPIO_PIN_SET);
  309. }
  310. else
  311. {
  312. HAL_GPIO_WritePin(GPIOH, Y12_Pin, GPIO_PIN_RESET);
  313. }
  314. }
  315. if (Options.DirPost == 1)
  316. {
  317. if (Options.Dir == 1)
  318. {
  319. HAL_GPIO_WritePin(GPIOH, Y13_Pin, GPIO_PIN_SET);
  320. }
  321. else
  322. {
  323. HAL_GPIO_WritePin(GPIOH, Y13_Pin, GPIO_PIN_RESET);
  324. }
  325. }
  326. if (Options.DirPost == 2)
  327. {
  328. if (Options.Dir == 1)
  329. {
  330. HAL_GPIO_WritePin(GPIOH, Y14_Pin, GPIO_PIN_SET);
  331. }
  332. else
  333. {
  334. HAL_GPIO_WritePin(GPIOH, Y14_Pin, GPIO_PIN_RESET);
  335. }
  336. }
  337. if (Options.DirPost == 3)
  338. {
  339. if (Options.Dir == 1)
  340. {
  341. HAL_GPIO_WritePin(GPIOH, Y15_Pin, GPIO_PIN_SET);
  342. }
  343. else
  344. {
  345. HAL_GPIO_WritePin(GPIOH, Y15_Pin, GPIO_PIN_RESET);
  346. }
  347. }
  348. /* 预留时间给其他任务 */
  349. OSTimeDly(100, OS_OPT_TIME_DLY, &err); // 延时 100 个节拍
  350. }
  351. }
  352. /**
  353. * @brief 任务4,脉冲计数
  354. * @return 无
  355. */
  356. void PulseGetCount(void *p_arg)
  357. {
  358. p_arg = p_arg;
  359. OS_ERR err;
  360. while(1)
  361. {
  362. /* 根据当前脉冲的方向设置输出的方向 */
  363. if(PulseOutput[NowPulse].PulseCount < 0)
  364. {
  365. Options.Dir = 1;
  366. }
  367. else
  368. {
  369. Options.Dir = 0;
  370. }
  371. if(TIM2->CNT != 0)
  372. {
  373. if (Options.Dir == 1)
  374. {
  375. CNT_Only[NowPulse] = 0 - (TIM2->CNT);
  376. }
  377. else if (Options.Dir == 0)
  378. {
  379. CNT_Only[NowPulse] = TIM2->CNT;
  380. }
  381. }
  382. AllPulseCNT = CNT_Only[0] + CNT_Only[1] + CNT_Only[2] + CNT_Only[3] +
  383. CNT_Only[4] + CNT_Only[5] + CNT_Only[6] + CNT_Only[7] +
  384. CNT_Only[8] + CNT_Only[9];
  385. CountSave();
  386. OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  387. }
  388. }
  389. /**
  390. * @brief 任务4,EXT
  391. * @return 无
  392. */
  393. void EXTSet(void *p_arg)
  394. {
  395. p_arg = p_arg;
  396. OS_ERR err;
  397. uint8_t X4_Sta, X5_Sta;
  398. while(1)
  399. {
  400. if(HAL_GPIO_ReadPin(GPIOB, X4_Pin) == GPIO_PIN_SET)
  401. {
  402. OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  403. if(HAL_GPIO_ReadPin(GPIOB, X4_Pin) == GPIO_PIN_SET)
  404. {
  405. X4_Sta = 1;
  406. }
  407. }
  408. if(HAL_GPIO_ReadPin(GPIOB, X5_Pin) == GPIO_PIN_RESET)
  409. {
  410. OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  411. if(HAL_GPIO_ReadPin(GPIOB, X5_Pin) == GPIO_PIN_RESET)
  412. {
  413. X5_Sta = 1;
  414. }
  415. }
  416. if(X4_Sta == 1 && Options.EXT == 0)
  417. {
  418. EXT_Flag = 1;
  419. X4_Sta = 0;
  420. }
  421. if(X5_Sta == 1 && Options.EXT == 1)
  422. {
  423. EXT_Flag = 1;
  424. X5_Sta = 0;
  425. }
  426. if(EXT_Flag == 1)
  427. {
  428. EXT_Flag = 0;
  429. HAL_TIM_GenerateEvent(&htim2, TIM_EVENTSOURCE_UPDATE);
  430. }
  431. OSTimeDly(100, OS_OPT_TIME_DLY, &err);
  432. }
  433. }
  434. /**
  435. * @brief 定时器中断回调函数,用来实现脉冲加减速(定时时间1ms)
  436. * @return 无
  437. */
  438. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  439. {
  440. if (htim == (&htim3))
  441. {
  442. if (ArrFlag == 1)
  443. {
  444. /* 脉冲加速 */
  445. if (Acc > 0)
  446. {
  447. if (ArrTimes <= Options.AccUpTime)
  448. {
  449. SetFrequency(Options.SentPost, PulseOutput[PrePulse].Frequency + ArrTimes * Acc);
  450. if(ArrTimes == 0) PulseStart(); /* 开始产生脉冲 */
  451. ArrTimes++;
  452. }
  453. else
  454. {
  455. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  456. ArrTimes = 0;
  457. ArrFlag = 0;
  458. HAL_TIM_Base_Stop_IT(&htim3); // 停止定时器并禁用中断
  459. }
  460. }
  461. /* 脉冲减速 */
  462. else if (Acc <= 0)
  463. {
  464. if (ArrTimes <= Options.AccDownTime)
  465. {
  466. SetFrequency(Options.SentPost, PulseOutput[PrePulse].Frequency + ArrTimes * Acc);
  467. if (ArrTimes == 0) PulseStart(); /* 开始产生脉冲 */
  468. ArrTimes++;
  469. }
  470. else
  471. {
  472. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  473. ArrTimes = 0;
  474. ArrFlag = 0;
  475. HAL_TIM_Base_Stop_IT(&htim3); // 停止定时器并禁用中断
  476. }
  477. }
  478. }
  479. /* 第一段脉冲的加速 */
  480. if (NowPulse == Options.StartPulse && PulseStartFlag == 1)
  481. {
  482. Acc = PulseOutput[NowPulse].Frequency / Options.AccUpTime;/* 计算加速度 */
  483. if(ArrTimes <= Options.AccUpTime)
  484. {
  485. ArrTimes++;
  486. SetFrequency(Options.SentPost, ArrTimes * Acc);
  487. if (ArrTimes == 1) PulseStart(); /* 开始产生脉冲 */
  488. }
  489. else
  490. {
  491. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  492. HAL_TIM_Base_Stop_IT(&htim3); // 停止定时器并禁用中断
  493. PulseStartFlag = 0;
  494. ArrTimes = 0;
  495. }
  496. }
  497. /* 最后一段脉冲的减速 */
  498. if(Options.AllPulse == PulseNum)
  499. {
  500. Acc = - PulseOutput[NowPulse].Frequency / Options.AccUpTime;/* 计算加速度 */
  501. /* 思路: 在中断内计算正常情况下减速时间对应多少脉冲,在给最后一段脉冲赋值时减去对应的值,同时使能减速标志位
  502. 在此函数内实现最后一段脉冲的减速过程。 */
  503. }
  504. }
  505. }
  506. /* USER CODE END 4 */
  507. /**
  508. * @brief This function is executed in case of error occurrence.
  509. * @retval None
  510. */
  511. void Error_Handler(void)
  512. {
  513. /* USER CODE BEGIN Error_Handler_Debug */
  514. /* User can add his own implementation to report the HAL error return state */
  515. __disable_irq();
  516. while (1)
  517. {
  518. }
  519. /* USER CODE END Error_Handler_Debug */
  520. }
  521. #ifdef USE_FULL_ASSERT
  522. /**
  523. * @brief Reports the name of the source file and the source line number
  524. * where the assert_param error has occurred.
  525. * @param file: pointer to the source file name
  526. * @param line: assert_param error line source number
  527. * @retval None
  528. */
  529. void assert_failed(uint8_t *file, uint32_t line)
  530. {
  531. /* USER CODE BEGIN 6 */
  532. /* User can add his own implementation to report the file name and line number,
  533. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  534. /* USER CODE END 6 */
  535. }
  536. #endif /* USE_FULL_ASSERT */