嵌入式GNUC环境下自定义printf

GNUC的printf必须使用一个\n,或者使用fflush函数才能将缓冲输出至串口,抑或是等到缓冲区满,一次性将缓冲区内数据全部输出。对于并不习惯Linux编程的人来说,这也是不方便的。因此可以基于sprintf自定义一个“printf”函数,这里我们命名为APP_PRINT,不习惯GNUC的printf的话,可以选择使用这个带参宏。

APP_PRINT的使用方法与printf完全一致。

注意,如果需要打印浮点数的话,需要修改项目环境,默认情况下不支持浮点。

这里以Renesas RA系列单片机为例。stm32的话没差太多。

头文件

#include "hal_data.h"
#include "stdio.h"

#define DEBUG_STR_LEN 0x1000 //缓冲区长度

#if defined __GNUC__ && !defined __clang__ //GNUC环境使用自定义printf
#define APP_PRINT(fn, ...) Debug_UART_print(debug_str,sprintf((char *)debug_str, fn , ##__VA_ARGS__));
extern uint8_t debug_str[DEBUG_STR_LEN];
#else  //标准库环境直接使用printf
#define APP_PRINT(fn, ...) printf(fn, ##__VA_ARGS__);
#endif

void Debug_UART_print(uint8_t *str, int bytes); //自定义的串口打印,配合宏APP_PRINT使用或者直接用都行

void Debug_UART_Init(void); //调用APP_PRINT前记得初始化串口

源文件

//使用GNUC则需要此全局变量,自定义的print需要使用到
#if defined __GNUC__ && !defined __clang__
uint8_t debug_str[DEBUG_STR_LEN];
#endif

static volatile uint8_t uart_send_complete_flag = false; //必须加上volatile,否则可能被编译器优化


/**
 * @brief 串口初始化并开始接收
 * @param 无
 * @return 无
 */
void Debug_UART_Init(void)
{
    R_SCI_UART_Open (&Debug_UART_ctrl, &Debug_UART_cfg); //打开串口
}

/**
 * @brief 串口中断回调函数
 * @param p_args
 */
void Debug_UART_Callback(uart_callback_args_t * p_args)
{
    switch(p_args->event)
    {
        case UART_EVENT_RX_CHAR:  //收到数据后发给上位机
            R_SCI_UART_Write(Debug_UART.p_ctrl, (uint8_t *)&p_args->data, 1);
            break;
        case UART_EVENT_TX_COMPLETE:
            /*发送完成后设置此标志位置1,即可开始下一次printf打印*/
            uart_send_complete_flag = true;
            break;
        default:
            break;
    }
}

/**
 * @brief 因为直接使用printf需要修改C开发环境,需要分配堆,且需要/n或者手动fflush或者等缓冲区满了才会打印,不方便移植,故这里写了个自定义的print
 * @param str 字符串
 * @param bytes 字符串长度
 */
void Debug_UART_print(uint8_t *str, int bytes)
{
    uart_send_complete_flag = false;
    R_SCI_UART_Write(Debug_UART.p_ctrl, str, (uint32_t)bytes);
    while(uart_send_complete_flag == false);
    uart_send_complete_flag = false;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值