DAControl.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. // DAControl.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include "stdafx.h"
  4. #include "DAControl.h"
  5. #include "SynSerial.h"
  6. #ifdef __MAKE_PYD__
  7. #include "Python.h"
  8. #endif
  9. #define SENDLEN 6
  10. bool g_bEnableLoad = false;
  11. std::string g_strXMLPath;
  12. std::vector<KeyItem> g_vtKeyItem;
  13. CSynSerial g_synSerial;
  14. // 最大电压值;
  15. float g_fMaxVoltage = 0.0;
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #endif
  19. unsigned char Integer2Hex(int val);
  20. #ifdef __CONSOLE__
  21. // 唯一的应用程序对象
  22. CWinApp theApp;
  23. using namespace std;
  24. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  25. {
  26. int nRetCode = 0;
  27. // 初始化 MFC 并在失败时显示错误
  28. if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  29. {
  30. // TODO: 更改错误代码以符合您的需要
  31. _tprintf(_T("错误: MFC 初始化失败\n"));
  32. nRetCode = 1;
  33. }
  34. else
  35. {
  36. // TODO: 在此处为应用程序的行为编写代码。
  37. #if 1
  38. // 获取个位数和小数位;
  39. int a = 0, b = 0; // 个位数,小数位;
  40. TCHAR szVolt[16] = {0};
  41. _gcvt_s(szVolt, 3.256, 4);
  42. sscanf_s(szVolt, _T("%d.%d"), &a, &b);
  43. for ( int i = 1; i >= 0; i--) {
  44. byte szSendData[10] = {0};
  45. _stprintf_s((TCHAR*)szSendData, 10, _T("%c%c%c%c%c"), 0x5A, 0, i ? Integer2Hex(a) : 0, i ? Integer2Hex(b) : 0, 0xA5);
  46. int len = sizeof(szSendData);
  47. printf("%s, %d,%d\n", szSendData, a, b);
  48. }
  49. #else
  50. // 打开设备;
  51. if ( OpenDevice(3, 19200, 8, 0, 1) )
  52. {
  53. // 加载指定的电压表;
  54. if ( OpenXML(_T("E:\\bin\\DAControl\\demo.xml")) == 0 )
  55. {
  56. SendKey(_T("left"));
  57. }
  58. }
  59. #endif
  60. }
  61. system("pause");
  62. return nRetCode;
  63. }
  64. #endif
  65. std::string tolower(const char *p)
  66. {
  67. if ( p == NULL )
  68. return std::string();
  69. std::string str;
  70. while ( *p != '\0') {
  71. if ( *p >= 'A' && *p <= 'Z' )
  72. str.append(1,*p + 32);
  73. else
  74. str.append(1,*p);
  75. p++;
  76. }
  77. return str;
  78. }
  79. std::string toupper(const char *p)
  80. {
  81. if ( p == NULL )
  82. return std::string();
  83. std::string str;
  84. while ( *p != '\0') {
  85. if ( *p >= 'a' && *p <= 'z' )
  86. str.append(1,*p - 32);
  87. else
  88. str.append(1,*p);
  89. p++;
  90. }
  91. return str;
  92. }
  93. // 数字转16进制,如:12 => 0x12
  94. unsigned char Integer2Hex(int val)
  95. {
  96. // 只取10数和个数;
  97. while( val > 99 )
  98. val = val/10;
  99. char Numb1 = val/10 + '0'; // 10位数;
  100. char Numb2 = val%10 + '0'; // 个位数;
  101. if (Numb1 >= 'A')
  102. Numb1 = (toupper(Numb1) - '0' - 7) * 16;
  103. else
  104. Numb1 = (Numb1 - '0') * 16;
  105. if (Numb2 >= 'A')
  106. Numb2 = (toupper(Numb2) - '0' - 7);
  107. else
  108. Numb2 = (Numb2 - '0');
  109. return (Numb1 + Numb2);
  110. }
  111. int __LoadXML(LPCTSTR lpXMLPath)
  112. {
  113. if ( !lpXMLPath || !PathFileExists(lpXMLPath) )
  114. return -1;
  115. g_strXMLPath = lpXMLPath;
  116. // 解析xml;
  117. tinyxml2::XMLDocument doc;
  118. if (tinyxml2::XML_SUCCESS != doc.LoadFile(lpXMLPath))
  119. return -1;
  120. tinyxml2::XMLElement *pXmlRoot = NULL;
  121. if ((pXmlRoot = doc.RootElement()) != NULL) {
  122. if (_tcsicmp(pXmlRoot->Value(), "KeyList") == 0) {
  123. // 属性;
  124. const tinyxml2::XMLAttribute *pAttr = pXmlRoot->FirstAttribute();
  125. while (pAttr) {
  126. if (_tcsicmp(pAttr->Name(), "MaxVolt") == 0) {
  127. // 读出最大电压值;
  128. const char* pVal = pAttr->Value();
  129. if ( pVal ) {
  130. g_fMaxVoltage = _tstof(pVal);
  131. }
  132. break;
  133. }
  134. pAttr = pAttr->Next();
  135. }
  136. // 没有限制电压值;
  137. if ( g_fMaxVoltage == 0.0 )
  138. return -1;
  139. // 子项;
  140. tinyxml2::XMLElement *pXmlElent = pXmlRoot->FirstChildElement();
  141. while (pXmlElent) {
  142. KeyItem keyItem;
  143. if (_tcsicmp(pXmlElent->Value(), _T("ITEM")) == 0) {
  144. tinyxml2::XMLElement *pItem = pXmlElent->FirstChildElement();
  145. while (pItem) {
  146. if (_tcsicmp(pItem->Value(), _T("KeyName")) == 0) {
  147. keyItem.keyName = tolower(pItem->GetText());
  148. }
  149. else if (_tcsicmp(pItem->Value(), _T("KeyDesc")) == 0) {
  150. keyItem.keyDesc = pItem->GetText();
  151. }
  152. else if (_tcsicmp(pItem->Value(), _T("KeyVolt")) == 0) {
  153. keyItem.keyVolt = _tstof(pItem->GetText());
  154. }
  155. else if (_tcsicmp(pItem->Value(), _T("KeyIndex")) == 0) {
  156. keyItem.keyIndex = _tstoi(pItem->GetText());
  157. }
  158. pItem = pItem->NextSiblingElement();
  159. }
  160. }
  161. // 如果已经添加过的;
  162. KeyItem *pkeyItem = FindItem(keyItem.keyName.c_str());
  163. if ( pkeyItem ) {
  164. pkeyItem->keyDesc = keyItem.keyDesc;
  165. pkeyItem->keyVolt = keyItem.keyVolt;
  166. pkeyItem->keyIndex = keyItem.keyIndex;
  167. }
  168. else
  169. g_vtKeyItem.push_back(keyItem);
  170. pXmlElent = pXmlElent->NextSiblingElement();
  171. }
  172. }
  173. }
  174. return 0;
  175. }
  176. //////////////////////////////////////////////////////////////////////////
  177. // API函数接口;
  178. DACONTROL_API KeyItem* FindItem(LPCTSTR lpKeyName)
  179. {
  180. if ( !lpKeyName || lpKeyName[0] == '\0' )
  181. return NULL;
  182. for ( std::vector<KeyItem>::iterator it = g_vtKeyItem.begin(); it != g_vtKeyItem.end(); it++ ) {
  183. if ( _tcsicmp(it->keyName.c_str(), lpKeyName) == 0 ) {
  184. return &*it;
  185. break;
  186. }
  187. }
  188. return NULL;
  189. }
  190. DACONTROL_API int OpenXML(LPCTSTR lpXMLPath)
  191. {
  192. g_vtKeyItem.clear();
  193. return __LoadXML(lpXMLPath);
  194. }
  195. DACONTROL_API int LoadXML(LPCTSTR lpXMLPath)
  196. {
  197. return __LoadXML(lpXMLPath);
  198. }
  199. // 打开串口;
  200. DACONTROL_API BOOL OpenDevice(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE Parity, BYTE StopBits)
  201. {
  202. // 关闭打开的;
  203. if ( g_synSerial.IsOpen() )
  204. g_synSerial.CloseSerialPort();
  205. g_synSerial.OpenSerialPort(nPort, dwBaudrate, ByteSize, Parity, StopBits, 0, 1000);
  206. return g_synSerial.IsOpen();
  207. }
  208. // 关闭串口;
  209. DACONTROL_API void CloseDevice()
  210. {
  211. if ( g_synSerial.IsOpen() )
  212. g_synSerial.CloseSerialPort();
  213. }
  214. DACONTROL_API bool SendKey(LPCTSTR lpKeyName)
  215. {
  216. if ( !g_synSerial.IsOpen() )
  217. return false;
  218. KeyItem *pkeyItem = FindItem(lpKeyName);
  219. if ( pkeyItem == NULL )
  220. return false;
  221. // 电压过限;
  222. if ( pkeyItem->keyVolt > g_fMaxVoltage )
  223. return false;
  224. // 获取个位数和小数位;
  225. int a = 0, b = 0; // 个位数,小数位;
  226. TCHAR szVolt[16] = {0};
  227. _gcvt_s(szVolt, pkeyItem->keyVolt, 4);
  228. sscanf_s(szVolt, _T("%d.%d"), &a, &b);
  229. // 封装发送包[0x5A, <通道号>, <电压个位数>, <电压小数位>, <A5>];
  230. // 串口返回:原样返回数据;
  231. for ( int i = 1; i >= 0; i--) {
  232. byte szSendData[SENDLEN] = {0};
  233. _stprintf_s((TCHAR*)szSendData, SENDLEN, _T("%c%c%c%c%c"), 0x5A, pkeyItem->keyIndex, i ? Integer2Hex(a) : 0, i ? Integer2Hex(b) : 0, 0xA5);
  234. DWORD dwNumberOfBytesWritten = g_synSerial.WriteComm(szSendData, SENDLEN - 1);
  235. if ( dwNumberOfBytesWritten != (SENDLEN - 1) )
  236. return false;
  237. DWORD dwNumberOfBytesRead = g_synSerial.ReadComm(szSendData, dwNumberOfBytesWritten);
  238. //return dwNumberOfBytesRead ? true : false;
  239. Sleep(300);
  240. }
  241. return true;
  242. }
  243. #ifdef __MAKE_PYD__
  244. //////////////////////////////////////////////////////////////////////////
  245. // PYD接口;
  246. static PyObject* OpenXML(PyObject* self, PyObject* args)
  247. {
  248. // 电压表程序路径;
  249. const char* pszXmlPath = NULL;
  250. if (!PyArg_ParseTuple(args, "s", &pszXmlPath))
  251. return NULL;
  252. // 加载成功返回0;
  253. return Py_BuildValue("i", OpenXML(pszXmlPath));
  254. }
  255. static PyObject* LoadXML(PyObject* self, PyObject* args)
  256. {
  257. // 电压表程序路径;
  258. const char* pszXmlPath = NULL;
  259. if (!PyArg_ParseTuple(args, "s", &pszXmlPath))
  260. return NULL;
  261. // 加载成功返回0;
  262. return Py_BuildValue("i", LoadXML(pszXmlPath));
  263. }
  264. static PyObject* OpenDevice(PyObject* self, PyObject* args)
  265. {
  266. int nPort;
  267. if (!PyArg_ParseTuple(args, "i", &nPort))
  268. return NULL;
  269. return Py_BuildValue("b", OpenDevice(nPort, 9600, 8, 0, 1)); // 返回None;
  270. }
  271. //描述:连接设备,默认连接索引为0的设备;
  272. static PyObject* CloseDevice(PyObject* self, PyObject* args)
  273. {
  274. ::CloseDevice();
  275. return Py_BuildValue("");
  276. }
  277. static PyObject* SendKey(PyObject* self, PyObject* args)
  278. {
  279. const char* pszKenName = NULL;
  280. if (!PyArg_ParseTuple(args, "s", &pszKenName))
  281. return NULL;
  282. return Py_BuildValue("b", SendKey(pszKenName));
  283. }
  284. // 描述方法,暴露给python的函数;
  285. static PyMethodDef DAControl_Methods[] = {
  286. {"OpenXML",OpenXML,METH_VARARGS,"打开电压表文件(清空之前的)"},
  287. {"LoadXML", LoadXML, METH_VARARGS, "打开电压表文件(不清空,累加)"},
  288. {"OpenDevice", OpenDevice, METH_VARARGS, "打开设备"},
  289. {"CloseDevice", CloseDevice, METH_VARARGS, "关闭设备"},
  290. {"SendKey", SendKey, METH_VARARGS, "发送物理电压"},
  291. {NULL,NULL}
  292. };
  293. // 初始模块;//格式:init<模块名称>
  294. PyMODINIT_FUNC initDAControl()
  295. {
  296. // 初始化pyd函数列表;
  297. PyObject* m, * d;
  298. m = Py_InitModule("DAControl", DAControl_Methods);
  299. d = PyModule_GetDict(m);
  300. }
  301. #endif