OscData.cpp 33 KB

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