ST芯片使用串口 + DMA接收 + 空闲中断处理,有USART1和LPUART

普通串口:USART1

首先是DMA初始化

//DMA初始化
void MX_DMA_Init(void) 
{
  /* Init with LL driver */
  /* DMA controller clock enable */
  LL_AHB_EnableClock(LL_AHB_PERIPH_DMA); 
  
  /* DMA interrupt init */
  /* DMA_IRQn interrupt configuration */
  NVIC_SetPriority(DMA_IRQn, IRQ_CRITICAL_PRIORITY);
  NVIC_EnableIRQ(DMA_IRQn);  
	
	  /* USART1_RX Init */
  LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_6, LL_DMAMUX_REQ_USART1_RX);
  
  LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_6, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
  
  LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PRIORITY_HIGH);
  
  LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MODE_CIRCULAR);
  
  LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PERIPH_NOINCREMENT);
  
  LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MEMORY_INCREMENT);
  
  LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PDATAALIGN_BYTE);
  
  LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MDATAALIGN_BYTE);
	
	LL_DMA_ConfigAddresses(DMA1, 
                         LL_DMA_CHANNEL_6,
                         LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_RECEIVE),
                         (uint32_t)RamPara.RxBuffer,
                         LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_6));

  LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_6, DMA_DATA_LEN);
	LL_DMA_ClearFlag_TC6(DMA1);	
	LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_6);
}

再是串口初始化:

void BSP_COM_init(void)
{
	
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

	LL_AHB_EnableClock(LL_AHB_PERIPH_GPIOA);

	LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_10);

	
	GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
	LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	 
  
  LL_APB1_EnableClock(LL_APB1_PERIPH_USART);
  
  GPIO_InitStruct.Pin = LL_GPIO_PIN_8|LL_GPIO_PIN_9;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	NVIC_SetPriority(USART1_IRQn, IRQ_HIGH_PRIORITY);
  NVIC_EnableIRQ(USART1_IRQn);
	}

再来个可以更改波特率的配置:

void BSP_COM_config(uint32_t BaudRate)
{

  LL_USART_DeInit(USART1);

	
	LL_USART_SetTransferDirection(USART1,LL_USART_DIRECTION_TX_RX);
	LL_USART_ConfigCharacter(USART1,LL_USART_DATAWIDTH_8B,LL_USART_PARITY_NONE,LL_USART_STOPBITS_1);
  LL_USART_SetBaudRate(USART1,LL_USART_PRESCALER_DIV1,LL_USART_OVERSAMPLING_16,BaudRate);

	

	
	
	LL_USART_Enable(USART1);

		  /* Enable DMA RX Interrupt */
	LL_USART_EnableIT_IDLE(USART1);
  LL_USART_EnableDMAReq_RX(USART1);
	

	
	USART2_485_reset();//这个是用485的时候才要

}

再来一个空闲中断处理:

#define DMA_DATA_LEN 8

static void USART_RxIdleCallback(void)
{

	if(LL_USART_IsActiveFlag_IDLE(USART1) != RESET)
	{
		LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_6);
		LL_USART_ClearFlag_IDLE(USART1);		
		LL_DMA_ClearFlag_TC6(DMA1);
		RamPara.DMA_Rx_Length = LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_6);
		if(RamPara.DMA_Rx_Length == DMA_DATA_LEN && (RamPara.RxBuffer[0] == 0x01 && RamPara.RxBuffer[1] == 0x03))
		{
			Uart_RxHandle(&UartAr.Prv.UartDrCB[UART_id_uart1],UART_id_uart1);		
		}
		else
		{
			RamPara.RxBuffer[0] = 0x0;
			RamPara.RxBuffer[1] = 0x0;
			LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_6,DMA_DATA_LEN);
		}		
		LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_6);
	}
		
}


//RamPara.RxBuffer这个就是全局变量,,设置一个大小就可以了,比如RxBuffer[10]


//最后丢进去就行了
void USART1_IRQHandler(void)
{

	USART_RxIdleCallback();

	BSP_Uart1IRQ();  //这个是发送中断的处理,,就是正常的那种,没用DMA,可以自行写一个
	
}

最后一个初始化顺序:

MX_DMA_Init();
	
BSP_COM_init(); 

BSP_COM_config(9600);

接下来是低功耗串口:LPUART

全部一起放了:跟上面结构一样

