串口的离散数据包超时接收

我自己起的名字

最近调一个电表, 485的, 他回复的报文不是连续的, 用stm32的idle中断就会被打断.

所以简单写了一个通过超时判断接收完毕的功能

.h文件

struct Discrete_Data_Serial {
	int timeout_config;
	int size;
	int count;
	int timeout;
	uint8_t data_buff[512];
};

void dds_timer_handle(struct Discrete_Data_Serial *s);
void dds_uart_isr_handle(struct Discrete_Data_Serial *s, uint8_t *src, uint16_t size);

int dds_is_avliable(struct Discrete_Data_Serial *s);
void dds_copy(struct Discrete_Data_Serial *s, uint8_t *buff, uint16_t *size);
void dds_initial(struct Discrete_Data_Serial *s, uint32_t timeout_config);

.c文件


void dds_reset(struct Discrete_Data_Serial *s)
{
	s->size = 0;
	s->count = 0;
	s->timeout = 0;
	memset(s->data_buff, 0, sizeof(s->data_buff));
}

void dds_initial(struct Discrete_Data_Serial *s, uint32_t timeout_config)
{
	s->timeout_config = timeout_config;

	dds_reset(s);
}

void dds_timer_handle(struct Discrete_Data_Serial *s)
{
	if (s->count > 0) {
		s->timeout++;
	}

	if (s->timeout > s->timeout_config) {
		s->size = s->count;
	}
}

void dds_uart_isr_handle(struct Discrete_Data_Serial *s, uint8_t *src, uint16_t size)
{
	// copy mem
	memcpy(&(s->data_buff[s->count]), src, size);
	s->count += size;

	// reset timer count
	s->timeout = 0;
}

int dds_is_avliable(struct Discrete_Data_Serial *s)
{
	return s->size;
}

void dds_copy(struct Discrete_Data_Serial *s, uint8_t *buff, uint16_t *size)
{
	*size = s->size;
	memcpy(buff, s->data_buff, s->size);
	dds_reset(s);
}

使用方法:

//全局变量
struct Discrete_Data_Serial s1;


//main()开始
dds_initial(&s1, 500);



// main()的死循环里面

		if (dds_is_avliable(&s1)) {
			uint8_t buff[256];
			uint16_t len;
			dds_copy(&s1, buff, &len);

			printf("serial get packet, len:%d\r\n", len);
			for (int i = 0; i < len; i++) {
				printf(" %02X", buff[i]);
			}
			printf("\r\n");
		}




// 1ms的定时器中断里面
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 1 */
	if (htim->Instance == TIM3) {
		app_1ms_tick_handle(&app);
		dds_timer_handle(&s1);
	}
  /* USER CODE END Callback 1 */
}



// 串口中断里面
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if (huart->Instance == USART1) {
		dds_uart_isr_handle(&s1, u1_rx_buff, Size);
		HAL_UARTEx_ReceiveToIdle_IT(&huart1, u1_rx_buff, BUFF_SIZE);
		return;
	} 
}

效果

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值