由于使用串口数量较多,并且串口1接收的数据量较大,不想占用中断,所以使用dma方式接收,使用串口的空闲总线中断方式来判定是否接收完一帧数据。
问题描述:
使用上述方式接收数据帧结果每次收到数据后都要进串口中断溢出错误。
DMA_InitTypeDef DMA_InitStructure;
[code]
void USART1_IRQHandler(void) //串口1 中断服务程序
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL(); //保存全局中断标志,关总中断// Tell uC/OS-II that we are starting an ISR
OSIntNesting++;
OS_EXIT_CRITICAL(); //恢复全局中断标志
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_ORE);
USART_ReceiveData(USART1);
}
if(USART_GetFlagStatus(USART1,USART_FLAG_NE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_NE);
USART_ReceiveData(USART1);
}
if(USART_GetFlagStatus(USART1,USART_FLAG_FE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_FE);
USART_ReceiveData(USART1);
}
/*
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET)
{
if(RxCnt1<200)
RxCnt1++;
else
RxCnt1 = 0;
RxBuf1[RxCnt1] = USART_ReceiveData(USART1);
}
*/
if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_IDLE);
USART_ReceiveData(USART1); //清除中断标志位
DMA_Cmd(DMA1_Channel5,DISABLE); //关闭dma防止干扰
OSMboxPost(UsartWS_MBOX,(void *)RxBuf1); //发送邮箱供前台处理
}
OSIntExit(); //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换
}
USART_InitTypeDef USART_InitStructure;
/*dma配置*/
DMA_Cmd(DMA1_Channel5,DISABLE);
DMA_DeInit(DMA1_Channel5); //恢复缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Addr; //DMA外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RxBuf1; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设为数据源
DMA_InitStructure.DMA_BufferSize = 255; //DMA缓存大小 ,单位为DataSize的值 要大于实际接收最大值
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_VeryHigh; //高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //没设置内存到内存传输
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
DMA_ClearFlag(DMA1_FLAG_GL5); //清除dma所有标志
DMA_Cmd(DMA1_Channel5,ENABLE);
USART_InitStructure.USART_BaudRate = 4800; //速率4800bps
USART_InitStructure.USART_WordLength = USART_WordLength_9b; //数据位8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位
USART_InitStructure.USART_Parity = USART_Parity_Even; //偶校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
/* Configure USARTx */
USART_Init(USART1, &USART_InitStructure); //配置串口参数函数
/* Enable USARTx Receive and Transmit interrupts */
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启串口空闲中断
/* Enable the USARTx */
USART_DMACmd( USART1,USART_DMAReq_Rx,ENABLE); //开启串口dma接收
USART_Cmd(USART1, ENABLE); [/code] |