这里以二进制文本文件为例,有两个方法可以实现:
- 在文件尾添加一个结束标志(与接收方约定好),当接收方检测到这个结束标志,认为对方发送结束。该方法也称为协议法,具体实现可以如下:
在文件头加一个协议,包括三个数据,u8 a,b,c,a标识该文件是目标文件,b为该文件字节数,c为给该文件添加的校验数据,使得该文件所有字节加起来等于0xff,可以防止漏掉数据。比如下面的协议头就很好:对方接收到后,对应解析即可。
优点:对方断断续续发送也能正确接收完文件,不会漏掉,能区分接收到的文件做对应处理,而且还有校验功能,更加安全可靠。
缺点:自己得写程序加工待发送得文件,添加协议头。
- 以一定的时间间隔来更新接收数据的字节数,如果在此间隔内(比如10ms),没有接收到数据了,说明对方发送结束(因为对方如果要发送文件,那么会连续不断的发完文件中所有数据为止,不会断断续续发送)。可以用如下代码实现:
while(1) { if(USART_RX_CNT) { if(oldcount==USART_RX_CNT)//新周期内没有收到数据,认为本次数据接收完成. { applenth=USART_RX_CNT; oldcount=0; USART_RX_CNT=0; printf("用户程序接收完成!\r\n"); printf("代码长度:%dBytes\r\n",applenth); } else oldcount=USART_RX_CNT; } t++; delay_ms(10); }
优点:实现简单,可以利用普通串口软件实现文件接收,指令接收,否则按照方法1,得用特制的串口软件来封装协议头,才能发送,发送指令也得封装。
缺点:和方法一相反
串口接收程序如下所示:
//串口 1 中断服务程序
//注意,读取 USARTx->SR 能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN] __attribute__ ((at(0X20001000)));
//接收缓冲,最大 USART_REC_LEN 个字节,起始地址为 0X20001000.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到 0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
u16 USART_RX_CNT=0; //接收的字节数
void USART1_IRQHandler(void)
{
u8 res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//接收到数据
{
res=USART_ReceiveData(USART1);
if(USART_RX_CNT<USART_REC_LEN)
{
USART_RX_BUF[USART_RX_CNT]=res;
USART_RX_CNT++;
}
}
}