串口DMA
static void Usart1Init(int iBaudRate)
{
#if (TX_USE_MODE == USE_MODE_DMA) || (RX_USE_MODE == USE_MODE_DMA)
DMA_InitTypeDef DMA_InitStructure;
#endif
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1EN | RCC_AHBENR_DMA2EN, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
Usart1BaseInit(iBaudRate);
#if (TX_USE_MODE != USE_MODE_POL)
FifoInit(&gsstUsart1TxFifo, gsucUsart1TxBuf, sizeof(gsucUsart1TxBuf), Usart1TxCrtCtrl, FALSE);
#endif
#if (RX_USE_MODE != USE_MODE_POL)
FifoInit(&gsstUsart1RxFifo, gsucUsart1RxBuf, sizeof(gsucUsart1RxBuf), Usart1RxCrtCtrl, TRUE);
#endif
#if (TX_USE_MODE == USE_MODE_DMA)
DMA_InitStructure.DMA_BufferSize = sizeof(gsucUsart1TxBuf);//DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//数据传输方向,从内存读取发送到外设
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
//内存
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(gsucUsart1TxBuf); //DMA内存基地址
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//数据宽度为8位
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//工作在正常缓存模式
//外设
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);//DMA外设USART1基地址
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据宽度为8位
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道 x拥有高优先级
DMA_Cmd(DMA1_Channel4, DISABLE); //!!!! DISABLE STATE CNDTR REGISTER CAN BE UPDATE
DMA_Init(DMA1_Channel4, &DMA_InitStructure);//根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);//=====================DMA_IT_TC定义为传输数据给外设地址满了才发生
DMA_Cmd(DMA1_Channel4, DISABLE); //DISABLE
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
#endif
#if (RX_USE_MODE == USE_MODE_DMA)
DMA_InitStructure.DMA_BufferSize = sizeof(gsucUsart1RxBuf);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//数据传输方向,从外设读取到内存[外设是数据源]
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(gsucUsart1RxBuf);
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//这句是设置 DMA 的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal。
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//
DMA_Cmd(DMA1_Channel5, DISABLE); //!!!! DISABLE STATE CNDTR REGISTER CAN BE UPDATE
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel5, ENABLE);
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
#elif (RX_USE_MODE == USE_MODE_INT)
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
#endif
USART_Cmd(USART1, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#if (TX_USE_MODE == USE_MODE_DMA)
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; //TX DMA
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
}
/*****************************************************************
函数名称:USART1_IRQHandler
函数描述:
输入参数:
输出参数:
返回说明:
其它说明:
*****************************************************************/
void USART1_IRQHandler(void)
{
#if (RX_USE_MODE == USE_MODE_INT)
if((USART1->CR1 & USART_FLAG_RXNE) && (USART1->SR & USART_FLAG_RXNE))
{
u8 ucData = USART1->DR;
UsartRxCheckSymbol(&gsstCnter1, ucData);
FifoPushByte(&gsstUsart1RxFifo, ucData);
}
#endif
#if (TX_USE_MODE == USE_MODE_INT)
if((USART1->CR1 & USART_FLAG_TXE) && (USART1->SR & USART_FLAG_TXE))
{
int iData = FifoPopByte(&gsstUsart1TxFifo);
if(iData >= 0)
{
USART1->DR = (u8)(iData);
}
else
{
USART1->CR1 &= ~USART_FLAG_TXE;
}
}
#endif
#if (RX_USE_MODE == USE_MODE_DMA)
if((USART1->CR1 & USART_FLAG_IDLE) && (USART1->SR & USART_FLAG_IDLE)) //空闲才中断
{
int iInPoint = USART1->SR;
iInPoint = USART1->DR;
iInPoint = sizeof(gsucUsart1RxBuf) - DMA1_Channel5->CNDTR;
UsartRxDMACheckReset(&gsstUsart1RxFifo, &gsstCnter1, iInPoint);
FifoPushSetPoint(&gsstUsart1RxFifo, iInPoint);
}
#endif
}
#if (TX_USE_MODE == USE_MODE_DMA)
/*****************************************************************
函数名称:DMA1_Channel4_IRQHandler
函数描述:
输入参数:
输出参数:
返回说明:
其它说明:
*****************************************************************/
void DMA1_Channel4_IRQHandler(void)
{
stUsartDmaOperationArgs_t stArgs = {FALSE, 256, DMA1_Channel4}; //FALSE 不检查
DMA_ClearITPendingBit(DMA1_IT_TC4);
FifoSafeOperation(&gsstUsart1TxFifo, UsartTxDMAOperation, &stArgs);
}
static void Usart1Init(int iBaudRate){ #if (TX_USE_MODE == USE_MODE_DMA) || (RX_USE_MODE == USE_MODE_DMA) DMA_InitTypeDef DMA_InitStructure; #endif GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1EN | RCC_AHBENR_DMA2EN, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure);
Usart1BaseInit(iBaudRate); #if (TX_USE_MODE != USE_MODE_POL) FifoInit(&gsstUsart1TxFifo, gsucUsart1TxBuf, sizeof(gsucUsart1TxBuf), Usart1TxCrtCtrl, FALSE); #endif #if (RX_USE_MODE != USE_MODE_POL) FifoInit(&gsstUsart1RxFifo, gsucUsart1RxBuf, sizeof(gsucUsart1RxBuf), Usart1RxCrtCtrl, TRUE); #endif #if (TX_USE_MODE == USE_MODE_DMA) DMA_InitStructure.DMA_BufferSize = sizeof(gsucUsart1TxBuf);//DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输//内存 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(gsucUsart1TxBuf); //DMA内存基地址 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//数据宽度为8位 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//工作在正常缓存模式//外设 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);//DMA外设USART1基地址 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据宽度为8位 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变 DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道 x拥有高优先级 DMA_Cmd(DMA1_Channel4, DISABLE); //!!!! DISABLE STATE CNDTR REGISTER CAN BE UPDATE DMA_Init(DMA1_Channel4, &DMA_InitStructure);//根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器 DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);//=====================DMA_IT_TC定义为传输数据给外设地址满了才发生 DMA_Cmd(DMA1_Channel4, DISABLE); //DISABLE USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); #endif
#if (RX_USE_MODE == USE_MODE_DMA) DMA_InitStructure.DMA_BufferSize = sizeof(gsucUsart1RxBuf); DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//数据传输方向,从外设读取到内存[外设是数据源] DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(gsucUsart1RxBuf); DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//这句是设置 DMA 的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal。 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR); DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;// DMA_Cmd(DMA1_Channel5, DISABLE); //!!!! DISABLE STATE CNDTR REGISTER CAN BE UPDATE DMA_Init(DMA1_Channel5, &DMA_InitStructure); DMA_Cmd(DMA1_Channel5, ENABLE); USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); #elif (RX_USE_MODE == USE_MODE_INT) USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); #endif USART_Cmd(USART1, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
#if (TX_USE_MODE == USE_MODE_DMA) NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; //TX DMA NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif}

浙公网安备 33010602011771号