微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > stm32F407之USART6的DMA工作方式

stm32F407之USART6的DMA工作方式

时间:11-10 来源:互联网 点击:

/*配置GPIOC_Pin6为TX输出*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //设置为复用,必须为AF,OUT不行
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);

/*配置GPIOC_Pin7为RX输入*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //这也必须为复用,与M3不同!
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);

/*IO引脚复用功能设置,与之前版本不同*/
/*配置USART6*/
USART_StructInit(&USART_InitStructure);
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(USART6, &USART_InitStructure);
USART_ClockStructInit(&USART_ClockInitStruct); //之前没有填入缺省值,是不行的
USART_ClockInit(USART6, &USART_ClockInitStruct);

USART_ITConfig(USART6, USART_IT_RXNE, ENABLE); //使能 USART6中断
USART_Cmd(USART6, ENABLE); //使能 USART6
//USART_DMACmd(USART6, USART_DMAReq_Tx, ENABLE); //使能USART6的发送数据DMA请求,至此USART6与DMA开始工作,可以写在主函数里随时工作
}

void NVIC_Config()
{
/*USART6中断配置*/
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //嵌套优先级分组为 1
NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; //嵌套通道为USART6_IRQn
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级为 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能
NVIC_Init(&NVIC_InitStructure);

/*DMA中断配置*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //嵌套优先级分组为 1
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn; //嵌套通道为DMA2_Stream6_IRQn
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级为 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级为 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能
NVIC_Init(&NVIC_InitStructure);

}

/*************************************************
Function: void USART6_Puts(char * str)
Description: USART6发送数据
Input: 待发送数据指针
Output:无
Return:无
*************************************************/
void USART6_Puts(char * str)
{
while (*str)
{
USART_SendData(USART6, *str++);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART6, USART_FLAG_TXE) == RESET); //详见英文参考的521页,当TXE被置起时,一帧数据传输完成
}
}

/*************************************************
Function: void DMA_Config(void)
Description: DMA配置函数
Input: 延时的时间
Output:无
Return:无
*************************************************/
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
/*首先开DMA2时钟,由407参考手册-RM0090-Reference manual
165页可知,UASRT6与DMA2映射,而且DMA2挂载在AHB1时钟总线上*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/*由RM0090-Reference manual第165页映射表可知,USART6映射在
Channel_5的Stream6和Stream7上,在这里可以选择Stream6 */
DMA_DeInit(DMA2_Stream6);
DMA_StructInit( &DMA_InitStructure);
DMA_InitStructure.DMA_Channel = DMA_Channel_5; //选择Channel_5
DMA_InitStructure.DMA_PeripheralBaseAddr = USART6_DR_Addr; //数据传输的外设首地址,详解见上
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Buffer; //自己定义待发送数组的首地址,要强制转换为32位
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //数据传输方向选择为内存->外设
DMA_InitStructure.DMA_BufferSize = 8; //传输数据大小为8,单位由以下确定,大小要配合定义的数组类型和外设数据类型
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器自动增加禁止,因为这里只用到了DR数据寄存器
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增允许,因为要读取一个数组
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设的数据大小,因为USART6_DR数据寄存器为8为,故选Byte
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //这里也选Byte
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA传输模式为Normal,如果为Circular,将会循环传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //优先级为High
/*双缓冲模式,在DMA_Init之前调用在Circular模式有效,会强制Circular,
*不支持Memory toMemory,(uint32_t)Buffer2为DMA_Memory_1,DMA先将Buffer
*中的数据发送完毕后在发送Buffer2的数据,当然顺序可以改变
DMA_DoubleBufferModeConfig(DMA2_Stream6, (uint32_t)Buffer2, DMA_Memory_0);
DMA_DoubleBufferModeCmd(DMA2_Stream6, ENABLE);
*/
DMA_Init(DMA2_Stream6, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream6, ENABLE);//使能DMA2_Stream6通道
/*DMA中断开*/
DMA_ITConfig(DMA2_Stream6, DMA_IT_TC, ENABLE);
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top