DMA模式的串口通信

之前试过了DMA的ADC,这次用DMA结合串口的收发。

初始化一些需要用到的参数

#define USART_MAX_BUFFER_SIZE 512
typedef struct usartRT {
   
	uint8_t status;
	uint16_t rxBufferSize;
	uint16_t txBufferSize;
	uint8_t txBuffer[USART_MAX_BUFFER_SIZE]; 
	uint8_t rxBuffer[USART_MAX_BUFFER_SIZE];
}usartPacket_s;
typedef struct serialHandle {
   
	USART_Type* USARTx;
	DMA_Channel_Type* rxChannel;//接收频道
	DMA_Channel_Type* txChannel;//发送频道
	usartPacket_s packet;
	usartPacket_s DMApacket;
}SerialHandle_s;
//以串口1为例
SerialHandle_s serialHandle[serialCount] = {
   
	[serial1] = {
   
		.USARTx = USART1,
		.rxChannel = DMA1_Channel5,
		.txChannel = DMA1_Channel4,
		.packet.rxBufferSize = 0,
		.DMApacket.rxBufferSize = 0,
	},
}

初始化DMA

void USART_DMA_INIT(DMA_Channel_Type* DMAchannelx, uint32_t periphAddr, uint32_t bufferAddr, uint16_t bufferSize, uint32_t Direction)
{
   
	DMA_InitType DMA_InitStructure;

	DMA_Reset(DMAchannelx);
	DMA_DefaultInitParaConfig(&DMA_InitStructure);
	DMA_InitStructure.DMA_PeripheralBaseAddr = periphAddr;						//传输地址
	DMA_InitStructure.DMA_MemoryBaseAddr = bufferAddr;							//缓存地址
	DMA_InitStructure.DMA_Direction = Direction;								//传输方向(收发)
	DMA_InitStructure.DMA_BufferSize = bufferSize;								//缓存大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;			//外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;						//内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_BYTE;	//数据宽度8位
	DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_BYTE;			//数据宽度8位
	DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;								//正常模式
	DMA_InitStructure.DMA_Priority = DMA_PRIORITY_LOW;							//优先级低
	DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;							//不使用内存到内存传输
	DMA_Init(DMAchannelx, &DMA_InitStructure);
}

设置DMA参数

void USART_DMA_SETUP(SerialHandle_s* serialx)
{
   
	USART_DMA_INIT(serialx->txChannel, (uint32_t) & (serialx->USARTx->DT), (uint32_t)(serialx->DMApacket.txBuffer), USART_MAX_BUFFER_SIZE, UART_TX);
	USART_DMA_INIT(serialx->rxChannel, (uint32_t) & (serialx->USARTx->DT), (uint32_t)(serialx->DMApacket.rxBuffer), USART_MAX_BUFFER_SIZE, UART_RX);
	// DMA_ChannelEnable(serialx->txChannel, ENABLE);
	DMA_ChannelEnable(serialx->rxChannel, ENABLE);
	/* Enable USARTx DMA Rx and TX request */
	USART_DMACmd(serialx->USARTx, USART_DMAReq_Rx, ENABLE);
	USART_DMACmd(serialx->USARTx, USART_DMAReq_Tx, ENABLE);
	}

初始化串口

void USART_ClkCmd(USART_Type* USARTx, FunctionalState NewState)
{
   
	if (USARTx == USART1)
	{
   
	RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_USART1, NewState);				//不同的串口硬件时钟不同,要注意
	}
}

void USART_NVIC_Cmd(USART_Type* USARTx, FunctionalState NewState)
{
   
	if (USARTx == USART1)
	{
   
		NVIC_Config(USART1_IRQn, 4, 1, NewState);
	}
}

void Usart_Setup(SerialHandle_s* serialx, uint32_t baudrate, uint16_t Wordlength, uint16_t Stopbits, uint16_t Parity, uint16_t Mode, uint16_t HardwareFlowControl)
{
   
	USART_Reset(serialx->USARTx);
	USART_ClkCmd(serialx->USARTx, ENABLE);									//开启串口时钟
	USART_NVIC_Cmd(serialx->USARTx, ENABLE);								//串口中断
	USART_InitType USARTx_InitStructure;
	USARTx_InitStructure.USART_BaudRate = baudrate;							//波特率		
	USARTx_InitStructure.USART_WordLength = Wordlength;						//数据长度
	USARTx_InitStructure.USART_StopBits = Stopbits;							//停止位
	USARTx_InitStructure.USART_Parity = Parity;								//校验位
	USARTx_InitStructure.USART_Mode = Mode;				
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值