aple0807 发表于 2022-3-16 09:07

【GD32L233C-START评测】串口打印

<p><br />
虽然IDE自带printf函数可以用于打印,但只能支持单个串口,且在keil中需要microlib支持,microlib做了高度优化,但重入特性被阉割,在RTOS中使用可能存在问题。下面介绍一种自定义打印的方法,可以支持任意串口,且无需microlib。</p>

<p>&nbsp;</p>

<p>底层还是要实现串口收发,串口底层采用缓冲的方式,可以最大程度的减少程序阻塞,提高运行效率。打印函数打印数据时不直接输出到硬件,而是写入到环形缓冲区,然后通过中断将缓冲区数据发送到端口。</p>

<p>&nbsp;</p>

<p>打印函数封装方法如下:</p>

<pre>
<code>
#define PT_NEW_LINE         0      //0-n , 1-\r\n , 2-\n\r
#define com_port com.obj00

/*******************************************************************************
* @brief __sys_put_ch
* \param none
* \retval: none
*******************************************************************************/
void __sys_put_ch(char ch)
{
#if PT_NEW_LINE == 0
    com_port.fun-&gt;cycle_snd_byte(ch);
#elif PT_NEW_LINE == 1
    if (ch != '\n')
    {
      com_port.fun-&gt;cycle_snd_byte(ch);
    }
    else
    {
      com_port.fun-&gt;cycle_snd_byte('\r');
      com_port.fun-&gt;cycle_snd_byte('\n');
    }
#elif PT_NEW_LINE == 2
    if(ch != '\n')
    {
      com_port.fun-&gt;cycle_snd_byte(ch);
    }
    else
    {
      com_port.fun-&gt;cycle_snd_byte('\n');
      com_port.fun-&gt;cycle_snd_byte('\r');
    }
#endif
}

/*******************************************************************************
* @briefsys_hw_console_output
* \param str : string to print
* \retval: none
*******************************************************************************/
void sys_hw_console_output(const char *str)
{
    /* empty console output */
    while (*str)
    {
      __sys_put_ch(*str++);
    }
}

/*******************************************************************************
* @briefsys_hw_puts
* \paramstr : string to print
* \retval: none
*******************************************************************************/
void sys_hw_puts(const char *str)
{
        osMutexWait(os_obj.mid_printf, 1000);
       
    sys_hw_console_output(str);
       
        osMutexRelease(os_obj.mid_printf);
}

/*******************************************************************************
* @briefsys_hw_printf
* \param fmt: format var like printf
* \retval: none
*******************************************************************************/
static charbuf_str;
void sys_hw_printf(char* fmt, ...)
{
    va_list   v_args;

        osMutexWait(os_obj.mid_printf, 1000);
       
    va_start(v_args, fmt);
   (void)vsnprintf((char       *)        &amp;buf_str,
                   (size_t      )        sizeof(buf_str)-5,
                   (char const *)        fmt,
                                         v_args);
    va_end(v_args);
   
    sys_hw_console_output(buf_str);
       
        osMutexRelease(os_obj.mid_printf);
}
</code></pre>

<p>重映射</p>

<pre>
<code>#if DBG_EN &gt; 0
#define dbg_print sys_hw_printf
#define dbg_puts sys_hw_puts
#define dbg_notice gui_notice
#define dbg_u8_print mem_u8_disp
#define dbg_u16_print mem_u16_disp
#define dbg_u32_print mem_u32_disp
#else
#define dbg_print(...)
#define dbg_puts(...)
#define dbg_notice(...)
#define dbg_u8_print(...)
#define dbg_u16_print(...)
#define dbg_u32_print(...)
#endif
</code></pre>

<p>应用示例</p>

<pre>
<code>void task_system(const void *argument)
{
        printf("::start --------------------------------------\n");
       
        while (1)
        {
                sys_st.u_tick = app_tick_get();
                pulse_create(&amp;sys_st.pulse, sys_st.u_tick);
               
                sys_led_ctr();
               
                // 按键采集
                sys_st.key.st.pulse_sample = 1;
                sys_st.key.st.pulse_time = sys_st.pulse.bPulse_100ms;
                io_flt_ext(&amp;sys_st.key, 3, key.in_st());
               
                // 按键动作
                if(sys_st.key.st.edge_found)
                {
                        dbg_print("key press down ! \n");
                }
                if(sys_st.key.st.edge_lost)
                {
                        dbg_print("key release! \n");
                }
               
      osDelay(5);
        }
}
</code></pre>

<p>结果</p>

<p></p>

<p>附上测试工程:</p>

<p></p>
页: [1]
查看完整版本: 【GD32L233C-START评测】串口打印