//全局变量
#define USART3_RX_BUFFER_SIZE 8
#define USART3_TX_BUFFER_SIZE 5
uint8_t USART3_Rx_Buffer[USART3_RX_BUFFER_SIZE] = {0};
uint8_t USART3_Tx_Buffer[USART3_TX_BUFFER_SIZE] = {0};
uint8_t USART3_Rx_DMA_Buffer[USART3_RX_BUFFER_SIZE] = {0};
uint8_t USART3_Tx_DMA_Buffer[USART3_TX_BUFFER_SIZE] = {'1','2','3','4','\n'};
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx:DMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
//par:外设地址
//mar:存储器地址
//ndtr:数据传输量
void DMA_Config(DMA_Stream_TypeDef *DMA_Streamx,uint32_t chx,uint32_t par,uint32_t mar,uint32_t dir,u16 ndtr)
{
DMA_InitTypeDef DMA_InitStructure;
if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
else
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能
DMA_DeInit(DMA_Streamx);
while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = chx; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = par; //DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = mar; //DMA 存储器0地址
DMA_InitStructure.DMA_DIR = dir; //direction of transmit.
DMA_InitStructure.DMA_BufferSize = ndtr; //数据传输量
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_High; //中等优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不用FIFO
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
DMA_Init(DMA_Streamx, &DMA_InitStructure);
DMA_Cmd(DMA_Streamx,ENABLE);
}
//开启一次DMA传输
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//ndtr:数据传输量
void DMA_Transfer_Enable(DMA_Stream_TypeDef *DMA_Streamx,u16 ndtr)
{
DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输
while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){} //确保DMA可以被设置
DMA_SetCurrDataCounter(DMA_Streamx,ndtr); //数据传输量
DMA_Cmd(DMA_Streamx, ENABLE); //开启DMA传输
}
//配置usart3
void USART3_Init(uint32_t bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_USART3); //GPIOD8复用为USART3_TX
GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_USART3); //GPIOD9复用为USART3_RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD,&GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
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);
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ClearFlag(USART3, USART_FLAG_TC);
// USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); //串口空闲中断
USART_ITConfig(USART3, USART_IT_TC, ENABLE); //发送完成中断
USART_DMACmd(USART3,USART_DMAReq_Rx | USART_DMAReq_Tx,ENABLE);
DMA_Cmd(DMA1_Stream1,ENABLE);
USART_Cmd(USART3, ENABLE);
//DMA for rx
DMA_Config(DMA1_Stream1,DMA_Channel_4,
(uint32_t)&(USART3->DR),
(uint32_t)USART3_Rx_DMA_Buffer,
DMA_DIR_PeripheralToMemory,
USART3_RX_BUFFER_SIZE);
//DMA for tx
DMA_Config(DMA1_Stream3,DMA_Channel_4,
(uint32_t)&(USART3->DR),
(uint32_t)USART3_Tx_DMA_Buffer,
DMA_DIR_MemoryToPeripheral,
USART3_TX_BUFFER_SIZE);
usart3.update=0;
usart3.locked=0;
usart3.tx_length=0;
usart3.rx_length=0;
usart3.rx_size=USART3_RX_BUFFER_SIZE;
usart3.tx_size=USART3_TX_BUFFER_SIZE;
usart3.tx_buf=USART3_Tx_DMA_Buffer;
usart3.rx_buf=USART3_Rx_DMA_Buffer;
DMA_Transfer_Enable(DMA1_Stream1,USART3_RX_BUFFER_SIZE); //开启一次DMA接收
// DMA_Transfer_Enable(DMA1_Stream3,USART3_TX_BUFFER_SIZE); //开启一次DMA发送
}
//中断服务函数
void USART3_IRQHandler(void)
{
uint8_t rc_tmp;
uint16_t rc_len;
//空闲中断(接收)---------------------------------------------------------------------------------------
if(USART_GetITStatus(USART3,USART_IT_IDLE)!=RESET)
{
//清除IDLE标志
rc_tmp=USART3->SR;
rc_tmp=USART3->DR;
DMA_Cmd(DMA1_Stream1, DISABLE);
DMA_ClearITPendingBit(DMA1_Stream1, DMA_IT_TCIF1); //清除发送完成标志
DMA_ClearITPendingBit(DMA1_Stream1, DMA_IT_TEIF1); //清除发送错误标志
rc_len = USART3_RX_BUFFER_SIZE - DMA_GetCurrDataCounter(DMA1_Stream1); //计算本次收到的数据帧长度
if(!usart3.locked)
{
usart3.rx_length=rc_len;
Data_Decode(USART3_Rx_DMA_Buffer);
DMA_Transfer_Enable(DMA1_Stream1,USART3_RX_BUFFER_SIZE);
}
}
//发送完成中断(发送)---------------------------------------------------------------------------------------
if(USART_GetITStatus(USART3,USART_IT_TC)!=RESET)
{
DMA_ClearFlag(DMA1_Stream3, DMA_FLAG_TCIF3); //清除DMA发送完成标志
USART_ClearITPendingBit(USART3, USART_IT_TC); //清除发送完成标志
DMA_Cmd(DMA1_Stream3, DISABLE);
}
}
|