STM32F1系列学习总结:对DMA学习(标准库方式)

*学习路线指引*:

1.DMA功能介绍

2.DMA的配置

一、我的学习认知程度--DMA功能介绍

        DMA能实现一个地址下的数据,硬件自动搬运到另一个地址下,实现硬件全自动化,无需软件干预,即减轻CPU的负担。

二、我的学习认知程度--DMA的配置

结合代码理解:

// 定义接收缓冲区大小
#define BUFFER_SIZE 1

// 定义接收缓冲区
uint8_t rx_buffer[BUFFER_SIZE];

void DMA_Configuration(void) {
    DMA_InitTypeDef DMA_InitStructure;

    // DMA配置
    DMA_DeInit(DMA1_Channel3);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (USART3->DR); // USART3数据寄存器地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rx_buffer; // 存储接收数据的内存地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; // 接收缓冲区大小
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 设置为循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);
	
		// 使能USART3的DMA接收
    USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);

    // 使能DMA1_Channel3
    DMA_Cmd(DMA1_Channel3, ENABLE);
}

代码有详细介绍。

这里提一下DMA的启动条件:

1.有触发源。 //  USART33使能并且打通通道DMA1_Channel3让触发源USART_DMAReq_Rx触发DMA请求。

2.搬运量不为0。

3.DMA使能。

三.总结

最后,总结一下:

尽可能利用DMA来做一些大量的、重复的工作,来最大限度减轻CPU的负担。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是使用STM32F1标准中的DMA实现串口收发的示例代码,供您参考: ``` // 定义缓冲区大小 #define BUFFER_SIZE 100 // 定义缓冲区 uint8_t RxBuffer[BUFFER_SIZE]; uint8_t TxBuffer[BUFFER_SIZE]; // 定义DMA通道和USART DMA_Channel_TypeDef* DMA_CHx; USART_TypeDef* USARTx; // 初始化串口 void USART_Init(void) { // 使能USART时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 配置USART参数 USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 115200; 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(USART1, &USART_InitStructure); // 使能USART USART_Cmd(USART1, ENABLE); } // 初始化DMA void DMA_Init(void) { // 使能DMA时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 配置DMA通道 DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USARTx->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA_CHx, &DMA_InitStructure); // 使能DMA通道中断 DMA_ITConfig(DMA_CHx, DMA_IT_TC, ENABLE); // 使能DMA通道 DMA_Cmd(DMA_CHx, ENABLE); } // DMA传输完成中断处理函数 void DMA1_Channel4_IRQHandler(void) { // 判断传输是否完成 if (DMA_GetFlagStatus(DMA_CHx, DMA_FLAG_TC)) { // 清除传输完成标志 DMA_ClearFlag(DMA_CHx, DMA_FLAG_TC); // 处理接收数据 uint16_t length = BUFFER_SIZE - DMA_GetCurrDataCounter(DMA_CHx); for (uint16_t i = 0; i < length; i++) { // 处理接收到的数据 // ... } // 启动下一次DMA传输 DMA_SetCurrDataCounter(DMA_CHx, BUFFER_SIZE); DMA_Cmd(DMA_CHx, ENABLE); } } // 发送数据 void USART_SendData(uint8_t* data, uint16_t length) { // 等待USART发送缓冲区为空 while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); // 启动DMA传输 DMA_Cmd(DMA_CHx, DISABLE); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)data; DMA_InitStructure.DMA_BufferSize = length; DMA_Init(DMA_CHx, &DMA_InitStructure); DMA_Cmd(DMA_CHx, ENABLE); // 等待DMA传输完成 while (DMA_GetFlagStatus(DMA_CHx, DMA_FLAG_TC) == RESET); } ``` 以上代码仅供参考,具体实现还需要根据实际情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值