void MX_DMA_Init(void) 
{
  /* Init with LL driver */
  /* DMA controller clock enable */
  LL_AHB_EnableClock(LL_AHB_PERIPH_DMA); 
  
  /* DMA interrupt init */
  /* DMA_IRQn interrupt configuration */
  NVIC_SetPriority(DMA_IRQn, IRQ_CRITICAL_PRIORITY);
  NVIC_EnableIRQ(DMA_IRQn);  
	
	  /* USART1_RX Init */
  LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_6, LL_DMAMUX_REQ_USART1_RX);
  
  LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_6, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
  
  LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PRIORITY_HIGH);
  
  LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MODE_CIRCULAR);
  
  LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PERIPH_NOINCREMENT);
  
  LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MEMORY_INCREMENT);
  
  LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PDATAALIGN_BYTE);
  
  LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MDATAALIGN_BYTE);
	
	LL_DMA_ConfigAddresses(DMA1, 
                         LL_DMA_CHANNEL_6,
                         LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_RECEIVE),
                         (uint32_t)RamPara.RxBuffer,
                         LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_6));

  LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_6, DMA_DATA_LEN);
	LL_DMA_ClearFlag_TC6(DMA1);	
	LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_6);


	/* LPUART1_RX Init */
	LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_7, LL_DMAMUX_REQ_LPUART1_RX);
  
  LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_7, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
  
  LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PRIORITY_HIGH);
  
  LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MODE_CIRCULAR);
  
  LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PERIPH_NOINCREMENT);
  
  LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MEMORY_INCREMENT);
  
  LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PDATAALIGN_BYTE);
  
  LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MDATAALIGN_BYTE);
	
	LL_DMA_ConfigAddresses(DMA1, 
                         LL_DMA_CHANNEL_7,
                         LL_USART_DMA_GetRegAddr(LPUART1, LL_LPUART_DMA_REG_DATA_RECEIVE),
                         (uint32_t)RamPara.LPRxBuffer,
                         LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_7));

  LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_7, DMA_DATA_LEN);
	LL_DMA_ClearFlag_TC7(DMA1);
	
	LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_7);
	 
}


void BSP_COM_config(uint32_t BaudRate)
{

  LL_USART_DeInit(USART1);
	LL_LPUART_DeInit(LPUART1);

	
	LL_USART_SetTransferDirection(USART1,LL_USART_DIRECTION_TX_RX);
	LL_USART_ConfigCharacter(USART1,LL_USART_DATAWIDTH_8B,LL_USART_PARITY_NONE,LL_USART_STOPBITS_1);
  LL_USART_SetBaudRate(USART1,LL_USART_PRESCALER_DIV1,LL_USART_OVERSAMPLING_16,BaudRate);

	
	LL_LPUART_SetTransferDirection(LPUART1, LL_LPUART_DIRECTION_TX_RX);
  LL_LPUART_ConfigCharacter(LPUART1, LL_LPUART_DATAWIDTH_8B, LL_LPUART_PARITY_NONE, LL_LPUART_STOPBITS_1);
	LL_LPUART_SetBaudRate(LPUART1, LL_LPUART_PRESCALER_DIV1, BaudRate); 
	
	
	LL_USART_Enable(USART1);
	LL_LPUART_Enable(LPUART1);
		  /* Enable DMA RX Interrupt */
	LL_USART_EnableIT_IDLE(USART1);
  LL_USART_EnableDMAReq_RX(USART1);
	
	LL_LPUART_EnableIT_IDLE(LPUART1);
  LL_LPUART_EnableDMAReq_RX(LPUART1);
	
	USART2_485_reset();
	LP_UART1_485_reset();
}

void Configure_LPUART1(void)
{
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

	LL_AHB_EnableClock(LL_AHB_PERIPH_GPIOB);

	LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_0);

	//485¿ØÖÆÒý½ÅB0
	GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
	LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	LL_APB1_EnableClock(LL_APB1_PERIPH_LPUART);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_4|LL_GPIO_PIN_5;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  NVIC_SetPriority(LPUART1_IRQn, IRQ_HIGH_PRIORITY);
  NVIC_EnableIRQ(LPUART1_IRQn);

//  LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1);  
//  LL_LPUART_EnableIT_ERROR(LPUART1);
}

static void LPUART_RxIdleCallback(void)
{

	if(LL_LPUART_IsActiveFlag_IDLE(LPUART1) != RESET)
	{
		LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_7);
		LL_LPUART_ClearFlag_IDLE(LPUART1);		
		LL_DMA_ClearFlag_TC7(DMA1);
		RamPara.LP_DMA_Rx_Length = LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_7);
		if(RamPara.LP_DMA_Rx_Length == DMA_DATA_LEN && (RamPara.LPRxBuffer[0] == 0x01 && RamPara.LPRxBuffer[1] == 0x03))
		{
			Uart_RxHandle(&UartAr.Prv.UartDrCB[UART_id_uart2] , UART_id_uart2);		
		}
		else
		{
			RamPara.LPRxBuffer[0] = 0x0;
			RamPara.LPRxBuffer[1] = 0x0;
			LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_7,DMA_DATA_LEN);
		}		
		LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_7);
	}	
}

void LPUART1_IRQHandler(void)
{
	LPUART_RxIdleCallback();
	
	BSP_Uart2IRQ();
}

//初始化

        MX_DMA_Init();
	
		BSP_COM_init();  				//usartºÍ485¿ØÖÆÒý½Å³õʼ»¯
	
		Configure_LPUART1();  	//lp_uartºÍ485¿ØÖÆÒý½Å³õʼ»¯
	
		BSP_COM_config(BaudRate_Talble[OptPara.BasePara.BaudRate]); //´®¿Ú²¨ÌØÂÊÅäÖÃ

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮若于心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值