标题:
STM32的RXNE+IDLE接收不定长的数据包源程序
[打印本页]
作者:
小橡皮
时间:
2018-5-2 21:40
标题:
STM32的RXNE+IDLE接收不定长的数据包源程序
最近跟老师一起准备省电子设计竞赛了,老师要求先准备好基础的调试环境,当然选择usart的调试接收方法啦,由于没确定这个项目后期会加进来什么功能,不好确定每个包的大小,于是先写好串口的不定长接收包,想到的方式自然是IDLE+RXNE的查询
1->
在IDLE里头通过systick检测接收空闲的时间,如果空闲时间>10ms就给标记,停止IDLE中断而去处理这个数据包
//USART1 IRQ handler
void USART1_IRQHandler(void)
{
#if defined (USART_RECIEVE_BY_DMA)
//handle by DMA + IDLE inquiry
uint16_t dmaCounter = DMA_GetCurrDataCounter(DMA1_Channel5);
if ( USART_GetITStatus( USART1 , USART_IT_IDLE ) != RESET ) {
printf("DMA counter:%d\r\n",dmaCounter);
//has dealt rx buffer
// if (dmaCounter != USART_BUFF_SIZE) {
usartRx.isDeal = false;
DMA_Cmd(DMA1_Channel5,DISABLE);
DMA_ClearFlag(DMA1_FLAG_GL3);
usartRx.buffHead = USART_BUFF_SIZE - dmaCounter;
DMA_SetCurrDataCounter( DMA1_Channel5 , USART_BUFF_SIZE );
//reset the counter register
// }
USART_ClearITPendingBit(USART1,USART_IT_IDLE);
USART_ITConfig(USART1,USART_IT_IDLE,DISABLE);
//close usart IDLE interrupt
}
#else
//IRQ handle by SYSTICK + IDLE inquiry
static uint32_t thisRcvTime = 0;
if ( USART_GetITStatus( USART1 , USART_IT_RXNE ) != RESET ) {
usartRx.endTime = thisRcvTime;
thisRcvTime = millis();
//update lastTime recieved a byte
usartRx.buff[usartRx.buffHead] = USART1->DR;
//interval > 10ms
if(thisRcvTime - usartRx.endTime > 10){
usartRx.frameHead = usartRx.buffHead;
}else{
// usartRx.isDeal = true;
usartRx.frameEnd = usartRx.buffHead;
//if interval < 10ms ,stream belong to same frame
USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
//start idle time detect
}
usartRx.buffHead = (usartRx.buffHead + 1)%USART_BUFF_SIZE;
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
//detect IDLE time
if ( USART_GetITStatus( USART1 , USART_IT_IDLE ) != RESET ) {
if(millis() - thisRcvTime > 10 ){
USART_ITConfig(USART1,USART_IT_IDLE,DISABLE);
//close idle interrupt for save CPU
usartRx.isDeal = false;
}
USART_ClearITPendingBit(USART1,USART_IT_IDLE);
}
#endif
}
复制代码
2->
然后再处理函数里头实现一个简单的回显
#if defined(USART_RECIEVE_BY_SYSTICK)
//USART1 recieve frame by systick + RXNE
void usart_recieve_systick_handler(void)
{
uint16_t i;
if(usartRx.isDeal == false){
USART_ITConfig(USART1,USART_IT_IDLE|USART_IT_RXNE,DISABLE);
if(usartRx.frameHead < usartRx.frameEnd){
// printf("%d < %d\r\n",usartRx.frameHead,usartRx.frameEnd);
for(i=usartRx.frameHead; i<=usartRx.frameEnd; i++){
while((USART1->SR & 0X40)==0);
USART1->DR = usartRx.buff[i];
}
}else{
// printf("%d > %d\r\n",usartRx.frameHead,usartRx.frameEnd);
for(i=usartRx.frameHead; i<USART_BUFF_SIZE; i++){
while((USART1->SR & 0X40)==0);
USART1->DR = usartRx.buff[i];
}
for(i=0; i<usartRx.frameEnd; i++){
while((USART1->SR & 0X40)==0);
USART1->DR = usartRx.buff[i];
}
}
USART_ITConfig(USART1,USART_IT_IDLE|USART_IT_RXNE,ENABLE);
usartRx.isDeal = true;
}
}
#endif
复制代码
全部资料51hei下载地址:
ST.rar
(264.57 KB, 下载次数: 11)
2018-5-2 23:29 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
小橡皮
时间:
2018-5-2 21:44
我这里还没用DMA+IDLE查询来写数据包的接收,这段代码能实现的基础是知道发送端发送数据的最小间隔大于10ms
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1