搜索
bottom↓
回复: 19

求一份可以用printf这样简洁的函数来进行串口打印ASCII码的...

[复制链接]

出0入0汤圆

发表于 2016-4-8 11:18:40 | 显示全部楼层 |阅读模式
寻求一份可以再AVR单片机上用printf这样简单的函数就能进行ASCII码串口输出的程序。在正点原子的STM32里我看见可以用printf来串口输出,很是方便。在AVR里不知道该怎么弄了,寻求帮助。。。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出10入23汤圆

发表于 2016-4-8 11:19:51 来自手机 | 显示全部楼层
avr gcc可以做到

出0入0汤圆

发表于 2016-4-8 11:23:00 | 显示全部楼层


  1. //初始化串口
  2. static void Uart_Init(void)
  3. {

  4. }

  5. //此函数用于与Print()函数进行接口
  6. static void putch_uart(unsigned char c)
  7. {
  8.         usart_putchar(DEBUG_USART, c);
  9. }

  10. //初始化调试打印接口
  11. void Print_Init(void)
  12. {
  13.         Uart_Init();
  14. }

  15. //#########################################################################
  16. // printf.c
  17. //
  18. // *** printf() based on sprintf() from gcctest9.c Volker Oth
  19. //
  20. // *** Changes made by Holger Klabunde
  21. // Now takes format strings from FLASH (was into RAM ! before)
  22. // Fixed bug for %i, %I. u_val was used before it had the right value
  23. // Added %d, %D (is same as %i, %I)
  24. // Support for long variables %li, %ld, %Lu, %LX ....
  25. // %x, %X now gives upper case hex characters A,B,C,D,E,F
  26. // Output can be redirected in a single function: putch_uart()
  27. // Make printf() smaller by commenting out a few #defines
  28. // Added some SPACE and ZERO padding %02x or % 3u up to 9 characters
  29. //
  30. // Todo:
  31. // %f, %F for floating point numbers
  32. //
  33. // *** Changes made by Martin Thomas for the efsl debug output:
  34. // - removed AVR "progmem"
  35. // - added function pointer for "putchar"// - devopen function
  36. //
  37. //#########################################################################

  38. #include <stdarg.h>
  39. #include <string.h>

  40. #define SCRATCH 12                //32Bits go up to 4GB + 1 Byte for \0

  41. //Spare some program space by making a comment of all not used format flag lines
  42. #define USE_LONG                 // %lx, %Lu and so on, else only 16 bit integer is allowed
  43. #define USE_STRING      // %s, %S Strings as parameters
  44. #define USE_CHAR                // %c, %C Chars as parameters
  45. #define USE_INTEGER                // %i, %I Remove this format flag. %d, %D does the same
  46. #define USE_HEX                        // %x, %X Hexadezimal output
  47. #define USE_UPPERHEX        // %x, %X outputs A,B,C... else a,b,c...
  48. #ifndef USE_HEX
  49. #undef USE_UPPERHEX            // ;)
  50. #endif
  51. #define USE_UPPER                // uncommenting this removes %C,%D,%I,%O,%S,%U,%X and %L..
  52. // only lowercase format flags are used
  53. #define PADDING         //SPACE and ZERO padding

  54. void Print_Function(char const *format, ...)
  55. {
  56.         unsigned char scratch[SCRATCH];
  57.         unsigned char format_flag;
  58.         unsigned short base;
  59.         unsigned char *ptr;
  60.         unsigned char issigned=0;
  61.         va_list ap;

  62. #ifdef USE_LONG
  63.         unsigned char islong=0;
  64.         unsigned long u_val=0;
  65.         long s_val=0;
  66. #else
  67.         unsigned int u_val=0;
  68.         int s_val=0;
  69. #endif

  70.         unsigned char fill;
  71.         unsigned char width;

  72.         va_start (ap, format);
  73.         for (;;)
  74.         {
  75.                 while ((format_flag = *(format++)) != '%'){      // Until '%' or '\0'
  76.                         if (!format_flag){va_end (ap); return;}
  77.                         putch_uart(format_flag);
  78.                 }

  79.                 issigned=0; //default unsigned
  80.                 base = 10;

  81.                 format_flag = *format++; //get char after '%'

  82. #ifdef PADDING
  83.                 width=0; //no formatting
  84.                 fill=0;  //no formatting
  85.                 if(format_flag=='0' || format_flag==' ') //SPACE or ZERO padding  ?
  86.                 {
  87.                         fill=format_flag;
  88.                         format_flag = *format++; //get char after padding char
  89.                         if(format_flag>='0' && format_flag<='9')
  90.                         {
  91.                                 width=format_flag-'0';
  92.                                 format_flag = *format++; //get char after width char
  93.                         }
  94.                 }
  95. #endif

  96. #ifdef USE_LONG
  97.                 islong=0; //default int value
  98. #ifdef USE_UPPER
  99.                 if(format_flag=='l' || format_flag=='L') //Long value
  100. #else
  101.                         if(format_flag=='l') //Long value
  102. #endif
  103.                         {
  104.                                 islong=1;
  105.                                 format_flag = *format++; //get char after 'l' or 'L'
  106.                         }
  107. #endif

  108.                 switch (format_flag)
  109.                 {
  110. #ifdef USE_CHAR
  111.                 case 'c':
  112. #ifdef USE_UPPER
  113.                 case 'C':
  114. #endif
  115.                         format_flag = va_arg(ap,int);
  116.                         // no break -> run into default
  117. #endif

  118.                 default:
  119.                         putch_uart(format_flag);
  120.                         continue;

  121. #ifdef USE_STRING
  122. #ifdef USE_UPPER
  123.                 case 'S':
  124. #endif
  125.                 case 's':
  126.                         ptr = (unsigned char*)va_arg(ap,char *);
  127.                         while(*ptr) { putch_uart(*ptr); ptr++; }
  128.                         continue;
  129. #endif

  130. #ifdef USE_INTEGER //don't use %i, is same as %d
  131.                 case 'i':
  132. #ifdef USE_UPPER
  133.                 case 'I':
  134. #endif
  135. #endif
  136.                 case 'd':
  137. #ifdef USE_UPPER
  138.                 case 'D':
  139. #endif
  140.                         issigned=1;
  141.                         // no break -> run into next case
  142.                 case 'u':
  143. #ifdef USE_UPPER
  144.                 case 'U':
  145. #endif

  146.                         //don't insert some case below this if USE_HEX is undefined !
  147.                         //or put       goto CONVERSION_LOOP;  before next case.
  148. #ifdef USE_HEX
  149.                         goto CONVERSION_LOOP;
  150.                 case 'x':
  151. #ifdef USE_UPPER
  152.                 case 'X':
  153. #endif
  154.                         base = 16;
  155. #endif

  156.                         CONVERSION_LOOP:

  157.                         if(issigned) //Signed types
  158.                         {
  159. #ifdef USE_LONG
  160.                                 if(islong) { s_val = va_arg(ap,long); }
  161.                                 else { s_val = va_arg(ap,int); }
  162. #else
  163.                                 s_val = va_arg(ap,int);
  164. #endif

  165.                                 if(s_val < 0) //Value negativ ?
  166.                                 {
  167.                                         s_val = - s_val; //Make it positiv
  168.                                         putch_uart('-');    //Output sign
  169.                                 }

  170.                                 u_val = (unsigned long)s_val;
  171.                         }
  172.                         else //Unsigned types
  173.                         {
  174. #ifdef USE_LONG
  175.                                 if(islong) { u_val = va_arg(ap,unsigned long); }
  176.                                 else { u_val = va_arg(ap,unsigned int); }
  177. #else
  178.                                 u_val = va_arg(ap,unsigned int);
  179. #endif
  180.                         }

  181.                         ptr = scratch + SCRATCH;
  182.                         *--ptr = 0;
  183.                         do
  184.                         {
  185.                                 char ch = u_val % base + '0';
  186. #ifdef USE_HEX
  187.                                 if (ch > '9')
  188.                                 {
  189.                                         ch += 'a' - '9' - 1;
  190. #ifdef USE_UPPERHEX
  191.                                         ch-=0x20;
  192. #endif
  193.                                 }
  194. #endif
  195.                                 *--ptr = ch;
  196.                                 u_val /= base;

  197. #ifdef PADDING
  198.                                 if(width) width--; //calculate number of padding chars
  199. #endif
  200.                         } while (u_val);

  201. #ifdef PADDING
  202.                         while(width--) *--ptr = fill; //insert padding chars
  203. #endif

  204.                         while(*ptr) { putch_uart(*ptr); ptr++; }
  205.                 }
  206.         }
  207. }
