Nuru_Banmian
Nuru_Banmian
Published on 2025-07-17 / 49 Visits
0
0

DMA-RAM到外设(串口)-寄存器&HAL库实现

需求描述

使用寄存器实现把RAM中的数据直接传输到usart1的Tx引脚,然后数据被发送到电脑端。

DMA-RAM到外设-需求描述-1

DMA-RAM到外设-需求描述-2

串口1使能DMA传输

代码

/* 10. 串口1使能 DMA传输 */
USART1->CR3 |= USART_CR3_DMAT;
USART1->CR3 |= USART_CR3_DMAR;

DMA-RAM到外设-串口1使能DMA传输-1

DMA-RAM到外设-串口1使能DMA传输-2

寄存器实现

dma.h

#ifndef __DMA_H
#define __DMA_H

#include "stm32f10x.h"

extern uint8_t isFinished;

// 初始化
void DMA1_Init(void);

// 数据传输
void DMA1_Transmit(uint32_t srcAddr, uint32_t destAddr, uint16_t dataLen);

#endif

dma.c

#include "dma.h"

// 初始化
void DMA1_Init(void)
{
    // 1. 开启时钟
    RCC->AHBENR |= RCC_AHBENR_DMA1EN;

    // 2. DMA相关配置
    // 2.1 数据传输方向: 从存储器读,发往串口外设
    DMA1_Channel4->CCR |= DMA_CCR4_DIR;

    // 2.2 数据宽度: 8位 - 00
    DMA1_Channel4->CCR &= ~DMA_CCR4_PSIZE;
    DMA1_Channel4->CCR &= ~DMA_CCR4_MSIZE;

    // 2.3 地址自增:开启自增,串口地址不能自增
    DMA1_Channel4->CCR &= ~DMA_CCR4_PINC;
    DMA1_Channel4->CCR |= DMA_CCR4_MINC;

    // 2.4 开启数据传输完成中断标志
    DMA1_Channel4->CCR |= DMA_CCR4_TCIE;

    // 2.5 使能串口的DMA传输功能
    USART1->CR3 |= USART_CR3_DMAT;

    // 2.6 开启循环传输功能
    DMA1_Channel4->CCR |= DMA_CCR4_CIRC;

    // 3. NVIC配置
    NVIC_SetPriorityGrouping(3);
    NVIC_SetPriority(DMA1_Channel4_IRQn, 2);
    NVIC_EnableIRQ(DMA1_Channel4_IRQn);

}

// 数据传输
void DMA1_Transmit(uint32_t srcAddr, uint32_t destAddr, uint16_t dataLen)
{
    // 1. 设置外设地址
    DMA1_Channel4->CPAR = destAddr;

    // 2. 设置存储器地址
    DMA1_Channel4->CMAR = srcAddr;

    // 3. 设置传输的数据量
    DMA1_Channel4->CNDTR = dataLen;

    // 4. 开启通道,开始传输数据
    DMA1_Channel4->CCR |= DMA_CCR4_EN;
}

// 中断服务程序
void DMA1_Channel4_IRQHandler(void)
{
    // 判断中断标志位
    if (DMA1->ISR & DMA_ISR_TCIF4)
    {
        // 清除中断标志位
        DMA1->IFCR |= DMA_IFCR_CTCIF4;

        // 关闭DMA通道
        // DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
    }
    
}

main.c

#include "usart.h"
#include "dma.h"
#include "delay.h"

// 定义变量数组,放置在RAM中,用来存储接收到的数据
uint8_t src[4] = {'a','b','c','d'};

int main(void)
{
	// 初始化
	USART_Init();
	DMA1_Init();

	printf("Hello, world!\n\n");
	Delay_ms(1);

	// 开启DMA通道进行传输
	DMA1_Transmit((uint32_t)src, (uint32_t)&(USART1->DR), 4);

	while(1)
	{}
}

HAL库实现

HAL库配置

DMA-RAM到外设-HAL库配置

增加的代码

uint8_t src[] = {'a', 'b', 'c', 'd', 'e'};

int main(void)
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_USART1_UART_Init();
   
    HAL_UART_Transmit_DMA(&huart1, src, 5);
    while (1)
    {
    }
}


Comment