SMT32:DMA代码部分(内含:1.接线图/实物图+2.代码部分+3.补充的DMA数据传输部分库函数)

发布于:2022-11-28 ⋅ 阅读:(283) ⋅ 点赞:(0)

1.接线图/实物图如下:

 

2.代码部分如下:

主函数(main.c)代码部分:

 

 

 

#include "stm32f10x.h" // Device header

#include "Delay.h"

#include "OLED.h"

#include "MyDMA.h"

uint8_t DataA[] = {0x01, 0x02, 0x03, 0x04};

uint8_t DataB[] = {0, 0, 0, 0};

int main(void)

{

OLED_Init();

MyDMA_Init((uint32_t)DataA, (uint32_t)DataB, 4);

OLED_ShowString(1, 1, "DataA");

OLED_ShowString(3, 1, "DataB");

OLED_ShowHexNum(1, 8, (uint32_t)DataA, 8);

OLED_ShowHexNum(3, 8, (uint32_t)DataB, 8);

while (1)

{

DataA[0] ++;

DataA[1] ++;

DataA[2] ++;

DataA[3] ++;

OLED_ShowHexNum(2, 1, DataA[0], 2);

OLED_ShowHexNum(2, 4, DataA[1], 2);

OLED_ShowHexNum(2, 7, DataA[2], 2);

OLED_ShowHexNum(2, 10, DataA[3], 2);

OLED_ShowHexNum(4, 1, DataB[0], 2);

OLED_ShowHexNum(4, 4, DataB[1], 2);

OLED_ShowHexNum(4, 7, DataB[2], 2);

OLED_ShowHexNum(4, 10, DataB[3], 2);

Delay_ms(1000);

MyDMA_Transfer();

OLED_ShowHexNum(2, 1, DataA[0], 2);

OLED_ShowHexNum(2, 4, DataA[1], 2);

OLED_ShowHexNum(2, 7, DataA[2], 2);

OLED_ShowHexNum(2, 10, DataA[3], 2);

OLED_ShowHexNum(4, 1, DataB[0], 2);

OLED_ShowHexNum(4, 4, DataB[1], 2);

OLED_ShowHexNum(4, 7, DataB[2], 2);

OLED_ShowHexNum(4, 10, DataB[3], 2);

Delay_ms(1000);

}

}

//补充:

//在寄存器里,OLED_ShowHexNum(2, 1, (uint32_t)&ADC1->DR,8);//&ADC1->DR,取结构体指针成员的地址。

//&ADC1->HexNum表示ADC结构指针指向ADC1外设的起始地址,访问结构体成员,就相当于加一个地址偏移.起始地址+偏移=寄存器

//我们可以自己定义:

//#define ADC_DR (uint32_t*)0x4001244C

//*ADC1_DR

直接存储器(DMA.c)代码部分:

 

 

MyDMA_Size=Size;

//1.RCC开启DMA时钟

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

//2.初始化DMA_Init结构体

DMA_InitTypeDef DMA_InitStructure;

DMA_InitStructure.DMA_MemoryBaseAddr=AddrB;//存储器站点的起始地址(32位),参数代替固定的地址。

DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//存储器站点的数据宽度(字节形式)

DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//存储器站点的是否自增

DMA_InitStructure.DMA_PeripheralBaseAddr=AddrA;//外设站点的起始地址

DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//外设站点的数据宽度

DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Enable;//外设站点的是否自增

DMA_InitStructure.DMA_BufferSize=Size;//缓冲区大小,(传输计数器,指定传输几次)

DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//数据传输方向(DST:存储器-->外设站点,SRC:外设站点-->存储器)

DMA_InitStructure.DMA_M2M=DMA_M2M_Enable;//选择硬件触发还是软件触发(M2M_Enable存储器到存储器就是软件触发,Disable是硬件触发)

DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//传输模式(指定是否自动重装)DMA_Mode_Normal:正常模式,转运之后停止

DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;//优先级(多个通道需要设置优先级,此处无所谓)

DMA_Init(DMA1_Channel1,&DMA_InitStructure);//把结构体配置的参数给DMA1里的通道1.

//第一个参数:既选择了是哪个DMA,又选择了是哪个通道。

//3.开关控制DMA_Cmd

DMA_Cmd(DMA1_Channel1,DISABLE);

}//转运一次,传输寄存器自减一次。传输寄存器为0时,转运结束。

//调用该函数,就在进行一次转运(给传输计数器重新赋值)

void MyDMA_Transfer(void)

{

DMA_Cmd(DMA1_Channel1,DISABLE);//关闭

DMA_SetCurrDataCounter(DMA1_Channel1,MyDMA_Size);//给传输计数器赋值

DMA_Cmd(DMA1_Channel1,ENABLE);//开启

while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);//检查DMA1的通道1转运完成标志位,转运完成,标志位置1

DMA_ClearFlag(DMA1_FLAG_TC1);//清除标志位状态

}

直接存储器(DMA.h)代码部分:

 

#ifndef __MyDMA_H

#define __MyDMA_H

void MyDMA_Init(uint32_t AddrA,uint32_t AddrB,uint16_t Size);

#endif

3.//补充的DMA(数据传输部分)库函数:

//void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);//中断输出使能

//void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); //给传输计数器赋值

//uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);//获取数据寄存器的数据

//FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);//获取标志位状态函数

//void DMA_ClearFlag(uint32_t DMAy_FLAG);清除标志位状态

//ITStatus DMA_GetITStatus(uint32_t DMAy_IT);//获取中断状态

//void DMA_ClearITPendingBit(uint32_t DMAy_IT);//清除中断状态

 


网站公告

今日签到

点亮在社区的每一天
去签到