通过DMA向串口发送数据

2020-07-04来源: eefocus关键字:DMA  串口  发送数据

//DMA —- Directional Memory Access, 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作


//串口初始化

void USART1_Init(u32 baud)

{

    GPIO_InitTypeDef GPIO_Initstructure;

    USART_InitTypeDef USART_Initstructure;

    NVIC_InitTypeDef NVIC_Initstructure;

    

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); //使能PA和USART1的时钟

    //USART1_TX  PA9

    GPIO_Initstructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽复用输出

    GPIO_Initstructure.GPIO_Pin = GPIO_Pin_9; //PA9

    GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz

    GPIO_Init(GPIOA, &GPIO_Initstructure); //初始化

    //USART1_RX  PA10

    GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入

    GPIO_Initstructure.GPIO_Pin = GPIO_Pin_10; //PA10

    GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz

    GPIO_Init(GPIOA, &GPIO_Initstructure);

 

    USART_DeInit(USART1);

 

    

    NVIC_Initstructure.NVIC_IRQChannel = USART1_IRQn; //串口1

    NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级3

    NVIC_Initstructure.NVIC_IRQChannelSubPriority = 0; //子优先级3

    NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE; //使能中断

    NVIC_Init(&NVIC_Initstructure);

    

    USART_Initstructure.USART_BaudRate = baud; //波特率

    USART_Initstructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制

    USART_Initstructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //收发模式

    USART_Initstructure.USART_Parity = USART_Parity_No; //无奇偶校验位

    USART_Initstructure.USART_StopBits = USART_StopBits_1; //一位停止位

    USART_Initstructure.USART_WordLength = USART_WordLength_8b; //8位数据位

    

    USART_Init(USART1, &USART_Initstructure); //初始化

 

    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

    DMA1_Channel4_UseForUSART1_Config();

 

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接受中断

    USART_Cmd(USART1, ENABLE);                    //使能串口1

}

void DMA1_Channel4_UseForUSART1_Config(void)

{

    DMA_InitTypeDef DMA_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    

    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_Init(&NVIC_InitStructure);

    

    DMA_DeInit(DMA1_Channel4); //将DMA的通道寄存器重设为缺省值

    DMA_InitStructure.DMA_BufferSize = 0; //DMA缓存大小 暂时设置为6个字节

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为目的地

    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //不设置为内存到内存

    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; //内存地址暂时设置为0, 启动传输的时候再指定具体位置

    DMA_InitStructure.DMA_MemoryDataSize = SENDBUFF_SIZE;

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增

    DMA_InitStructure.DMA_Mode = 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_High; //高优先级

    

    DMA_Init(DMA1_Channel4, &DMA_InitStructure);

    DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); //开启传输完成中断

}

//通过DMA发送数据到串口

FlagStatus FlagStatus_DMA1_Channel4_Busy; //DMA1_Channel4忙标志位

ErrorStatus USART1_SendDataByDMA(u32 memoryaddr, u16 buffersize)

{

    if(FlagStatus_DMA1_Channel4_Busy != SET) //通道空闲

    {

        LED_TX_Onepulse();

        FlagStatus_DMA1_Channel4_Busy = SET; //设置通道忙标志

        DMA_Cmd(DMA1_Channel4, DISABLE);

        DMA_SetCurrDataCounter(DMA1_Channel4, buffersize);     //缓存大小

        DMA1_Channel4->CMAR = memoryaddr; //内存地址

        DMA_Cmd(DMA1_Channel4, ENABLE); //启动传输

        return SUCCESS;

    }

    else //通道忙

    {

        return ERROR;

    }

}


//通道4中断函数,用于清除忙标志位

void DMA1_Channel4_IRQHandler(void)

{

    if(DMA_GetITStatus(DMA1_IT_GL4) != RESET)

    {

        if(DMA_GetITStatus(DMA1_IT_TC4) != RESET)

        {

            FlagStatus_DMA1_Channel4_Busy = RESET; //清除忙标志

            DMA_ClearITPendingBit(DMA1_IT_TC4);

        }

        DMA_ClearITPendingBit(DMA1_IT_GL4);

    }

}


关键字:DMA  串口  发送数据 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic502126.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32:DMA实例之串口(USART)通信
下一篇:串口DMA方式发送&接收

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

