【N32L40X】学习笔记06-串口dma空闲中断+dma接收数据

串口dma

8 个可独立配置的 DMA 通道。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VchCudlf-1689952378831)(./picture/dma.png)]

【N32L40X】学习笔记06-串口dma空闲中断+dma接收数据_第1张图片

实例代码

串口dma使用的是串口绑定方式实现串口的dma数据传输

【N32L40X】学习笔记06-串口dma空闲中断+dma接收数据_第2张图片

bsp_uart_dma.h

#ifndef _BSP_UART_DMA_H_
#define _BSP_UART_DMA_H_
#include
#include
#include "n32l40x.h"

#define BUFF_SIZE 48
//调试串口指定
#define DEBUG_UART USART1

//dma接收数据和中断接收数据不可以同时使用

typedef enum
{
    UART1_DMA_RECV,//串口1接收
	UART1_DMA_SEND,//串口1发送
    UART2_DMA_RECV,//串口2接收
    UART3_DMA_RECV,//串口3接收
    UART_DMA_NUM,
}em_uart_dma_t;

typedef struct
{

    DMA_ChannelType* dma_ch_rx;//dma 发送通道
    uint32_t dma_remap_rx;//串口接收映射的dma通道
    uint16_t dma_irq_rx;//dma rx 中断编号
    uint32_t send_or_recv;//发送还是接收

} uart_dma_t;

/*
	一键初始化所有串口
*/
void bsp_uart_dma_config(uart_dma_t *puartx,uint32_t reg_data,const uint32_t *buff,const uint16_t len);

uart_dma_t* bsp_uart_dma_get_handler(em_uart_dma_t id);

void bsp_uart_dma_send_ex(uart_dma_t *puartx,uint8_t *data,uint16_t len);

#endif


bsp_uart_dma.c

#include 
#include 
#include 
#include "bsp_include.h"
#include "uart/bsp_uart_dma.h"

//这里的通道和外设随便映射,没得固定的映射关系
static uart_dma_t s_uart_dma_s[UART_DMA_NUM]= {
    //UART1
    {  DMA_CH4,DMA_REMAP_USART1_RX,DMA_Channel4_IRQn,DMA_DIR_PERIPH_SRC},
    {  DMA_CH5,DMA_REMAP_USART1_TX,DMA_Channel5_IRQn,DMA_DIR_PERIPH_DST},
    //UART2
    {  DMA_CH2,DMA_REMAP_USART2_RX,DMA_Channel2_IRQn,DMA_DIR_PERIPH_SRC},
    //UART3
    {  DMA_CH3,DMA_REMAP_USART3_RX,DMA_Channel3_IRQn,DMA_DIR_PERIPH_SRC},

};

uart_dma_t* bsp_uart_dma_get_handler(em_uart_dma_t id)
{	
	if(UART_DMA_NUM>id)
		return s_uart_dma_s+id;
	else 
		return 0;
}


void bsp_uart_dma_nvic_config(uart_dma_t *puartx)
{
    NVIC_InitType NVIC_InitStructure;
	
	
	NVIC_InitStructure.NVIC_IRQChannel					 = puartx->dma_irq_rx;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority		 = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd				 = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
 
}


void bsp_uart_dma_config(uart_dma_t *puartx,uint32_t reg_data,const uint32_t *buff,const uint16_t len)
{
   DMA_InitType DMA_InitStructure;

   // USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config
	//使能时钟
	RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);
   
  	DMA_StructInit(&DMA_InitStructure);
	
	DMA_DeInit(puartx->dma_ch_rx);
	DMA_InitStructure.PeriphAddr     = reg_data;
	DMA_InitStructure.MemAddr        = buff;
	DMA_InitStructure.Direction      = puartx->send_or_recv;//外设是源数据
	if(DMA_DIR_PERIPH_DST==puartx->send_or_recv)//发送模式就是默认发送数量为0
	{
		DMA_InitStructure.BufSize        = 0;
	}
	else
	{
	DMA_InitStructure.BufSize        = len;
	}
	DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;//外设地址自动增加关闭
	DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;	//内存地址自动增加
	DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;//数据宽度
	DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Byte;//数据宽度
	DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;//工作模式-普通模式
	DMA_InitStructure.Priority       = DMA_PRIORITY_MEDIUM;//中等优先级
	DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;//不是内存到内存的传输方式
	DMA_Init(puartx->dma_ch_rx, &DMA_InitStructure);
	//dma 通道映射
	DMA_RequestRemap(puartx->dma_remap_rx, DMA, puartx->dma_ch_rx, ENABLE);
	//中断分组
	bsp_uart_dma_nvic_config(puartx);
	//使能dma中断
	DMA_ConfigInt(puartx->dma_ch_rx,DMA_INT_TXC,ENABLE);
	
	//通道使能
   DMA_EnableChannel(puartx->dma_ch_rx, ENABLE);
	
	

}


void bsp_uart_dma_send_ex(uart_dma_t *puartx,uint8_t *data,uint16_t len)
{
	//通道使能
	DMA_EnableChannel(puartx->dma_ch_rx, DISABLE);
	DMA_SetCurrDataCounter(puartx->dma_ch_rx,len);
	//通道使能
	DMA_EnableChannel(puartx->dma_ch_rx, ENABLE);
}


/**

DMA_Channel1_IRQHandler
DMA_Channel2_IRQHandler
DMA_Channel3_IRQHandler
DMA_Channel4_IRQHandler
DMA_Channel5_IRQHandler
DMA_Channel6_IRQHandler
DMA_Channel7_IRQHandler
DMA_Channel8_IRQHandler
*/


void  bsp_uart_dam_irq_handler(uint32_t DMA_IT)
{
    //DMA_INT_HTX1 这个是个变量
    if( DMA_GetIntStatus(DMA_IT, DMA))
    {
        DMA_ClrIntPendingBit(DMA_IT, DMA);
       
    }

}




//发送/接收 dma
void DMA_Channel4_IRQHandler(void)
{	
		bsp_uart_dam_irq_handler(DMA_INT_TXC4);
	

}

//发送/接收 dma
void DMA_Channel5_IRQHandler(void)
{

		bsp_uart_dam_irq_handler(DMA_INT_TXC5);
	

}




你可能感兴趣的:(N32L40X,N32L40X,串口,dma,空闲中断)