freeelectron 发表于 2022-3-4 17:40

【AT-START-F425测评】3、串口接收不定长数据

本帖最后由 freeelectron 于 2022-3-7 09:34 编辑

系列**:
AT-START-F425测评】1、初识AT32F425开发板(开箱)
【AT-START-F425测评】2、非阻塞方式点灯,blink,blink,blink…...

1、硬件连接
本文使用串口1,对应的引脚为PB6和PB7。2、GPIO复用功能可以看出,复用功能为MUX0。3、实现思路
利用串口接收相邻两个字符的时间来判断一串数据是否接收完成,如果超过设定的时间,还没有接收到下一个字符,则认为一串数据接收完成。
如果使用115200波特率,数据长度为8bit,停止位为1bit,那么接收一个字节大约需要,(1/115200)9=0.78ms。
那么就可以利用,接收完一个字符后,如果0.78ms之内没有下一个数据,那么就可以认为一串数据接收完成,考虑到单片机接收数据保存,这里设定超时时间为5ms。4、核心代码
主要是利用串口接收中断和应用层超时。#define UART_MAX_LEN200

struct
{
      uint8_t Timeout;
      uint8_t RecvBuff;
      uint8_t RecvLen;
} SerialStr;


void SerialInit(void)
{
      gpio_init_type gpio_init_struct;

      /* enable the usart1 and gpio clock */
      crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
         crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);

      gpio_default_para_init(&gpio_init_struct);

      /* configure the usart1 tx/rx pin */
      gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
      gpio_init_struct.gpio_out_type= GPIO_OUTPUT_PUSH_PULL;
      gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
      gpio_init_struct.gpio_pins = GPIO_PINS_6 | GPIO_PINS_7;
      gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
      gpio_init(GPIOB, &gpio_init_struct);

      /* config usart1 iomux */
      gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE6, GPIO_MUX_0);
      gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE7, GPIO_MUX_0);

      /* config usart1 nvic interrupt */
      nvic_irq_enable(USART1_IRQn, 3, 0);

      /* configure usart1 param */
      usart_init(USART1, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
      usart_parity_selection_config(USART1, USART_PARITY_NONE);
    usart_hardware_flow_control_set(USART1,USART_HARDWARE_FLOW_NONE);

      usart_transmitter_enable(USART1, TRUE);
      usart_receiver_enable(USART1, TRUE);

      usart_interrupt_enable(USART1, USART_RDBF_INT, TRUE);
      usart_enable(USART1, TRUE);
}


void SerialRecvTimeout(void)
{
      if(SerialStr.Timeout>0)
      {
                SerialStr.Timeout--;
      }
}


void SerialRecv(uint8_t data)
{
      SerialStr.Timeout=5;
      
      if(SerialStr.RecvLen<UART_MAX_LEN)
      {
                SerialStr.RecvBuff=data;
      }
}


void SerialSend(uint8_t *data,uint8_t len)
{
      for(uint8_t i=0; i<len;i++)
      {
                while (RESET == usart_flag_get(USART1, USART_TDC_FLAG));

                usart_data_transmit(USART1, data);
      }
}


void SerialPro(void)
{
      if(!SerialStr.Timeout&&SerialStr.RecvLen)
      {
                printf("Recv:%d,[",SerialStr.RecvLen);
#if 1               
                SerialSend(SerialStr.RecvBuff,SerialStr.RecvLen);
#else
                for(uint8_t i=0;i<SerialStr.RecvLen;i++)
                {
                        printf(" %02d",SerialStr.RecvBuff);
                }
#endif
                printf("]\r\n");

                SerialStr.RecvLen=0;
      }
}


void USART1_IRQHandler(void)
{
      uint16_t ch;
      
      if(usart_flag_get(USART1, USART_RDBF_FLAG) != RESET)
      {
                ch=usart_data_receive(USART1);
                SerialRecv(ch);
    }
}


/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
      while(usart_flag_get(USART1, USART_TDC_FLAG) == RESET);
      usart_data_transmit(USART1, (uint8_t) ch);
      
    return ch;
}
5、现象












freeelectron 发表于 2022-3-4 17:42

好奇怪,编辑的超链接,怎么没有了,@21ic大掌柜
页: [1]
查看完整版本: 【AT-START-F425测评】3、串口接收不定长数据