您的位置:首页 > 其它

STM32 DMA 应用之(二) DMA 串口 数据传输--发送

2013-12-09 09:40 656 查看
一、DMA请求映像





由此我们知道如果需要使用串口1的发送功能需要用到的是DMA1_Channel4

使用串口1的接收功能需要用到的是DMA1_Channel5

二、怎样配置软件来使用DMA 把数据传到串口发送?

(1)配置dma

/**************************************************************************
*函数名称:  Dma_Init
*功能描述: 利用DMA 把内存的数据传输到串口发送达到高速传输的目的
*
*输入参数:无
*返回值  :无
*其他说明:无
*当前版本:v1.0
*作者     :尹宣
*完成时间:2013年12月1日
*修改日期              版本号              修改人              修改内容
*-----------------------------------------------------------------
*
******************************************************************/
#define UART_RX_LEN     5
u8 Uart_Send_Buffer[UART_RX_LEN] = {0x12,0x34,0x56,0x78,0x90};
u8 i=0;
u8 Flag_Uart_Send=0;

void Dma_Init(void)
{
DMA_InitTypeDef  DMA_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* DMA channel6configuration */
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr       = (u32)(&USART1->DR);  //外设地址
DMA_InitStructure.DMA_MemoryBaseAddr                    =(u32)Uart_Send_Buffer;
DMA_InitStructure.DMA_DIR                                      =DMA_DIR_PeripheralDST;   //外设作为目的地址   //DMA_DIR_PeripheralSRC;   //外设作为DMA的源端
DMA_InitStructure.DMA_BufferSize                          =5; //BufferSize;      //传输大小
DMA_InitStructure.DMA_PeripheralInc                   =DMA_PeripheralInc_Disable; //外设递增模式禁止   DMA_PeripheralInc_Enable;            //外设地址增加
DMA_InitStructure.DMA_MemoryInc                       =DMA_MemoryInc_Enable;   //内存地址自增
DMA_InitStructure.DMA_PeripheralDataSize         = DMA_PeripheralDataSize_Byte; //传输方式:字节   DMA_PeripheralDataSize_Word;    //字(32位)
DMA_InitStructure.DMA_MemoryDataSize            =DMA_PeripheralDataSize_Byte;  //内存存储方式:字节  DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode                                  =DMA_Mode_Circular;  //DMA_Mode_Normal 正常模式,只传送一次;  DMA_Mode_Circular:循环模式,不停的传送;
DMA_InitStructure.DMA_Priority                      =DMA_Priority_High;
DMA_InitStructure.DMA_M2M                                   =DMA_M2M_Disable;             //DMA_M2M_Enable;
DMA_Init(DMA1_Channel4,&DMA_InitStructure);

/* Enable DMA Channel4Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC, ENABLE);
//
// USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);                                                                    //串口接收器DMA
//采用DMA方式发送
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
//启动串口
USART_Cmd(USART1,ENABLE);

DMA_ITConfig(DMA1_Channel4,DMA_IT_TC, ENABLE);
传输完成则进入DMA1_Channel4中断;


注意这句话:USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 这是使能指定USART的DMA请求;(不同的外设都有这个 xxx_DMACmd()请求;)

USART_DMAReq_Tx:发送DMA请求

USART_DMAReq_Rx:接收DMA请求

串口配置

/*****************************************************************
*函数名称: USART1_Init
*功能描述:   配置串口1初始化
*
*输入参数:无
*返回值  :无
*其他说明:无
*当前版本:v1.0
*作者     :尹宣
*完成时间:2013年12月1日
*修改日期              版本号              修改人              修改内容
*-----------------------------------------------------------------
*
******************************************************************/
void USART1_Init(uint32 baud)
{
GPIO_InitTypeDef       GPIO_InitStructure;
USART_InitTypeDef      USART_InitStructure;
USART_ClockInitTypeDefUSART_ClockInitStructure;

//使能串口1,PA,AFIO总线
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_AFIO |
RCC_APB2Periph_USART1 ,
(FunctionalState)ENABLE);

// A9 USART1_Tx
GPIO_InitStructure.GPIO_Pin   =GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode  =GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);

// A10 USART1_Rx
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);

USART_InitStructure.USART_BaudRate            = baud;
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_ClockInitStructure.USART_Clock   = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL    = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA    = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit= USART_LastBit_Disable;
USART_ClockInit(USART1,&USART_ClockInitStructure);

USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1,(FunctionalState)ENABLE);
//  USART_ClearFlag(USART3, USART_FLAG_TC);
//串口1使用接收中断
USART_ITConfig(USART1,USART_IT_RXNE,(FunctionalState)ENABLE);
}

2.设置DMA优先级

/*****************************************************************
*函数名称:  NVIC_Config
*功能描述:   配置DMA的中断优先级
*
*输入参数:无
*返回值  :无
*其他说明:无
*当前版本:v1.0
*作者     :尹宣
*完成时间:2013年12月1日
*修改日期              版本号              修改人              修改内容
*-----------------------------------------------------------------
*
******************************************************************/
void NVIC_Config(void)
{
NVIC_InitTypeDefNVIC_InitStructure;

//DMA优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
NVIC_InitStructure.NVIC_IRQChannel= DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1;
NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
NVIC_Init(&NVIC_InitStructure);

/*Configure one bit for preemption priority -------------------------------- */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

/*UART1 -------------------------------------------------------------------- */
NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1;
NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
NVIC_Init(&NVIC_InitStructure);

}


3.在stm3210x_it.c 文件中添加 DMA中断处理函数

/*******************************************************************************
* Function Name  : DMAChannel1_IRQHandler
* Description    : This function handles DMA Stream 1interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
//串口1  DMA方式发送中断
void DMA1_Channel4_IRQHandler(void)
{

//清除标志位
DMA_ClearFlag(DMA1_FLAG_TC4);
//关闭DMA
DMA_Cmd(DMA1_Channel4,DISABLE);
Flag_Uart_Send = 0;

}


如果DMA是正常模式DMA_Mode_Normal时,传输结束后将不再产生DMA操作;所以需要在传输完成的中断中暂时把DMA关闭—即:DMA_Cmd(DMA1_Channel4,DISABLE);

之后在main函数的while(1)循环中打开DMA_Cmd(DMA1_Channel4,ENABLE);进行下一次的传输;

测试:

数据源地址为数组Uart_Send_Buffer ,它的定义如下:

#define UART_RX_LEN 5

u8 Uart_Send_Buffer[UART_RX_LEN] ={0x12,0x34,0x56,0x78,0x90};

当程序开始全速运行时,串口助手打印

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: