YX5200_uart.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. #include "YX5200_uart.h"
  2. #include "YX5200_main.h"
  3. /******************************************************************************************************************
  4. +--------------------------------------------------+
  5. 串口通讯模块
  6. +--------------------------------------------------+
  7. - 实现功能:
  8. - 目前进展:
  9. - 运行环境:STC 晶振:11.0592M 波特率:9600 [硬件串口操作]
  10. - 备注 :在普中科技的51开发板上调试OK --- STC89C516RD+
  11. ******************************************************************************************************************/
  12. static INT8U Send_buf[YX5200_MSGLEN] = {0} ;
  13. INT8U Recv_buf[YX5200_MSGLEN] = {0} ;
  14. const INT8U hex[] = {"0123456789ABCDEF"};
  15. void DoSum ( INT8U *Str, INT8U len ) ;
  16. void Uart_Task ( INT8U *pr );
  17. void Clear_Uart2_Recv ( void )
  18. {
  19. memset ( RxBufferUart2, 0, RxCounterUart2 );
  20. RxCounterUart2 = 0;
  21. }
  22. void Init_YX5200_VOL(void)
  23. {
  24. #if xy5200_Uart2_def
  25. input_vol = 25;
  26. put_msg_lifo ( MSG_VOL_DOWN );
  27. #endif
  28. }
  29. void YX5200_Key_handler ( void )
  30. {
  31. #if xy5200_Uart2_def
  32. char i;
  33. static bool key4_play_pause = false;
  34. if ( System_Flag_Prin_Music )
  35. {
  36. if ( POINTNUM_FOLDER == PointFunc ) //指定文件夹的状态
  37. {
  38. //播放模式
  39. if ( Keys[10].Res == ONE_HITS_KEY_FLAG )
  40. {
  41. Keys[10].Res = NO_KEY_FLAG;
  42. put_msg_lifo ( MSG_SET_PLAYMODE );
  43. }
  44. for ( i = 0; i < 10; i++ )
  45. {
  46. if ( Keys[i].Res == ONE_HITS_KEY_FLAG )
  47. {
  48. Keys[i].Res = NO_KEY_FLAG;
  49. put_msg_lifo ( i );
  50. }
  51. }
  52. }
  53. else
  54. {
  55. //播放模式
  56. if ( Keys[10].Res == ONE_HITS_KEY_FLAG )
  57. {
  58. Keys[10].Res = NO_KEY_FLAG;
  59. put_msg_lifo ( MSG_SET_PLAYMODE );
  60. }
  61. //上一曲/下一曲
  62. if ( Keys[0].Res == ONE_HITS_KEY_FLAG )
  63. {
  64. Keys[0].Res = NO_KEY_FLAG;
  65. put_msg_lifo ( MSG_MUSIC_PREV_FILE );
  66. }
  67. if ( Keys[1].Res == ONE_HITS_KEY_FLAG )
  68. {
  69. Keys[1].Res = NO_KEY_FLAG;
  70. put_msg_lifo ( MSG_MUSIC_NEXT_FILE );
  71. }
  72. //音量10-20-30
  73. if ( Keys[2].Res == ONE_HITS_KEY_FLAG )
  74. {
  75. Keys[2].Res = NO_KEY_FLAG;
  76. input_vol = 13;
  77. put_msg_lifo ( MSG_VOL_DOWN );
  78. }
  79. else if ( Keys[2].Res == TWO_HITS_KEY_FLAG )
  80. {
  81. Keys[2].Res = NO_KEY_FLAG;
  82. input_vol = 19;
  83. put_msg_lifo ( MSG_VOL_DOWN );
  84. }
  85. else if ( Keys[2].Res == THREE_HITS_KEY_FLAG )
  86. {
  87. Keys[2].Res = NO_KEY_FLAG;
  88. input_vol = 25;
  89. put_msg_lifo ( MSG_VOL_DOWN );
  90. }
  91. else if ( Keys[2].Res == LONG_KEY_FLAG )
  92. {
  93. Keys[2].Res = NO_KEY_FLAG;
  94. input_vol = 31;
  95. put_msg_lifo ( MSG_VOL_DOWN );
  96. }
  97. //查询ALLNUM/CURNUM
  98. if ( Keys[3].Res == ONE_HITS_KEY_FLAG )
  99. {
  100. Keys[3].Res = NO_KEY_FLAG;
  101. put_msg_lifo ( MSG_QUERY_NUMTOTAL );
  102. }
  103. else if ( Keys[3].Res == TWO_HITS_KEY_FLAG )
  104. {
  105. Keys[3].Res = NO_KEY_FLAG;
  106. put_msg_lifo ( MSG_QUERY_CURNUM );
  107. }
  108. //播放/停止
  109. if ( Keys[4].Res == ONE_HITS_KEY_FLAG )
  110. {
  111. Keys[4].Res = NO_KEY_FLAG;
  112. key4_play_pause = ! key4_play_pause;
  113. if ( key4_play_pause )
  114. put_msg_lifo ( MSG_MUSIC_PLAY );
  115. else
  116. put_msg_lifo ( MSG_MUSIC_PAUSE );
  117. }
  118. //全播*全停
  119. if ( Keys[5].Res == ONE_HITS_KEY_FLAG )
  120. {
  121. Keys[5].Res = NO_KEY_FLAG;
  122. put_msg_lifo ( MSG_PLAYALL );
  123. }
  124. }
  125. }
  126. #endif
  127. }
  128. void YX5200_UART_Handler ( void )
  129. {
  130. #if xy5200_Uart2_def
  131. if ( YX5200HaveRecFlag )
  132. {
  133. YX5200HaveRecFlag = false;
  134. UartRecvACKFlag = false;
  135. RecvOver_Flag = 1;
  136. Uart_communication();
  137. Clear_Uart2_Recv();
  138. }
  139. else
  140. {
  141. if ( ( UartRecvACK == 0 ) && UartRecvACKFlag )
  142. {
  143. UartRecvACKFlag = 0;
  144. RecvError_Flag = 1;
  145. Uart_communication();
  146. }
  147. }
  148. #endif
  149. }
  150. /********************************************************************************************
  151. - 功能描述:争对接收的命令进行处理
  152. - 隶属模块:外部
  153. - 参数说明:无
  154. - 返回说明:无
  155. - 注:
  156. ********************************************************************************************/
  157. void Uart_communication ( void )
  158. {
  159. INT8U i, *pi ;
  160. INT16U xorsum = 0, xorsum1 = 0 ;
  161. if ( 1 == RecvError_Flag ) //接收错误处理
  162. {
  163. RecvError_Flag = 0 ;
  164. UartRecvStatus = UART_RECV_IDLE ;
  165. if ( ResendCount-- != 0 )
  166. {
  167. Uart_ReSendCMD ( 0x40 , 0 , 1 ) ; //错误处理请求重发
  168. }
  169. return ;
  170. }
  171. if ( 1 == RecvOver_Flag ) //一帧数据接收完毕
  172. {
  173. RecvOver_Flag = 0 ;
  174. pi = Recv_buf;
  175. for ( i = 0; i < ( * ( pi + 1 ) ); i++ )
  176. {
  177. xorsum = xorsum + pi[i] ;
  178. }
  179. xorsum1 = ( ( INT16U ) ( ( * ( pi + i ) ) << 8 ) ) | ( * ( pi + i + 1 ) );
  180. xorsum = xorsum + xorsum1;
  181. if ( !xorsum )
  182. {
  183. Uart_Task ( pi ); //串口处理
  184. }
  185. else
  186. {
  187. RecvError_Flag = 1 ;//错误处理
  188. }
  189. UartRecvStatus = UART_RECV_IDLE ;
  190. }
  191. }
  192. /**********************************************************************************************
  193. - 功能描述: 串口处理函数
  194. - 隶属模块: 内部
  195. - 参数说明: *pr :串口0需要接收的数据的地址指针
  196. - 返回说明: 无
  197. - 注:
  198. **********************************************************************************************/
  199. void Uart_Task ( INT8U *pr )
  200. {
  201. INT16U Temp16 = 0 ;
  202. INT8U *pi , tempH , tempL , CMD , FeedBack;
  203. pi = pr;
  204. tempH = * ( pi + 4 ) ;
  205. tempL = * ( pi + 5 ) ;
  206. Temp16 = ( ( ( INT16U ) ( tempH ) ) << 8 ) | tempL ;
  207. CMD = * ( pi + 2 ) ;
  208. FeedBack = * ( pi + 3 ) ;
  209. switch ( CMD )
  210. {
  211. case ( 0x41 ) : //收到应答ACK
  212. UartRecvACK = 0 ;
  213. //PlayledCnt = PLAYLEDCNT ;
  214. //PlayledStatus = SET_PLAYLED_ON;
  215. break ;
  216. /**********************************************************************
  217. - 1、设备插入拔出消息
  218. **********************************************************************/
  219. case ( 0x3A ) : //设备插入
  220. if ( tempL == 0x01 )
  221. {
  222. put_msg_lifo ( MSG_UDISK_IN );
  223. }
  224. else if ( tempL == 0x02 )
  225. {
  226. put_msg_lifo ( MSG_TF_IN );
  227. }
  228. else if ( tempL == 0x04 )
  229. {
  230. put_msg_lifo ( MSG_PC_IN );
  231. }
  232. break;
  233. case ( 0x3B ) : //设备拔出
  234. if ( tempL == 0x01 )
  235. {
  236. put_msg_lifo ( MSG_UDISK_OUT );
  237. }
  238. else if ( tempL == 0x02 )
  239. {
  240. put_msg_lifo ( MSG_TF_OUT );
  241. }
  242. else if ( tempL == 0x04 )
  243. {
  244. put_msg_lifo ( MSG_PC_OUT );
  245. }
  246. break;
  247. /**********************************************************************
  248. - 1、收到当前曲目播放完毕消息
  249. **********************************************************************/
  250. case ( 0x3C ) : //U盘当前曲目播放完毕
  251. if ( PLAYDEVICE_UDISK == PlayDevice )
  252. {
  253. put_msg_lifo ( MSG_MUSIC_OVER );
  254. }
  255. break;
  256. case ( 0x3D ) : //TF当前曲目播放完毕
  257. if ( PLAYDEVICE_TFCARD == PlayDevice )
  258. {
  259. put_msg_lifo ( MSG_MUSIC_OVER );
  260. }
  261. break ;
  262. case ( 0x3E ) : //FLASH当前曲目播放完毕
  263. if ( PLAYDEVICE_FLASH == PlayDevice )
  264. {
  265. put_msg_lifo ( MSG_MUSIC_OVER );
  266. }
  267. break ;
  268. /**********************************************************************
  269. - 1、模块上电返回的数据
  270. **********************************************************************/
  271. case ( 0x3F ) :
  272. OnlineDevice = tempL ;
  273. put_msg_lifo ( MSG_RETURN_MINIT );
  274. break ;
  275. /**********************************************************************
  276. - 1、模块返回的错误
  277. **********************************************************************/
  278. case ( 0x40 ) :
  279. _ErrorStatus = tempL ;
  280. put_msg_lifo ( MSG_RECV_ERROR );
  281. break ;
  282. /**********************************************************************
  283. - 1、查询参数
  284. **********************************************************************/
  285. case ( 0x42 ) : //查询当前状态
  286. break;
  287. case ( 0x43 ) : //查询当前系统音量
  288. input_vol = tempL ;
  289. put_msg_lifo ( MSG_RETURN_VOL );
  290. break;
  291. case ( 0x44 ) : //查询当前EQ
  292. CurrentEQ = tempL ;
  293. put_msg_lifo ( MSG_RETURN_EQ );
  294. break;
  295. case ( 0x45 ) : //查询当前播放模式
  296. PlayMode = tempL ;
  297. put_msg_lifo ( MSG_RETURN_PLAYMODE );
  298. break;
  299. case ( 0x46 ) : //查询当前软件版本
  300. break;
  301. /**********************************************************************
  302. - 1、查询参数 --- 设备总文件数
  303. **********************************************************************/
  304. case ( 0x47 ) : //查询UDISK文件总数
  305. UDiskTotal = Temp16 ;
  306. put_msg_lifo ( MSG_RETURN_NUMTOTAL );
  307. break ;
  308. case ( 0x48 ) : //查询TFCARD文件总数
  309. TFTotal = Temp16 ;
  310. put_msg_lifo ( MSG_RETURN_NUMTOTAL );
  311. break ;
  312. case ( 0x49 ) : //查询FLASH文件总数
  313. FlashTotal = Temp16 ;
  314. put_msg_lifo ( MSG_RETURN_NUMTOTAL );
  315. break;
  316. case ( 0x4A ) : //保留
  317. break;
  318. /**********************************************************************
  319. - 1、查询参数 --- 设备当前播放的文件数
  320. **********************************************************************/
  321. case ( 0x4B ) : //查询UDISK的当前曲目
  322. UDiskCurFile = Temp16 ;
  323. put_msg_lifo ( MSG_RETURN_CURNUM );
  324. break;
  325. case ( 0x4C ) : //查询TF卡的当前曲目
  326. TFCurFile = Temp16 ;
  327. put_msg_lifo ( MSG_RETURN_CURNUM );
  328. break ;
  329. case ( 0x4D ) : //查询FLASH的当前曲目
  330. FlashCurFile = Temp16 ;
  331. put_msg_lifo ( MSG_RETURN_CURNUM );
  332. break;
  333. case ( 0x4E ) : //查询文件总数
  334. CurFileNum = Temp16 ;
  335. put_msg_lifo ( MSG_RETURN_FILENUM );
  336. break;
  337. case ( 0x4F ) : //查询文件夹数
  338. CurFoldNum = Temp16 ;
  339. put_msg_lifo ( MSG_RETURN_FOLDNUM );
  340. break;
  341. default:
  342. break;
  343. }
  344. }
  345. /********************************************************************************************
  346. - 功能描述: 串口向外发送命令[包括控制和查询]
  347. - 隶属模块: 外部
  348. - 参数说明: CMD:表示控制指令,请查阅指令表,还包括查询的相关指令
  349. feedback:是否需要应答[0:不需要应答,1:需要应答]
  350. data:传送的参数
  351. - 返回说明:
  352. - 注:
  353. ********************************************************************************************/
  354. void Uart_SendCMD ( INT8U CMD , INT8U feedback , INT16U dat )
  355. {
  356. Send_buf[0] = 0x7E; //保留字节
  357. Send_buf[1] = 0xff; //保留字节
  358. Send_buf[2] = 0x06; //长度
  359. Send_buf[3] = CMD; //控制指令
  360. Send_buf[4] = feedback;//是否需要反馈
  361. Send_buf[5] = ( INT8U ) ( dat >> 8 ); //datah
  362. Send_buf[6] = ( INT8U ) ( dat ); //datal
  363. DoSum ( &Send_buf[1], 6 ); //校验
  364. Send_buf[9] = 0xEF; //结束
  365. Uart2Send ( ( char * ) Send_buf, YX5200_MSGLEN );
  366. UartRecvACK = WAIT_ACK_TIME ;//设定等待应答的时间[300ms]
  367. UartRecvACKFlag = true;
  368. ResendCount = 3;
  369. }
  370. void Uart_ReSendCMD ( INT8U CMD , INT8U feedback , INT16U dat )
  371. {
  372. Send_buf[0] = 0x7E; //保留字节
  373. Send_buf[1] = 0xff; //保留字节
  374. Send_buf[2] = 0x06; //长度
  375. Send_buf[3] = CMD; //控制指令
  376. Send_buf[4] = feedback;//是否需要反馈
  377. Send_buf[5] = ( INT8U ) ( dat >> 8 ); //datah
  378. Send_buf[6] = ( INT8U ) ( dat ); //datal
  379. DoSum ( &Send_buf[1], 6 ); //校验
  380. Send_buf[9] = 0xEF; //结束
  381. Uart2Send ( ( char * ) Send_buf, YX5200_MSGLEN );
  382. UartRecvACK = WAIT_ACK_TIME ;//设定等待应答的时间[300ms]
  383. UartRecvACKFlag = true;
  384. }
  385. /********************************************************************************************
  386. - 功能描述:求和校验
  387. - 隶属模块:
  388. - 参数说明:
  389. - 返回说明:
  390. - 注: 和校验的思路如下
  391. 发送的指令,去掉起始和结束。将中间的6个字节进行累加,最后取反码
  392. 接收端就将接收到的一帧数据,去掉起始和结束。将中间的数据累加,再加上接收到的校验
  393. 字节。刚好为0.这样就代表接收到的数据完全正确。
  394. ********************************************************************************************/
  395. void DoSum ( INT8U *Str, INT8U len )
  396. {
  397. INT16U xorsum = 0;
  398. INT8U i;
  399. for ( i = 0; i < len; i++ )
  400. {
  401. xorsum = xorsum + Str[i];
  402. }
  403. xorsum = 0 - xorsum;
  404. * ( Str + i ) = ( INT8U ) ( xorsum >> 8 );
  405. * ( Str + i + 1 ) = ( INT8U ) ( xorsum & 0x00ff );
  406. }