STM32之DMA(二)

1.将FALSH中的数据传输到SRAM中(存储器到存储器)

用const关键字定义的数据存放到FLASH,而其他普通变量存放到SRAM中。

DMA头文件:

#ifndef _DMA_H
#define _DMA_H
#include "stm32f10x.h"
//DMA宏定义
#define DMA_CLK   RCC_AHBPeriph_DMA1
#define DMA       DMA1
#define    DMA_CHANNEL  DMA1_Channel1
//导出接收数组
extern uint8_t receiveData[];
void DMA_Config(void);
#endif

DMA c文件:

#include "dma.h"
const uint8_t sendData[10]={1,2,3,4,5,6,7,8,9,10};
uint8_t receiveData[10];

void DMA_Config(void)
{
    DMA_InitTypeDef DMA_InitStruct;
    //开启时钟
    RCC_AHBPeriphClockCmd(DMA_CLK,ENABLE);
    
    DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)sendData;//外设基地址 这里为发送数组首地址
    DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)receiveData;//存储器基地址 这里为接收数据首地址
    DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralSRC;//传输方向 这里为外设到存储器
    DMA_InitStruct.DMA_BufferSize=10;//传输数量
    DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Enable;//外设地址是否自增
    DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;//存储器地址是否自增
    DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//外设传输数据基本单元
    DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//存储器传输数据基本单位
    DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;//模式 普通模式(一次性)
    DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;//优先级
    DMA_InitStruct.DMA_M2M=DMA_M2M_Enable;//是否存储器到存储器
    DMA_Init(DMA_CHANNEL,&DMA_InitStruct);//初始化
    DMA_Cmd(DMA_CHANNEL,ENABLE);//使能 
}

main 函数:

#include "stm32f10x.h"
#include "usart.h"
#include "dma.h"

int main()
{
    USART_Config();
    DMA_Config();
    for(uint8_t i=0;i<10;i++)
    {
        printf("%d\t",receiveData[i]);
    }
    while(1);
}

实验效果:

 2.将SRAM中的数据传输到USART1的数据寄存器中(存储器到外设)

 DMA头文件:

#ifndef _DMA_H
#define _DMA_H
#include "stm32f10x.h"
//DMA宏定义
#define DMA_CLK   RCC_AHBPeriph_DMA1
#define DMA       DMA1
#define    DMA_CHANNEL  DMA1_Channel4   //USART TX引脚对应 DMA1通道4

void DMA_Config(void);
#endif

USART1的TX请求对应DMA1通道4

DMA c文件:

#include "dma.h"
uint8_t sendData[]="Hello World!";
void DMA_Config(void)
{
    DMA_InitTypeDef DMA_InitStruct;
    //开启时钟
    RCC_AHBPeriphClockCmd(DMA_CLK,ENABLE);
    
    DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)&USART1->DR;//外设基地址 这里USART1的数据寄存器地址
    DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)sendData;//存储器基地址 这里为接收数据首地址
    DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST;//传输方向 这里为存储器到外设
    DMA_InitStruct.DMA_BufferSize=sizeof(sendData)/sizeof(uint8_t);//传输数量 发送数据的大小
    DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址是否自增
    DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;//存储器地址是否自增
    DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//外设传输数据基本单元
    DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//存储器传输数据基本单位
    DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;//模式 普通模式(一次性)
    DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;//优先级
    DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;//是否存储器到存储器 由于是从存储器到外设 所以这里失能
    
    DMA_Init(DMA_CHANNEL,&DMA_InitStruct);//初始化
    DMA_Cmd(DMA_CHANNEL,ENABLE);//使能 
    
    USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);//USAER使能DMA发送请求
}

注意:在最后要有 USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);因为前面的配置只是把SRAM中的数据传输到了USART1的数据寄存器中,还没有发送出去

实验效果:

当把传输模式改成循环发送模式时  DMA_InitStruct.DMA_Mode=DMA_Mode_Circular;

实验效果:

由于单片机没有间隔的发送数据,所以将导致下次烧写程序烧不进去。

在我开发板上(PZ6806L)解决方法:将BOOT0引脚接3.3v,烧写完成再接地。

猜你喜欢

转载自www.cnblogs.com/nwjlq/p/12939753.html