stm32之DMA数据传输
  从字面意思上看,DMA即为“直接内存读取”的意思,换句话说DMA就是用来传输数据的,它也属于一个外设。只是在传输数据时,无需占用CPU。  DMA请求  某个外设在通过DMA传输数据前,必须先给DMA控制器发送请求,控制器会返回一个应答信号给外设,外设应答后并且DMA控制器收到外设应答信号后,便会启动DMA传输。这个过程类似于TCP的“三次握手”。  DMA有DMA1和DMA2两个控制器,每个控制器都有不同的通道,每个通道对应不同的外设请求。如图12-1为DMA1的通道请求、图12-2为DMA2的通道请求。图12-1图12-2  如以上两图所示,DMA1有7个通道,DMA2有5个通道,每个通道都对应着不同的外设请求
发表于 2020-07-19
stm32之<font color='red'>DMA</font>数据传输
2440 DMA寄存器总结
2440 DMA寄存器:1.DISRCn(DMA initial source c):始端数据基地址。2.DISRCCn(DMA initial source control register):始端总线类型(系统总线AHB or 外围总线 APB)和地址类型(increment or fixed)。3.DIDSTn(DMA initial destination register):终端数据基地址。4.DIDSTCn(DMA initial destination control register):中断产生时刻,终端总线类型(系统总线AHB or 外围总线 APB)和地址类型(increment or fixed
发表于 2020-07-19
mini2440之ads下dma测试
在网上找到一个dma的ads工程,将其dma功能整到了原来的ads工程TQ2440_Test里面用下面的main.c换下原来TQ2440_Test的main.chttp://download.csdn.net/detail/songqqnew/3636198之所以要介绍DMA,因为它对性能太重要了!只有活用了DMA,CPU的性能才能上去!S3c2410有四个DMA,每个DMA支持工作方式基本相同,但支持的source Dest可能略有不同,具体见Datasheet。这里具体DMA CONTROL寄存器(DCON)的配置说明,进而引出DMA的各种工作方式。Atomic transfer:指的是DMA的单次原子操作,它可以是Unit
发表于 2020-07-19
STM32中DMA编程分析
在上篇博客简单介绍DMA后,我将在这里详细介绍下一个简单的DMA传输例子,即将FLASH中的数据传输到SRAM中,是一种MtoM(存储器传输到存储器)的方式。首先按老步骤DMA的点C和点H文件,然后在点C种定义一个32位常量数组SRC自动cu存放在FLASH中,然后定义一个对应的DST数组在SRAM中(一般变量都在SRAM中)。然后是初始化步骤,详细代码如下:具体实现功能就是设置为32位传输8个字节,用MtoM的模式并且是DMA1通道6,注意不要将L6看成16。然后我们需要去判断是否传输成功,我们再写一个比较函数并且把结果用LED去显示出来。具体图如下:详细结果我们可以看到最终STM32开发板上的绿灯点亮了,表示传输数据成功,图如下:
发表于 2020-07-19
STM32中<font color='red'>DMA</font>编程分析
STM32CubeMX HAL库串口+DMA数据发送不定长度数据接收
_HandleTypeDef hdma;volatile uint8_t rx_len = 0;             //接收一帧数据的长度volatile uint8_t recv_end_flag = 0;    //一帧数据接收完成标志uint8_t rx_buffer[100]={0};   //接收数据缓存
发表于 2020-07-18
STM32CubeMX HAL库串口+DMA<font color='red'>数据</font><font color='red'>发送</font>不定长度<font color='red'>数据</font>接收
STM32CubeMX—串口空闲中断+DMA接收
一、实验说明实验平台:STM32F103C8T6实验内容:使用串口一空闲中断结合DMA 完成不定长数据接收STM32的串口接收数据的方式1、轮询接收所谓轮询,就是在主函数中判断接收完成的标志位。举个不太恰当例子,就比如,此时你正在考试作弊,手机藏在兜里,你的队友再给你发答案,但是你的手机静音,所以你不得不写一会题看一会手机,有的时候答案已经发来了但是你此时在假装写,没有看,导致你没能及时看到答案浪费了时间(仅仅为了举例而已。。。。)。轮询接收数据也是这样。2、中断接收串口接收配置为中断模式,当有数据收到时,进入到串口接收中断中读取数据。继续上面的例子(你为了不浪费时间且及时抄到答案,你把手机开了震动,消息一来立马看,这是就比上
发表于 2020-07-18
STM32CubeMX—串口空闲中断+<font color='red'>DMA</font>接收
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved