#include #include #define LIB_CFG_DISK_IO 1 /* 磁盘读写的数据的复制方式,1为"单DPTR复制",2为"双DPTR复制",3为"单DPTR和P2+R0复制" */ #define LIB_CFG_FILE_IO 1 /* 文件读写的数据的复制方式,0为"外部子程序",1为"单DPTR复制",2为"双DPTR复制",3为"单DPTR和P2+R0复制" */ #define LIB_CFG_INT_EN 0 /* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */ #define CH375_CMD_PORT_ADDR 0xBDF1 /* CH375命令端口的I/O地址 */ #define CH375_DAT_PORT_ADDR 0xBCF0 /* CH375数据端口的I/O地址 #define MAX_BUFF_SIZE 250 #define COMM_NO_ERROR 0 #define COMM_RX_FULL 1
#include "CH375HF6.H" UINT8 i,c; UINT8 *err; UINT8X CommBuffer[MAX_BUFF_SIZE]; //串口环形缓冲区 UINT8 ReceiveCharcount; //接收到的字符数 UINT8 StartFlag; //接收开始标志 UINT8 ReceiveFlag; //接收到字符标志 UINT8X *pBufferIn=&CommBuffer[0]; //写入指针 UINT8X *pBufferOut=&CommBuffer[0]; //读出指针 UINT16 OverTimeCount=0 ;
/* 延时100毫秒,不精确 */ void mDelay100mS( ) { UINT8 i, j, c; for ( i = 200; i != 0; i -- ) for ( j = 200; j != 0; j -- ) c+=3; }
/* 将程序空间的字符串复制到内部RAM中,返回字符串长度 */ UINT8 mCopyCodeStringToIRAM( UINT8 idata *iDestination, UINT8 code *iSource ) { UINT8 i = 0; while ( *iDestination = *iSource ) { iDestination ++; iSource ++; i ++; } return( i ); }
/* 检查操作状态,如果错误则显示错误代码并停机 */ void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ printf( "Error: %02X\n", (UINT16)iError ); /* 显示错误 */ while ( 1 ) { LED_OUT_ACT( ); /* LED闪烁 */ mDelay100mS( ); LED_OUT_INACT( ); mDelay100mS( ); } }
/* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( ) { SCON = 0x50; PCON&= 0x7f; TMOD = 0x20; TH1 = 0xf3; /* 24MHz晶振, 4800bps */ TR1 = 1; TI = 1; EA=1; ES=1; ReceiveCharcount=0; pBufferIn=&CommBuffer[0]; //写入指针 pBufferOut=&CommBuffer[0]; //读出指针 StartFlag=0; }
void RI_Interrupt() interrupt 4 using 1 { if(RI) { c=SBUF; RI=0; StartFlag=1; ReceiveFlag=1; OverTimeCount=0; if(ReceiveCharcount { ReceiveCharcount++; //串口缓存区里的字符数 *pBufferIn=c; pBufferIn++; if(pBufferIn==&CommBuffer[MAX_BUFF_SIZE]) { pBufferIn=&CommBuffer[0];} *err=COMM_NO_ERROR; } else{ *err=COMM_RX_FULL; } } }
void main( ) { UINT8 count=0; mInitSTDIO( ); /* 为了让计算机通过串口监控演示过程 */ printf( "Start\n" ); i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */ mStopIfError( i ); while ( 1 ) { printf( "Wait Udisk\n" ); while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( ); for ( i = 0; i < 5; i ++ ) { mDelay100mS( ); printf( "Ready ?\n" ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; } #ifdef EN_DISK_WRITE LED_WR_ACT( ); printf( "Create\n" ); mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "/new.TXT" ); i = CH375FileCreate( ); mStopIfError( i ); printf( "Write\n" ); while(1) { while(StartFlag) /*发生第一次接收中断*/ { OverTimeCount++; /*主循环接收超时计数*/ if(ReceiveFlag==1) { ReceiveFlag=0; mCmdParam.ByteWrite.mByteBuffer[count]=*pBufferOut++; if(pBufferOut==&CommBuffer[MAX_BUFF_SIZE]) {pBufferOut=&CommBuffer[0];} ReceiveCharcount--; //串口缓存中的总数减一 if(count==MAX_BYTE_IO) { count=0; mCmdParam.ByteWrite.mByteCount = MAX_BYTE_IO; i = CH375ByteWrite( ); mStopIfError( i ); } else{count++;} /*写缓冲区计数*/ } if(OverTimeCount>50000)//超时处理,如果循环50000次还没有中断则认为结束 { mCmdParam.ByteWrite.mByteCount = count; i = CH375ByteWrite( ); mStopIfError( i ); mCmdParam.Close.mUpdateLen = 1; printf( "Close\n" ); i = CH375FileClose( ); mStopIfError( i ); OverTimeCount=0; StartFlag=0; ReceiveCharcount=0; pBufferOut=&CommBuffer[0]; pBufferIn=&CommBuffer[0]; printf( "Take out\n" ); while ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( ); mDelay100mS( ); mDelay100mS( ); } } } } } #endif
我的程序用在写到U盘后,有乱码和丢失数据,各位大侠,给我出出主意,怎么能处理好串口接收和写U盘之间的时序问题,很苦恼,怎么改更好一点.(字节模式读写).我用的单片机是STC89C51RD+ ,1280RAM,