复制代码

出0入0汤圆

发表于 2016-4-8 11:24:08 | 显示全部楼层
本帖最后由 cheungman 于 2016-4-8 11:25 编辑

  1. #define DEBUG_ON

  2. #if defined(DEBUG_ON) || defined(SIMULATOR)
  3. #define Print Print_Function
  4. #else
  5. #define Print(...)
  6. #endif
复制代码

出0入0汤圆

 楼主| 发表于 2016-4-8 11:26:16 | 显示全部楼层

你说的是在ATMEL STDIO编译器里面吗?比如我想输出0x90,对应的值就是144,现在就只用调用这个函数,在里面用个转义符号就可以转成ASCII形式吗?

出0入0汤圆

 楼主| 发表于 2016-4-8 11:27:25 | 显示全部楼层

亲,这个是AVR的吗

出10入23汤圆

发表于 2016-4-8 11:29:35 来自手机 | 显示全部楼层
dragonFANG 发表于 2016-4-8 11:26
你说的是在ATMEL STDIO编译器里面吗?比如我想输出0x90,对应的值就是144,现在就只用调用这个函数,在里 ...

是的,可以做到,晚上回家给你贴代码,手机不方便,需要初始化串口,自定义串口发送字节函数,重定向stdout流
然后就可以使用printf等函数了

