从零实现 串口DMA加空闲中断任意长度收发

这篇文章强烈建议收藏,很实用

前言:

原文为STM32F407的实现,https://blog.csdn.net/medojonh/article/details/80135567,如果要用STM32F103还需要修改部分。

在此感谢原作者!

关于CubeMx的配置可直接看原文,我省懒事直接把修改后的代码贴上来。

实现的功能是,串口接收上来的数值再发出去。

因为我用的是485,所以在发送前还是得改变一下485的使能管脚。

和原文不同的是,原文在发送后没有等待过程,我在调试时发现接收到的时候没问题,发的时候有问题。所以是需要加上等待发送完成的。

代码实现:

把大象放进冰箱一共分几步?分四步。。。

1.在main.c中添加

/* USER CODE BEGIN 2 */

    HAL_UART_Receive_DMA(&huart1, UsartType.RX_pData, RX_LEN);  
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 

/* USER CODE END 2 */

2.在usart.c中添加

/* USER CODE BEGIN 0 */
USART_RECEIVETYPE UsartType; 
/* USER CODE END 0 */

/* USER CODE BEGIN 1 */
void UsartReceive_IDLE(UART_HandleTypeDef *huart)  
{  
    uint32_t temp;  
	
    if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))  
    {   
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);  

        HAL_UART_DMAStop(&huart1);  

        temp = huart1.hdmarx->Instance->CNDTR;  //stm32f429 ->NDTR	//stm32f103 ->CNDTR

        UsartType.RX_Size =  RX_LEN - temp;   

        UsartType.RX_flag=1;  

        HAL_UART_Receive_DMA(&huart1,UsartType.RX_pData,RX_LEN);  
    }  
    if(UsartType.RX_flag)    	// Receive flag		
    {  			
	UsartType.RX_flag=0;	// clean flag			
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_SET);
	HAL_UART_Transmit_DMA(&huart1, UsartType.RX_pData, UsartType.RX_Size);
	while(__HAL_UART_GET_FLAG(huart,UART_FLAG_TC)!=SET);		//等待发送结束	
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_RESET);	
    } 
} 

void USART2_TransmitData(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
	PCF8574_WriteBit(RS485_RE_IO, 1);
	HAL_UART_Transmit_DMA(huart, pData, Size);
	while(__HAL_UART_GET_FLAG(huart,UART_FLAG_TC)!=SET);		//等待发送结束
	PCF8574_WriteBit(RS485_RE_IO, 0);
}

int fputc(int ch,FILE *f)
{
    uint32_t temp = ch;

//如果重定向到485串口上,不要忘记控制线
//    HAL_GPIO_WritePin( GPIOA, GPIO_PIN_11, GPIO_PIN_SET );
    HAL_UART_Transmit_DMA(&huart1,(uint8_t *)&temp,1);        //huart1串口的句柄
//    HAL_GPIO_WritePin( GPIOA, GPIO_PIN_11, GPIO_PIN_RESET );
    HAL_Delay(2);

	return ch;
}

/* USER CODE END 1 */

3.在usart.h中添加

/* USER CODE BEGIN Private defines */

#define RX_LEN 1024  

typedef struct  

{  
	uint8_t  RX_flag:1;        //IDLE receive flag

	uint16_t RX_Size;          //receive length

	uint8_t  RX_pData[RX_LEN]; //DMA receive buffer

}USART_RECEIVETYPE;  

extern USART_RECEIVETYPE UsartType; 

/* USER CODE END Private defines */

/* USER CODE BEGIN Prototypes */
extern void UsartReceive_IDLE(UART_HandleTypeDef *huart);
/* USER CODE END Prototypes */

4.在stm32f1xx_it.c中添加

/* USER CODE BEGIN 0 */
#include "usart.h"
/* USER CODE END 0 */

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	UsartReceive_IDLE(&huart1); 
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值