训练营PLSR题目
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

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