MSegment.cpp
上传用户:hailongwei
上传日期:2020-11-29
资源大小:5839k
文件大小:6k
源码类别:

单片机开发

开发平台:

Visual C++

  1. // MSegment.cpp : CMSegment 的实现
  2. #include "stdafx.h"
  3. #include "MSegment.h"
  4. // CMSegment
  5. //接受串口数据
  6. LRESULT CMSegment::OnReceivedData( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  7. {
  8. long len;
  9. char str[100];
  10. len = comm.Read( str, 100 );
  11. if ( len > 0 ) doPraseString( str );
  12. return 0;
  13. }
  14. long CMSegment::doChartToLong(char s)
  15. {
  16. switch( s )
  17. {
  18. case '0':
  19. return 0X0;
  20. break;
  21. case '1':
  22. return 0X1;
  23. break;
  24. case '2':
  25. return 0X2;
  26. break;
  27. case '3':
  28. return 0X3;
  29. break;
  30. case '4':
  31. return 0X4;
  32. break;
  33. case '5':
  34. return 0X5;
  35. break;
  36. case '6':
  37. return 0X6;
  38. break;
  39. case '7':
  40. return 0X7;
  41. break;
  42. case '8':
  43. return 0X8;
  44. break;
  45. case '9':
  46. return 0X9;
  47. break;
  48. case 'A':
  49. return 0XA;
  50. break;
  51. case 'B':
  52. return 0XB;
  53. break;
  54. case 'C':
  55. return 0XC;
  56. break;
  57. case 'D':
  58. return 0XD;
  59. break;
  60. case 'E':
  61. return 0XE;
  62. break;
  63. case 'F':
  64. return 0XF;
  65. break;
  66. default:
  67. return 0X0;
  68. break;
  69. }
  70. }
  71. void CMSegment::doPraseString( char* ps )
  72. {
  73. int i = 0;
  74. long data0 = 0;
  75. char* s = ps;
  76. do
  77. {
  78. switch ( *s )
  79. {
  80. case 'x3A':
  81. bz = 1;
  82. m_index = 0;
  83. m_Char1[0] = *s;
  84. break;
  85. case 'x0A':
  86. if ( bz = 1 )
  87. {
  88. bz = 0;
  89. if ( m_Char1[1] == 'x30' && m_Char1[2] == 'x31' && m_Char1[3] == 'x30' && m_Char1[4] == 'x32' )
  90. {
  91. for ( i = 0; i < 32; i++ )
  92. {
  93. data0 = 0;
  94. data0 += doChartToLong( m_Char1[ 7 + 2 * i ] ) * 0X10;
  95. data0 += doChartToLong( m_Char1[ 8 + 2 * i ] ) ;
  96. data[ 8 * i + 7 ] =data0 & 0X80;
  97. data[ 8 * i + 6 ] =data0 & 0X40;
  98. data[ 8 * i + 5 ] =data0 & 0X20;
  99. data[ 8 * i + 4 ] =data0 & 0X10;
  100. data[ 8 * i + 3 ] =data0 & 0X8;
  101. data[ 8 * i + 2 ] =data0 & 0X4;
  102. data[ 8 * i + 1 ] =data0 & 0X2;
  103. data[ 8 * i + 0 ] =data0 & 0X1;
  104. }
  105. //if ( m_DataReceived )
  106. //{
  107. //通知信号变化
  108. for ( i = 0; i < 256; i++ )
  109. {
  110. if ( m_notify[i] )
  111. {
  112. if ( data[i] ^ m_data[i] )
  113. {
  114. ::PostMessage( m_hWndCD, WM_MYSELF, 1, i );
  115. }
  116. }
  117. m_data[ i ] = data[ i ];
  118. }
  119. //} 
  120. //for ( i = 0; i < 256; i++ )
  121. //{
  122. // m_data[ i ] = data[ i ];
  123. //}
  124. m_DataReceived = true;
  125. }
  126. }
  127. break;
  128. default:
  129. if ( bz = 1 )
  130. {
  131. bz = 0;
  132. m_index++;
  133. if ( m_index < 300 ) m_Char1[m_index] = *s;
  134. }
  135. break;
  136. }
  137. s++;
  138. while( *s );
  139. }
  140. //延时
  141. void CMSegment::doDelay( long TimeSpan )
  142. {
  143. long dwStart = GetTickCount();
  144. long dwEnd = dwStart;
  145. do
  146. {
  147. MSG msg;
  148. if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  149. {
  150. GetMessage( &msg, NULL, 0, 0 );
  151. TranslateMessage( &msg );
  152. DispatchMessage( &msg );
  153. dwEnd = GetTickCount() - dwStart;
  154. } while( dwEnd < TimeSpan );
  155. }
  156. //请求联机用的延时判断
  157. bool CMSegment::doWaitOpenLink( void )
  158. {
  159. bool waitresult = false;
  160. m_DataReceived = false;
  161. DWORD dwStart = GetTickCount();
  162. DWORD dwEnd = dwStart;
  163. do
  164. {
  165. if ( m_DataReceived )
  166. {
  167. waitresult = true;
  168. break;
  169. }
  170. MSG  msg;
  171. if ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  172. {
  173. GetMessage( &msg, NULL, 0, 0 );
  174. TranslateMessage( &msg );
  175. DispatchMessage( &msg );
  176. dwEnd = GetTickCount() - dwStart;
  177. } while ( dwEnd < 2000 );
  178. return waitresult;
  179. }
  180. //初始化变量
  181. void CMSegment::doinit( void )
  182. {
  183. for ( int i = 0; i < 256; i++ )
  184. {
  185. data[i] = false;
  186. m_data[i] = false;
  187. }
  188. bz = 0;
  189. m_index = 0;
  190. m_link = false; 
  191. m_DataReceived = false;
  192. m_allowsend = true;
  193. m_NoneInterval = 0;
  194. }
  195. //联机
  196. STDMETHODIMP CMSegment::OpenLink(LONG Comport, BSTR CommString)
  197. {
  198. //取串口通讯协议
  199. CString str1( CommString );
  200. SysFreeString( CommString );
  201. KillTimer( IDT_TIMER1 );
  202. if ( comm.IsOpen() ) comm.Close();
  203. doinit();
  204. if ( comm.Open( Comport, ( char* )( LPCTSTR )str1 ) )//打开串口,通讯协议9600,e,7,1
  205. {
  206. comm.SetWnd( m_hWndCD );
  207. comm.Write( ":0102080000FFF6x0Dx0A" );//发送读取状态
  208. if( doWaitOpenLink() )
  209. {
  210. m_link = true;
  211. SetTimer( IDT_TIMER1 , 500 , NULL );
  212. }
  213. }
  214. Fire_OnLink( m_link ? VARIANT_TRUE : VARIANT_FALSE );
  215. return S_OK;
  216. }
  217. //脱机
  218. STDMETHODIMP CMSegment::CloseLink(void)
  219. {
  220. KillTimer( IDT_TIMER1 );
  221. comm.Close();
  222. doinit();
  223. ::PostMessage( m_hWndCD, WM_MYSELF, 2, 0 );
  224. return S_OK;
  225. }
  226. //读取联机状态
  227. STDMETHODIMP CMSegment::GetLink(VARIANT_BOOL* pVal)
  228. {
  229. * pVal = m_link ? VARIANT_TRUE : VARIANT_FALSE;
  230. return S_OK;
  231. }
  232. //读取寄存器
  233. STDMETHODIMP CMSegment::GetBit(LONG Addr, VARIANT_BOOL* pVal)
  234. {
  235. if ( Addr < 0X0 || Addr > 0XFF )
  236. {
  237. *pVal = VARIANT_FALSE;
  238. else
  239. {
  240. *pVal = data[Addr] ? VARIANT_TRUE : VARIANT_FALSE;
  241. }
  242. return S_OK;
  243. }
  244. //写入寄存器
  245. STDMETHODIMP CMSegment::PutBit(LONG Addr, VARIANT_BOOL OnOff)
  246. {
  247. if ( Addr < 0X0 || Addr > 0XFF ) return S_OK;
  248. Addr += 0X0800;
  249. //MODBUSASCII LRC校验码计算
  250. long checkcode = 0X01 + 0X05 + ( ( Addr & 0XFF00 ) >> 8 ) + ( Addr & 0XFF ) + ( OnOff ? 0XFF : 0X00 ) + 0X00;
  251. checkcode = ~checkcode;
  252. checkcode += 0X01;
  253. checkcode &= 0XFF;
  254. char s[32];
  255. sprintf( s, ":0105%04X%02X00%02Xx0Dx0A", Addr, OnOff ? 0XFF : 0X00, checkcode );
  256. m_allowsend = false;
  257. doDelay( 20 );
  258. comm.Write( s );
  259. doDelay( 20 );
  260. m_allowsend = true;
  261. //MessageBox(s);
  262. return S_OK;
  263. }
  264. //通知信号变化
  265. STDMETHODIMP CMSegment::SetNotify(LONG Addr,  VARIANT_BOOL AllowNotify)
  266. {
  267. if ( Addr < 0X0 || Addr > 0XFF )
  268. {
  269. return S_OK;
  270. else
  271. {
  272. m_notify[Addr] = AllowNotify;
  273. }
  274. return S_OK;
  275. }
  276. //延时
  277. STDMETHODIMP CMSegment::Delay( LONG TimeSpan )
  278. {
  279. doDelay( TimeSpan );
  280. return S_OK;
  281. }
  282. LRESULT CMSegment::OnTimer(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  283. {
  284. if ( m_allowsend )
  285. {
  286. comm.Write( ":0102080000FFF6x0Dx0A" );//发送读取状态
  287. }
  288. //检查联机
  289. if ( !m_DataReceived )
  290. {
  291. m_NoneInterval++;
  292. if ( m_NoneInterval > 20 ) CloseLink();
  293. }
  294. else
  295. {
  296. m_NoneInterval = 0;
  297. }
  298. m_DataReceived = false;
  299. return 0;
  300. }
  301. //MySelf事件
  302. LRESULT CMSegment::OnMySelf( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  303. {
  304. //::PostMessage( m_hWndCD, WM_MYSELF, 5, DMC_SERVO_OFF);
  305. switch( wParam )
  306. {
  307. case 1:
  308. Fire_OnNotify( (LONG)lParam );
  309. break;
  310. case 2:
  311. Fire_OnLink( lParam == 0 ? VARIANT_FALSE : VARIANT_TRUE );
  312. break;
  313. default:
  314. break;
  315. }
  316. return 0;
  317. }