DMA使用心得-STM32

DMA使用心得-STM32 本文结构DMA简要介绍DMA主体思路DMA代码实现与分析DMA简要介绍什么是DMADMA(Direct Memory Access, 直接存储器访问)允许外设与内存直接传输数据的技术无需CPU干预。DMA的特点是什么不受CPU直接控制的“数据搬运工”说人话如果不用DMA你在调试串口时上位机发送数据过来你在接收的地方打了断点你就接收不到完整的数据但是如果你用了DMA你打了断点数据照常接收。DMA主体思路DMA代码的实现/** * brief 串口dma接收完成中断处理 * param * retval */voiduart_dmarx_done_isr(uint8_tuart_id){uint16_trecv_size;recv_sizes_uart_dev[uart_id].dmarx_buf_size-s_uart_dev[uart_id].last_dmarx_size;s_UartTxRxCount[uart_id*21]recv_size;fifo_write(s_uart_dev[uart_id].rx_fifo,(constuint8_t*)(s_uart_dev[uart_id].dmarx_buf[s_uart_dev[uart_id].last_dmarx_size]),recv_size);s_uart_dev[uart_id].last_dmarx_size0;}/** * brief 串口dma接收缓存大小一半数据中断处理 * param * retval * 描述 * 将接收的数据 */voiduart_dmarx_half_done_isr(uint8_tuart_id){uint16_trecv_total_size;uint16_trecv_size;if(uart_id0){recv_total_sizes_uart_dev[uart_id].dmarx_buf_size-bsp_uart1_get_dmarx_buf_remain_size();}elseif(uart_id1){recv_total_sizes_uart_dev[uart_id].dmarx_buf_size-bsp_uart2_get_dmarx_buf_remain_size();}recv_sizerecv_total_size-s_uart_dev[uart_id].last_dmarx_size;s_UartTxRxCount[uart_id*21]recv_size;fifo_write(s_uart_dev[uart_id].rx_fifo,(constuint8_t*)(s_uart_dev[uart_id].dmarx_buf[s_uart_dev[uart_id].last_dmarx_size]),recv_size);s_uart_dev[uart_id].last_dmarx_sizerecv_total_size;}/** * brief 串口空闲中断处理 * param * retval */voiduart_dmarx_idle_isr(uint8_tuart_id){uint16_trecv_total_size;uint16_trecv_size;if(uart_id0){recv_total_sizes_uart_dev[uart_id].dmarx_buf_size-bsp_uart1_get_dmarx_buf_remain_size();}elseif(uart_id1){recv_total_sizes_uart_dev[uart_id].dmarx_buf_size-bsp_uart2_get_dmarx_buf_remain_size();}recv_sizerecv_total_size-s_uart_dev[uart_id].last_dmarx_size;s_UartTxRxCount[uart_id*21]recv_size;fifo_write(s_uart_dev[uart_id].rx_fifo,(constuint8_t*)(s_uart_dev[uart_id].dmarx_buf[s_uart_dev[uart_id].last_dmarx_size]),recv_size);s_uart_dev[uart_id].last_dmarx_sizerecv_total_size;}代码解析这里有三个中断处理函数半满中断、满中断和空闲中断处理函数半满中断和全满中断我们设置DMA接收区域的长度128ByteDMA的CNDTR寄存器的值为128每接收一个字节数据数值就减1。当该数值减少为64时进入半满中断。当数值减少为0时进入全满中断空闲中断除非每帧数据刚好是半帧长度或者满帧长度否则空闲中断处理必然有效案例初始条件下以帧数据长度10为例连续发送6次都不会进入半满中断仅进入空闲中断第7次时便会进入半满中断同时也会进入空闲中断图片中NDT的值不为64第13次时便会进入全满中断同时也会进入空闲中断图片中NDT的值不为0而是翻板到0X7E。