欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32 hal库DMA串口不定长

程序员文章站 2022-06-03 20:49:52
...
//切记切记要在实验板上测试,不能用软件仿真
//方法1--------------------------------------------
//main.c
uint8_t receive_buff[BUFFER_SIZE];

//usart.c
extern uint8_t receive_buff[BUFFER_SIZE];                                                //接收缓冲区
void MX_USART1_UART_Init(void)
{ // ........
   __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
   HAL_UART_Receive_DMA(&huart1, (uint8_t*)receive_buff, BUFFER_SIZE);
}
/* USER CODE BEGIN 1 */
//只能接受BUFFER_SIZE-1个字符
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{
    HAL_UART_DMAStop(&huart1);
    i++;
    
    uint8_t data_length  = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);

    printf("Receive Data(length = %d): ",data_length);
    HAL_UART_Transmit(&huart1,receive_buff,data_length,0x200);
    printf("\r\n");

    memset(receive_buff,0,data_length);
    data_length = 0;
    HAL_UART_Receive_DMA(&huart1, (uint8_t*)receive_buff, BUFFER_SIZE);
}

void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
{
    if(USART1 == huart1.Instance)
    {
        if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
        {
            __HAL_UART_CLEAR_IDLEFLAG(&huart1);
            printf("\r\nUART1 Idle IQR Detected\r\n");
            USAR_UART_IDLECallback(huart);
        }
    }
}
/* USER CODE END 1 */

//中断stm32f1xx_it.c文件内
extern void USER_UART_IRQHandler(UART_HandleTypeDef *huart);

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
//printf("ceshi");
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
//添加IDLE中断函数
USER_UART_IRQHandler(&huart1);
  /* USER CODE END USART1_IRQn 1 */
}


//方法2---------------------------------------------
//中断stm32f1xx_it.c文件内
extern void UsartReceive_IDLE(UART_HandleTypeDef *huart);
void USART1_IRQHandler(void)
{
  UsartReceive_IDLE(&huart1); //进入空闲中断
  HAL_UART_IRQHandler(&huart1);
}
//usart.c
USART_RECEIVETYPE UsartType; //定义结构体变量存储状态
//空闲中断调用函数
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_GET_FLAG(huart,UART_FLAG_IDLE) ;
        HAL_UART_DMAStop(&huart1);  
        temp = huart1.hdmarx->Instance->CNDTR; //获取剩余dma长度 
        UsartType.RX_Size =  RX_LEN - temp;   
        UsartType.RX_flag=1;  
        HAL_UART_Receive_DMA(&huart1,UsartType.RX_pData,RX_LEN);  
    }  
} 

//usart.h
#define RX_LEN 10  
	 
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;

//main.c
int main(void)
{
     __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //开启空闲中断
  HAL_UART_Receive_DMA(&huart1, UsartType.RX_pData, RX_LEN);  //开启串口DMA接收中断
while (1)
  {
      if(UsartType.RX_flag)    	// 接收到数据的标志
      {  
           UsartType.RX_flag=0;	//清除接收到标志
           HAL_UART_Transmit(&huart1, UsartType.RX_pData, UsartType.RX_Size, 0xFFFF);
      } 
   
}

相关标签: stm32