标题:
关于STM32串口1IDLE模式兼DMA接收数据会丢失数据的问题
[打印本页]
作者:
Sanada
时间:
2018-11-24 19:55
标题:
关于STM32串口1IDLE模式兼DMA接收数据会丢失数据的问题
本人想用STM32的DMA和串口1 的ILDE模式接收不定长数据帧,遇到一个奇怪的现象,当串口助手V2.0(正点原子的)手动发送所需要的数据包时,误包率很高,而改为60ms自动发送就几乎没有出现误包的问题,所谓的误包问题要不出现功能码出错,要不帧长度出现错误了。
void Configuration_GPIO()
{
GPIO_InitTypeDef GPIO_InitStructure;
// USART1_TX:PA9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// USART1_RX:PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
复制代码
#include "Configuration_DMA.h"
u8 RecBuffer[RecLength] = {0};
u8 Usart1_Rec_Cnt = 0;
void Configuration_DMA_USART()
{
DMA_InitTypeDef DMA_InitStructure;
/* 该DMA用于USART快速传输一帧数据,单字节时不需要 */
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) &USART1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) &RecBuffer;//这是初始化时候配置,可以根据程序运行重新设置。
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = RecLength;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel5, ENABLE);
}
复制代码
void Control_NVIC_USART1(FunctionalState NewStatus)
{
NVIC_InitTypeDef NVIC_InitStructure;
// 设置NVIC中断分组4:4位抢占优先级,0位响应优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = NewStatus;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
}
复制代码
void Configuration_USART(u32 baudrate)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); // 不使能接收中断
USART_ITConfig(USART1, USART_IT_TC, DISABLE); // 不使能发送中断
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); // 使能空闲中断
USART_ClearFlag(USART1, USART_FLAG_TC);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
USART_Cmd(USART1, ENABLE);
// 防止首字节丢失
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
}
void USART1_SendByte(uint8_t c)
{
USART_SendData(USART1, (uint8_t)c);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
}
void USART1_SendNByte(u8 *pData,u8 Length)
{
while(Length--)
{
USART1_SendByte(*pData);
pData++;
}
}
void USART1_IRQHandler(void)
{
u8 i;
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
{
// 关闭USART1 TX DMA1 所指示的通道
DMA_Cmd(DMA1_Channel5, DISABLE);
// 读取数据 注意:这句必须要,否则不能够清除中断标志位。我也不知道为啥!
USART_ReceiveData(USART1);
// 算出接本帧数据长度
Usart1_Rec_Cnt = RecLength - DMA_GetCurrDataCounter(DMA1_Channel5);
if(Usart1_Rec_Cnt != 8)
Usart1_Rec_Cnt = 0;
/*------------------------串口测试段--------------------------------*/
for(i = 0;i < Usart1_Rec_Cnt;i++)
RecBuffer1[i] = RecBuffer[i];
//***********帧数据处理函数************//
// printf ("The lenght:%d\r\n",Usart1_Rec_Cnt);
// printf ("The data:\r\n");
// USART1_SendNByte(RecBuffer, Usart1_Rec_Cnt);
// printf ("\r\nOver! \r\n");
//*************************************//
// 清除中断标志
USART_ClearITPendingBit(USART1, USART_IT_IDLE);
// DMA通道的DMA缓存的大小
DMA_SetCurrDataCounter(DMA1_Channel5, RecLength);
// 使能USART1 TX DMA1 所指示的通道
DMA_Cmd(DMA1_Channel5, ENABLE);
}
}
复制代码
以上是我的GPIO。DMA、USART和中断的配置,请遇到过类似问题的大佬能够伸出援手,在下感激不尽!
作者:
Dradece
时间:
2019-2-15 20:39
楼主解决了吗,我也遇到过了这问题
作者:
pkoko
时间:
2019-12-25 20:42
遇到类似问题,用串口助手自动发送,一样丢包
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1