Mega128使用printf ,scanf

                  Mega128 实现UART1用printf,scanf函数的一点心得及疑问

 编译环境:ICCAVR

  MCU : Mega128

  仿真测试软件: Protues

系统默认的printf函数是基于UART0的。跟踪了ICCAVR的库函数源代码发现,printf函数最终调用的是putchar.

贴出源代码:

 int printf(CONST char *fmt, ...)
 {
 va_list va;
 int val;

 va_start(va, fmt);
 val = _print((void (*)(char))putchar, fmt, va);
 va_end(va);

 return val;
 }

因此只需要重新定义putchar函数就可以把printf函数重定向到UART1,当然最好是可以实现在UART0 和UART1之间根据需要来选择。

贴出我的代码:

char UARTx ; //UART0 or UART1

 

 char  send_byte(char data)
{
  if (UARTx == 0)
    {
      while(!(UCSR0A &(1<<UDRE0)))//waiting for UDR0 empty
            {
         }
      UDR0=data;
      while(!(UCSR0A &(1<<TXC0))) //waiting for sending finish
           {
        
    }
  else if (UARTx == 1)
    {
      while(!(UCSR1A &(1<<UDRE1)))//waiting for UDR1 empty
            {
         }
      UDR1=data;
      while(!(UCSR1A &(1<<TXC1))) //waiting for sending finish
           {
        
    }
 
 else
   {
    return FALSE;
   }
  
   return TRUE ;
       
 
}


int putchar(char c)  
send_byte(c);
}


char UARTx_select(unsigned char ch)
{ if( (0 <= ch) && (ch < 2) )
  {UARTx = ch ;
   return TRUE ;
   }
  else
     return FALSE ;
}

经测试,printf函数在UART0 和UART1都可以正常工作。

测试代码:

void main()
{ int   = 128 ;
  int   -128;
  int   0xfa;
  char  = 'J';
  char  *s = "Hello Jackwen!";
  float PI  = 3.1415926535;
  uart0_init();
  uart1_init();
 
  UARTx_select(0);
  printf("UART0 Test !\r\n");
  printf("a = %d \r\n",a);
  printf("b = %d \r\n",b);
  printf("c = %x \r\n",c);
  printf("d = %sc \r\n",d);
  printf("s = %s \r\n",s);
  printf("PI = %f \r\n",PI);
 
  UARTx_select(1);
  printf("UART1 Test !\r\n");
  printf("a = %d \r\n",a);
  printf("b = %d \r\n",b);
  printf("c = %x \r\n",c);
  printf("d = %sc \r\n",d);
  printf("s = %s \r\n",s);
  printf("PI = %f \r\n",PI);
 
}

运行的结果:

Mega128使用printf <wbr>,scanf

 

同理,将getchar重新定义一下,就可以使用scanf函数了

贴出我的代码:


char receive_byte(void)
{ if(UARTx == UART0)
   {
    while( (!(UCSR0A & (1<<RXC0))) );
    return UDR0;
   }
   else if(UARTx ==UART1) 
     {while( ( !(UCSR1A & (1<<RXC1)) ) ) ;
    return UDR1;
  }
  else
     return FALSE ;
}

 

int getchar(void)  
 
 int res ;
 res = receive_byte();
 return res;
}

关于重新定义的putchar ,getchar函数,个人认为C编译器先判断自定义的函数,然后在调用系统的库函数。也就是说自定义的函数优先级比库函数的优先级高!如果我的理解错误还请高人指点,谢谢!

ICCAVR库函数原型代码下载:http://www.ouravr.com/bbs/bbs_upload565213/files_3/armok0168487.rar

 

 

IAR AVR中如果需要实现上面的功能,就需要设置一下

1.Data stack 的大小,当设置为256时候,才能完全实现打印float.

2.库文件选择可是是DLIB ,也可以是CLIB

3.printf formatter设置为large 或则是 full

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值