
一、ROM和RAM通过DMA进行通信(reg)
ROM可以给RAM传输数据,RAM不可以给ROM传输数据。一般数据较多的时候可以使用DMA进行高速传输,数据较少的时候可以使用CPU,因此处要学习DMA,所以代码均和DMA相关。
1、函数分析
//初始化函数
void Dri_DMA_Init(void);
//直接存储访问 - 传输
void Dri_DMA_Transmit(uint32_t rom_address, uint32_t ram_address, uint32_t length);
2、具体函数分析:此次函数进行了优化,防止数据尚未传输完就开始了读数据操作。
uint8_t dma_tranmit_complete_flg = 0; 用来进行判断
/**
* 直接存储访问 - 初始化
*/
void Dri_DMA_Init(void) {
// 1. 开启时钟
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
// 2. 配置引脚
// 3. 配置外设(DMA:寄存器)
// 3.1 开启存储器到存储器的数据传输模式
DMA1_Channel1->CCR |= DMA_CCR1_MEM2MEM;
// 3.2 数据传输的位宽
// 将ROM当成外设(P),将RAM当成存储(M)
DMA1_Channel1->CCR &= ~DMA_CCR1_MSIZE;
DMA1_Channel1->CCR &= ~DMA_CCR1_PSIZE;
// 3.3 数据传输方向 : P -> M
DMA1_Channel1->CCR &= ~DMA_CCR1_DIR;
// !数据传输时地址需要增量操作
DMA1_Channel1->CCR |= DMA_CCR1_MINC;
DMA1_Channel1->CCR |= DMA_CCR1_PINC;
// 3.4 开启传输完成中断
DMA1_Channel1->CCR |= DMA_CCR1_TCIE;
NVIC_SetPriorityGrouping(3);
NVIC_SetPriority(DMA1_Channel1_IRQn, 3);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
/**
* 中断处理函数 数据量小适合每次关通道,数据量大不适合关
*/
void DMA1_Channel1_IRQHandler(void) {
if ( (DMA1->ISR & DMA_ISR_TCIF1) != 0 ) {
// 标志位复位
DMA1->IFCR |= DMA_IFCR_CTCIF1;
dma_tranmit_complete_flg = 1;
// 关闭传输通道
DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
}
}
/**
* 直接存储访问 - 传输
* DMA中存储到存储的功能是后加,最开始是没有,只有外设到存储
* 再存储到存储场合下,可以将任何一个存储作为外设使用
*/
void Dri_DMA_Transmit(uint32_t rom_address, uint32_t ram_address, uint32_t length) {
DMA1_Channel1->CPAR = rom_address;
DMA1_Channel1->CMAR = ram_address;
DMA1_Channel1->CNDTR = length;
// 开启传输
DMA1_Channel1->CCR |= DMA_CCR1_EN;
}
// 存储和存储之间数据传输
const uint8_t v1[4] = {'a', 'b', 'c', 'd'}; // FLASH ->ROM
uint8_t v2[5] = {0}; // RAM
extern uint8_t dma_tranmit_complete_flg; 外部调用其他函数的成员变量使用extern
int main(void)
{
USART_Init();
Dri_DMA_Init();
printf("ROM存储和RAM存储之间数据传输 \n");
Dri_DMA_Transmit((uint32_t)v1, (uint32_t)v2, 4);
while (1)
{
if(dma_tranmit_complete_flg == 1)
{
printf("v2 = %s \n", v2); //防止数据没传输完,就开始打印数据了
dma_tranmit_complete_flg = 0;
}
}
二、ROM和RAM通过DMA进行通信(HAL)
1 配置RCC SYS clock USART1 DMA



在stmit.32 中找到回调函数 中断函数(复位、关通道)
使用DMA传输数据->指针函数->状态(flag)
callback往前找一下,往后找,就可以把整个代码连贯起来

