OscData.cpp 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. #include "OscData.h"
  2. #include <QApplication>
  3. #include <QRandomGenerator>
  4. #include "ThreadPool/ThreadPool.h"
  5. OscilloscopeData::OscilloscopeData()
  6. {
  7. }
  8. OscilloscopeData::~OscilloscopeData()
  9. {
  10. if(m_isOpen)
  11. {
  12. closeOSC();
  13. }
  14. if(m_buffer != nullptr)
  15. {
  16. delete[] m_buffer;
  17. m_buffer = nullptr;
  18. }
  19. if(m_bufferChnA != nullptr)
  20. {
  21. delete[] m_bufferChnA;
  22. m_bufferChnA = nullptr;
  23. }
  24. if(m_bufferChnB != nullptr)
  25. {
  26. delete[] m_bufferChnB;
  27. m_bufferChnB = nullptr;
  28. }
  29. }
  30. /* 初始化示波器 */
  31. void OscilloscopeData::initOsc()
  32. {
  33. m_logger = spdlog::get("OscData");
  34. if(m_logger == nullptr)
  35. {
  36. SPDLOG_ERROR("获取 OscData logger 失败");
  37. return;
  38. }
  39. m_usbInterface = std::make_shared<USBInterface>();
  40. if(!m_usbInterface->loadLib(QApplication::applicationDirPath()))
  41. {
  42. return;
  43. }
  44. /* 分配缓冲区内存 */
  45. m_buffer = new unsigned char[BUFFER_SIZE];
  46. m_bufferChnA = new unsigned char[BUFFER_SIZE / 2];
  47. m_bufferChnB = new unsigned char[BUFFER_SIZE / 2];
  48. }
  49. /* 打开示波器 */
  50. bool OscilloscopeData::openOSC()
  51. {
  52. if(m_usbInterface == nullptr)
  53. {
  54. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  55. return false;
  56. }
  57. /* 指定示波器设备型号,OSCA02是6 */
  58. m_usbInterface->specifyDevId(6);
  59. auto ret = m_usbInterface->devOpen();
  60. if(ret != 0)
  61. {
  62. SPDLOG_LOGGER_ERROR(m_logger, "打开示波器失败!");
  63. return false;
  64. }
  65. /* 获取缓冲区首指针 */
  66. m_devBuffer = m_usbInterface->bufferWR(-1);
  67. if(m_devBuffer == nullptr)
  68. {
  69. SPDLOG_LOGGER_ERROR(m_logger, "获取缓冲区指针失败!");
  70. return false;
  71. }
  72. /* 设置硬件触发命令,关闭外部触发,好像是有的设备需要,有的不需要 */
  73. m_ctrlByte1 &= 0xdf;
  74. m_ctrlByte1 |= 0x00;
  75. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  76. /* 设置触发位置在缓冲区中间 */
  77. m_usbInterface->usbCtrlTrans(0x18, 0xff);
  78. m_usbInterface->usbCtrlTrans(0x17, 0x7f);
  79. /* 设置缓冲区大小 */
  80. m_usbInterface->setInfo(BUFFER_SIZE);
  81. /* 获取零电压值 */
  82. getZeroVoltage();
  83. /* 获取电压校准系数 */
  84. getVoltageCalibration();
  85. m_isOpen = true;
  86. return true;
  87. }
  88. /* 关闭示波器 */
  89. void OscilloscopeData::closeOSC()
  90. {
  91. if(m_runCapture)
  92. {
  93. stopCapture();
  94. }
  95. while (m_isRunCapture)
  96. {
  97. std::this_thread::sleep_for(std::chrono::milliseconds(5));
  98. }
  99. if(m_usbInterface != nullptr)
  100. {
  101. m_usbInterface->devClose();
  102. }
  103. m_isOpen = false;
  104. SPDLOG_INFO("示波器已关闭");
  105. }
  106. /* 开始采集数据 */
  107. bool OscilloscopeData::startCapture()
  108. {
  109. if(m_buffer == nullptr)
  110. {
  111. SPDLOG_LOGGER_ERROR(m_logger, "缓冲区指针为空!");
  112. return false;
  113. }
  114. /* 启动子线程 */
  115. m_runCapture = true;
  116. CPPTP.add_task(&OscilloscopeData::threadCaptureData, this);
  117. CPPTP.add_task(&OscilloscopeData::threadProcessData, this);
  118. CPPTP.add_task(&OscilloscopeData::threadAddColorBySample, this);
  119. return true;
  120. }
  121. /* 停止采集数据 */
  122. void OscilloscopeData::stopCapture()
  123. {
  124. m_runCapture = false;
  125. }
  126. /* 设置示波器的采样率 */
  127. void OscilloscopeData::setSampleRate(OscSampleRate rate)
  128. {
  129. if(m_usbInterface == nullptr)
  130. {
  131. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  132. return;
  133. }
  134. m_ctrlByte0 &= 0xf0;
  135. if(rate == OscSampleRate::SR_49KHZ)
  136. {
  137. m_ctrlByte0 |= 0x0e;
  138. OscParams.SampleIntervalTime = 20408.16;
  139. }
  140. else if(rate == OscSampleRate::SR_96KHZ)
  141. {
  142. m_ctrlByte0 |= 0x04;
  143. OscParams.SampleIntervalTime = 10416.67;
  144. }
  145. else if(rate == OscSampleRate::SR_781KHZ)
  146. {
  147. m_ctrlByte0 |= 0x0c;
  148. OscParams.SampleIntervalTime = 1280.0;
  149. }
  150. else if(rate == OscSampleRate::SR_12_5MHZ)
  151. {
  152. m_ctrlByte0 |= 0x08;
  153. OscParams.SampleIntervalTime = 80.0;
  154. }
  155. else if(rate == OscSampleRate::SR_100MHZ)
  156. {
  157. m_ctrlByte0 |= 0x00;
  158. OscParams.SampleIntervalTime = 10;
  159. }
  160. else
  161. {
  162. SPDLOG_LOGGER_ERROR(m_logger, "采样率设置错误!");
  163. return;
  164. }
  165. m_usbInterface->usbCtrlTrans(0x94, m_ctrlByte0);
  166. }
  167. /**
  168. * @brief 将示波器两个通道合并为一个通道
  169. * 将AB两个通道的资源全部给A,B通道失效,A通道的采样率和带宽翻倍
  170. * @param merge 是否合并
  171. */
  172. void OscilloscopeData::setChannelMerge(bool merge)
  173. {
  174. if(m_usbInterface == nullptr)
  175. {
  176. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  177. return;
  178. }
  179. if(merge)
  180. {
  181. m_ctrlByte1 |= 0x80;
  182. }else {
  183. m_ctrlByte1 &= 0x7f;
  184. }
  185. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  186. }
  187. /**
  188. * @brief 设置通道A输入量程,这个函数需要在打开示波器之后调用
  189. *
  190. * @param range
  191. */
  192. void OscilloscopeData::setChannelARange(OscChannelRange range)
  193. {
  194. if(m_usbInterface == nullptr)
  195. {
  196. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  197. return;
  198. }
  199. m_ctrlByte1 &= 0xf7;
  200. if(range == OscChannelRange::CR_100MV)
  201. {
  202. m_usbInterface->usbCtrlTrans(0x22, 0x06);
  203. }
  204. else if(range == OscChannelRange::CR_250MV)
  205. {
  206. m_usbInterface->usbCtrlTrans(0x22, 0x04);
  207. }
  208. else if(range == OscChannelRange::CR_500MV)
  209. {
  210. m_usbInterface->usbCtrlTrans(0x22, 0x02);
  211. }
  212. else if(range == OscChannelRange::CR_1V)
  213. {
  214. m_ctrlByte1 |= 0x08;
  215. m_usbInterface->usbCtrlTrans(0x22, 0x06);
  216. }
  217. else if(range == OscChannelRange::CR_2V5)
  218. {
  219. m_ctrlByte1 |= 0x08;
  220. m_usbInterface->usbCtrlTrans(0x22, 0x04);
  221. }
  222. else if(range == OscChannelRange::CR_5V)
  223. {
  224. m_ctrlByte1 |= 0x08;
  225. m_usbInterface->usbCtrlTrans(0x22, 0x02);
  226. }
  227. else if(range == OscChannelRange::CR_8V)
  228. {
  229. m_ctrlByte1 |= 0x08;
  230. m_usbInterface->usbCtrlTrans(0x22, 0x00);
  231. }
  232. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  233. setZeroVoltageAndCalibration(OscChannel::CH_A, range);
  234. }
  235. /**
  236. * @brief 设置通道B输入量程
  237. *
  238. * @param range
  239. */
  240. void OscilloscopeData::setChannelBRange(OscChannelRange range)
  241. {
  242. if(m_usbInterface == nullptr)
  243. {
  244. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  245. return;
  246. }
  247. m_ctrlByte1 &= 0xf9;
  248. if(range == OscChannelRange::CR_100MV)
  249. {
  250. m_ctrlByte1 |= 0x06;
  251. m_usbInterface->usbCtrlTrans(0x23, 0x40);
  252. }
  253. else if(range == OscChannelRange::CR_250MV)
  254. {
  255. m_ctrlByte1 |= 0x04;
  256. m_usbInterface->usbCtrlTrans(0x23, 0x40);
  257. }
  258. else if(range == OscChannelRange::CR_500MV)
  259. {
  260. m_ctrlByte1 |= 0x02;
  261. m_usbInterface->usbCtrlTrans(0x23, 0x40);
  262. }
  263. else if(range == OscChannelRange::CR_1V)
  264. {
  265. m_ctrlByte1 |= 0x06;
  266. m_usbInterface->usbCtrlTrans(0x23, 0x00);
  267. }
  268. else if(range == OscChannelRange::CR_2V5)
  269. {
  270. m_ctrlByte1 |= 0x04;
  271. m_usbInterface->usbCtrlTrans(0x23, 0x00);
  272. }
  273. else if(range == OscChannelRange::CR_5V)
  274. {
  275. m_ctrlByte1 |= 0x02;
  276. m_usbInterface->usbCtrlTrans(0x23, 0x00);
  277. }
  278. else if(range == OscChannelRange::CR_8V)
  279. {
  280. m_usbInterface->usbCtrlTrans(0x23, 0x00);
  281. }
  282. else
  283. {
  284. SPDLOG_LOGGER_ERROR(m_logger, "输入量程设置错误!");
  285. return;
  286. }
  287. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  288. setZeroVoltageAndCalibration(OscChannel::CH_B, range);
  289. }
  290. /**
  291. * @brief 设置通道耦合方式
  292. *
  293. * @param channel 通道
  294. * @param coupling 耦合方式,DC或者AC
  295. */
  296. void OscilloscopeData::setChannelCoupling(OscChannel channel, OscChannelCoupling coupling)
  297. {
  298. if(m_usbInterface == nullptr)
  299. {
  300. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  301. return;
  302. }
  303. if(channel == OscChannel::CH_A)
  304. {
  305. m_ctrlByte0 &= 0xef;
  306. if(coupling == OscChannelCoupling::DC) {
  307. m_ctrlByte0 |= 0x10;
  308. }
  309. else if(coupling == OscChannelCoupling::AC) {}
  310. else {
  311. SPDLOG_LOGGER_ERROR(m_logger, "耦合方式设置错误!");
  312. return;
  313. }
  314. m_usbInterface->usbCtrlTrans(0x94, m_ctrlByte0);
  315. }
  316. else if(channel == OscChannel::CH_B)
  317. {
  318. m_ctrlByte1 &= 0xef;
  319. if(coupling == OscChannelCoupling::AC) {
  320. m_ctrlByte1 |= 0x10;
  321. }
  322. else if(coupling == OscChannelCoupling::DC) {}
  323. else {
  324. SPDLOG_LOGGER_ERROR(m_logger, "耦合方式设置错误!");
  325. return;
  326. }
  327. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  328. }
  329. else
  330. {
  331. SPDLOG_LOGGER_ERROR(m_logger, "通道设置错误!");
  332. return;
  333. }
  334. }
  335. /* 开启或关闭通道A触发 */
  336. void OscilloscopeData::setChannelATrigger(bool enable)
  337. {
  338. if(m_usbInterface == nullptr)
  339. {
  340. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  341. return;
  342. }
  343. if(enable)
  344. {
  345. m_usbInterface->usbCtrlTrans(0xE7, 0x01);
  346. }
  347. else
  348. {
  349. m_usbInterface->usbCtrlTrans(0xE7, 0x00);
  350. }
  351. }
  352. /* 开启外触发 */
  353. void OscilloscopeData::setExternalTrigger(bool enable)
  354. {
  355. if(m_usbInterface == nullptr)
  356. {
  357. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  358. return;
  359. }
  360. if(enable)
  361. {
  362. m_usbInterface->usbCtrlTrans(0xE7, 0x01);
  363. m_ctrlByte1 &= 0xdf;
  364. m_ctrlByte1 |= 0x20;
  365. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  366. }
  367. else
  368. {
  369. m_usbInterface->usbCtrlTrans(0xE7, 0x00);
  370. m_ctrlByte1 &= 0xdf;
  371. m_ctrlByte1 |= 0x00;
  372. m_usbInterface->usbCtrlTrans(0x24, m_ctrlByte1);
  373. }
  374. }
  375. /* 设置触发方式 */
  376. void OscilloscopeData::setTriggerMode(OscTriggerMode mode)
  377. {
  378. if(m_usbInterface == nullptr)
  379. {
  380. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  381. return;
  382. }
  383. if(mode == OscTriggerMode::TM_RISE)
  384. {
  385. m_usbInterface->usbCtrlTrans(0xC5, 0x00);
  386. }
  387. else if (mode == OscTriggerMode::TM_DOWN)
  388. {
  389. m_usbInterface->usbCtrlTrans(0xC5, 0x01);
  390. }
  391. else if (mode == OscTriggerMode::TM_DOUBLE)
  392. {
  393. m_usbInterface->usbCtrlTrans(0xC5, 0x03);
  394. }
  395. }
  396. /**
  397. * @brief 设置触发电平
  398. *
  399. * @param level 0~255的值
  400. */
  401. void OscilloscopeData::setTriggerLevel(unsigned char level)
  402. {
  403. if(m_usbInterface == nullptr)
  404. {
  405. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  406. return;
  407. }
  408. m_usbInterface->usbCtrlTrans(0x16, level);
  409. }
  410. /* 设置触发灵敏度 */
  411. void OscilloscopeData::setTriggerSensitivity(OscTriggerSensitivity sensitivity)
  412. {
  413. if(m_usbInterface == nullptr)
  414. {
  415. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  416. return;
  417. }
  418. if(sensitivity == OscTriggerSensitivity::TS_LOW)
  419. {
  420. m_usbInterface->usbCtrlTrans(0x2b, 0);
  421. }
  422. else if(sensitivity == OscTriggerSensitivity::TS_HIGH)
  423. {
  424. m_usbInterface->usbCtrlTrans(0x2b, 1);
  425. }
  426. else
  427. {
  428. SPDLOG_LOGGER_ERROR(m_logger, "触发灵敏度设置错误!");
  429. return;
  430. }
  431. }
  432. /* 设置触发在缓冲区的哪个位置 */
  433. void OscilloscopeData::setTriggerPosition(unsigned char lowByte, unsigned char highByte)
  434. {
  435. if(m_usbInterface == nullptr)
  436. {
  437. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  438. return;
  439. }
  440. m_usbInterface->usbCtrlTrans(0x18, lowByte);
  441. m_usbInterface->usbCtrlTrans(0x17, highByte);
  442. }
  443. /* 获取示波器不同档位下的零电压值 */
  444. void OscilloscopeData::getZeroVoltage()
  445. {
  446. if(m_usbInterface == nullptr)
  447. {
  448. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  449. return;
  450. }
  451. /* 获取通道A零电压值 */
  452. unsigned char zeroVoltage = 0;
  453. /* 2V档位,正负8V量程 */
  454. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x82);
  455. m_mapChAZeroVoltage.insert(OscChannelRange::CR_8V, zeroVoltage);
  456. /* 1V档位,正负5V量程 */
  457. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x01);
  458. m_mapChAZeroVoltage.insert(OscChannelRange::CR_5V, zeroVoltage);
  459. /* 500mV档位,正负2.5V量程 */
  460. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x0e);
  461. m_mapChAZeroVoltage.insert(OscChannelRange::CR_2V5, zeroVoltage);
  462. /* 200mV档位,正负1V量程 */
  463. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x14);
  464. m_mapChAZeroVoltage.insert(OscChannelRange::CR_1V, zeroVoltage);
  465. /* 100mV档位,正负500mV量程 */
  466. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x12);
  467. m_mapChAZeroVoltage.insert(OscChannelRange::CR_500MV, zeroVoltage);
  468. /* 50mV档位,正负250mV量程 */
  469. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x10);
  470. m_mapChAZeroVoltage.insert(OscChannelRange::CR_250MV, zeroVoltage);
  471. /* 20mV档位,正负100mV量程 */
  472. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0xa0);
  473. m_mapChAZeroVoltage.insert(OscChannelRange::CR_100MV, zeroVoltage);
  474. /* 获取通道B零电压值 */
  475. /* 2V档位,正负8V量程 */
  476. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x72);
  477. m_mapChBZeroVoltage.insert(OscChannelRange::CR_8V, zeroVoltage);
  478. /* 1V档位,正负5V量程 */
  479. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x02);
  480. m_mapChBZeroVoltage.insert(OscChannelRange::CR_5V, zeroVoltage);
  481. /* 500mV档位,正负2.5V量程 */
  482. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x0f);
  483. m_mapChBZeroVoltage.insert(OscChannelRange::CR_2V5, zeroVoltage);
  484. /* 200mV档位,正负1V量程 */
  485. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x15);
  486. m_mapChBZeroVoltage.insert(OscChannelRange::CR_1V, zeroVoltage);
  487. /* 100mV档位,正负500mV量程 */
  488. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x13);
  489. m_mapChBZeroVoltage.insert(OscChannelRange::CR_500MV, zeroVoltage);
  490. /* 50mV档位,正负250mV量程 */
  491. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0x11);
  492. m_mapChBZeroVoltage.insert(OscChannelRange::CR_250MV, zeroVoltage);
  493. /* 20mV档位,正负100mV量程 */
  494. zeroVoltage = m_usbInterface->usbCtrlTrans(0x90, 0xa1);
  495. m_mapChBZeroVoltage.insert(OscChannelRange::CR_100MV, zeroVoltage);
  496. }
  497. /* 打印出零电压值 */
  498. void OscilloscopeData::printZeroVoltage(OscChannel channel)
  499. {
  500. if(channel == OscChannel::CH_A)
  501. {
  502. for(auto it = m_mapChAZeroVoltage.begin(); it != m_mapChAZeroVoltage.end(); ++it)
  503. {
  504. SPDLOG_LOGGER_INFO(m_logger, "通道A {} 量程下的零电压值为: {}", static_cast<int>(it.key()), it.value());
  505. }
  506. }
  507. else if(channel == OscChannel::CH_B)
  508. {
  509. for(auto it = m_mapChBZeroVoltage.begin(); it != m_mapChBZeroVoltage.end(); ++it)
  510. {
  511. SPDLOG_LOGGER_INFO(m_logger, "通道B {} 量程下的零电压值为: {}", static_cast<int>(it.key()), it.value());
  512. }
  513. }
  514. else
  515. {
  516. SPDLOG_LOGGER_ERROR(m_logger, "通道设置错误!");
  517. return;
  518. }
  519. }
  520. /* 获取不同档位下电压校准系数 */
  521. void OscilloscopeData::getVoltageCalibration()
  522. {
  523. if (m_usbInterface == nullptr)
  524. {
  525. SPDLOG_LOGGER_ERROR(m_logger, "USBInterface指针为空!");
  526. return;
  527. }
  528. /* 获取通道A电压校准系数 */
  529. unsigned char voltageCalibration = 0;
  530. /* 2V档位,正负8V量程 */
  531. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0xc2);
  532. m_mapChAVoltageAmplitudeRatio.insert(OscChannelRange::CR_8V, voltageCalibration);
  533. /* 1V档位,正负5V量程 */
  534. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x03);
  535. m_mapChAVoltageAmplitudeRatio.insert(OscChannelRange::CR_5V, voltageCalibration);
  536. /* 500mV档位,正负2.5V量程 */
  537. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x08);
  538. m_mapChAVoltageAmplitudeRatio.insert(OscChannelRange::CR_2V5, voltageCalibration);
  539. /* 200mV档位,正负1V量程 */
  540. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x06);
  541. m_mapChAVoltageAmplitudeRatio.insert(OscChannelRange::CR_1V, voltageCalibration);
  542. /* 100mV档位,正负500mV量程 */
  543. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x09);
  544. m_mapChAVoltageAmplitudeRatio.insert(OscChannelRange::CR_500MV, voltageCalibration);
  545. /* 50mV档位,正负250mV量程 */
  546. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x0a);
  547. m_mapChAVoltageAmplitudeRatio.insert(OscChannelRange::CR_250MV, voltageCalibration);
  548. /* 20mV档位,正负100mV量程 */
  549. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x2a);
  550. m_mapChAVoltageAmplitudeRatio.insert(OscChannelRange::CR_100MV, voltageCalibration);
  551. /* 获取通道B电压校准系数 */
  552. /* 2V档位,正负8V量程 */
  553. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0xd2);
  554. m_mapChBVoltageAmplitudeRatio.insert(OscChannelRange::CR_8V, voltageCalibration);
  555. /* 1V档位,正负5V量程 */
  556. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x04);
  557. m_mapChBVoltageAmplitudeRatio.insert(OscChannelRange::CR_5V, voltageCalibration);
  558. /* 500mV档位,正负2.5V量程 */
  559. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x0b);
  560. m_mapChBVoltageAmplitudeRatio.insert(OscChannelRange::CR_2V5, voltageCalibration);
  561. /* 200mV档位,正负1V量程 */
  562. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x07);
  563. m_mapChBVoltageAmplitudeRatio.insert(OscChannelRange::CR_1V, voltageCalibration);
  564. /* 100mV档位,正负500mV量程 */
  565. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x0c);
  566. m_mapChBVoltageAmplitudeRatio.insert(OscChannelRange::CR_500MV, voltageCalibration);
  567. /* 50mV档位,正负250mV量程 */
  568. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x0d);
  569. m_mapChBVoltageAmplitudeRatio.insert(OscChannelRange::CR_250MV, voltageCalibration);
  570. /* 20mV档位,正负100mV量程 */
  571. voltageCalibration = m_usbInterface->usbCtrlTrans(0x90, 0x2d);
  572. m_mapChBVoltageAmplitudeRatio.insert(OscChannelRange::CR_100MV, voltageCalibration);
  573. }
  574. /* 打印出电压校准系数 */
  575. void OscilloscopeData::printVoltageCalibration(OscChannel channel)
  576. {
  577. if(channel == OscChannel::CH_A)
  578. {
  579. for(auto it = m_mapChAVoltageAmplitudeRatio.begin(); it != m_mapChAVoltageAmplitudeRatio.end(); ++it)
  580. {
  581. SPDLOG_LOGGER_INFO(m_logger, "通道A {} 量程下的电压校准系数为: {}", static_cast<int>(it.key()), it.value());
  582. }
  583. }
  584. else if(channel == OscChannel::CH_B)
  585. {
  586. for(auto it = m_mapChBVoltageAmplitudeRatio.begin(); it != m_mapChBVoltageAmplitudeRatio.end(); ++it)
  587. {
  588. SPDLOG_LOGGER_INFO(m_logger, "通道B {} 量程下的电压校准系数为: {}", static_cast<int>(it.key()), it.value());
  589. }
  590. }
  591. else
  592. {
  593. SPDLOG_LOGGER_ERROR(m_logger, "通道设置错误!");
  594. return;
  595. }
  596. }
  597. /**
  598. * @brief 采集数据,这个是子线程
  599. *
  600. */
  601. void OscilloscopeData::threadCaptureData()
  602. {
  603. SPDLOG_LOGGER_INFO(m_logger, "开始采集数据线程");
  604. m_isRunCapture = true;
  605. // unsigned char* buffer = nullptr;
  606. while(m_runCapture)
  607. {
  608. // SPDLOG_LOGGER_DEBUG(m_logger, "开始采集数据");
  609. /* 开始采集数据 */
  610. m_usbInterface->usbCtrlTransSimple(0x33);
  611. /* 清空数据缓冲区 */
  612. for(uint32_t i = 0; i < BUFFER_SIZE; i++)
  613. {
  614. m_buffer[i] = 0;
  615. }
  616. /* 查询数据是否采集完成(应该是填充满128KB的SRAM)
  617. * 注意,这里是十进制33,不是0x33 */
  618. while(m_usbInterface->usbCtrlTransSimple(0x50) != 33)
  619. {
  620. std::this_thread::sleep_for(std::chrono::microseconds(10));
  621. }
  622. // SPDLOG_LOGGER_DEBUG(m_logger, "硬件缓冲区已满");
  623. /* 将数据从示波器的SRAM中拷贝到电脑内存中,1次传输完成,设置超时时间1ms */
  624. m_usbInterface->readBulkData(BUFFER_SIZE, 1, 100, m_devBuffer);
  625. /* 等待传输完成 */
  626. auto ret = m_usbInterface->eventCheck(100);
  627. if(ret == 0x555)
  628. {
  629. SPDLOG_LOGGER_ERROR(m_logger, "数据传输超时!");
  630. // continue;
  631. }
  632. // SPDLOG_LOGGER_DEBUG(m_logger, "数据通过USB传输完成");
  633. /* 取出数据 */
  634. // buffer = m_ringQueue.back();
  635. m_mutexCaptureData.lock();
  636. std::memcpy(m_buffer, m_devBuffer, BUFFER_SIZE);
  637. m_isCaptureData = true;
  638. m_mutexCaptureData.unlock();
  639. /* 清空缓冲区 */
  640. m_usbInterface->resetPipe();
  641. // SPDLOG_LOGGER_DEBUG(m_logger, "count: {}", count++);
  642. }
  643. m_isRunCapture = false;
  644. }
  645. /* 处理数据线程 */
  646. void OscilloscopeData::threadProcessData()
  647. {
  648. SPDLOG_LOGGER_INFO(m_logger, "开始处理数据线程");
  649. while(m_runCapture)
  650. {
  651. if(m_isCaptureData.load())
  652. {
  653. m_mutexCaptureData.lock();
  654. /* 分离通道AB的数据 */
  655. for(uint32_t i = 0; i < BUFFER_SIZE / 2; i++)
  656. {
  657. m_bufferChnA[i] = m_buffer[i * 2];
  658. // m_bufferChnB[i] = m_buffer[i * 2 + 1];
  659. }
  660. m_isCaptureData = false;
  661. m_mutexCaptureData.unlock();
  662. /* 处理数据 */
  663. // SPDLOG_LOGGER_DEBUG(m_logger, "开始处理数据,通道A数据: {}, 通道B数据: {}", m_bufferChnA[32000], m_bufferChnB[32000]);
  664. /* 矫正零电压值 */
  665. }
  666. /* 打印1000个数据 */
  667. // for(uint32_t i = 0; i < BUFFER_SIZE/2; i++)
  668. // {
  669. // if((m_bufferChnA[i] == 128) && (m_bufferChnB[i] == 128))
  670. // continue;
  671. // SPDLOG_LOGGER_DEBUG(m_logger, "A: {}, B: {}", m_bufferChnA[i], m_bufferChnB[i]);
  672. // }
  673. // SPDLOG_LOGGER_DEBUG(m_logger, "输出完成");
  674. /* 对零电平进行矫正 */
  675. /* 处理眼图数据 */
  676. parseEyeMapData(m_bufferChnA, BUFFER_SIZE / 2);
  677. std::this_thread::sleep_for(std::chrono::microseconds(10));
  678. }
  679. }
  680. /* 根据采样点数添加颜色 */
  681. void OscilloscopeData::threadAddColorBySample()
  682. {
  683. while(m_runCapture)
  684. {
  685. g_eyeMapMatrix.mutexEyeData.lock();
  686. g_eyeMapMatrix.addColorBySample();
  687. g_eyeMapMatrix.mutexEyeData.unlock();
  688. // SPDLOG_LOGGER_DEBUG(m_logger, "添加颜色完成");
  689. /* 延时一下,让别的线程拿到锁 */
  690. std::this_thread::sleep_for(std::chrono::microseconds(10));
  691. }
  692. }
  693. /**
  694. * @brief 解析数据,眼图需要的数据,从C#代码中移植过来
  695. *
  696. * @param buffer 数据缓冲区
  697. * @param size 缓冲区大小,单位字节
  698. */
  699. void OscilloscopeData::parseEyeMapData(unsigned char* buffer, unsigned int size)
  700. {
  701. int bufferSize = size;
  702. uint8_t* array = buffer;
  703. uint8_t vaMax = 128;
  704. uint8_t vaMin = 128;
  705. uint8_t tmp = 128;
  706. /* 数据预处理,找出最大值和最小值 */
  707. for (int i = 0; i < bufferSize; i++)
  708. {
  709. /* 取出这组数据的最大值和最小值 */
  710. tmp = array[i];
  711. if (tmp < vaMin)
  712. {
  713. vaMin = tmp;
  714. }
  715. if (tmp > vaMax)
  716. {
  717. vaMax = tmp;
  718. }
  719. }
  720. /* 取绝对值,小于15丢弃,丢弃幅度小于15的数据,这部分可能不是触发的数据 */
  721. int numAmp = std::abs(vaMax - vaMin);
  722. if (numAmp <= 15)
  723. {
  724. return;
  725. }
  726. /* 计算最大值和最小值的中间数 */
  727. uint8_t vaMid = (vaMax + vaMin) / 2;
  728. /* ======================================================================== */
  729. /* 将采样点添加bool值,如果时间很短,就进行插值,每个采样点之间插入30个值 */
  730. /* 时间尺度,OscCurrentTimeScale = 100,num7 = 1.0,100MHz下每个采样点间距10ns */
  731. // double num7 = OscParams.dataNumPerPixar * OscParams.OscCurrentTimeScale / 100.0;
  732. // /* num7 * OscOneGridTime是一个时间格子中采样点的个数 */
  733. // long oneGridTime = num7 * OscParams.OscOneGridTime;
  734. // if (oneGridTime % 2 != 0L)
  735. // {
  736. // oneGridTime++;
  737. // }
  738. /* 采样率为100MHz的时候,采样点间隔时间是10ns
  739. * x轴时间是1000分度,当x轴整体时间是10us的时候,采样点和分辨率一一对应
  740. * x轴时间大于10us,采样点比分辨率高,无需做什么操作
  741. * x轴时间小于10us,采样点数量会小于1000,那么绘制的矩形小点间隔会比较长,这时候就需要进行插帧 */
  742. /* 一个时间格子的采样率个数 */
  743. int oneGridSa = OscParams.oneGridTime / OscParams.SampleIntervalTime; /* 当前一个格子中采样点的数目 */
  744. int saTotal = oneGridSa * 10; /* 一个时间格子中采样点的总数 */
  745. bool isNeedFrameInsertion = ( (oneGridSa * 10) < OscParams.eyeMapWidth ) ? true : false;
  746. int num9 = (int)((double)oneGridSa * 0.25); /* 1/4个时间格子长度 */
  747. /* 记录buffer的值,并添加bool */
  748. std::vector<EyeDataT> vecData;
  749. int numMulti = 0; /* 倍率,可能是1可能是30 */
  750. if (isNeedFrameInsertion == false)
  751. {
  752. /* 将数据放入到list中,带有bool标志位,全部启用 */
  753. for (int i = 0; i < bufferSize; i++)
  754. {
  755. vecData.push_back(EyeDataT(true, array[i]));
  756. }
  757. numMulti = 1;
  758. }
  759. else
  760. {
  761. /* 缩放系数小于1.0,下面会进行插值 */
  762. int numTmp = bufferSize - 1;
  763. float num11 = 0.0;
  764. bool flag2 = false;
  765. /* */
  766. uint8_t b2 = 0;
  767. uint8_t b3 = 0;
  768. uint8_t b = 0;
  769. int num5 = 0;
  770. /* 进行插值,每个采样点之间插30个值 */
  771. for (int i = 0; i < numTmp; i++)
  772. {
  773. b2 = array[i]; /* 偶数位 */
  774. b3 = array[i + 1]; /* 奇数位 */
  775. /* 在b2和b3之间添加30个插值 */
  776. num11 = (float)(b3 - b2) / 30.f; /* 将幅值分成30份 */
  777. vecData.push_back(EyeDataT(true, b2));
  778. num5 = 30;
  779. /* Qt的全局随机数生成器 */
  780. auto random = QRandomGenerator::global();
  781. for (int j = 0; j < num5; j++)
  782. {
  783. /* 四舍五入 */
  784. b = std::round((num11 * (float)j) + (int)b2);
  785. // flag2 = ((1 == random.Next(1)) ? true : false);
  786. // flag2 = ((1 == random->bounded(0, 1)) ? true : false);
  787. vecData.push_back(EyeDataT(true, b));
  788. }
  789. vecData.push_back(EyeDataT(true, b3));
  790. }
  791. numMulti = 30;
  792. }
  793. if (vecData.size() <= 0)
  794. {
  795. return;
  796. }
  797. num9 *= numMulti; /* 1/4个时间格子长度,乘以倍数 */
  798. /* oneJumpSa是一个跳变沿的采样点个数 */
  799. // long oneJumpSa = oneGridSa * numMulti;
  800. long oneJumpSa = saTotal * numMulti;
  801. // long oneJumpSa = 1000;
  802. /* ======================================================================== */
  803. /* 寻找波形,找到上升沿和下降沿 */
  804. /* 存储下标 */
  805. std::vector<int> listSub;
  806. size_t numDataSize = vecData.size() - num9;
  807. bool flag3 = true;
  808. /* 找到数组中的上升沿和下降沿,并记录其坐标
  809. * 这里寻找上升沿和下降沿是检测的中间值,是每个跳变沿的中部
  810. * 中间值理论上是零值 */
  811. uint8_t vaPre = 0;
  812. // uint8_t va = 0;
  813. uint8_t vaNext = 0;
  814. for (int i = 10; i < numDataSize; i++)
  815. {
  816. /* 取出相邻的三个值 */
  817. vaPre = vecData[i - 1].value;
  818. // va = vecData[i].value;
  819. vaNext = vecData[i + 1].value;
  820. if (flag3)
  821. {
  822. /* 上升沿,就是中间值 */
  823. if (vaPre <= vaMid && vaNext > vaMid)
  824. {
  825. listSub.push_back(i); /* 记录下标 */
  826. flag3 = !flag3; /* 不再检测上升沿,检测下降沿 */
  827. }
  828. }
  829. /* 下降沿 */
  830. else if (vaPre >= vaMid && vaNext < vaMid)
  831. {
  832. listSub.push_back(i);
  833. flag3 = !flag3;
  834. }
  835. /* 采集到600个上升沿和下降沿 */
  836. if (listSub.size() >= 600)
  837. {
  838. break;
  839. }
  840. }
  841. if (listSub.size() <= 0)
  842. {
  843. return;
  844. }
  845. /* ======================================================================== */
  846. /* 这里应该是根据跳变沿的中间值,取出完整的跳变沿
  847. * 创建一个二维数组,每一行就是一个跳变沿 */
  848. std::vector<std::vector<EyeDataT>> vec2DEyeData;
  849. int jumpStart = 0; /* 跳变沿起点 */
  850. size_t jumpEnd = 0; /* 跳变沿终点 */
  851. int num17 = 0;
  852. size_t numSubSize = listSub.size(); /* 跳变沿下标的个数 */
  853. int oneThirdSa = (int)(oneJumpSa / 3); /* 一个时间格子中三分之一的采样点个数 */
  854. int numSub1 = 0;
  855. int numSub2 = 0;
  856. for (int i = 0; i < numSubSize; i++)
  857. {
  858. int j = 0;
  859. /* 这一个数组就是一个跳变沿,num12是一个跳变沿所有的采样点的个数 */
  860. std::vector<EyeDataT> vecDataTmp(oneJumpSa, EyeDataT(false, 0));
  861. numSub1 = listSub[i]; /* 取出下标值 */
  862. numSub2 = numSub1 - oneThirdSa; /* 下标往后倒退1/3个时间格子的采样点数,当作起点 */
  863. /* 判断是否小于0,这里是起点 */
  864. jumpStart = numSub2;
  865. if (jumpStart <= 0)
  866. {
  867. jumpStart = 0;
  868. }
  869. /* 终点往后2/3个时间格子的采样点数,当作终点 */
  870. jumpEnd = numSub1 + oneThirdSa * 2;
  871. if (jumpEnd >= vecData.size())
  872. {
  873. jumpEnd = vecData.size() - 1;
  874. }
  875. /* 这里为了去掉jumpStart前面的值,让vecDataTmp从0开始计数 */
  876. num17 = 0;
  877. if (numSub2 < 0)
  878. {
  879. num17 = std::abs(numSub2);
  880. }
  881. if (numSub2 > 0)
  882. {
  883. num17 = -numSub2;
  884. }
  885. /* num14是起点,num15是终点,num17应该是个负值,num17+j从0开始计数 */
  886. for (j = jumpStart; j < jumpEnd; j++)
  887. {
  888. vecDataTmp[num17 + j].isEyeData = vecData[j].isEyeData;
  889. vecDataTmp[num17 + j].value = vecData[j].value;
  890. }
  891. // for(j = 0; j < oneGridTime2; j++)
  892. // {
  893. // vecDataTmp[j].isEyeData = vecData[jumpStart + j].isEyeData;
  894. // vecDataTmp[j].value = vecData[jumpStart + j].value;
  895. // }
  896. vec2DEyeData.push_back(vecDataTmp);
  897. }
  898. // listSub.clear();
  899. // vecData.clear();
  900. if (vec2DEyeData.size() <= 0)
  901. {
  902. return;
  903. }
  904. /* ======================================================================== */
  905. int num18 = 0;
  906. float num20 = 0.0;
  907. /* 将数据拷贝到OscData的Matrix中 */
  908. size_t numTmp = 0;
  909. int ValTmp = 0;
  910. /* 将跳变沿数据放入到全局变量中,并根据坐标进行排列
  911. * x轴是这个跳变沿根据时间平分1000份
  912. * y轴是这个值 */
  913. g_eyeDataMatrix.mutexEyeData.lock();
  914. for (int i = 0; i < vec2DEyeData.size(); i++)
  915. {
  916. /* 取出一个跳变沿,将其分布在整个 1000 * 256像素的矩阵中 */
  917. std::vector<EyeDataT>& vecTmp = vec2DEyeData[i];
  918. numTmp = vecTmp.size();
  919. num20 = numTmp / 1000.f; /* x轴方向1000分 */
  920. for (int i = 0; i < numTmp; i++)
  921. {
  922. if (vecTmp[i].isEyeData)
  923. {
  924. ValTmp = vecTmp[i].value;
  925. num18 = (int)((float)i / num20);
  926. /* 将数据添加到眼图矩阵中 */
  927. g_eyeDataMatrix.addData(num18, ValTmp);
  928. }
  929. }
  930. }
  931. g_eyeDataMatrix.eyeStatisticalWeight();
  932. g_eyeDataMatrix.eyeLessenTheBurden();
  933. vec2DEyeData.clear();
  934. auto eyeData = g_eyeDataMatrix.eyeZoomOut();
  935. g_eyeDataMatrix.mutexEyeData.unlock();
  936. g_eyeMapMatrix.mutexEyeData.lock();
  937. g_eyeMapMatrix.copyDataMatrix(*eyeData);
  938. g_eyeMapMatrix.mutexEyeData.unlock();
  939. }
  940. /* 设置零电压值和电压校准系数 */
  941. void OscilloscopeData::setZeroVoltageAndCalibration(OscChannel chn, OscChannelRange range)
  942. {
  943. if(chn == OscChannel::CH_A)
  944. {
  945. /* 电压幅值比 */
  946. uint8_t altitudeByteA = 0;
  947. m_zeroVoltageA = m_mapChAZeroVoltage.value(range);
  948. altitudeByteA = m_mapChAVoltageAmplitudeRatio.value(range);
  949. if(range == OscChannelRange::CR_100MV)
  950. {
  951. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  952. m_rangeRatioA = 0.1 / 255.0;
  953. }
  954. else if(range == OscChannelRange::CR_250MV)
  955. {
  956. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  957. m_rangeRatioA = 0.25 / 255.0;
  958. }
  959. else if(range == OscChannelRange::CR_500MV)
  960. {
  961. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  962. m_rangeRatioA = 0.5 / 255.0;
  963. }
  964. else if(range == OscChannelRange::CR_1V)
  965. {
  966. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  967. m_rangeRatioA = 1.0 / 255.0;
  968. }
  969. else if(range == OscChannelRange::CR_2V5)
  970. {
  971. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  972. m_rangeRatioA = 2.5 / 255.0;
  973. }
  974. else if(range == OscChannelRange::CR_5V)
  975. {
  976. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  977. m_rangeRatioA = 5.0 / 255.0;
  978. }
  979. else if(range == OscChannelRange::CR_8V)
  980. {
  981. m_voltageCalibrationA = (altitudeByteA * 2) / 255.0;
  982. m_rangeRatioA = 8.0 / 255.0;
  983. }
  984. }
  985. else if(chn == OscChannel::CH_B)
  986. {
  987. /* 电压幅值比 */
  988. uint8_t altitudeByteB = 0;
  989. m_zeroVoltageB = m_mapChBZeroVoltage.value(range);
  990. altitudeByteB = m_mapChBVoltageAmplitudeRatio.value(range);
  991. if(range == OscChannelRange::CR_100MV)
  992. {
  993. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  994. m_rangeRatioB = 0.1 / 255.0;
  995. }
  996. else if(range == OscChannelRange::CR_250MV)
  997. {
  998. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  999. m_rangeRatioB = 0.25 / 255.0;
  1000. }
  1001. else if(range == OscChannelRange::CR_500MV)
  1002. {
  1003. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1004. m_rangeRatioB = 0.5 / 255.0;
  1005. }
  1006. else if(range == OscChannelRange::CR_1V)
  1007. {
  1008. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1009. m_rangeRatioB = 1.0 / 255.0;
  1010. }
  1011. else if(range == OscChannelRange::CR_2V5)
  1012. {
  1013. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1014. m_rangeRatioB = 2.5 / 255.0;
  1015. }
  1016. else if(range == OscChannelRange::CR_5V)
  1017. {
  1018. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1019. m_rangeRatioB = 5.0 / 255.0;
  1020. }
  1021. else if(range == OscChannelRange::CR_8V)
  1022. {
  1023. m_voltageCalibrationB = (altitudeByteB * 2) / 255.0;
  1024. m_rangeRatioB = 8.0 / 255.0;
  1025. }
  1026. }
  1027. }
  1028. /* 校准电压 */
  1029. double OscilloscopeData::calibrationVoltageA(uint8_t& data)
  1030. {
  1031. return m_voltageCalibrationA * m_rangeRatioA * (data - m_zeroVoltageA);
  1032. }
  1033. double OscilloscopeData::calibrationVoltageB(uint8_t& data)
  1034. {
  1035. return m_voltageCalibrationB * m_rangeRatioB * (data - m_zeroVoltageB);
  1036. }