stm32l0xx基于CubeMX使用UART+DMA实现数据接收

stm32基于CubeMX使用UART+DMA实现数据接收发送

  • 前言
    • CubeMx软件的配置过程
  • 代码部分
    • C语言的重定向fputc函数
    • 变量定义
    • 中断函数
    • 发送主函数
  • 对于程序的理解
    • 串口助手效果

前言

最近用了NUCLEO的板子做一些东西,用到了串口通讯,结合一些资料再加上自己整合基本实现了发送和接收任意长度数据段(第一次写博客有点小紧张哈哈)。

CubeMx软件的配置过程

首先,建立新的工程,选择芯片类型,这里我用的是stm32l073rz。
stm32l0xx基于CubeMX使用UART+DMA实现数据接收_第1张图片
下面选择sys部分,勾选Debug Serial Wire (这个好像是下载调试 st-link,也不是很清楚)。
stm32l0xx基于CubeMX使用UART+DMA实现数据接收_第2张图片
选择USART2,选择模式Asynchronous(异步通信)模式。

stm32l0xx基于CubeMX使用UART+DMA实现数据接收_第3张图片
选择下面DMA模式 ,添加rx tx,并设置tx为循环模式。
stm32l0xx基于CubeMX使用UART+DMA实现数据接收_第4张图片
勾选USART2全局中断。
stm32l0xx基于CubeMX使用UART+DMA实现数据接收_第5张图片
保存工程,选择相应的选项,生成代码即可。
stm32l0xx基于CubeMX使用UART+DMA实现数据接收_第6张图片

代码部分

C语言的重定向fputc函数

 int fputc(int ch,FILE *f)
{
 HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
 return ch;
}

ch为要写入的参数,fp指向FILE结构的指针;这样重新定向后就可以使用printf直接输出。

变量定义

#define RX_LEN 1024 //定义总的数据长度
 volatile uint8_t  RX_flag=0;        //IDLE 接收标志
 volatile uint8_t RX_Size=0;          //接收的数据段长度
 uint8_t  RX_pData[RX_LEN]; //DMA 接收的数组

volatile 关键字提醒编译器定义的变量是易变的,编译后的程序每次需要存储或读取该变量时,会直接从变量地址读取数据。在中断或多线程中使用volatile关键字可以避免不同优化等级时程序出错,提高程序的鲁棒性。

中断函数

void UsartReceive_IDLE(UART_HandleTypeDef *huart)  
 {  
uint32_t temp;  
uint32_t tmp_flag=0;
tmp_flag =__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE); // USART_IT_IDLE中断,是串口收到一帧数据(也可以叫做一包数据)后,发生的中断。
	if((tmp_flag != RESET))//tmp_flag不等于0
{   
__HAL_UART_CLEAR_IDLEFLAG(huart);  //tmp_flag=0;
 HAL_UART_DMAStop(huart);  
  temp = hdma_usart2_rx.Instance->CNDTR;  //cndtr为未传输的数据
RX_Size =  RX_LEN - temp;   //总数减去未传输的,得到发送的数据长度
RX_flag=1;  
 }  
 }

在中断请求函数加入自定义的中断函数。

 void USART2_IRQHandler(void)//串口中断请求
{
  /* USER CODE BEGIN USART2_IRQn 0 */
  UsartReceive_IDLE(&huart2);
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);

} 
static void MX_USART2_UART_Init(void)//在这个中间加入使能函数   切记切记
{
  /* USER CODE BEGIN USART2_Init 2 */
    __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);//使能idle中断

  /* USER CODE END USART2_Init 2 */

}

发送主函数

 void uart_pc_com (UART_HandleTypeDef *huart)
   {
   if(RX_flag ==1)
   	{
   		printf("rx_len=%d\r\n",RX_Size);//\r是回车符,\n是换行符
   		HAL_UART_Transmit(&huart ,RX_pData, RX_Size,200);
   		for(uint8_t i=0;i<RX_Size;i++)
   			{
   				RX_pData[i]=0;//清除缓存
   			}
   		RX_Size=0;
   		RX_flag=0;//清除结束标志位
   	 }
   	HAL_UART_Receive_DMA(huart,RX_pData,RX_LEN );//打开dma数据存入rx——RX_pData
   	 //加在 MX_USART2_UART_Init中  pc串口助手只能接受到一次数据  只有处于main函数while循环才能一直接受发送
 }

在main函数的while循环里面加入此函数,并注明使用的uart。

对于程序的理解

首先uart接受数据,触发idle中断,进入中断请求函数,获取接受到的数据以及数据长度,并将标志位置1,进入主函数输出到串口助手

串口助手效果

stm32l0xx基于CubeMX使用UART+DMA实现数据接收_第7张图片
基本可以实现本次的目的,首次写,表达不够清楚,望理解。

你可能感兴趣的:(stm32)