asp做網(wǎng)站搜索免費seo教程分享
在配置前要記得先定義一下DMA轉(zhuǎn)運的源端數(shù)組和目標數(shù)組兩個數(shù)組哦。
接下來我們就開始準備配置吧
配置
初始化
1.RCC開啟時鐘(開啟DMA的時鐘)
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
作用:開啟時鐘
2.初始化DAM參數(shù)(包括外設(shè)和存儲器站點的起始地址、數(shù)據(jù)寬度、地址是否自增、方向、傳輸計數(shù)器、是否要自動重裝、選擇觸發(fā)源、通道優(yōu)先級等)
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
作用:初始化DMA。
注意:如果選擇硬件觸發(fā),還需要調(diào)用×××_DMACmd,開啟觸發(fā)信號的輸出。
如果需要DMA的中斷,需要調(diào)用DMA_ITConfig,開啟中斷輸出,再在NVIC里配置相應(yīng)的中斷通道,然后寫中斷函數(shù)就行了
3.打開DMA
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState)
作用:設(shè)置DMA是使能/失能
注意:在運行的過程中,如果轉(zhuǎn)運完成,傳輸寄存器就會清0.這時,如果還想給傳輸寄存器賦值的話,就關(guān)閉DMA(失能)——寫傳輸寄存器——開啟DMA(使能)
那我們接下來寫一下這個函數(shù)
DMA傳輸函數(shù)
1.將DMA失能
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState)
2.給傳輸寄存器賦值
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber);?
作用:設(shè)置當前數(shù)據(jù)寄存器(給傳輸寄存器寫數(shù)據(jù))
3.給DMA使能
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState)
4.獲取標志位觀察是否轉(zhuǎn)運完成
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
作用:獲取標志位狀態(tài)
5.清除標志位
void DMA_ClearFlag(uint32_t DMAy_FLAG);
?
代碼
MyDMA.c
#include "stm32f10x.h" // Device headeruint16_t MyDMA_Size;void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{MyDMA_Size = Size;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = Size;DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;DMA_Init(DMA1_Channel1, &DMA_InitStructure);DMA_Cmd(DMA1_Channel1, DISABLE);
}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);DMA_ClearFlag(DMA1_FLAG_TC1);
}
MyDMA.h
#ifndef __MYDMA_H
#define __MYDMA_Hvoid MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size);
void MyDMA_Transfer(void);#endif
例題
DMA轉(zhuǎn)運數(shù)據(jù)
接線
代碼?
#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);}
}
?其他重要庫函數(shù)
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);
作用:獲取當前數(shù)據(jù)寄存器(返回當前傳輸寄存器的值)
?ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
作用:獲取中斷狀態(tài)
void DMA_ClearITPendingBit(uint32_t DMAy_IT);
作用:清除中斷掛起位
有什么問題在評論區(qū)說哦!