出0入0汤圆

 楼主| 发表于 2016-4-8 11:31:03 | 显示全部楼层
zouzhichao 发表于 2016-4-8 11:29
是的,可以做到,晚上回家给你贴代码,手机不方便,需要初始化串口,自定义串口发送字节函数,重定向stdo ...

太感谢了,坐等大神的代码

出10入23汤圆

发表于 2016-4-8 11:32:46 来自手机 | 显示全部楼层
dragonFANG 发表于 2016-4-8 11:31
太感谢了,坐等大神的代码

不谢,给你转个别人的链接吧
http://www.ndiy.cn/thread-17329-1-1.html
如果你测试不行,我再给你发我自己的代码

出0入0汤圆

发表于 2016-4-8 11:34:06 | 显示全部楼层
printf atmel studio自带啊,而且挺大的,lz慎用啊

出0入4汤圆

发表于 2016-4-8 11:58:20 | 显示全部楼层
看一下usart stdio的源码就知道了,给你个我的代码,avr32上了,类似
void usart0Init(usart_serial_options_t *opt)
{
        const gpio_map_t GPIO_MAP =
        {
                { USART_RX_PIN, USART_RX_FUNCTION },
                { USART_TX_PIN, USART_TX_FUNCTION }
        };

        gpio_enable_module( GPIO_MAP, sizeof( GPIO_MAP ) / sizeof( GPIO_MAP[0] ) );

        // Initialize USART
        usart_serial_init(usart, opt);
        /* We're not fully done yet: disable receiver and transmitter. */
        usart->cr |= AVR32_USART_CR_RXDIS_MASK | AVR32_USART_CR_TXDIS_MASK;
        /* Register the USART interrupt handler to the interrupt controller and enable the USART interrupt. */
        INTC_register_interrupt((__int_handler)(usart0ISR), USART_IRQ, AVR32_INTC_INT1);
        /* Enable USART interrupt sources (but not Tx for now)... */
        usart->ier = AVR32_USART_IER_RXRDY_MASK;
        /* Enable receiver and transmitter... */
        usart->cr |= AVR32_USART_CR_TXEN_MASK | AVR32_USART_CR_RXEN_MASK;

下面就是printf要用的
        // stdio setting
        stdio_base = (void *)(usart);
        ptr_put = (int (*)(void volatile*,char))&myusart_serial_putchar;
        ptr_get = (void (*)(void volatile*,char*))&myusart_serial_getchar;
        // Specify that stdin stdout should not be buffered.
        setbuf(stdin, NULL);
        setbuf(stdout, NULL);
}

出0入0汤圆

发表于 2016-4-8 13:54:37 | 显示全部楼层
重定义函数putchar()就好了,然后printf就可以用了。

出0入0汤圆

 楼主| 发表于 2016-4-12 09:47:47 | 显示全部楼层
zouzhichao 发表于 2016-4-8 11:32
不谢,给你转个别人的链接吧
http://www.ndiy.cn/thread-17329-1-1.html
如果你测试不行,我再给你发我自 ...

我按照你提供的网址上的方法试了,不管用。还麻烦大神给我一下您的代码让小弟参考一下。。。谢谢了!!!

出10入23汤圆

发表于 2016-4-12 09:50:53 | 显示全部楼层
dragonFANG 发表于 2016-4-12 09:47
我按照你提供的网址上的方法试了,不管用。还麻烦大神给我一下您的代码让小弟参考一下。。。谢谢了!!! ...

好的,晚上回家给你发

出0入0汤圆

 楼主| 发表于 2016-4-12 12:49:38 | 显示全部楼层
zouzhichao 发表于 2016-4-12 09:50
好的,晚上回家给你发

谢谢。。。

出0入0汤圆

发表于 2016-4-12 13:10:10 | 显示全部楼层
printf重定向到串口

出10入23汤圆

发表于 2016-4-12 21:44:06 | 显示全部楼层
本帖最后由 zouzhichao 于 2016-4-12 21:50 编辑


这个是以前写的,ATmega8

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出10入23汤圆

发表于 2016-4-12 22:05:08 | 显示全部楼层

再上传一个

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出70入0汤圆

发表于 2016-4-12 22:12:55 | 显示全部楼层
根本不需要那么复杂,只需几条语句就实现

static char printf_string[2048]; //可动态申请内存
void YourPrintf(const char *fmt,...)
{
       
    va_list ap;

    va_start(ap,fmt);
    vsprintf(printf_string,fmt,ap);
    while (*printf_string)UART_SendByte(*str++);
    va_end(ap);
}

出0入0汤圆

 楼主| 发表于 2016-4-13 09:16:13 | 显示全部楼层

谢谢啊,虽然有些看不懂,我慢慢领悟吧、、、
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-12 02:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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