找回密码
 立即注册
查看: 926|回复: 6

【SDCC】如何使用printf函数发送串口数据

[复制链接]
  • TA的每日心情
    开心
    昨天 10:41
  • 签到天数: 289 天

    [LV.8]以坛为家I

    33

    主题

    158

    回帖

    1921

    积分

    金牌会员

    积分
    1921
    发表于 2024-1-10 01:05:40 | 显示全部楼层 |阅读模式
    本帖最后由 大锤子 于 2024-1-10 01:18 编辑

    背景

    相信大家一定都有使用串口助手通过串口跟单片机交互的经历。在学习瑞生大佬的STC8G学习机的时候,有个例程是使用eeprom来记录最后的按键。然后单片机重新上电后从eeprom中读出,再通过串口发送出去,然后使用串口助手接收。除此之外在很多调试的场景也都可以将关键步骤的信息通过串口发送到串口助手。

    比如这个例子中串口的初始化,和发送数据函数:

    1. void UartInit(void)
    2. {
    3.     SCON = 0x50;                //8位数据,可变波特率
    4.         AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
    5.         AUXR |= 0x04;                //定时器时钟1T模式
    6.         T2L = 0xB4;                        //设置定时初始值
    7.         T2H = 0xFF;                        //设置定时初始值
    8.         AUXR |= 0x10;                //定时器2开始计时
    9. }
    10. void Uart_Send_Byte(unsigned char dat)
    11. {
    12.         SBUF = dat;
    13.         while (!TI);
    14.         TI = 0;
    15.         
    16. }
    复制代码
    SDCC 中使用printf
           在简单的使用场景中可以直接使用上边的简单方法来发送单字节数据。但是如果我们希望发送字符串呢,比如优化成"the last press key is: 03" 再使用这种方式就比较难实现了。 大家肯定也都想得到,可以将printf函数重定向到串口;确实是可以的。而且sdcc 也是支持的。只是有所不同;
           在sdcc用户手册中找到了下边的一段话:

    2024-01-10-00-16-12.png
            意思是说标准库中的getchar和putchar这两个函数再嵌入式开发中需要用户自己来实现,因为SDCC不知道他们具体是通过什么通信的。因此如果我们是通过串口UART通信那就重写它。 下边也给出了示例;

      按照示例程序改写成下边的代码:

    2024-01-10-01-17-23.png

    看效果:

            
           如果到这里就完了其实也没啥,大家大概也是都知道的。当继续看用户手册时,手册给出了一些最佳实践及数据对比,恰好对比使用的MCU是mcs51的:


    2024-01-10-00-37-42.png



            这里强调了几点,printf 在printf_large.c 这个源文件中实现,并且默认是不支持float的。而且printf这个函数占用的存储很大,建议在使用的时候将存储模式设置成model-large。 因此对于存储空间不大,且在应用中对存储较为关注时最好不要使用printf。 而且也提供了更加合适的方法比如:printf_small, 这个函数我已经验证过了这里就不贴代码了。

            下边分别在model-large模式下分别使用printf和prinf_small 编译的结果:


    2024-01-10-00-47-51.png 2024-01-10-00-48-07.png
















    IMG_1982.MP4

    19.43 MB, 下载次数: 60

    不争是争
    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 10:41
  • 签到天数: 289 天

    [LV.8]以坛为家I

    33

    主题

    158

    回帖

    1921

    积分

    金牌会员

    积分
    1921
     楼主| 发表于 2024-1-10 01:19:05 | 显示全部楼层
    哎这个编辑工具啊, 真糟心

    点评

    毕竟是跳出了舒适圈,总得适应适应  发表于 2024-1-10 11:08
    不争是争
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 22:24
  • 签到天数: 204 天

    [LV.7]常住居民III

    3

    主题

    233

    回帖

    674

    积分

    高级会员

    积分
    674
    发表于 2024-1-10 20:47:52 | 显示全部楼层
    SDCC用过一段时间,和keil比还是差很多。完整的printf比keil效率、代码体积差得远。不过float计算的精度比keil高。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 10:41
  • 签到天数: 289 天

    [LV.8]以坛为家I

    33

    主题

    158

    回帖

    1921

    积分

    金牌会员

    积分
    1921
     楼主| 发表于 2024-1-10 21:11:17 | 显示全部楼层
    Snapdragon 发表于 2024-1-10 20:47
    SDCC用过一段时间,和keil比还是差很多。完整的printf比keil效率、代码体积差得远。不过float计算的精度比k ...

    不争是争
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    4 天前
  • 签到天数: 185 天

    [LV.7]常住居民III

    10

    主题

    51

    回帖

    1000

    积分

    金牌会员

    积分
    1000
    发表于 2024-5-4 10:59:57 | 显示全部楼层
    如果用串口2,串口3,如何用printf
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 10:41
  • 签到天数: 289 天

    [LV.8]以坛为家I

    33

    主题

    158

    回帖

    1921

    积分

    金牌会员

    积分
    1921
     楼主| 发表于 2024-5-4 13:28:58 | 显示全部楼层
    清风迎明月 发表于 2024-5-4 10:59
    如果用串口2,串口3,如何用printf

    类似的重写putchar函数, ti和buff 改成串口2,3对应的寄存器就可以了。
    不争是争
    回复 支持 1 反对 0 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-11-1 06:59 , Processed in 0.093947 second(s), 63 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表