1
0

registers.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. const {
  2. parseHexInteger
  3. } = require('./base-utils')
  4. const MODBUS_AREAS = {
  5. coil: {
  6. key: 'coil',
  7. label: '线圈',
  8. readFunction: '01',
  9. writeFunction: '05 / 0F',
  10. access: '读写'
  11. },
  12. input: {
  13. key: 'input',
  14. label: '输入寄存器',
  15. readFunction: '04',
  16. writeFunction: '--',
  17. access: '只读'
  18. },
  19. holding: {
  20. key: 'holding',
  21. label: '保持寄存器',
  22. readFunction: '03',
  23. writeFunction: '06 / 10',
  24. access: '读写'
  25. }
  26. }
  27. const BYTE_POSITIONS = {
  28. high: {
  29. label: '高8位',
  30. shift: 8
  31. },
  32. low: {
  33. label: '低8位',
  34. shift: 0
  35. }
  36. }
  37. function hex(address) {
  38. return `0x${address}`
  39. }
  40. function getRegisterCount(item) {
  41. return item.registerCount || (item.type === 'float' ? 2 : 1)
  42. }
  43. function getAddressDisplay(address, registerCount) {
  44. if (registerCount <= 1) return hex(address)
  45. const start = parseHexInteger(address)
  46. const end = start + registerCount - 1
  47. return `${hex(address)}-${hex(end.toString(16).toUpperCase())}`
  48. }
  49. function withArea(items, areaKey, category) {
  50. return items.map((item) => ({
  51. ...item,
  52. ...(() => {
  53. const byteMeta = item.bytePosition ? BYTE_POSITIONS[item.bytePosition] : null
  54. const byteLabel = item.byteLabel || (byteMeta ? byteMeta.label : '')
  55. const registerCount = getRegisterCount(item)
  56. const addressDisplay = byteLabel
  57. ? `${getAddressDisplay(item.address, registerCount)} ${byteLabel}`
  58. : getAddressDisplay(item.address, registerCount)
  59. return {
  60. byteLabel,
  61. byteShift: byteMeta ? byteMeta.shift : null,
  62. category,
  63. addressText: hex(item.address),
  64. addressDisplay,
  65. registerCount,
  66. area: MODBUS_AREAS[areaKey]
  67. }
  68. })()
  69. }))
  70. }
  71. const OBS_ADDRESSES = {
  72. EK1: '30',
  73. EK2: '31',
  74. EK3: '32',
  75. EK4: '33',
  76. FOC_KFG: '34',
  77. SPEED_KLPF: '35',
  78. OBS_FBASE: '36',
  79. OBS_EA_KS: '37',
  80. OBS_KP_START: '38',
  81. OBS_KI_START: '39',
  82. OBS_KP_RUN1: '3A',
  83. OBS_KI_RUN1: '3B',
  84. OBS_KP_RUN2: '3C',
  85. OBS_KI_RUN2: '3D',
  86. OBS_KP_RUN3: '3E',
  87. OBS_KI_RUN3: '3F',
  88. OBS_KP_RUN4: '40',
  89. OBS_KI_RUN4: '41',
  90. DQ_KP_START: '42',
  91. DQ_KI_START: '43',
  92. DQ_KP_RUN: '44',
  93. DQ_KI_RUN: '45',
  94. TAILWIND_SPEED_KLPF: '46',
  95. TAILWIND_OBS_EA_KS: '47',
  96. TAILWIND_OBS_KP: '48',
  97. TAILWIND_OBS_KI: '49',
  98. ALIGN_ANGLE: '4A'
  99. }
  100. const CONFIG_ADDRESSES = {
  101. LD: '60',
  102. LQ: '62',
  103. RS: '64',
  104. POLE_PAIRS: '66',
  105. SPEED_BASE: '67',
  106. SPEED_CTRL: '68',
  107. CURVE_MAX_SPEED: '69',
  108. CURVE_MIN_SPEED: '6A',
  109. SOUT_MAX: '6B',
  110. START_RAMP_INC: '6C',
  111. START_RAMP_DEC: '6E',
  112. RUN_RAMP_INC: '70',
  113. RUN_RAMP_DEC: '72',
  114. START_VOLT: '74',
  115. STOP_VOLT: '75',
  116. CURVE_MAX_VOLT: '76',
  117. CURVE_MIN_VOLT: '77',
  118. SPEED_CURVE_K: '78',
  119. OIL_SPEED: '7A',
  120. OIL_TIME: '7B'
  121. }
  122. const controlButtonRegisters = withArea([
  123. { key: 'protocol', address: '00', type: 'uint8_t', name: 'Modbus控制', writeValue: 1, nextName: 'VSP控制', nextWriteValue: 0 },
  124. { key: 'direction', address: '02', type: 'uint8_t', name: '正转', writeValue: 0, nextName: '反转', nextWriteValue: 1 },
  125. { key: 'power', address: '01', type: 'uint8_t', name: '开机', writeValue: 1, nextName: '关机', nextWriteValue: 0 },
  126. { key: 'save', address: '03', type: 'uint8_t', name: '固化', writeValue: 1, momentary: true },
  127. { key: 'reset', address: '04', type: 'uint8_t', name: '复位', writeValue: 1, momentary: true }
  128. ], 'coil', '控制类寄存器')
  129. const speedCommandRegister = withArea([
  130. { address: CONFIG_ADDRESSES.SPEED_CTRL, type: 'uint16_t', name: '转速命令', unit: 'RPM', inputValue: '', writeValue: '--' }
  131. ], 'holding', '参数配置')[0]
  132. const tailwindSwitchRegisters = withArea([
  133. { address: '05', type: 'uint8_t', name: '顺逆风启用', value: false, writeValue: 0 },
  134. { address: '06', type: 'uint8_t', name: '预定位启用', value: false, writeValue: 0 }
  135. ], 'coil', '顺逆风控制')
  136. const protectionSwitchRegisters = withArea([
  137. { address: '07', type: 'uint8_t', name: '保护使能', value: false, writeValue: 0 },
  138. { address: '08', type: 'uint8_t', name: '恢复使能', value: false, writeValue: 0 },
  139. { address: '09', type: 'uint8_t', name: '电压保护使能', value: false, writeValue: 0 },
  140. { address: '0A', type: 'uint8_t', name: '电流保护使能', value: false, writeValue: 0 },
  141. { address: '0B', type: 'uint8_t', name: '堵转保护使能', value: false, writeValue: 0 },
  142. { address: '0C', type: 'uint8_t', name: '功率保护使能', value: false, writeValue: 0 },
  143. { address: '0D', type: 'uint8_t', name: '温度保护使能', value: false, writeValue: 0 },
  144. { address: '0E', type: 'uint8_t', name: '缺相保护使能', value: false, writeValue: 0 },
  145. { address: '0F', type: 'uint8_t', name: 'PWM丢失保护使能', value: false, writeValue: 0 },
  146. { address: '10', type: 'uint8_t', name: '串口保护使能', value: false, writeValue: 0 }
  147. ], 'coil', '保护')
  148. const estimatorRegisters = withArea([
  149. { address: OBS_ADDRESSES.EK1, type: 'uint16_t', name: 'OBS_E1K', conversion: '2047 * 3.0 / 125.0 * LQ / TPWM_VALUE * 电流基准 / 电压基准' },
  150. { address: OBS_ADDRESSES.EK2, type: 'uint16_t', name: 'OBS_E2K', conversion: '2047 * 0.8 * RS * 电流基准 / 电压基准' },
  151. { address: OBS_ADDRESSES.EK3, type: 'uint16_t', name: 'OBS_E3K', conversion: '255 * 2.5' },
  152. { address: OBS_ADDRESSES.EK4, type: 'uint16_t', name: 'OBS_E4K', conversion: '((LD - LQ) * TPWM_VALUE * MAX_OMEGA_RAD_SEC) / (LD + RS * TPWM_VALUE)' },
  153. { address: OBS_ADDRESSES.FOC_KFG, type: 'uint16_t', name: 'FOC_KFG', conversion: 'TIM4频率 / BASE_FREQ / FG_K * 极对数' },
  154. { address: OBS_ADDRESSES.SPEED_KLPF, type: 'uint16_t', name: 'SPEED_KLPF', conversion: '32767 * 2PI * SPD_BW * TPWM_VALUE' },
  155. { address: OBS_ADDRESSES.OBS_FBASE, type: 'uint16_t', name: 'OBS_FBASE', conversion: '32767 * TPWM_VALUE' },
  156. { address: OBS_ADDRESSES.OBS_EA_KS, type: 'uint16_t', name: 'OBS_EA_KS', conversion: '32767 * 2 * SMOMIN * 2PI * BASE_FREQ * TPWM_VALUE / 速度基准' },
  157. { address: OBS_ADDRESSES.OBS_KP_START, type: 'uint16_t', name: 'OBS_KP_START', conversion: '4095 * 2PI * ATT_COEF * ATO_BW / BASE_FREQ' },
  158. { address: OBS_ADDRESSES.OBS_KI_START, type: 'uint16_t', name: 'OBS_KI_START', conversion: '32767 * 2PI * ATO_BW * ATO_BW * TPWM_VALUE / BASE_FREQ' },
  159. { address: OBS_ADDRESSES.OBS_KP_RUN1, type: 'uint16_t', name: 'OBS_KP_RUN1' },
  160. { address: OBS_ADDRESSES.OBS_KI_RUN1, type: 'uint16_t', name: 'OBS_KI_RUN1' },
  161. { address: OBS_ADDRESSES.OBS_KP_RUN2, type: 'uint16_t', name: 'OBS_KP_RUN2' },
  162. { address: OBS_ADDRESSES.OBS_KI_RUN2, type: 'uint16_t', name: 'OBS_KI_RUN2' },
  163. { address: OBS_ADDRESSES.OBS_KP_RUN3, type: 'uint16_t', name: 'OBS_KP_RUN3' },
  164. { address: OBS_ADDRESSES.OBS_KI_RUN3, type: 'uint16_t', name: 'OBS_KI_RUN3' },
  165. { address: OBS_ADDRESSES.OBS_KP_RUN4, type: 'uint16_t', name: 'OBS_KP_RUN4' },
  166. { address: OBS_ADDRESSES.OBS_KI_RUN4, type: 'uint16_t', name: 'OBS_KI_RUN4' },
  167. { address: OBS_ADDRESSES.DQ_KP_START, type: 'uint16_t', name: 'DQ_KP_START' },
  168. { address: OBS_ADDRESSES.DQ_KI_START, type: 'uint16_t', name: 'DQ_KI_START' },
  169. { address: OBS_ADDRESSES.DQ_KP_RUN, type: 'uint16_t', name: 'DQ_KP_RUN' },
  170. { address: OBS_ADDRESSES.DQ_KI_RUN, type: 'uint16_t', name: 'DQ_KI_RUN' },
  171. { address: OBS_ADDRESSES.TAILWIND_SPEED_KLPF, type: 'uint16_t', name: 'SPEED_KLPF_TAILWIND' },
  172. { address: OBS_ADDRESSES.TAILWIND_OBS_EA_KS, type: 'uint16_t', name: 'OBS_EA_KS_TAILWIND' },
  173. { address: OBS_ADDRESSES.TAILWIND_OBS_KP, type: 'uint16_t', name: 'OBS_KP_TAILWIND' },
  174. { address: OBS_ADDRESSES.TAILWIND_OBS_KI, type: 'uint16_t', name: 'OBS_KI_TAILWIND' },
  175. { address: OBS_ADDRESSES.ALIGN_ANGLE, type: 'uint16_t', name: '预定位角度' }
  176. ], 'holding', '估算器配置参数')
  177. const atoBandwidthInputRegisters = [
  178. { suffix: 'START', name: 'ATO_BW_START', kpAddress: OBS_ADDRESSES.OBS_KP_START, kiAddress: OBS_ADDRESSES.OBS_KI_START, kpName: 'OBS_KP_START', kiName: 'OBS_KI_START' },
  179. { suffix: 'RUN1', name: 'ATO_BW_RUN1', kpAddress: OBS_ADDRESSES.OBS_KP_RUN1, kiAddress: OBS_ADDRESSES.OBS_KI_RUN1, kpName: 'OBS_KP_RUN1', kiName: 'OBS_KI_RUN1' },
  180. { suffix: 'RUN2', name: 'ATO_BW_RUN2', kpAddress: OBS_ADDRESSES.OBS_KP_RUN2, kiAddress: OBS_ADDRESSES.OBS_KI_RUN2, kpName: 'OBS_KP_RUN2', kiName: 'OBS_KI_RUN2' },
  181. { suffix: 'RUN3', name: 'ATO_BW_RUN3', kpAddress: OBS_ADDRESSES.OBS_KP_RUN3, kiAddress: OBS_ADDRESSES.OBS_KI_RUN3, kpName: 'OBS_KP_RUN3', kiName: 'OBS_KI_RUN3' },
  182. { suffix: 'RUN4', name: 'ATO_BW_RUN4', kpAddress: OBS_ADDRESSES.OBS_KP_RUN4, kiAddress: OBS_ADDRESSES.OBS_KI_RUN4, kpName: 'OBS_KP_RUN4', kiName: 'OBS_KI_RUN4' },
  183. { suffix: 'TAILWIND', name: 'ATO_BW_TAILWIND', kpAddress: OBS_ADDRESSES.TAILWIND_OBS_KP, kiAddress: OBS_ADDRESSES.TAILWIND_OBS_KI, kpName: 'OBS_KP_TAILWIND', kiName: 'OBS_KI_TAILWIND' }
  184. ].map((item) => ({
  185. ...item,
  186. type: 'float',
  187. inputValue: '',
  188. writeValue: '--',
  189. kpWriteValue: '--',
  190. kiWriteValue: '--',
  191. category: '估算器配置参数',
  192. addressDisplay: `${hex(item.kpAddress)}/${hex(item.kiAddress)}`,
  193. area: MODBUS_AREAS.holding
  194. }))
  195. const dqGainInputRegisters = withArea([
  196. { address: OBS_ADDRESSES.DQ_KP_START, type: 'uint16_t', name: 'DQ_KP_START', protocolName: 'DQ_KP_START', gainType: 'kp' },
  197. { address: OBS_ADDRESSES.DQ_KI_START, type: 'uint16_t', name: 'DQ_KI_START', protocolName: 'DQ_KI_START', gainType: 'ki' },
  198. { address: OBS_ADDRESSES.DQ_KP_RUN, type: 'uint16_t', name: 'DQ_KP_RUN', protocolName: 'DQ_KP_RUN', gainType: 'kp' },
  199. { address: OBS_ADDRESSES.DQ_KI_RUN, type: 'uint16_t', name: 'DQ_KI_RUN', protocolName: 'DQ_KI_RUN', gainType: 'ki' }
  200. ], 'holding', '估算器配置参数').map((item) => ({
  201. ...item,
  202. inputValue: '',
  203. writeValue: '--'
  204. }))
  205. const parameterRegisters = withArea([
  206. { address: CONFIG_ADDRESSES.LD, type: 'float', name: 'LD', unit: 'H', step: '0.000001' },
  207. { address: CONFIG_ADDRESSES.LQ, type: 'float', name: 'LQ', unit: 'H', step: '0.000001' },
  208. { address: CONFIG_ADDRESSES.RS, type: 'float', name: 'RS', unit: 'Ω', step: '0.0001' },
  209. { address: CONFIG_ADDRESSES.POLE_PAIRS, type: 'uint16_t', name: '极对数' },
  210. { address: CONFIG_ADDRESSES.SPEED_BASE, type: 'uint16_t', name: '速度基准', unit: 'RPM' },
  211. { address: CONFIG_ADDRESSES.CURVE_MAX_SPEED, type: 'uint16_t', name: '速度最大值', unit: 'RPM' },
  212. { address: CONFIG_ADDRESSES.CURVE_MIN_SPEED, type: 'uint16_t', name: '速度最小值', unit: 'RPM' },
  213. { address: CONFIG_ADDRESSES.SOUT_MAX, type: 'uint16_t', name: 'SOUT_MAX', unit: 'A' },
  214. { address: CONFIG_ADDRESSES.START_RAMP_INC, type: 'float', name: '启动加速加速度', unit: 'RPM/S' },
  215. { address: CONFIG_ADDRESSES.START_RAMP_DEC, type: 'float', name: '启动减速加速度', unit: 'RPM/S' },
  216. { address: CONFIG_ADDRESSES.RUN_RAMP_INC, type: 'float', name: '运行加速加速度', unit: 'RPM/S' },
  217. { address: CONFIG_ADDRESSES.RUN_RAMP_DEC, type: 'float', name: '运行减速加速度', unit: 'RPM/S' },
  218. { address: CONFIG_ADDRESSES.START_VOLT, type: 'uint16_t', name: '开机电压', unit: 'V' },
  219. { address: CONFIG_ADDRESSES.STOP_VOLT, type: 'uint16_t', name: '关机电压', unit: 'V' },
  220. { address: CONFIG_ADDRESSES.CURVE_MAX_VOLT, type: 'uint16_t', name: '调速最高电压', unit: 'V' },
  221. { address: CONFIG_ADDRESSES.CURVE_MIN_VOLT, type: 'uint16_t', name: '调速最低电压', unit: 'V' },
  222. { address: CONFIG_ADDRESSES.SPEED_CURVE_K, type: 'float', name: '调速曲线斜率' },
  223. { address: CONFIG_ADDRESSES.OIL_SPEED, type: 'uint16_t', name: '上油转速', unit: 'RPM' },
  224. { address: CONFIG_ADDRESSES.OIL_TIME, type: 'uint16_t', name: '上油时间', unit: 's' }
  225. ], 'holding', '参数配置')
  226. const parameterInputNames = [
  227. 'LD',
  228. 'LQ',
  229. 'RS',
  230. '极对数',
  231. '速度基准'
  232. ]
  233. const configParameterInputNames = [
  234. '开机电压',
  235. '关机电压',
  236. '速度最小值',
  237. '速度最大值',
  238. 'SOUT_MAX',
  239. '调速最低电压',
  240. '调速最高电压'
  241. ]
  242. const speedLoopExtraInputNames = [
  243. '启动加速加速度',
  244. '启动减速加速度',
  245. '运行加速加速度',
  246. '运行减速加速度'
  247. ]
  248. const oilParameterInputNames = [
  249. '上油转速',
  250. '上油时间'
  251. ]
  252. const prepositionParameterInputNames = [
  253. '预定位角度'
  254. ]
  255. const parameterByName = parameterRegisters.reduce((result, item) => {
  256. result[item.name] = item
  257. return result
  258. }, {})
  259. const motorParameterInputRegisters = parameterInputNames
  260. .map((name) => parameterByName[name])
  261. .filter(Boolean)
  262. .map((item) => ({
  263. ...item,
  264. inputValue: item.inputValue || '',
  265. writeValue: item.writeValue || '--'
  266. }))
  267. const parameterInputRegisters = configParameterInputNames
  268. .map((name) => parameterByName[name])
  269. .filter(Boolean)
  270. .map((item) => ({
  271. ...item,
  272. inputValue: item.inputValue || '',
  273. writeValue: item.writeValue || '--'
  274. }))
  275. const speedSlopeRegister = {
  276. ...parameterByName['调速曲线斜率'],
  277. inputValue: '',
  278. writeValue: '--'
  279. }
  280. const speedLoopExtraRegisters = speedLoopExtraInputNames
  281. .map((name) => parameterByName[name])
  282. .filter(Boolean)
  283. .map((item) => ({
  284. ...item,
  285. inputValue: '',
  286. writeValue: '--'
  287. }))
  288. const oilParameterInputRegisters = oilParameterInputNames
  289. .map((name) => parameterByName[name])
  290. .filter(Boolean)
  291. .map((item) => ({
  292. ...item,
  293. inputValue: '',
  294. writeValue: '--'
  295. }))
  296. const prepositionParameterInputRegisters = prepositionParameterInputNames
  297. .map((name) => estimatorRegisters.find((item) => item.name === name))
  298. .filter(Boolean)
  299. .map((item) => ({
  300. ...item,
  301. inputValue: '',
  302. writeValue: '--'
  303. }))
  304. function isAtoGainRegister(item) {
  305. return item.name.startsWith('OBS_KP_') || item.name.startsWith('OBS_KI_')
  306. }
  307. function isDqGainRegister(item) {
  308. return item.name.startsWith('DQ_KP_') || item.name.startsWith('DQ_KI_')
  309. }
  310. const calculatedParameterRegisters = [
  311. ...estimatorRegisters.filter((item) => !isAtoGainRegister(item) && !isDqGainRegister(item) && !prepositionParameterInputNames.includes(item.name)),
  312. ...parameterRegisters.filter((item) => !parameterInputNames.includes(item.name)
  313. && !configParameterInputNames.includes(item.name)
  314. && !speedLoopExtraInputNames.includes(item.name)
  315. && !oilParameterInputNames.includes(item.name)
  316. && !prepositionParameterInputNames.includes(item.name)
  317. && item.name !== '调速曲线斜率')
  318. ].map((item) => ({
  319. ...item,
  320. inputValue: '',
  321. writeValue: '--'
  322. }))
  323. const protectionRegisters = withArea([
  324. { address: '7C', type: 'uint16_t', name: '硬件过流值', unit: 'A' },
  325. { address: '7D', type: 'uint16_t', name: '软件过流值', unit: 'A', conversion: '32767 * 限制值 / 电流基准' },
  326. { address: '7E', type: 'uint16_t', name: '过压保护值', unit: 'V', conversion: '32767 * 限制值 / 电压采样最大值' },
  327. { address: '7F', type: 'uint16_t', name: '欠压保护值', unit: 'V' },
  328. { address: '80', type: 'uint16_t', name: '过压恢复值', unit: 'V' },
  329. { address: '81', type: 'uint16_t', name: '欠压恢复值', unit: 'V' },
  330. { address: '82', type: 'uint16_t', name: '速度限制最大值', unit: 'RPM', conversion: '32767 * 限制值 / 速度基准' },
  331. { address: '83', type: 'uint16_t', name: '速度限制最小值', unit: 'RPM' },
  332. { address: '84', type: 'uint16_t', name: '反电动势低阈值' },
  333. { address: '85', type: 'uint16_t', name: '反电动势高阈值' },
  334. { address: '86', type: 'uint16_t', name: '速度中间值', unit: 'RPM' },
  335. { address: '87', type: 'uint16_t', name: '功率保护值', unit: 'W', conversion: '32767 * 保护值 / 电流采样最大值 / 电压采样最大值' },
  336. { address: '88', type: 'uint16_t', name: '功率保护时间', unit: 'ms' },
  337. { address: '89', type: 'uint16_t', name: '温度保护值', unit: '℃' },
  338. { address: '8A', type: 'uint16_t', name: '温度恢复值', unit: '℃' },
  339. { address: '8B', type: 'uint16_t', name: '温度保护时间', unit: 'ms' },
  340. { address: '8C', type: 'uint16_t', name: '故障恢复时间', unit: 's' },
  341. { address: '8D', type: 'uint16_t', name: '串口丢失检测时间', unit: 'ms' }
  342. ], 'holding', '保护配置')
  343. const readonlyParamRegisters = withArea([
  344. { address: 'A8', type: 'ascii', name: '芯片型号', displayValue: '--', registerCount: 4, hideMeta: true },
  345. { address: 'AC', type: 'ascii', name: '型号', displayValue: '--', registerCount: 8, hideMeta: true },
  346. { address: 'A0', type: 'uint8_t', name: '载波频率', unit: 'KHz', displayValue: '--', bytePosition: 'high' },
  347. { address: 'A0', type: 'uint8_t', name: '基准电压', unit: 'V', displayValue: '--', bytePosition: 'low' },
  348. { address: 'A1', type: 'uint16_t', name: '运放倍数', displayValue: '--' },
  349. { address: 'A2', type: 'uint16_t', name: '采样电阻', unit: 'mΩ', displayValue: '--' },
  350. { address: 'A3', type: 'uint16_t', name: '全区 Flash 校验码', displayValue: '--' },
  351. { address: 'A4', type: 'float', name: '母线电压分压比', displayValue: '--' },
  352. { address: 'A6', type: 'float', name: '模拟输入电压分压比', displayValue: '--' }
  353. ], 'input', '只读参数寄存器')
  354. const userStatusRegisters = Array.from({ length: 10 }, (_, index) => ({
  355. address: (0xD3 + index).toString(16).toUpperCase(),
  356. type: 'uint16_t',
  357. name: `用户状态字 ${index + 1}`
  358. }))
  359. const statusRegisters = withArea([
  360. { address: 'C0', type: 'uint8_t', name: '状态机', bytePosition: 'high' },
  361. { address: 'C0', type: 'uint8_t', name: '故障码', bytePosition: 'low' },
  362. { address: 'C1', type: 'int16_t', name: 'UQ' },
  363. { address: 'C2', type: 'int16_t', name: 'UD' },
  364. { address: 'C3', type: 'int16_t', name: 'IQ' },
  365. { address: 'C4', type: 'int16_t', name: 'ID' },
  366. { address: 'C5', type: 'int16_t', name: 'A 相电流' },
  367. { address: 'C6', type: 'int16_t', name: 'B 相电流' },
  368. { address: 'C7', type: 'int16_t', name: 'C 相电流' },
  369. { address: 'C8', type: 'uint16_t', name: '相电流最大值' },
  370. { address: 'C9', type: 'uint16_t', name: '相电流最小值' },
  371. { address: 'CA', type: 'int16_t', name: '估算速度', unit: 'RPM' },
  372. { address: 'CB', type: 'uint16_t', name: '估算反电动势' },
  373. { address: 'CC', type: 'uint16_t', name: '母线电压', unit: '0.1V', displayUnit: 'V' },
  374. { address: 'CD', type: 'uint16_t', name: '母线电流', unit: '0.01A', displayUnit: 'A' },
  375. { address: 'CE', type: 'uint16_t', name: '估算功率', unit: 'W' },
  376. { address: 'CF', type: 'uint16_t', name: 'NTC 温度', unit: '℃', displayUnit: '℃' },
  377. { address: 'D0', type: 'uint16_t', name: '模拟输入电压', unit: 'V', displayUnit: 'V' },
  378. { address: 'D1', type: 'uint16_t', name: '频率', unit: 'Hz', displayUnit: 'Hz' },
  379. { address: 'D2', type: 'uint16_t', name: '占空比', unit: '%', displayUnit: '%' },
  380. ...userStatusRegisters
  381. ], 'input', '状态类寄存器')
  382. function getByteRegisterValue(item, wordValue) {
  383. if (!item || item.type !== 'uint8_t' || !item.bytePosition) return wordValue
  384. return (Number(wordValue) >> item.byteShift) & 0xFF
  385. }
  386. module.exports = {
  387. controlButtonRegisters,
  388. speedCommandRegister,
  389. atoBandwidthInputRegisters,
  390. dqGainInputRegisters,
  391. oilParameterInputRegisters,
  392. prepositionParameterInputRegisters,
  393. motorParameterInputRegisters,
  394. parameterInputRegisters,
  395. calculatedParameterRegisters,
  396. protectionSwitchRegisters,
  397. protectionRegisters,
  398. readonlyParamRegisters,
  399. speedLoopExtraRegisters,
  400. speedSlopeRegister,
  401. statusRegisters,
  402. tailwindSwitchRegisters,
  403. getByteRegisterValue,
  404. getRegisterCount
  405. }