#include "YX5200_uart.h" #include "YX5200_main.h" /****************************************************************************************************************** +--------------------------------------------------+ 串口通讯模块 +--------------------------------------------------+ - 实现功能: - 目前进展: - 运行环境:STC 晶振:11.0592M 波特率:9600 [硬件串口操作] - 备注 :在普中科技的51开发板上调试OK --- STC89C516RD+ ******************************************************************************************************************/ static INT8U Send_buf[YX5200_MSGLEN] = {0} ; INT8U Recv_buf[YX5200_MSGLEN] = {0} ; const INT8U hex[] = {"0123456789ABCDEF"}; void DoSum ( INT8U *Str, INT8U len ) ; void Uart_Task ( INT8U *pr ); void Clear_Uart2_Recv ( void ) { memset ( RxBufferUart2, 0, RxCounterUart2 ); RxCounterUart2 = 0; } void Init_YX5200_VOL(void) { #if xy5200_Uart2_def input_vol = 25; put_msg_lifo ( MSG_VOL_DOWN ); #endif } void YX5200_Key_handler ( void ) { #if xy5200_Uart2_def char i; static bool key4_play_pause = false; if ( System_Flag_Prin_Music ) { if ( POINTNUM_FOLDER == PointFunc ) //指定文件夹的状态 { //播放模式 if ( Keys[10].Res == ONE_HITS_KEY_FLAG ) { Keys[10].Res = NO_KEY_FLAG; put_msg_lifo ( MSG_SET_PLAYMODE ); } for ( i = 0; i < 10; i++ ) { if ( Keys[i].Res == ONE_HITS_KEY_FLAG ) { Keys[i].Res = NO_KEY_FLAG; put_msg_lifo ( i ); } } } else { //播放模式 if ( Keys[10].Res == ONE_HITS_KEY_FLAG ) { Keys[10].Res = NO_KEY_FLAG; put_msg_lifo ( MSG_SET_PLAYMODE ); } //上一曲/下一曲 if ( Keys[0].Res == ONE_HITS_KEY_FLAG ) { Keys[0].Res = NO_KEY_FLAG; put_msg_lifo ( MSG_MUSIC_PREV_FILE ); } if ( Keys[1].Res == ONE_HITS_KEY_FLAG ) { Keys[1].Res = NO_KEY_FLAG; put_msg_lifo ( MSG_MUSIC_NEXT_FILE ); } //音量10-20-30 if ( Keys[2].Res == ONE_HITS_KEY_FLAG ) { Keys[2].Res = NO_KEY_FLAG; input_vol = 13; put_msg_lifo ( MSG_VOL_DOWN ); } else if ( Keys[2].Res == TWO_HITS_KEY_FLAG ) { Keys[2].Res = NO_KEY_FLAG; input_vol = 19; put_msg_lifo ( MSG_VOL_DOWN ); } else if ( Keys[2].Res == THREE_HITS_KEY_FLAG ) { Keys[2].Res = NO_KEY_FLAG; input_vol = 25; put_msg_lifo ( MSG_VOL_DOWN ); } else if ( Keys[2].Res == LONG_KEY_FLAG ) { Keys[2].Res = NO_KEY_FLAG; input_vol = 31; put_msg_lifo ( MSG_VOL_DOWN ); } //查询ALLNUM/CURNUM if ( Keys[3].Res == ONE_HITS_KEY_FLAG ) { Keys[3].Res = NO_KEY_FLAG; put_msg_lifo ( MSG_QUERY_NUMTOTAL ); } else if ( Keys[3].Res == TWO_HITS_KEY_FLAG ) { Keys[3].Res = NO_KEY_FLAG; put_msg_lifo ( MSG_QUERY_CURNUM ); } //播放/停止 if ( Keys[4].Res == ONE_HITS_KEY_FLAG ) { Keys[4].Res = NO_KEY_FLAG; key4_play_pause = ! key4_play_pause; if ( key4_play_pause ) put_msg_lifo ( MSG_MUSIC_PLAY ); else put_msg_lifo ( MSG_MUSIC_PAUSE ); } //全播*全停 if ( Keys[5].Res == ONE_HITS_KEY_FLAG ) { Keys[5].Res = NO_KEY_FLAG; put_msg_lifo ( MSG_PLAYALL ); } } } #endif } void YX5200_UART_Handler ( void ) { #if xy5200_Uart2_def if ( YX5200HaveRecFlag ) { YX5200HaveRecFlag = false; UartRecvACKFlag = false; RecvOver_Flag = 1; Uart_communication(); Clear_Uart2_Recv(); } else { if ( ( UartRecvACK == 0 ) && UartRecvACKFlag ) { UartRecvACKFlag = 0; RecvError_Flag = 1; Uart_communication(); } } #endif } /******************************************************************************************** - 功能描述:争对接收的命令进行处理 - 隶属模块:外部 - 参数说明:无 - 返回说明:无 - 注: ********************************************************************************************/ void Uart_communication ( void ) { INT8U i, *pi ; INT16U xorsum = 0, xorsum1 = 0 ; if ( 1 == RecvError_Flag ) //接收错误处理 { RecvError_Flag = 0 ; UartRecvStatus = UART_RECV_IDLE ; if ( ResendCount-- != 0 ) { Uart_ReSendCMD ( 0x40 , 0 , 1 ) ; //错误处理请求重发 } return ; } if ( 1 == RecvOver_Flag ) //一帧数据接收完毕 { RecvOver_Flag = 0 ; pi = Recv_buf; for ( i = 0; i < ( * ( pi + 1 ) ); i++ ) { xorsum = xorsum + pi[i] ; } xorsum1 = ( ( INT16U ) ( ( * ( pi + i ) ) << 8 ) ) | ( * ( pi + i + 1 ) ); xorsum = xorsum + xorsum1; if ( !xorsum ) { Uart_Task ( pi ); //串口处理 } else { RecvError_Flag = 1 ;//错误处理 } UartRecvStatus = UART_RECV_IDLE ; } } /********************************************************************************************** - 功能描述: 串口处理函数 - 隶属模块: 内部 - 参数说明: *pr :串口0需要接收的数据的地址指针 - 返回说明: 无 - 注: **********************************************************************************************/ void Uart_Task ( INT8U *pr ) { INT16U Temp16 = 0 ; INT8U *pi , tempH , tempL , CMD , FeedBack; pi = pr; tempH = * ( pi + 4 ) ; tempL = * ( pi + 5 ) ; Temp16 = ( ( ( INT16U ) ( tempH ) ) << 8 ) | tempL ; CMD = * ( pi + 2 ) ; FeedBack = * ( pi + 3 ) ; switch ( CMD ) { case ( 0x41 ) : //收到应答ACK UartRecvACK = 0 ; //PlayledCnt = PLAYLEDCNT ; //PlayledStatus = SET_PLAYLED_ON; break ; /********************************************************************** - 1、设备插入拔出消息 **********************************************************************/ case ( 0x3A ) : //设备插入 if ( tempL == 0x01 ) { put_msg_lifo ( MSG_UDISK_IN ); } else if ( tempL == 0x02 ) { put_msg_lifo ( MSG_TF_IN ); } else if ( tempL == 0x04 ) { put_msg_lifo ( MSG_PC_IN ); } break; case ( 0x3B ) : //设备拔出 if ( tempL == 0x01 ) { put_msg_lifo ( MSG_UDISK_OUT ); } else if ( tempL == 0x02 ) { put_msg_lifo ( MSG_TF_OUT ); } else if ( tempL == 0x04 ) { put_msg_lifo ( MSG_PC_OUT ); } break; /********************************************************************** - 1、收到当前曲目播放完毕消息 **********************************************************************/ case ( 0x3C ) : //U盘当前曲目播放完毕 if ( PLAYDEVICE_UDISK == PlayDevice ) { put_msg_lifo ( MSG_MUSIC_OVER ); } break; case ( 0x3D ) : //TF当前曲目播放完毕 if ( PLAYDEVICE_TFCARD == PlayDevice ) { put_msg_lifo ( MSG_MUSIC_OVER ); } break ; case ( 0x3E ) : //FLASH当前曲目播放完毕 if ( PLAYDEVICE_FLASH == PlayDevice ) { put_msg_lifo ( MSG_MUSIC_OVER ); } break ; /********************************************************************** - 1、模块上电返回的数据 **********************************************************************/ case ( 0x3F ) : OnlineDevice = tempL ; put_msg_lifo ( MSG_RETURN_MINIT ); break ; /********************************************************************** - 1、模块返回的错误 **********************************************************************/ case ( 0x40 ) : _ErrorStatus = tempL ; put_msg_lifo ( MSG_RECV_ERROR ); break ; /********************************************************************** - 1、查询参数 **********************************************************************/ case ( 0x42 ) : //查询当前状态 break; case ( 0x43 ) : //查询当前系统音量 input_vol = tempL ; put_msg_lifo ( MSG_RETURN_VOL ); break; case ( 0x44 ) : //查询当前EQ CurrentEQ = tempL ; put_msg_lifo ( MSG_RETURN_EQ ); break; case ( 0x45 ) : //查询当前播放模式 PlayMode = tempL ; put_msg_lifo ( MSG_RETURN_PLAYMODE ); break; case ( 0x46 ) : //查询当前软件版本 break; /********************************************************************** - 1、查询参数 --- 设备总文件数 **********************************************************************/ case ( 0x47 ) : //查询UDISK文件总数 UDiskTotal = Temp16 ; put_msg_lifo ( MSG_RETURN_NUMTOTAL ); break ; case ( 0x48 ) : //查询TFCARD文件总数 TFTotal = Temp16 ; put_msg_lifo ( MSG_RETURN_NUMTOTAL ); break ; case ( 0x49 ) : //查询FLASH文件总数 FlashTotal = Temp16 ; put_msg_lifo ( MSG_RETURN_NUMTOTAL ); break; case ( 0x4A ) : //保留 break; /********************************************************************** - 1、查询参数 --- 设备当前播放的文件数 **********************************************************************/ case ( 0x4B ) : //查询UDISK的当前曲目 UDiskCurFile = Temp16 ; put_msg_lifo ( MSG_RETURN_CURNUM ); break; case ( 0x4C ) : //查询TF卡的当前曲目 TFCurFile = Temp16 ; put_msg_lifo ( MSG_RETURN_CURNUM ); break ; case ( 0x4D ) : //查询FLASH的当前曲目 FlashCurFile = Temp16 ; put_msg_lifo ( MSG_RETURN_CURNUM ); break; case ( 0x4E ) : //查询文件总数 CurFileNum = Temp16 ; put_msg_lifo ( MSG_RETURN_FILENUM ); break; case ( 0x4F ) : //查询文件夹数 CurFoldNum = Temp16 ; put_msg_lifo ( MSG_RETURN_FOLDNUM ); break; default: break; } } /******************************************************************************************** - 功能描述: 串口向外发送命令[包括控制和查询] - 隶属模块: 外部 - 参数说明: CMD:表示控制指令,请查阅指令表,还包括查询的相关指令 feedback:是否需要应答[0:不需要应答,1:需要应答] data:传送的参数 - 返回说明: - 注: ********************************************************************************************/ void Uart_SendCMD ( INT8U CMD , INT8U feedback , INT16U dat ) { Send_buf[0] = 0x7E; //保留字节 Send_buf[1] = 0xff; //保留字节 Send_buf[2] = 0x06; //长度 Send_buf[3] = CMD; //控制指令 Send_buf[4] = feedback;//是否需要反馈 Send_buf[5] = ( INT8U ) ( dat >> 8 ); //datah Send_buf[6] = ( INT8U ) ( dat ); //datal DoSum ( &Send_buf[1], 6 ); //校验 Send_buf[9] = 0xEF; //结束 Uart2Send ( ( char * ) Send_buf, YX5200_MSGLEN ); UartRecvACK = WAIT_ACK_TIME ;//设定等待应答的时间[300ms] UartRecvACKFlag = true; ResendCount = 3; } void Uart_ReSendCMD ( INT8U CMD , INT8U feedback , INT16U dat ) { Send_buf[0] = 0x7E; //保留字节 Send_buf[1] = 0xff; //保留字节 Send_buf[2] = 0x06; //长度 Send_buf[3] = CMD; //控制指令 Send_buf[4] = feedback;//是否需要反馈 Send_buf[5] = ( INT8U ) ( dat >> 8 ); //datah Send_buf[6] = ( INT8U ) ( dat ); //datal DoSum ( &Send_buf[1], 6 ); //校验 Send_buf[9] = 0xEF; //结束 Uart2Send ( ( char * ) Send_buf, YX5200_MSGLEN ); UartRecvACK = WAIT_ACK_TIME ;//设定等待应答的时间[300ms] UartRecvACKFlag = true; } /******************************************************************************************** - 功能描述:求和校验 - 隶属模块: - 参数说明: - 返回说明: - 注: 和校验的思路如下 发送的指令,去掉起始和结束。将中间的6个字节进行累加,最后取反码 接收端就将接收到的一帧数据,去掉起始和结束。将中间的数据累加,再加上接收到的校验 字节。刚好为0.这样就代表接收到的数据完全正确。 ********************************************************************************************/ void DoSum ( INT8U *Str, INT8U len ) { INT16U xorsum = 0; INT8U i; for ( i = 0; i < len; i++ ) { xorsum = xorsum + Str[i]; } xorsum = 0 - xorsum; * ( Str + i ) = ( INT8U ) ( xorsum >> 8 ); * ( Str + i + 1 ) = ( INT8U ) ( xorsum & 0x00ff ); }