FR801xH串口接收方式-硬件定时器超时判断断帧



  • 为了判断串口接收的数据的断帧,最佳方式就是硬件定时器,刚好串口接收的时候也是要运行CPU,硬件定时器也需要运行CPU,我们就适应硬件定时器超时5ms没有数据来表示这报数据接收完成

    #include "driver_timer.h"
    #include "driver_gpio.h"
    #define UART_LEN_MAX 512 // 接收最大buf
    #define TIMEOUT_RX_MS 5 // 接收超时5M

    volatile uint8_t uart_recving_buffer[UART_LEN_MAX] = {0};
    volatile uint16_t timer_rx_flag = 0,index_uart0 = 0;

    volatile uint32_t add_up=0;

    void timer_demo(void)
    {
    co_printf("%s\r\n",func);

    system_set_port_mux(GPIO_PORT_A, 	GPIO_BIT_7, PORTA7_FUNC_A7);
    gpio_set_dir(GPIO_PORT_A, GPIO_BIT_7, GPIO_DIR_OUT);
    gpio_set_pin_value(GPIO_PORT_A,GPIO_BIT_7,0);
    
    system_set_port_mux(GPIO_PORT_A, 	GPIO_BIT_6, PORTA7_FUNC_A7);
    gpio_set_dir(GPIO_PORT_A, GPIO_BIT_6, GPIO_DIR_OUT);
    gpio_set_pin_value(GPIO_PORT_A,GPIO_BIT_6,0);
    
    
    timer_init(TIMER0,1000,TIMER_PERIODIC);
    timer_run(TIMER0);
    
    
    NVIC_SetPriority(TIMER0_IRQn, 2);
    NVIC_EnableIRQ(TIMER0_IRQn);
    

    }

    static uint8_t timer_flag=0, timer_flag1=0;
    /************************************************************************************

    • @fn timer0_handler

    • @brief timer0 interrupt handler
      */
      attribute((section("ram_code"))) void timer0_isr_ram(void)
      {
      timer_clear_interrupt(TIMER0);
      #if 0
      if(timer_rx_flag==1)
      {
      add_up++;

      if(add_up >= TIMEOUT_RX_MS)
      {
      	
      	at_spss_send_data(gAT_ctrl_env.transparent_conidx, uart_recving_buffer, index_uart0);
      	timer_rx_flag = 0;
      	index_uart0 = 0;
      	add_up = 0;
      }
      

      }
      #endif
      #if 1
      timer_flag1=!timer_flag1;
      gpio_set_pin_value(GPIO_PORT_A,GPIO_BIT_6, timer_flag);
      if(timer_rx_flag >= 1)
      {
      timer_rx_flag++;

      	if(timer_rx_flag >= TIMEOUT_RX_MS)
      	{
      

    // pmu_set_gpio_value(GPIO_PORT_A, BIT(6),0);
    at_spss_send_data(0, (uint8_t*)uart_recving_buffer, index_uart0);
    // co_printf("index_uart0:%d \r\n",index_uart0);
    timer_rx_flag = 0;
    index_uart0 = 0;
    }

    	}
    

    #endif
    // co_printf("timer0 count:%d \r\n", lu32_Count++);
    // pmu_set_gpio_value(GPIO_PORT_D, BIT(6),0);

    }

    /*********************************************************************

    • @fn uart0_isr_ram

    • @brief UART0 interruption, when uart0 FIFO received charaters, this ISR will be called

    • @param None

    • @return None
      */
      attribute((section("ram_code"))) void uart0_isr_ram(void)
      {
      uint8_t int_id;
      volatile struct uart_reg_t * const uart_reg_ram = (volatile struct uart_reg_t *)UART0_BASE;
      int_id = uart_reg_ram->u3.iir.int_id;

      if(int_id == 0x04 || int_id == 0x0c ) /* Receiver data available or Character time-out indication */
      {
      while(uart_reg_ram->lsr & 0x01)
      {
      uart_recving_buffer[index_uart0] = uart_reg_ram->u1.data;
      // co_printf("%x ",uart_recving_buffer[index_uart0]);
      timer_flag=!timer_flag;
      index_uart0++;
      timer_rx_flag=1;
      add_up = 1;
      gpio_set_pin_value(GPIO_PORT_A,GPIO_BIT_7, timer_flag);
      // app_at_recv_c(uart_reg_ram->u1.data);
      }
      }
      else if(int_id == 0x06)
      {
      uart_reg_ram->lsr = uart_reg_ram->lsr;
      uart_reg_ram->u3.iir.int_id = int_id;
      uart_reg_ram->u2.ier.erlsi = 0;
      }
      }

    void uart0_init(void)
    {
    system_set_port_pull(GPIO_PD4, true);
    system_set_port_mux(GPIO_PORT_D, GPIO_BIT_4, PORTD4_FUNC_UART0_RXD);
    system_set_port_mux(GPIO_PORT_D, GPIO_BIT_5, PORTD5_FUNC_UART0_TXD);
    //uart_init(UART0, find_uart_idx_from_baudrate(gAT_buff_env.uart_param.baud_rate));
    uart_param_t param =
    {
    .baud_rate = 921600,
    .data_bit_num = 8,
    .pari = 0,
    .stop_bit = 1,
    };
    uart_init1(UART0,param);
    NVIC_EnableIRQ(UART0_IRQn);
    NVIC_SetPriority(UART0_IRQn, 3);
    timer_demo();
    }



  • @mars 有疑问的同学,我知道的可以向你解答