本实验使用串口调试助手向串口发送数据,串口DMA接受到数据后,在中断处理函数里再次发送出去
第一步:配置串口,本实验采用串口一
//开启串口和GPIO引脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//串口tx引脚 配置为 复用推挽输出 速率50Mhz
GPIO_InitTypeDef serialgpio;
serialgpio.GPIO_Mode = GPIO_Mode_AF_PP;
serialgpio.GPIO_Pin = GPIO_Pin_9;
serialgpio.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&serialgpio);
//串口rx引脚 配置为 浮空输入
serialgpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
serialgpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA,&serialgpio);
/*
串口配置 波特率 流控位 停止位 数据位 模式等
*/
USART_InitTypeDef serialconfig;
serialconfig.USART_BaudRate = 115200;
serialconfig.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
serialconfig.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
serialconfig.USART_Parity = USART_Parity_No;
serialconfig.USART_StopBits = USART_StopBits_1;
serialconfig.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&serialconfig);
USART_Cmd(USART1,ENABLE);
串口发送单个字符代码
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}
串口发送数组数据代码
void Serial_SendArray(uint8_t *data,uint8_t len)
{
for(uint8_t i=0;i<len;i++)
{
Serial_SendByte(data[i]);
}
}
第二部:开启串口DMA接受
//开启串口DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
//开启串口接收DMA使能
USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
/*
DMA接收使能配置
*/
DMA_InitTypeDef serialdma;
//DMA外设地址 USART1->DR--->为串口数据寄存器
serialdma.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
//外设数据长度(8位 16位 32位) 本次实验使用8位数据
serialdma.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte;
//不开启外设地址增长
serialdma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//内存地址 这里的 buff位 全局变量用于存放接收数据 uint8_t buff[16];
serialdma.DMA_MemoryBaseAddr = (uint32_t)buff;
//外设数据长度(8位 16位 32位) 本次实验使用8位数据
serialdma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
//开启内存地址增长
serialdma.DMA_MemoryInc = DMA_MemoryInc_Enable;
//最高优先级
serialdma.DMA_Priority = DMA_Priority_VeryHigh;
//接收缓冲区大小
serialdma.DMA_BufferSize = sizeof(buff);
//开启从外设到内存的搬运模式
serialdma.DMA_DIR = DMA_DIR_PeripheralSRC;
//不使能内存到内存
serialdma.DMA_M2M = DMA_M2M_Disable;
//DMA模式为循环 及接收缓冲区满后从头再来
serialdma.DMA_Mode = DMA_Mode_Circular;
DMA_Init(DMA1_Channel5,&serialdma);
DMA_Cmd(DMA1_Channel5,ENABLE);
//开启DMA通道接收满中断
DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);
/*
NVIC的配置
*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitTypeDef serialnvic;
serialnvic.NVIC_IRQChannelPreemptionPriority = 1;
serialnvic.NVIC_IRQChannelSubPriority = 1;
serialnvic.NVIC_IRQChannelCmd = ENABLE;
serialnvic.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_Init(&serialnvic);
第三步:接收满中断
void DMA1_Channel5_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC5) == SET)
{
//把接收到的数据发送出去
Serial_SendArray(buff,sizeof(buff));
DMA_ClearITPendingBit(DMA1_IT_TC5);
}
}
使用串口调试助手测试结果
当buff缓冲区接收满时,数据发送出去