25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

237 satır
8.4 KiB

  1. #include "plsr_self_test.h"
  2. #include "plc_device.h"
  3. #include "plsr_core.h"
  4. #include "plsr_job.h"
  5. #include <string.h>
  6. /* 上电自测(验证后可删除):
  7. * - AB 模式使用 Q0(A)/Q1(B),其余用出厂默认参数(K1)
  8. * - 任务:3 段完整 AB 周期(H00 完成,顺序衔接):
  9. * 段1:2000Hz / +1000 周期(A 超前 B)
  10. * 段2:5000Hz / +6000 周期(A 超前 B)
  11. * 段3:1000Hz / -500 周期(B 超前 A,验证反向)
  12. * 数据源为静态数组,仅自测使用(正式 D 设备适配器见 Modbus 阶段)。 */
  13. #define SELF_TEST_WORD_CAPACITY (64U)
  14. #define SELF_TEST_S0_BASE (10U)
  15. #define SELF_TEST_S1_BASE (60U)
  16. #define SELF_TEST_DIR_POINT (4U)
  17. static uint16_t SelfTestWords[3][SELF_TEST_WORD_CAPACITY];
  18. static uint8_t SelfTestValidateWords(void *context,
  19. PLSR_DEVICE_TYPE device,
  20. uint32_t firstAddress,
  21. uint32_t wordCount)
  22. {
  23. (void)context;
  24. if ((device > PLSR_DEVICE_FD) || (wordCount == 0UL))
  25. {
  26. return 0U;
  27. }
  28. return (((uint64_t)firstAddress + wordCount)
  29. <= SELF_TEST_WORD_CAPACITY)
  30. ? 1U
  31. : 0U;
  32. }
  33. static uint8_t SelfTestReadWord(void *context,
  34. PLSR_DEVICE_TYPE device,
  35. uint32_t address,
  36. uint16_t *value)
  37. {
  38. (void)context;
  39. if ((device > PLSR_DEVICE_FD) || (value == NULL)
  40. || (address >= SELF_TEST_WORD_CAPACITY))
  41. {
  42. return 0U;
  43. }
  44. *value = SelfTestWords[device][address];
  45. return 1U;
  46. }
  47. static uint8_t SelfTestReadBit(void *context,
  48. PLSR_DEVICE_TYPE device,
  49. uint32_t address,
  50. uint8_t *value)
  51. {
  52. (void)context;
  53. (void)device;
  54. (void)address;
  55. *value = 0U;
  56. return 1U;
  57. }
  58. static void SelfTestWriteDword(PLSR_DEVICE_TYPE device,
  59. uint32_t address,
  60. uint32_t value)
  61. {
  62. SelfTestWords[device][address] = (uint16_t)(value & 0xFFFFUL);
  63. SelfTestWords[device][address + 1UL] = (uint16_t)(value >> 16U);
  64. }
  65. static void SelfTestWriteSfdDword(uint16_t address, uint32_t value)
  66. {
  67. (void)PlcDeviceWriteSfd(address, (uint16_t)(value & 0xFFFFUL));
  68. (void)PlcDeviceWriteSfd((uint16_t)(address + 1U),
  69. (uint16_t)(value >> 16U));
  70. }
  71. PLSR_RESULT PlsrSelfTestQueue(void)
  72. {
  73. PLSR_CALL call;
  74. (void)memset(SelfTestWords, 0, sizeof(SelfTestWords));
  75. /* 方向端子 Y4(PULSE/DIR 模式必需,接线参数)。 */
  76. (void)PlcDeviceWriteSfd(906U, SELF_TEST_DIR_POINT);
  77. (void)PlcDeviceWriteSfd(912U, 0U);
  78. (void)PlcDeviceWriteSfd(915U, 0xFFFFU);
  79. /* S0:3 段,H00 完成,顺序跳转。 */
  80. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE, 3U);
  81. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 10U, 2000UL);
  82. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 12U, 1000UL);
  83. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 20U, 5000UL);
  84. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 22U, 6000UL);
  85. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 30U, 1000UL);
  86. SelfTestWriteDword(PLSR_DEVICE_D,
  87. SELF_TEST_S0_BASE + 32U,
  88. (uint32_t)(int32_t)-500);
  89. /* S1:相对模式,起始段 0(=段1)。 */
  90. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S1_BASE, 0U);
  91. (void)memset(&call, 0, sizeof(call));
  92. call.sequence = 0xA5A5UL;
  93. call.source.context = NULL;
  94. call.source.validateWords = SelfTestValidateWords;
  95. call.source.readWord = SelfTestReadWord;
  96. call.source.readBit = SelfTestReadBit;
  97. call.s0.device = PLSR_DEVICE_D;
  98. call.s0.address = SELF_TEST_S0_BASE;
  99. call.s1.device = PLSR_DEVICE_D;
  100. call.s1.address = SELF_TEST_S1_BASE;
  101. call.s2.type = PLSR_OPERAND_CONSTANT;
  102. call.s2.constant = 1;
  103. call.dAxis = 0U;
  104. call.outputModeOverride = PLSR_OUTPUT_AB;
  105. return PlsrPostCall(&call);
  106. }
  107. PLSR_RESULT PlsrEquivalentSelfTestQueue(void)
  108. {
  109. PLSR_CALL call;
  110. (void)memset(SelfTestWords, 0, sizeof(SelfTestWords));
  111. /* SFD900 Bit10~8=001(1um当量);3脉冲/2单位。 */
  112. (void)PlcDeviceWriteSfd(900U, (1U << 8U));
  113. SelfTestWriteSfdDword(902U, 3UL);
  114. SelfTestWriteSfdDword(904U, 2UL);
  115. (void)PlcDeviceWriteSfd(906U, SELF_TEST_DIR_POINT);
  116. (void)PlcDeviceWriteSfd(907U, 10U);
  117. (void)PlcDeviceWriteSfd(912U, 0U);
  118. (void)PlcDeviceWriteSfd(915U, 0xFFFFU);
  119. /* 当量换算后物理最高速度=90000Hz,不超过硬件100kHz。 */
  120. SelfTestWriteSfdDword(956U, 60000UL);
  121. /* 板端可观察版本:两段各1001工程单位。
  122. * 3脉冲/2单位带余数换算后分别输出1501、1502脉冲,累计3003脉冲;
  123. * 1500Hz附近持续约2s,避免原3脉冲自检在逻辑分析仪启动前已经结束。 */
  124. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE, 2U);
  125. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 10U, 1000UL);
  126. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 12U, 1001UL);
  127. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 20U, 1000UL);
  128. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 22U, 1001UL);
  129. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S1_BASE, 0U);
  130. (void)memset(&call, 0, sizeof(call));
  131. call.sequence = 0xA5A6UL;
  132. call.source.context = NULL;
  133. call.source.validateWords = SelfTestValidateWords;
  134. call.source.readWord = SelfTestReadWord;
  135. call.source.readBit = SelfTestReadBit;
  136. call.s0.device = PLSR_DEVICE_D;
  137. call.s0.address = SELF_TEST_S0_BASE;
  138. call.s1.device = PLSR_DEVICE_D;
  139. call.s1.address = SELF_TEST_S1_BASE;
  140. call.s2.type = PLSR_OPERAND_CONSTANT;
  141. call.s2.constant = 1;
  142. call.dAxis = 0U;
  143. call.outputModeOverride = PLSR_OUTPUT_PULSE_DIR;
  144. return PlsrPostCall(&call);
  145. }
  146. PLSR_RESULT PlsrProtectionSelfTestQueue(void)
  147. {
  148. PLSR_CALL call;
  149. PLSR_COMMAND command;
  150. PLSR_RESULT result;
  151. (void)memset(SelfTestWords, 0, sizeof(SelfTestWords));
  152. /* Pulse unit, soft limits enabled, 1 pulse per position unit. */
  153. (void)PlcDeviceWriteSfd(900U, (1U << 2U));
  154. SelfTestWriteSfdDword(902U, 1UL);
  155. SelfTestWriteSfdDword(904U, 1UL);
  156. (void)PlcDeviceWriteSfd(906U, SELF_TEST_DIR_POINT);
  157. (void)PlcDeviceWriteSfd(907U, 10U);
  158. (void)PlcDeviceWriteSfd(912U, 0U);
  159. (void)PlcDeviceWriteSfd(915U, 0xFFFFU);
  160. SelfTestWriteSfdDword(930U, 500UL);
  161. SelfTestWriteSfdDword(932U, (uint32_t)(int32_t)-500);
  162. /* K1: 1000Hz, 100ms acceleration/deceleration, 1ms refresh. */
  163. SelfTestWriteSfdDword(950U, 1000UL);
  164. (void)PlcDeviceWriteSfd(952U, 100U);
  165. (void)PlcDeviceWriteSfd(953U, 100U);
  166. (void)PlcDeviceWriteSfd(954U, 0U);
  167. (void)PlcDeviceWriteSfd(955U, 0U);
  168. SelfTestWriteSfdDword(956U, 100000UL);
  169. SelfTestWriteSfdDword(958U, 1000UL);
  170. SelfTestWriteSfdDword(960U, 0UL);
  171. (void)PlcDeviceWriteSfd(962U, 50U);
  172. (void)PlcDeviceWriteSfd(963U, 0U);
  173. (void)PlcDeviceWriteSfd(964U, 0U);
  174. SelfTestWriteSfdDword(966U, 2000UL);
  175. SelfTestWriteSfdDword(968U, 200UL);
  176. /* One relative segment requests +10000 pulses; +500 must stop it. */
  177. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE, 1U);
  178. SelfTestWriteDword(PLSR_DEVICE_D,
  179. SELF_TEST_S0_BASE + 10U,
  180. 1000UL);
  181. SelfTestWriteDword(PLSR_DEVICE_D,
  182. SELF_TEST_S0_BASE + 12U,
  183. 10000UL);
  184. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S1_BASE, 0U);
  185. (void)memset(&command, 0, sizeof(command));
  186. command.sequence = 0xA5A7UL;
  187. command.axis = 0U;
  188. command.opcode = PLSR_CMD_SET_POSITION;
  189. command.argument = 0;
  190. result = PlsrPostCommand(&command);
  191. if (result != PLSR_RESULT_QUEUED)
  192. {
  193. return result;
  194. }
  195. (void)memset(&call, 0, sizeof(call));
  196. call.sequence = 0xA5A8UL;
  197. call.source.context = NULL;
  198. call.source.validateWords = SelfTestValidateWords;
  199. call.source.readWord = SelfTestReadWord;
  200. call.source.readBit = SelfTestReadBit;
  201. call.s0.device = PLSR_DEVICE_D;
  202. call.s0.address = SELF_TEST_S0_BASE;
  203. call.s1.device = PLSR_DEVICE_D;
  204. call.s1.address = SELF_TEST_S1_BASE;
  205. call.s2.type = PLSR_OPERAND_CONSTANT;
  206. call.s2.constant = 1;
  207. call.dAxis = 0U;
  208. call.outputModeOverride = PLSR_OUTPUT_PULSE_DIR;
  209. return PlsrPostCall(&call);
  210. }