DMA存储器到外设代码讲解
阅读原文时间:2023年07月11日阅读:5

实验目的:

bsp_dma_mtp.h

#ifndef __BSP_DMA_MTP_H
#define __BSP_DMA_MTP_H

#include "stm32f10x.h"
#include

// 串口工作参数宏定义
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200

// USART GPIO 引脚宏定义
#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd

#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10

#define USART_TX_DMA_CLK RCC_AHBPeriph_DMA1
#define USART_TX_DMA_CHANNEL DMA1_Channel4
#define USART_TX_DMA_FLAG_TC DMA1_FLAG_TC4
#define USART_DR_ADDRESS (USART1_BASE+0x04)

#define SENDBUFF_SIZE 5000

void USARTx_DMA_Config(void);
void USART_Config(void);
#endif /* __BSP_DMA_MTP_H */

bsp_dma_mtp.c

#include "bsp_dma_mtp.h"

uint8_t SendBuff[SENDBUFF_SIZE];

/**
* @brief USART GPIO 配置,工作参数配置
* @param
* @retval
*/
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;

// 打开串口GPIO的时钟  
DEBUG\_USART\_GPIO\_APBxClkCmd(DEBUG\_USART\_GPIO\_CLK, ENABLE);

// 打开串口外设的时钟  
DEBUG\_USART\_APBxClkCmd(DEBUG\_USART\_CLK, ENABLE);

// 将USART Tx的GPIO配置为推挽复用模式  
GPIO\_InitStructure.GPIO\_Pin = DEBUG\_USART\_TX\_GPIO\_PIN;  
GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_AF\_PP;  
GPIO\_InitStructure.GPIO\_Speed = GPIO\_Speed\_50MHz;  
GPIO\_Init(DEBUG\_USART\_TX\_GPIO\_PORT, &GPIO\_InitStructure);

    // 将USART Rx的GPIO配置为浮空输入模式  
GPIO\_InitStructure.GPIO\_Pin = DEBUG\_USART\_RX\_GPIO\_PIN;  
GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_IN\_FLOATING;  
GPIO\_Init(DEBUG\_USART\_RX\_GPIO\_PORT, &GPIO\_InitStructure);

// 配置串口的工作参数  
// 配置波特率  
USART\_InitStructure.USART\_BaudRate = DEBUG\_USART\_BAUDRATE;  
// 配置 针数据字长  
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(DEBUG\_USARTx, &USART\_InitStructure);

// 使能串口  
USART\_Cmd(DEBUG\_USARTx, ENABLE);  

}

///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口 */
USART_SendData(DEBUG_USARTx, (uint8_t) ch);

    /\* 等待发送完毕 \*/  
    while (USART\_GetFlagStatus(DEBUG\_USARTx, USART\_FLAG\_TXE) == RESET);

    return (ch);  

}

// Memory -> P (USART->DR)
void USARTx_DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStruct;

RCC\_AHBPeriphClockCmd(USART\_TX\_DMA\_CLK, ENABLE);

DMA\_InitStruct.DMA\_PeripheralBaseAddr = (uint32\_t)USART\_DR\_ADDRESS;  
DMA\_InitStruct.DMA\_MemoryBaseAddr = (uint32\_t)SendBuff;  
DMA\_InitStruct.DMA\_DIR = DMA\_DIR\_PeripheralDST;

DMA\_InitStruct.DMA\_BufferSize = SENDBUFF\_SIZE;

DMA\_InitStruct.DMA\_PeripheralInc = DMA\_PeripheralInc\_Disable;  
DMA\_InitStruct.DMA\_PeripheralDataSize = DMA\_PeripheralDataSize\_Byte;  
DMA\_InitStruct.DMA\_MemoryInc = DMA\_MemoryInc\_Enable;  
DMA\_InitStruct.DMA\_MemoryDataSize = DMA\_PeripheralDataSize\_Byte;

DMA\_InitStruct.DMA\_Mode = DMA\_Mode\_Normal;  
DMA\_InitStruct.DMA\_Priority = DMA\_Priority\_High;  
DMA\_InitStruct.DMA\_M2M = DMA\_M2M\_Disable;

DMA\_Init(USART\_TX\_DMA\_CHANNEL, &DMA\_InitStruct);

DMA\_ClearFlag(USART\_TX\_DMA\_FLAG\_TC);  
DMA\_Cmd(USART\_TX\_DMA\_CHANNEL, ENABLE);  

}

main.c

#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_dma_mtp.h"

extern uint8_t SendBuff[SENDBUFF_SIZE];

#define SOFT_DELAY Delay(0x0FFFFF);

void Delay(__IO u32 nCount);

/**
* @brief 主函数
* @param
* @retval
*/
int main(void)
{
uint16_t i=0;
/* LED 端口初始化 */
LED_GPIO_Config();

USART\_Config();

for(i=0; i<SENDBUFF\_SIZE; i++)  
{  
    SendBuff\[i\] = 'P';  
}

    USARTx\_DMA\_Config();

USART\_DMACmd(DEBUG\_USARTx, USART\_DMAReq\_Tx, ENABLE);

while (1)  
{  
     LED1\_TOGGLE  
     Delay(0xFFFFF);  
}  

}

void Delay(__IO uint32_t nCount) //简单的延时函数
{
for(; nCount != 0; nCount--);
}