目录
MCU型号:STM32H743ZI
IDE环境:MDK 535
文章目录
前言
我是一个单片机小白呀!!!!!!
一、DMA介绍
1. DMA概念
直接存储器访问 (DMA) :用于在外设与存储器之间以及存储器与存储器之间进行高速数据传输。DMA传输过程的初始化和启动由CPU完成,传输过 程由DMA控制器来执行,无需CPU参与,从而节省CPU资源,提高利用率。
2. DMA四要素
① 传输源 :DMA数据传输的来源
② 传输目标:DMA数据传输的目的
③ 传输数量:DMA传输数据的数量
④ 触发信号:启动一次DMA数据传输的动作
3. DMA数据传输方式
普通模式:传输结束后(即要传输数据的数量达到零),将不再产生DMA操作。若 开始新的DMA传输,需在关闭DMA通道情况下,重新启动DMA传输。
循环模式:可用于处理环形缓冲区和连续数据流(例如ADC扫描模式)。当激活循 环模式后,每轮传输结束时,要传输的数据数量将自动用设置的初始值 进行加载, 并继续响应DMA请求。
二、配置
1.接口函数
串口DMA方式发送函数:
HAL_StatusTypeDef HAL_UART_Transmit_DMA
(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size)
2 串口DMA方式接收函数:
HAL_StatusTypeDef HAL_UART_Receive_DMA
(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size)
目录
3 获取未传输数据个数函数: HAL_DMA_GET_COUNTER
2.STM32cubeMX的配置
然后配置Project Managei,接着生成工程,此时,STM32cubeMX的配置已经做完了!!
3.keil代码
在stm32h7xx_it.c文件中
extern DMA_HandleTypeDef hdma_usart3_rx;
extern DMA_HandleTypeDef hdma_usart3_tx;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
void USART3_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart3);
//添加idle中断处理
if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)!=RESET) //是否发生idle中断
{
__HAL_UART_CLEAR_IDLEFLAG(&huart3); //清除idle中断
HAL_UART_IdleCpltCallback(&huart3); //用户编写的中断回调函数
}
}
main.c文件,变量定义
uint8_t Rx_Flag = 0; //标志位
uint8_t RecCount = 0; //个数
uint8_t Rx_Buf[256]; //接收缓冲区
uint8_t Tx_Buf[256];
extern DMA_HandleTypeDef hdma_usart3_rx;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //接收中断函数
{
if(huart->Instance == USART3)
{
HAL_UART_Transmit(&huart3,(uint8_t *)Rx_Buf, 256,0xFFFF);
}
}
void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart) //空闲中断函数
{
Rx_Flag = 1; // 设置接收完成标志
HAL_UART_DMAStop(huart); // 停止DMA传输
//发生空闲中断时,已接受的数据等于数据总减去dma中待接收的数据
RecCount= 256 - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);
memcpy(Tx_Buf, Rx_Buf, RecCount); //内存复制函数
memset(Rx_Buf, 0, sizeof(Rx_Buf)); // 清零接收缓存区
HAL_UART_Receive_DMA(&huart3,Rx_Buf, sizeof(Rx_Buf)); //重新开启DMA传输
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init();
HAL_UART_Receive_DMA(&huart3, Rx_Buf,256); //使能dma中断
__HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE); //使能idle中断
while (1)
{
HAL_Delay(5);
if(Rx_Flag==1) //判断数据是否接收完成
{
Rx_Flag=0; //清除标志位
HAL_UART_Transmit_DMA(&huart3,Tx_Buf,RecCount); //采用DMA的方式将接收数据发送到PC
RecCount = 0;
}
}
}
总结
我只是一个小菜鸡啊。