我自己起的名字
最近调一个电表, 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;
}
}
效果