2023|6

7048

帖子

11

TA的资源

版主

楼主
 

[ ST NUCLEO-U575ZI-Q 测评] 串口中断不定长接收 [复制链接]

串口不定长接收,对数据进行分析判断。最近想弄个接收黑白图片的工程,所以要把串口接收再复习一遍:

1、串口stm32cubeMax配置:

  2、配置中断:

 3、配置串口发送PA9为USART1的TX,输出模式为上拉,PA10为USART1的RX:

  生成工程后打开工程。

# 串口接收自定义函数的编写

1、打开main.h,加入如下代码:

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
extern UART_HandleTypeDef huart1;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
#define RXBUFFSIZE 2048
typedef struct{
	UART_HandleTypeDef *huart;
	u8 rx_buf[RXBUFFSIZE]; //接收缓冲区
	u32 tx_count;  //发送完成次数计数标志位
	u32 rx_flage;   //接收完成标志位
	
	void (*init)(void);   //初始化函数指针
} rxtx_it_usart_t;


/* USER CODE END ET */

代码的主要功能是结构体并进行了初始化。

2、stm32u5xxit.c 声明结构体函数:

/* External variables --------------------------------------------------------*/

extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */

3、定义中断函数:

/**
  * [url=home.php?mod=space&uid=159083]@brief[/url] This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	HAL_UART_IDLE_HANDLER(&huart1); //自定义空闲中断接收
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);  //中断接收
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

/* USER CODE BEGIN 1 */
__weak void HAL_UART_IDLE_HANDLER(UART_HandleTypeDef *huart)
{
	UNUSED(huart);
}

4、在main.c主函数中增加初始化函数代码

/* USER CODE BEGIN PFP */
//声明一个结构体并进行初始化
void  uart1_user_init(void);

rxtx_it_usart_t rxtx_it_usart = {
	.huart = &huart1,
	.init = uart1_user_init, //为该指针赋值,指向init函数
};
/* USER CODE END PFP */

增加中断回调处理函数:

/* USER CODE BEGIN 4 */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	if(rxtx_it_usart.huart == huart)
	{
		rxtx_it_usart.tx_count++;
		
	}
	
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
 
	if(rxtx_it_usart.huart == huart)
	{
		rxtx_it_usart.rx_flage = 1;
	}
}

//初始化空闲中断
void uart1_user_init(void)
{
	__HAL_UART_ENABLE_IT(rxtx_it_usart.huart, UART_IT_IDLE);
	__HAL_UART_CLEAR_IDLEFLAG(rxtx_it_usart.huart);
	HAL_UART_Receive_IT(rxtx_it_usart.huart,rxtx_it_usart.rx_buf,RXBUFFSIZE);
}

//自定义空闲中断处理函数
void HAL_UART_IDLE_HANDLER(UART_HandleTypeDef *huart)
{
   uint32_t isrflags   =  READ_REG(huart->Instance->ISR); 
   if((USART_ISR_IDLE & isrflags) != RESET && ( huart->RxXferCount > 0))
   {
       printf("idle\r\n");
       __HAL_UART_CLEAR_IDLEFLAG(huart);
      /* Disable the UART Data Register not empty Interrupt */
      __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
      /* Disable the UART Parity Error Interrupt */
      __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
      /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
      __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
      /* Rx process is completed, restore huart->RxState to Ready */
      huart1.RxState = HAL_UART_STATE_READY;  
      HAL_UART_RxCpltCallback(huart); 
   }else if((USART_ISR_IDLE & isrflags) != RESET && ( huart->RxXferCount == 0 ))
   { 
       __HAL_UART_CLEAR_IDLEFLAG(huart);

   } 
}

//自定中断错误处理函数

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	if(rxtx_it_usart.huart == huart)
	{
		printf("error %d\r\n",huart->ErrorCode);
		
	}
}
/* USER CODE END 4 */

在main中函数中增加对数据处理的功能:

if (( HAL_GetTick()-tickend )>5000)
        {
            tickend = HAL_GetTick();
            HAL_UART_Transmit_IT(rxtx_it_usart.huart,send_data,sizeof(send_data)-1);
        }
        //发送成功一次,就发送send done
        if(rxtx_it_usart.tx_count>0)
        {
            rxtx_it_usart.tx_count --;
            printf("send done\r\n");
        }
        
        if(rxtx_it_usart.rx_flage == 1)
        {
            rxtx_it_usart.rx_flage = 0;
            //回显接收到的数据
            printf("\r\nrcv done:\r\n");
            printf("%s\r\n", rxtx_it_usart.rx_buf);
            //重新开始接收20个字节数据
            memset(rxtx_it_usart.rx_buf,0,sizeof(rxtx_it_usart.rx_buf));
            HAL_UART_Receive_IT(rxtx_it_usart.huart,rxtx_it_usart.rx_buf,RXBUFFSIZE);
        }

 

下载后的效果如下:

 

此帖出自无线连接论坛

最新回复

测评汇总:免费申请|ST NUCLEO-U575ZI-Q https://bbs.eeworld.com.cn/thread-1228653-1-1.html   详情 回复 发表于 2023-2-2 14:00
点赞 关注
 

回复
举报

6534

帖子

9

TA的资源

版主

沙发
 

不定长数据接收感觉还是感觉串口空闲中断加DMA最理想

此帖出自无线连接论坛

点评

DMA还没有弄好,按理来讲有dma还是优秀一些,一下子摸不透呀。  详情 回复 发表于 2023-1-13 10:44
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

回复

7048

帖子

11

TA的资源

版主

板凳
 
秦天qintian0303 发表于 2023-1-13 09:07 不定长数据接收感觉还是感觉串口空闲中断加DMA最理想

DMA还没有弄好,按理来讲有dma还是优秀一些,一下子摸不透呀。

此帖出自无线连接论坛
 
 
 

回复

1532

帖子

1

TA的资源

五彩晶圆(初级)

4
 

不错,有时间也试试。

此帖出自无线连接论坛

点评

老师,你弄这个是小马菜了,有时间写点例程我学习学习。  详情 回复 发表于 2023-1-16 22:46
 
 
 

回复

7048

帖子

11

TA的资源

版主

5
 
jinglixixi 发表于 2023-1-16 11:48 不错,有时间也试试。

老师,你弄这个是小马菜了,有时间写点例程我学习学习。

此帖出自无线连接论坛

点评

中断的我真的还没弄到,毕竟有许多事要做,有现成的要省时间。  详情 回复 发表于 2023-1-17 12:34
 
 
 

回复

1532

帖子

1

TA的资源

五彩晶圆(初级)

6
 
lugl4313820 发表于 2023-1-16 22:46 老师,你弄这个是小马菜了,有时间写点例程我学习学习。

中断的我真的还没弄到,毕竟有许多事要做,有现成的要省时间。

此帖出自无线连接论坛
 
 
 

回复

1万

帖子

203

TA的资源

管理员

7
 

测评汇总:免费申请|ST NUCLEO-U575ZI-Q https://bbs.eeworld.com.cn/thread-1228653-1-1.html

此帖出自无线连接论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
个人签名玩板看这里:
https://bbs.eeworld.com.cn/elecplay.html
EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表