精华内容
下载资源
问答
  • DMA

    2020-12-14 19:07:05
    DMA定义 DMA(Direct Memory Access,直接存储器存取),是一种完全由硬件执行数据交换的工作方式。它由DMA控制器而不是CPU来控制在存储器和存储器、存储器和外设之间的批量数据传输。STM32微控制器上集成了2个DMA...

    DMA定义

    DMA(Direct Memory Access,直接存储器存取),是一种完全由硬件执行数据交换的工作方式。它由DMA控制器而不是CPU来控制在存储器和存储器、存储器和外设之间的批量数据传输。STM32微控制器上集成了2个DMA控制器,DMA1有7个通道,DMA2有5个通道。
    在这里插入图片描述
    资料来自老师所发ppt,感谢!

    展开全文
  • 本文只要讲述了DMA的基本定义及工作过程
  • STM32 HAL库DMA定义printf函数

    千次阅读 2019-08-26 14:33:24
    DMA打印输出函数如下: #include "stdarg.h" uint8_t _dbg_TXBuff[150]; void uart1_printf(const char *format,...) { uint32_t length; va_list args; va_start(args, format); length = ...

    HAL库串口输出代码

    DMA打印输出函数如下:

    #include "stdarg.h"
    
    uint8_t _dbg_TXBuff[150];
    void uart1_printf(const char *format,...)
    {
    	uint32_t length;
    	va_list args;
    
    	va_start(args, format);
    	length = vsnprintf((char*)_dbg_TXBuff, sizeof(_dbg_TXBuff)+1, (char*)format, args);
    	va_end(args);
    	
    	HAL_UART_Transmit_DMA(&huart1,_dbg_TXBuff,length);
    }
    

    printf打印输出常规模式函数:

    #ifdef __GNUC__
      /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
         set to 'Yes') calls __io_putchar() */
      #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    #else
      #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    #endif /* __GNUC__ */
    /**
      * @brief  Retargets the C library printf function to the USART.
      * @param  None
      * @retval None
      */
    PUTCHAR_PROTOTYPE
    {
      /* Place your implementation of fputc here */
      /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
      HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
     
      return ch;
    }
    

    DMA方式输出的优势

    使用DMA方式输出最直接的好处就是可以大大提高CPU利用率,不会由于向外发送数据而对整个程序的运行周期产期变化。

    扫码关注公众号“TechChenSir”获取更多相关分享内容
    展开全文
  • DMA读写

    千次阅读 2014-03-04 11:14:02
    1 DMA定义 DMA是直接内存访问  Direct Memory Access(存储器直接访问)。这是指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据,既不通过CPU,也不需要CPU干预。整个数据传输操作在一个称为...
    一 DMA操作
    1 DMA定义
    DMA是直接内存访问 
    Direct Memory Access(存储器直接访问)。这是指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据,既不通过CPU,也不需要CPU干预。整个数据传输操作在一个称为"DMA控制器"的控制下进行的。CPU除了在数据传输开始和结束时做一点处理外,在传输过程中CPU可以进行其他的工作。这样,在大部分时间里,CPU和输入输出都处于并行操作。因此,使整个计算机系统的效率大大提高。 DMA的概念:DMA是在专门的硬件( DMA)控制下,实现高速外设和主存储器之间自动成批交换数据尽量减少CPU干预的输入/输出操作方式。通常有两种方式: 
    ◎独占总线方式 ◎周期挪用方式 。
    2 DMA组成
    DMA的组成: 
    ◎主存地址寄存器 
    ◎数据数量计数器 
    ◎DMA的控制/状态逻辑 
    ◎DMA请求触发器 
    ◎数据缓冲寄存器 
    ◎中断机构 
    3 DMA数据传输过程
    ◎传送前的预处理:由CPU完成以下步骤 
    向DMA卡送入设备识别信号,启动设备,测试设备运行状态,送入内存地址初值,传送数据个数, DMA的功能控制信号。 
    ◎数据传送:在DMA卡控制下自动完成 
    ◎传送结束处理 
    DMA 卡上应包括通用接口卡的全部组成部分,并多出如下内容: 
    主存地址寄存器,传送字数计数器,DMA控制逻辑,DMA请求,DMA响应,DMA工作方式,DMA优先级及排队逻辑等 一次完整的DMA传送过程: 
    DMA 预处理,CPU向DMA送命令,如DMA方式,主存地址,传送的字数等,之后CPU执行。
    展开全文
  • DMA发送重定义写在前面CubeMX配置bsp文件编写app文件编写 写在前面 本章主要分为三个部分:CubeMX配置、bsp驱动编写、应用层代码编写 详细的CubeMX配置,包含FreeRTOS任务的创建、信号量的创建、以及串口底层的创建...

    写在前面

    1. 本章主要分为三个部分:CubeMX配置、bsp驱动编写、应用层代码编写
    2. 详细的CubeMX配置,包含FreeRTOS任务的创建、信号量的创建、以及串口底层的创建
    3. 新建bsp文件夹及bsp_uart文件,在此文件中编写串口初始化及接口函数
    4. 新建app文件夹及app_log文件,在此文件夹编写任务函数。为后续教程做铺垫和当前教程测试
    5. stm32历史文章:https://blog.csdn.net/JiaLu0216/article/details/115471382

    CubeMX FreeRTOS配置

    1. 打开CubeMX新建工程后选择Middleware->FREERTOS选项
    2. 在Mode选择框中Interface种选择CMSIS_V2,这个选项主要选择CubeMX自定义接口,CMSIS_V2版本后面会方便很多
    3. 在Configuration对话框中选择Config parameters页,配置其中TICK_RATE_HZ为1000,这个参数配置任务调度的周期,默认为1000,可不修改
      在这里插入图片描述
    4. 在Configuration对话框中选择Task and Queues页,在Tasks任务框中点击添加按钮进行添加任务
      1、Task Name :任务名字
      2、Priority :任务优先级,可根据实际需求进行选择
      3、Stack Size(Words):任务的堆栈大小,根据任务实际使用进行配置
      4、Entry Function :入口函数,后期使用的任务函数,相当于裸机的main函数
      5、Code Generation Option :生成任务函数的方式,一般会选择As weak,选这个可以方便没有编写任务函数时,还有一个弱函数来运行。后期在任务文件夹重写后任务函数后,这个弱函数将会自动省略
      6、Parameter :函数入口参数,一般不使用
      7、Allocation :是否采用外部内存分配堆栈,一般采用系统内部总堆进行分配
      在这里插入图片描述
    5. 在Configuration对话框中选择Timers and Semaphores页,在Binary Semaphores任务框中点击添加按钮进行添加任务
      1、Semaphore Name :信号量名字
      2、Allocation :是否采用外部内存分配堆栈,一般采用系统内部总堆进行分配
      在这里插入图片描述

    CubeMX USART配置

    1. 根据自己板子选择对应串口,本例程采用串口2,选择Connectivityt->USART2选项
    2. 选择模式为异步模式,在Mode选择框中选择MODE :Asynchronous
    3. 在Configuration选择框中选择GPIO Settings页,检测配置的外部GPIO口是否正确,否则在右侧芯片图进行重新选择引脚
      在这里插入图片描述
    4. 在Configuration选择框中选择Parameter Settings页,在Basic Parameters下拉框中进行配置参数
      1、Baud Rate :设置串口波特率
      2、Word Length :设置数据位(如果有奇偶校验位时,此选项必须包含奇偶校验位,等于说在数据位+1)
      3、Parity :选择奇偶检验位
      4、Stop Bits :选择停止位
      在这里插入图片描述
    5. DMA配置,在Configuration选择框中选择DMA Settings页,选择添加按钮,上方会添加一个对话框,在对话框中选择USART2_TX
    6. DMA模式选择正常模式Mode :Normal,地址子增选择内存Increment Address :Memory
    7. 传输数据大小选择字节,Data Width :Byte
      在这里插入图片描述
    8. 中断配置,在Configuration选择框中选择NVIC Settings页,中断接面选择DMA中断,串口中断打开
      在这里插入图片描述

    CubeMX 内部计数器时钟源配置

    在这里插入图片描述

    bsp文件编写

    1. bsp_uart.h代码
    #ifndef __BSP_UART_H
    #define __BSP_UART_H
    
    #include "main.h"
    
    
    #define UART2_RX_MAX_LEN 400
    #define UART2_TX_MAX_LEN 400
    
    typedef struct 
    {
    
        uint8_t *tx_data;
    }UartHead;
    
    
    typedef struct 
    {
        UartHead uart2_head;
    }BspUartStr;
    
    uint8_t BspUartInit(void);
    void BspUartDeInit(void);
    uint8_t BspUart2Init(void);
    void BspUart2DeInit(void);
    void printf2(char* fmt,...);
    #endif
    
    1. bsp_uart.c代码
    #include "bsp_uart.h"
    #include "FreeRTOS.h"
    #include "task.h"
    #include "cmsis_os.h"
    #include "stdarg.h"	 	 
    #include "stdio.h"	 	 
    #include "string.h"
    #include "usart.h"
    #include "semphr.h"
    #include <stdarg.h>
    
    extern UART_HandleTypeDef huart2;
    extern osSemaphoreId_t uart2TxIdleBinarySemHandle;
    
    BspUartStr* bsp_uart_str = NULL;
    
    /**
     * @name: 
     * @description: 串口初始化,其中包含内存申请
     * @msg: 
     * @param {*}
     * @return {*} 0: 初始成功  bit 0 : 1结构体内存申请失败
     *                          bit 1 : 1发送数据缓存内存申请失败
     */
    uint8_t BspUartInit(void)
    {
        if(bsp_uart_str != NULL)
            BspUartDeInit();
        bsp_uart_str = pvPortMalloc(sizeof(BspUartStr));
        if(bsp_uart_str == NULL)
            return 1;
        bsp_uart_str->uart2_head.tx_data = NULL;
    
        
    	return BspUart2Init();
    }
    /**
     * @name: 
     * @description: 串口反初始化,内存释放
     * @msg: 
     * @param {*}
     * @return {*}
     */
    void BspUartDeInit(void)
    {
        if(bsp_uart_str == NULL)
            return;
        BspUart2DeInit();
        vPortFree(bsp_uart_str);
        bsp_uart_str = NULL;
    }
    
    /**
     * @name: 
     * @description: 串口2初始化,其中包含内存申请
     * @msg: 
     * @param {*}
     * @return {*} 0: 初始成功  bit 0 : 1结构体内存申请失败
     *                          bit 1 : 1发送数据缓存内存申请失败
     */
    uint8_t BspUart2Init(void)
    {
        if(bsp_uart_str == NULL)
            return 1;
        UartHead* uart2_head_str;
        uart2_head_str = &bsp_uart_str->uart2_head;
        if(uart2_head_str->tx_data != NULL)
            BspUart2DeInit();
        uart2_head_str->tx_data = pvPortMalloc(UART2_TX_MAX_LEN);
        if(uart2_head_str->tx_data == NULL)
            return 2;
        
        MX_USART2_UART_Init();  //初始化串口
        xSemaphoreGive(uart2TxIdleBinarySemHandle);	//释放信号量
    	return 0;
    }
    /**
     * @name: 
     * @description: 串口2反初始化,内存释放
     * @msg: 
     * @param {*}
     * @return {*}
     */
    void BspUart2DeInit(void)
    {
         if(bsp_uart_str == NULL)
            return;
        if(bsp_uart_str->uart2_head.tx_data != NULL)
        {
            vPortFree(bsp_uart_str->uart2_head.tx_data);
            bsp_uart_str->uart2_head.tx_data = NULL;
        }
    }
    
    /**
     * @name: 
     * @description: 串口打印函数重定义
     * @msg: 
     * @param {*}
     * @return {*}
     */
    void printf2(char* fmt,...)
    {
        uint16_t i;
        va_list ap;
        if(xSemaphoreTake(uart2TxIdleBinarySemHandle,1000) == pdTRUE)
        { 
            va_start(ap,fmt);
             if((bsp_uart_str == NULL)||(bsp_uart_str->uart2_head.tx_data == NULL))
    		 {
    			 xSemaphoreGive(uart2TxIdleBinarySemHandle);	//释放信号量
    			 return ;
    		 }
            UartHead* uart_head_str;
            uart_head_str = &bsp_uart_str->uart2_head;
            
            i=vsnprintf((char*)uart_head_str->tx_data,UART2_TX_MAX_LEN,fmt,ap);
            va_end(ap);
            if(i == 0)
    		{
    			xSemaphoreGive(uart2TxIdleBinarySemHandle);	//释放信号量
    			return;
    		}
            HAL_UART_Transmit_DMA(&huart2,uart_head_str->tx_data,i);
        }
    }
    /**
     * @name: 
     * @description: 串口发送完成回调函数
     * @msg: 
     * @param {*}
     * @return {*}
     */
    //TX回调函数
    void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
    {
    	if(huart->Instance == USART2)
    	{
    		BaseType_t  pxHigherPriorityTaskWoken;
    		xSemaphoreGiveFromISR(uart2TxIdleBinarySemHandle,&pxHigherPriorityTaskWoken);	//释放信号量
    		//如果需要的话进行一次任务切换
    		portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
    	}
    
    	
    }
    
    

    app文件编写

    1. app_log.h代码
    #ifndef __APP_LOG_H
    #define __APP_LOG_H
    
    #include "main.h"
    
    #define PRINTF_TASK_LOG 1
    
    
    #define APP_LOG_DEBUG(...)  printf2(__VA_ARGS__)
    
    #endif
    
    1. app_log.c代码
    #include "app_log.h"
    #include "bsp_led.h"
    #include "FreeRTOS.h"
    #include "task.h"
    #include "cmsis_os.h"
    #include "bsp_uart.h"
    #include "tim.h"
    #include "string.h"
    
    
    void StartLogTask(void *argument)
    {
        uint16_t cnt_ms = 0;
        uint32_t test_cnt = 0;
        BspUartInit();
        TickType_t last_time = xTaskGetTickCount();
        for(;;)
        {
            vTaskDelayUntil(&last_time,10);
            cnt_ms++;
            if(cnt_ms >99)
                cnt_ms = 0;
          
    		#if PRINTF_TASK_LOG
    			if(cnt_ms == 0)
    			{
    				APP_LOG_DEBUG("当前未分配堆大小: %dByte\r\n",xPortGetFreeHeapSize());
    				APP_LOG_DEBUG("未分配内存堆历史最小值 :%dByte\r\n\n",xPortGetMinimumEverFreeHeapSize());
    			}
    		#endif
        }
    }
    
    展开全文
  • diag_task功能:等待信号量,收到信号量后,判断循环队列是否为空,不为空的话读取循环队列的数据到DMA_buf中(初始化DMA传入的,因为DMA发送的时候地址递增或者递减)。使能DMA发送 4. DMA中断函数:判断发送中断...
  • 下面的在:stm32f10x_rcc.h中 #define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001) #define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002) 下面的在:stm32f10x.h中 #define DMA1_BASE 
  • UART接口定义DMA模式接收数据

    千次阅读 2012-05-03 09:18:42
    问题是这样:我把BF533的UART接口定义DMA模式接收数据,但是接收到的数据总是零. 我不知道是不是我的配置有问题.   请高手指点一下.多谢. 配置如下: void Init_DMA(void) {  *pDMA6_PERIPHERAL_MAP = 0x...
  • DMA库函数

    千次阅读 2018-08-07 15:58:29
    1.void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx) ...注释:RCC_ResetCmd中对DMA定义,因此采用的直接操纵DMA寄存器的方式 例如:DMA_DeInit(DMA1_Channel1);   2.void DMA_Init(DMA_Channel_TypeDef* ...
  • DMA的基本定义 DMA,全称Direct Memory Access,即直接存储器访问。 DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。当CPU初始化这个传输动作,...
  • DMA定义:直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。 翻译过来就是,如果两个设备想要进行...
  • DMA传送方式

    2020-11-13 02:27:44
    与外部DMA请求/应答协议不同的是,DMA传送方式定义了每次传送读/写的单元数,如表所示。  表 DMA传送方式  (1)单元传送方式  单元传送方式意味着每个DMA请求对应一对DMA读/写周期,即1个单元读,然后1...
  • 【STM32】 DMA原理,步骤超细详解,一文看懂DMA

    万次阅读 多人点赞 2020-03-19 21:50:24
    什么是DMA (DMA的基本定义) DMA,全称Direct Memory Access,即直接存储器访问。 DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。 我们知道CPU有...
  • DMA2D可以加快图像填充,并且支持像素格式转换。 /************************************************************************************************************* * 文件名 : dma2d.c * 功能 : STM32F7 ...
  • 基于UCOSII的DMA-SPI通信

    千次阅读 2017-09-06 15:56:26
    代码有点小bug,比如主机的dma定义长度为8位,发送8为数据为:0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08,从机第一次接收数据格式:0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08。第二次接收数据:0x01 0x01 0x02 0x03 ...
  • DMA原理

    2014-04-09 14:12:46
    下面是S3C2440A数据手册上的一段截图,展示了4个DMA通道和每个通道对应的DMA源: ... 对这些DMA通道和其对应...在文件dma.c中定义了一个结构体数组static struct s3c24xx_dma_map __initdata s3c2440_dma_mapp
  • STM32 DMA

    2021-02-03 14:37:21
    DMADMA介绍DMA的使用1.DMA进行串口数据的搬运 DMA介绍 DMA直接存储器存取 储存器可以是SRAM或者FLASH 一共有两个DMA DMA1和DMA2 DMA2只存在于大容量的单片机中 ...设置宏定义 #define DMA_CHANNEL4 DMA1_C
  • DMA理解

    千次阅读 2016-11-01 14:16:44
    单片机的DMA使用心得 本人也是最近才深入了解一下DMA,前期使用单片机的时候基本上没有用到。一是不需要用到,二是心理上觉得DMA比较...1. 从哪里搬运到哪里 一般是特殊寄存器到RAM(我们自己定义的数组里面),或
  • STM32的DMA

    2021-01-07 22:33:38
    1. DMA不占用CPU, 2. DMA的控制主要在CCR1寄存器中,可设置传输模式,方向,数据大小,地址自增,内存到内存,以及使能等 3. DMA传输数量寄存器CNDTR可以显示剩余传输数量 ... 必须将要传输的BUF定义
  • DMA控制方式

    千次阅读 2019-05-01 16:11:40
    定义DMA是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。这样数据的传送速度就取决于存储器和外设的工作速度。 通常系统总线是由CPU管理的,在DMA方式时,就希望CPU把这些总线让出来,即CPU连到这些...
  • 如需转载请注明地址:https://blog.csdn.net/as480133937/article/details/104927922 DMA的基本介绍 什么是DMA (DMA的基本定义) DMA,全称Direct Memory Access,即直接存储器访问。 DM...
  • DMA寄存器设置

    千次阅读 2014-12-22 15:47:22
    1.设置DMA模式:  寄存器名:DMAMODE0  寄存器类型:DMA配置寄存器 ... 寄存器值:DMAMODE0[1:0]=11:定义DMA总线宽度为32位;  DMAMODE0[9]=0:设置DMA传输模式为BLOCK模式;  DMAMODE0[6]
  • DMA分区管理

    2019-09-02 14:44:23
    在报告中,DMA定义为供配水系统中一个被切割分离的独立区域,通常采取关闭阀门或安装流量计,形成虚拟或实际独立区域。通过对进入或流出这一区域的水量进行计量,并对流量分析来定量泄漏水平,从而利于检漏人员更...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 596
精华内容 238
关键字:

dma定义