1 自定义帧格式
1.1 数据帧结构
定义一帧数据的结构
strcut FRAME
{
u8 head;//帧头
u8 len;//数据长度
u8 type;//数据包类型,例如 1代表成绩,2代表身高……
u8 data[16];//数据包缓冲区
};
1.2 填充数据帧
接下来,假设我要发一个数据包。例如发五个学生的成绩(假设成绩在buf[5]数组里), 那么需要定义一个数据帧变量score,并初始化:
strcut FRAME score;
score.head='#';
score.len=5;
score.type=0x01;
for(i=0;i
{
score.data
=buf;
}
1.3 填充数发送缓冲区
然后,把这帧数据放到发送缓冲区:
u8 send_buf[18]={0},index=0,i;
send_buf[index++]=score.head;
send_buf[index++]=score.len;
send_buf[index++]=score.type;
for(i=0;i
{
send_buf[index++]=score.data;
}
1.4 通过串口发送数据
最后,将缓冲区数据发送出去
for(i=0;i
{
while((USART1->SR&0X40)==0);
USART1->DR = send_buf;
}
2 超时接收
超时接收,就是接收过程可以不对数据进行任何处理。在接收到第一个数据时,就打开定时器开始计时,当定时器溢出后(例如设为10ms, 只要保证数据能传输完即可),认为数据接收结束,才开始处理数据。当然,不用定时器,使用空闲中断也可以,没用过所以这里不写。
2.1 串口中断服务程序
void USART1_IRQHandler(void) //´®¿Ú1ÖжϷþÎñ³ÌÐò
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
if(0==over_flag)//未超时或者数据未处理
{
Res =USART_ReceiveData(USART1);
ReceiveBuf[index++]=Res;
//当然,还要判断index的值是否过大,这里不做判断
if(0==time_flag)
{
TIM_Cmd(TIM3, ENABLE); //接收到第一个字节,开启定时器
time_flag=1;//定时器开启的标志
}
}
}
}
2.2 定时器中断服务函数:
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)
{
over_flag=1;//超时标志置1
}
TIM3->SR&=~(1<<0);
}
2.3 数据处理
业务程序大致这样:
if(over_flag) //超时,且数据未被处理
{
{
//对ReceiveBuf缓冲区的数据进行处理
//首先要做判断,判断第一个字节是不是‘#’(还有其他检验数据的正确性的方法,
//本文没涉及),如果数据有误,就丢弃
}
TIM_Cmd(TIM3, DISABLE);//关定时器
time_flag=0;//定时器标志置零
over_flag=0; //超时标志清零,也表示数据已经被处理
}
大概就是上面写的这样啦,理解不到位还请见谅。临时写的,没有源代码……估计存在不少问题,仅供参考思路。谢谢!
1 自定义帧格式
1.1 数据帧结构
定义一帧数据的结构
strcut FRAME
{
u8 head;//帧头
u8 len;//数据长度
u8 type;//数据包类型,例如 1代表成绩,2代表身高……
u8 data[16];//数据包缓冲区
};
1.2 填充数据帧
接下来,假设我要发一个数据包。例如发五个学生的成绩(假设成绩在buf[5]数组里), 那么需要定义一个数据帧变量score,并初始化:
strcut FRAME score;
score.head='#';
score.len=5;
score.type=0x01;
for(i=0;i
{
score.data=buf;
}
1.3 填充数发送缓冲区
然后,把这帧数据放到发送缓冲区:
u8 send_buf[18]={0},index=0,i;
send_buf[index++]=score.head;
send_buf[index++]=score.len;
send_buf[index++]=score.type;
for(i=0;i
{
send_buf[index++]=score.data;
}
1.4 通过串口发送数据
最后,将缓冲区数据发送出去
for(i=0;i
{
while((USART1->SR&0X40)==0);
USART1->DR = send_buf;
}
2 超时接收
超时接收,就是接收过程可以不对数据进行任何处理。在接收到第一个数据时,就打开定时器开始计时,当定时器溢出后(例如设为10ms, 只要保证数据能传输完即可),认为数据接收结束,才开始处理数据。当然,不用定时器,使用空闲中断也可以,没用过所以这里不写。
2.1 串口中断服务程序
void USART1_IRQHandler(void) //´®¿Ú1ÖжϷþÎñ³ÌÐò
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
if(0==over_flag)//未超时或者数据未处理
{
Res =USART_ReceiveData(USART1);
ReceiveBuf[index++]=Res;
//当然,还要判断index的值是否过大,这里不做判断
if(0==time_flag)
{
TIM_Cmd(TIM3, ENABLE); //接收到第一个字节,开启定时器
time_flag=1;//定时器开启的标志
}
}
}
}
2.2 定时器中断服务函数:
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)
{
over_flag=1;//超时标志置1
}
TIM3->SR&=~(1<<0);
}
2.3 数据处理
业务程序大致这样:
if(over_flag) //超时,且数据未被处理
{
{
//对ReceiveBuf缓冲区的数据进行处理
//首先要做判断,判断第一个字节是不是‘#’(还有其他检验数据的正确性的方法,
//本文没涉及),如果数据有误,就丢弃
}
TIM_Cmd(TIM3, DISABLE);//关定时器
time_flag=0;//定时器标志置零
over_flag=0; //超时标志清零,也表示数据已经被处理
}
大概就是上面写的这样啦,理解不到位还请见谅。临时写的,没有源代码……估计存在不少问题,仅供参考思路。谢谢!
举报