几乎是按照官方例子配出来的程序. 我是想设置4个字节到缓冲区后产生接收传输完成中断. 然后一次处理4个字节,但是PC只要向
STM32发送1个字节,DMA_FLAG_TCIF1马上就置位了, 缓冲区里面也没有数据,但是看USART-DR里是收到那个字符的.
下面是初始化代码,为了简化我没有中断,配置好串口后一直查询 DMA_FLAG_TCIF1 标志位.
// 初始化函数,外面会传一个BUF首地址和长度进来作为DMA接收缓冲区
void HAL_UARTDevInit (const UINT8 *p_rec_buf, UINT32 num)
{
UINT8 err;
DMA_InitTypeDef dma_init_structure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
/* Connect PXx to USARTx_Tx*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
/* Connect PXx to USARTx_Rx*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
/* Configure USART Tx as alternate func
tion */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure USART Rx as alternate function */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* USART configuration */
USART_InitStructure.USART_BaudRate = 115200;
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(USART3, &USART_InitStructure);
// USART_ClearFlag(USART3, USART_FLAG_TC | USART_FLAG_RXNE); /* 清除已有的标志位, 防止使能后直接进入该中断 */
USART_Cmd(USART3, ENABLE);
/* 当配置DMA时初始化DMA接收通道 */
DMA_DeInit(DMA1_Stream1);
dma_init_structure.DMA_Channel = DMA_Channel_4;
dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t)(USART3 + 0x04);
dma_init_structure.DMA_Memory0BaseAddr = (uint32_t)p_rec_buf;
dma_init_structure.DMA_DIR = DMA_DIR_PeripheralToMemory;
dma_init_structure.DMA_BufferSize = num;
dma_init_structure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_init_structure.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma_init_structure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma_init_structure.DMA_Mode = DMA_Mode_Normal;
dma_init_structure.DMA_Priority = DMA_Priority_VeryHigh;
dma_init_structure.DMA_FIFOMode = DMA_FIFOMode_Disable;
dma_init_structure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
dma_init_structure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
dma_init_structure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream1, &dma_init_structure);
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Stream1, ENABLE);
}
//测试代码
unsigned char buffer[4];
HAL_UARTDevInit(buffer, 4);
while (DMA_GetFlagStatus(DMA1_Stream1, DMA_FLAG_TCIF1) == RESET)
{
;
}
while(1); // 设个断点程序达到此处后停下来观察内存. 只要串口接受到1个字节就会到这里, buffer里全是0, 而USART3->DR里有我发过来的数据. 详细对比了几遍和例程 USART_TwoBoardsDataExchangeDMA. 几乎没有不同. 我禁止掉了FIFO模式, 如果启用FIFO也是一样
请高人帮忙!
官方的库/例程可以参考,但是不要完全不思考,个人建议
那接收到128个字节才会认为是接收完成啊
怎么第一个字节就进入接收完成中断了,楼主解决没?
一周热门 更多>