完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
串口接受不定长数据,就是数据格式不确定,长度不确定,我们需要找到判断是否接收完成的.
如果是一个数据侦,接收时数据字节之间的间隔时间是很短,但接收完成时,我们就无收到数据了,所以我们判断是否接收完成,就是判断数据字节间的间隔 我想到的到的方法有2: 1.串口接收数据+定时做超时判断 2.串口接收数据+IDLE空闲中断 3.DMA串口数据接收+IDLE空闲中断 以下是我整理的代码: Usart_Init 串口初始化 #include "ESP8266.h" #include "usart.h" //接收不定长度信息,两种处理方法 //方法1:串口接收数据,定时判断超时取出数据 //方法2:DMA接收 +IDLE中断取出数据 //方法3:串口接收+IDLE中断取出数据 /*---------------------------------------------------------------------------------------| * DMA串口通道表 | *-----|-------|-----------|------------|-----------|-----------|-----------|------------| *通道 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *-----|-------|-----------|------------|-----------|-----------|-----------|------------| *DMA1 | NC | USART3_TX | USART3_RX | USART1_TX | USART1_RX | USART2_RX | USART2_TX | *-----|-------|-----------|------------|-----------|-----------|-----------|------------| *DMA2 | NC | NC | UART4_RX | NC | UART4_TX | NC | NC | *-----|-------|-----------|------------|-----------|-----------|-----------|------------| */ //WiFi模块使用的是串口 //方法2:DMA接收 +IDLE中断取出数据 //参数(DMA通道,外设地址,储存地址,储存长度) void DMAx_InitRX ( DMA_Channel_TypeDef *DMAn_Channelx, u32 par, u32 mar, u16 ndtr ) { DMA_InitTypeDef DMA_InitStructure; if( DMAn_Channelx== DMA1_Channel1 || DMAn_Channelx== DMA1_Channel2 || DMAn_Channelx== DMA1_Channel3 || DMAn_Channelx== DMA1_Channel4 || DMAn_Channelx== DMA1_Channel5 || DMAn_Channelx== DMA1_Channel6 || DMAn_Channelx== DMA1_Channel7 ){ RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_DMA1, ENABLE ); //DMA1时钟使能 }else{ RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_DMA2, ENABLE ); //DMA1时钟使能 } //DMA_DeInit(DMAy_Channelx); /* 配置 DMA */ DMA_InitStructure.DMA_PeripheralBaseAddr = par; //DMA外设地址 DMA_InitStructure.DMA_MemoryBaseAddr = mar; //DMA 存储器0地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为数据传输的来源 DMA_InitStructure.DMA_BufferSize = ndtr; //数据传输量 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 使用普通模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init ( DMAn_Channelx, &DMA_InitStructure ); //初始化DMA } void ESP8266_Init2( COM_TypeDef COMx, u32 Baud, u8 Priority1, u8 Priority2 ,DMA_Channel_TypeDef *DMAn_Channelx,u8 *Buff,u16 buffsize) { Usart_Init(COMx,Baud, Priority1 , Priority2 ); /* 关闭串口接受中断*/ USART_ITConfig ( COMn_USART[COMx], USART_IT_RXNE, DISABLE ); //关闭串口接受中断 USART_Cmd ( COMn_USART[COMx], DISABLE ); //关闭串口中断 //配置DMA读取串口外设的数据 if(COMx == COM1 || COMx == COM2 || COMx == COM3 ) { DMAx_InitRX(DMAn_Channelx,(u32)&COMn_USART[COMx]->DR,(u32)Buff,buffsize);//DMA1通道5,外设为串口1,存储器为SendBuff,长度SEND_BUF_SIZE. USART_DMACmd( COMn_USART[COMx],USART_DMAReq_Rx,ENABLE); DMA_Cmd(DMAn_Channelx,ENABLE); } USART_ITConfig(COMn_USART[COMx],USART_IT_IDLE,ENABLE); //开始空闲中断 USART_Cmd( COMn_USART[COMx],ENABLE); //开启串口中断 } #if 0 u8 Uart1_RXbuff[100]={0}; //接收的数据包 void USART1_IRQHandler(void) { u32 temp = 0; u16 i = 0; u8 tempdat = 0; if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET) //产生空闲中断 { USART_ClearFlag(USART1,USART_IT_IDLE); #if 1 temp = USART1->SR; temp = USART1->DR; //清除空闲中断 #else USART_ReceiveData(USART1); //清除中断 #endif DMA_Cmd(DMA1_Channel5,DISABLE); //关闭DMA接收 temp = sizeof(Uart1_RXbuff) - DMA_GetCurrDataCounter(DMA1_Channel5); //得到数据长度 = 总长度 - 待传输的数目; for(i=0;i Usart_SendByte(COM1,Uart1_RXbuff); } //设置新的DMA传输地址,和接收缓存 DMA_SetCurrDataCounter(DMA1_Channel5,sizeof(Uart1_RXbuff)); //重新设置剩余的数目 DMA_Cmd(DMA1_Channel5,ENABLE); } } #endif //方法3:串口接收+IDLE中断取出数据 void ESP8266_Init3( COM_TypeDef COMx, u32 Baud, u8 Priority1, u8 Priority2 ) { Usart_Init(COMx,Baud, Priority1 , Priority2 ); USART_ITConfig(COMn_USART[COMx],USART_IT_IDLE,ENABLE); //开始空闲中断 USART_Cmd( COMn_USART[COMx],ENABLE); //开启串口中断 } #if 1 u8 Uart1_RXbuff[100]={0}; //接收的数据包 u8 Usart1_ReState = 0; void USART1_IRQHandler(void) { u32 temp = 0; static u16 i = 0; u8 tempdat = 0; if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET) //串口接收 { #if 1 Uart1_RXbuff[i++] = USART1->DR; //保存数据 #else Uart1_RXbuff[i++] = USART_ReceiveData(USART1); //保存数据 #endif } if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET) //产生空闲中断,取出一侦数据包 { USART_ClearFlag(USART1,USART_IT_IDLE); #if 1 temp = USART1->SR; temp = USART1->DR; //清除空闲中断 #else USART_ReceiveData(USART1); //清除中断 #endif /*可直接复制取出一帧数据包*/ Usart1_ReState = 1; } } #endif |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:42 , Processed in 0.815877 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号