训练营PLSR题目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

545 regels
15 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 AccITCount = 0;
  40. uint8_t PulseStartFlag = 0;
  41. extern uint8_t Register_H[16384]; ///<寄存器的高字节
  42. extern uint8_t Register_L[16384]; ///<寄存器的低字节
  43. /* USER CODE END PTD */
  44. /* Private define ------------------------------------------------------------*/
  45. /* USER CODE BEGIN PD */
  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. /* USER CODE END PV */
  53. /* Private function prototypes -----------------------------------------------*/
  54. void SystemClock_Config(void);
  55. /* USER CODE BEGIN PFP */
  56. void PVD_Init(void);
  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 6
  65. /* 任务堆栈大小 */
  66. #define Task_Y1Direction_SIZE 256
  67. #define Task_PulseStart_SIZE 512
  68. #define Task_DirOutput_SIZE 256
  69. #define Task_PulseGetCount_SIZE 256
  70. /* 任务控制块 */
  71. OS_TCB Y1Direction_Tsk;
  72. OS_TCB PulseStart_Tsk;
  73. OS_TCB DirOutput_Tsk;
  74. OS_TCB PulseGetCount_Tsk;
  75. /* 任务栈 */
  76. CPU_STK Task_Y1Direction_STK[Task_Y1Direction_SIZE];
  77. CPU_STK Task_PulseStart_STK[Task_PulseStart_SIZE];
  78. CPU_STK Task_DirOutput_STK[Task_DirOutput_SIZE];
  79. CPU_STK Task_PulseGetCount_STK[Task_PulseGetCount_SIZE];
  80. /* 任务函数 */
  81. void Y1Direction(void *p_arg);
  82. void PulseStartTsk(void *p_arg);
  83. void DirOutput(void *p_arg);
  84. void PulseGetCount(void *p_arg);
  85. /* USER CODE END 0 */
  86. /**
  87. * @brief The application entry point.
  88. * @retval int
  89. */
  90. int main(void)
  91. {
  92. /* USER CODE BEGIN 1 */
  93. OS_ERR err;
  94. /* USER CODE END 1 */
  95. /* MCU Configuration--------------------------------------------------------*/
  96. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  97. HAL_Init();
  98. /* USER CODE BEGIN Init */
  99. /* USER CODE END Init */
  100. /* Configure the system clock */
  101. SystemClock_Config();
  102. /* USER CODE BEGIN SysInit */
  103. HAL_PWR_EnableBkUpAccess();/* 使能备份域访问 */
  104. __HAL_RCC_BKPSRAM_CLK_ENABLE();/* 使能备份SRAM时钟 */
  105. HAL_PWREx_EnableBkUpReg();/* 使能备份SRAM */
  106. /* USER CODE END SysInit */
  107. /* Initialize all configured peripherals */
  108. MX_GPIO_Init();
  109. MX_DMA_Init();
  110. MX_USART1_UART_Init();
  111. MX_TIM10_Init();
  112. MX_TIM2_Init();
  113. MX_TIM11_Init();
  114. MX_TIM13_Init();
  115. MX_TIM14_Init();
  116. /* USER CODE BEGIN 2 */
  117. // PulseBaseInit(0, 0, 200);//设置为第0段脉冲开始,相对模式, 最大脉冲为0
  118. // PulseInit(0, 1, 5, 0); //第几段脉冲,频率,数量,下一段脉冲
  119. // AddPulse(1, 100, 200, 0);
  120. // AddPulse(2, 1, 55, 0);
  121. // Options.AccUpTime = 50;
  122. BSP_Init();
  123. OSInit(&err);
  124. CPU_SR_ALLOC();
  125. CPU_CRITICAL_ENTER();///进入临界区
  126. /* 任务1 */
  127. OSTaskCreate((OS_TCB * )&Y1Direction_Tsk, /* 任务控制块 */
  128. (CPU_CHAR* )"Y1Direction", /* 任务名字 */
  129. (OS_TASK_PTR)Y1Direction, /* 任务函数 */
  130. (void * )0, /* 传递给任务函数的参数 */
  131. (OS_PRIO )TASK_Y1Direction, /* 任务优先级 */
  132. (CPU_STK * )&Task_Y1Direction_STK[0], /* 任务堆栈基地址 */
  133. (CPU_STK_SIZE)Task_Y1Direction_SIZE/10, /* 任务堆栈深度限位 */
  134. (CPU_STK_SIZE)Task_Y1Direction_SIZE, /* 任务堆栈大小 */
  135. (OS_MSG_QTY)0, /* 任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息 */
  136. (OS_TICK )0, /* 当使能时间片轮转时的时间片长度,为0时为默认长度 */
  137. (void * )0, /* 用户补充的存储区 */
  138. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, /* 任务选项 */
  139. (OS_ERR * )&err); /* 存放该函数错误时的返回值 */
  140. /* 任务2 */
  141. OSTaskCreate((OS_TCB * )&PulseStart_Tsk,
  142. (CPU_CHAR* )"PulseStartTsk",
  143. (OS_TASK_PTR)PulseStartTsk,
  144. (void * )0,
  145. (OS_PRIO )TASK_PulseStart,
  146. (CPU_STK * )&Task_PulseStart_STK[0],
  147. (CPU_STK_SIZE)Task_PulseStart_SIZE/10,
  148. (CPU_STK_SIZE)Task_PulseStart_SIZE,
  149. (OS_MSG_QTY)0,
  150. (OS_TICK )0,
  151. (void * )0,
  152. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  153. (OS_ERR * )&err);
  154. /* 任务3 */
  155. OSTaskCreate((OS_TCB * )&DirOutput_Tsk,
  156. (CPU_CHAR* )"DirOutput_Tsk",
  157. (OS_TASK_PTR)DirOutput,
  158. (void * )0,
  159. (OS_PRIO )TASK_DirOutput,
  160. (CPU_STK * )&Task_DirOutput_STK[0],
  161. (CPU_STK_SIZE)Task_DirOutput_SIZE/10,
  162. (CPU_STK_SIZE)Task_DirOutput_SIZE,
  163. (OS_MSG_QTY)0,
  164. (OS_TICK )0,
  165. (void * )0,
  166. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  167. (OS_ERR * )&err);
  168. /* 任务4 */
  169. OSTaskCreate((OS_TCB * )&PulseGetCount_Tsk,
  170. (CPU_CHAR* )"PulseGetCount_Tsk",
  171. (OS_TASK_PTR)PulseGetCount,
  172. (void * )0,
  173. (OS_PRIO )TASK_PulseGetCount,
  174. (CPU_STK * )&Task_PulseGetCount_STK[0],
  175. (CPU_STK_SIZE)Task_PulseGetCount_SIZE/10,
  176. (CPU_STK_SIZE)Task_PulseGetCount_SIZE,
  177. (OS_MSG_QTY)0,
  178. (OS_TICK )0,
  179. (void * )0,
  180. (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
  181. (OS_ERR * )&err);
  182. /* 掉电数据读取 */
  183. ModbusLoadSRAM();
  184. CPU_CRITICAL_EXIT() ; ///退出临界区
  185. OSStart(&err);
  186. /* USER CODE END 2 */
  187. /* Infinite loop */
  188. /* USER CODE BEGIN WHILE */
  189. while (1)
  190. {
  191. /* USER CODE END WHILE */
  192. /* USER CODE BEGIN 3 */
  193. }
  194. /* USER CODE END 3 */
  195. }
  196. /**
  197. * @brief System Clock Configuration
  198. * @retval None
  199. */
  200. void SystemClock_Config(void)
  201. {
  202. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  203. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  204. /** Configure the main internal regulator output voltage
  205. */
  206. __HAL_RCC_PWR_CLK_ENABLE();
  207. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  208. /** Initializes the RCC Oscillators according to the specified parameters
  209. * in the RCC_OscInitTypeDef structure.
  210. */
  211. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  212. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  213. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  214. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  215. RCC_OscInitStruct.PLL.PLLM = 6;
  216. RCC_OscInitStruct.PLL.PLLN = 72;
  217. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  218. RCC_OscInitStruct.PLL.PLLQ = 4;
  219. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  220. {
  221. Error_Handler();
  222. }
  223. /** Initializes the CPU, AHB and APB buses clocks
  224. */
  225. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  226. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  227. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  228. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  229. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  230. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  231. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  232. {
  233. Error_Handler();
  234. }
  235. }
  236. /* USER CODE BEGIN 4 */
  237. /**
  238. * @brief 任务1, 脉冲加减速
  239. * @return 无
  240. */
  241. void Y1Direction(void *p_arg)
  242. {
  243. p_arg = p_arg;
  244. OS_ERR err;
  245. while(1)
  246. {
  247. /* 获取加减速所需要的脉冲数 */
  248. GetAddCount();
  249. /* 段切换时的脉冲加减速 */
  250. if (ArrFlag == 1)
  251. {
  252. /* 脉冲加速 */
  253. if (Acc > 0)
  254. {
  255. if (TIM2->CNT <= AccUpCount)
  256. {
  257. SetFrequency(Options.SentPost, PulseOutput[PrePulse].Frequency + TIM2->CNT * Acc);
  258. if (TIM2->CNT == 0) PulseStart(); /* 开始产生脉冲 */
  259. }
  260. else
  261. {
  262. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  263. ArrFlag = 0;
  264. }
  265. }
  266. /* 脉冲减速 */
  267. else if (Acc <= 0)
  268. {
  269. if (TIM2->CNT <= AccDownCount)
  270. {
  271. SetFrequency(Options.SentPost, PulseOutput[PrePulse].Frequency + TIM2->CNT * Acc);
  272. if(TIM2->CNT == 0) PulseStart(); /* 开始产生脉冲 */
  273. }
  274. else
  275. {
  276. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  277. ArrFlag = 0;
  278. }
  279. }
  280. }
  281. OSTimeDly(100, OS_OPT_TIME_DLY, &err); // 延时 100 个节拍
  282. }
  283. }
  284. /**
  285. * @brief 任务2,脉冲开始,数据处理
  286. * @return 无
  287. */
  288. void PulseStartTsk(void *p_arg)
  289. {
  290. p_arg = p_arg;
  291. OS_ERR err;
  292. uint8_t EN = 1;
  293. while(1)
  294. {
  295. PLSRPluseLoad(); //读取脉冲设置
  296. PLSROptionLoad(); //读取脉冲基础设置
  297. if(Register_L[0x3000] == 0x01 && EN == 1)
  298. {
  299. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  300. PulseStart();
  301. EN = 0;
  302. PulseStartFlag = 1;
  303. }
  304. else if(Register_L[0x3000] == 0x02 && EN == 0)
  305. {
  306. EN = 1;
  307. }
  308. ModbusSaveSRAM();
  309. /* 第一段脉冲的加速 */
  310. if (NowPulse == Options.StartPulse && PulseStartFlag == 1)
  311. {
  312. Acc = (float)PulseOutput[NowPulse].Frequency / (float)AccUpCount;/* 计算加速度 */
  313. if (AccUpCount < PulseOutput[NowPulse].PulseCount)//如果能够完成加速
  314. {
  315. if(TIM2->CNT < AccUpCount)
  316. {
  317. SetFrequency(Options.SentPost, TIM2->CNT * Acc);
  318. }
  319. else
  320. {
  321. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency);
  322. PulseStartFlag = 0;
  323. }
  324. }
  325. else //不能完成加速
  326. {
  327. }
  328. }
  329. /* 最后一段脉冲的减速 */
  330. if (NowPulse == Options.AllPulse - 1)
  331. {
  332. Acc = - (float)PulseOutput[NowPulse].Frequency / (float)AccDownCount;/* 计算加速度 */
  333. if (TIM2->CNT > PulseOutput[NowPulse].PulseCount - AccUpCount - AccDownCount) /* 当达到脉冲减速的位置开始减速 */
  334. {
  335. SetFrequency(Options.SentPost, PulseOutput[NowPulse].Frequency + TIM2->CNT * Acc);
  336. }
  337. }
  338. OSTimeDly(10, OS_OPT_TIME_DLY, &err); // 延时 10 个节拍
  339. }
  340. }
  341. /**
  342. * @brief 任务3,脉冲方向输出
  343. * @return 无
  344. */
  345. void DirOutput(void *p_arg)
  346. {
  347. p_arg = p_arg;
  348. OS_ERR err;
  349. while(1)
  350. {
  351. /* 根据当前的方向和输出的方向的端口进行输出的配置 */
  352. if (Options.DirPost == 0)
  353. {
  354. if (Options.Dir == 1)
  355. {
  356. HAL_GPIO_WritePin(GPIOH, Y12_Pin, GPIO_PIN_SET);
  357. }
  358. else
  359. {
  360. HAL_GPIO_WritePin(GPIOH, Y12_Pin, GPIO_PIN_RESET);
  361. }
  362. }
  363. if (Options.DirPost == 1)
  364. {
  365. if (Options.Dir == 1)
  366. {
  367. HAL_GPIO_WritePin(GPIOH, Y13_Pin, GPIO_PIN_SET);
  368. }
  369. else
  370. {
  371. HAL_GPIO_WritePin(GPIOH, Y13_Pin, GPIO_PIN_RESET);
  372. }
  373. }
  374. if (Options.DirPost == 2)
  375. {
  376. if (Options.Dir == 1)
  377. {
  378. HAL_GPIO_WritePin(GPIOH, Y14_Pin, GPIO_PIN_SET);
  379. }
  380. else
  381. {
  382. HAL_GPIO_WritePin(GPIOH, Y14_Pin, GPIO_PIN_RESET);
  383. }
  384. }
  385. if (Options.DirPost == 3)
  386. {
  387. if (Options.Dir == 1)
  388. {
  389. HAL_GPIO_WritePin(GPIOH, Y15_Pin, GPIO_PIN_SET);
  390. }
  391. else
  392. {
  393. HAL_GPIO_WritePin(GPIOH, Y15_Pin, GPIO_PIN_RESET);
  394. }
  395. }
  396. /* 预留时间给其他任务 */
  397. OSTimeDly(100, OS_OPT_TIME_DLY, &err); // 延时 100 个节拍
  398. }
  399. }
  400. /**
  401. * @brief 任务4,脉冲计数
  402. * @return 无
  403. */
  404. void PulseGetCount(void *p_arg)
  405. {
  406. p_arg = p_arg;
  407. OS_ERR err;
  408. while(1)
  409. {
  410. /* 根据当前脉冲的方向设置输出的方向 */
  411. if(PulseOutput[NowPulse].PulseCount < 0)
  412. {
  413. Options.Dir = 1;
  414. }
  415. else
  416. {
  417. Options.Dir = 0;
  418. }
  419. // if(Options.Dir == 0)
  420. // {
  421. // AllPulseCNT = BaseCNT + TIM2->CNT;
  422. // }
  423. // else if(Options.Dir == 1)
  424. // {
  425. // AllPulseCNT = BaseCNT - TIM2->CNT;
  426. // }
  427. if(TIM2->CNT != 0)
  428. {
  429. if (Options.Dir == 1)
  430. {
  431. CNT_Only[NowPulse] = 0 - (TIM2->CNT);
  432. }
  433. else if (Options.Dir == 0)
  434. {
  435. CNT_Only[NowPulse] = TIM2->CNT;
  436. }
  437. }
  438. AllPulseCNT = CNT_Only[0] + CNT_Only[1] + CNT_Only[2] + CNT_Only[3] +
  439. CNT_Only[4] + CNT_Only[5] + CNT_Only[6] + CNT_Only[7] +
  440. CNT_Only[8] + CNT_Only[9];
  441. CountSave();
  442. OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  443. }
  444. }
  445. /* USER CODE END 4 */
  446. /**
  447. * @brief This function is executed in case of error occurrence.
  448. * @retval None
  449. */
  450. void Error_Handler(void)
  451. {
  452. /* USER CODE BEGIN Error_Handler_Debug */
  453. /* User can add his own implementation to report the HAL error return state */
  454. __disable_irq();
  455. while (1)
  456. {
  457. }
  458. /* USER CODE END Error_Handler_Debug */
  459. }
  460. #ifdef USE_FULL_ASSERT
  461. /**
  462. * @brief Reports the name of the source file and the source line number
  463. * where the assert_param error has occurred.
  464. * @param file: pointer to the source file name
  465. * @param line: assert_param error line source number
  466. * @retval None
  467. */
  468. void assert_failed(uint8_t *file, uint32_t line)
  469. {
  470. /* USER CODE BEGIN 6 */
  471. /* User can add his own implementation to report the file name and line number,
  472. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  473. /* USER CODE END 6 */
  474. }
  475. #endif /* USE_FULL_ASSERT */