dengxm2009 发表于 2012-6-19 11:41:11

C8051f中用keil编程,printf()这个函数是不是直接向串口输?

C8051f中用keil编程,printf()这个函数是不是直接向串口输出字符串?用这个函数时,输出的是哪个串口(我用的C8051f023有两个串口)?用这个函数时,串口是否要初始化?初始化时主要设置哪几个参数?

techbaby 发表于 2012-6-19 11:52:18

要学会查找keil帮助文件!


int printf (
const char *fmtstr       /* format string */
<[>, arguments ... <]>);   /* additional arguments */

The printf function formats a series of strings and numeric values and builds a string to write to the output stream using the putchar function. The fmtstr argument is a format string that may be composed of characters, escape sequences, and format specifications.

在keil安装文件目录\C51\LIB中,找到PUTCHAR.C文件,将其包含进工程文件中,并修改。

/*
* putchar (full version):expands '\n' into CR LF and handles
*                        XON/XOFF (Ctrl+S/Ctrl+Q) protocol
*/
char putchar (char c){

if (c == '\n'){
    if (RI){
      if (SBUF == XOFF){
      do{
          RI = 0;
          while (!RI);
      }
      while (SBUF != XON);
      RI = 0;
      }
    }
    while (!TI);
    TI = 0;
    SBUF = 0x0d;                         /* output CR*/
}
if (RI){
    if (SBUF == XOFF){
      do{
      RI = 0;
      while (!RI);
      }
      while (SBUF != XON);
      RI = 0;
    }
}
while (!TI);
TI = 0;
return (SBUF = c);
}


上面的寄存器明显不是C8051串口的寄存器,需要修改。


techbaby 发表于 2012-6-19 11:54:00

使用printf之前,要先配置串口的,如波特率,数据格式等。

lingergz 发表于 2012-6-26 17:52:08

楼上写的很仔细...赞一个

yuanpooo 发表于 2012-6-26 18:00:45

以前还真没注意到....

dengxm2009 发表于 2012-6-26 20:13:02

看了一下,有点收获。

beihai326 发表于 2013-7-5 11:27:19

{:lol:}{:lol:}{:lol:}{:lol:}

tigeroser 发表于 2014-5-27 21:39:46

techbaby 发表于 2012-6-19 11:52
要学会查找keil帮助文件!




还是有些不懂,再此请教一下:
首先我确定printf是通过操作SBUF来实现的,
keil中stdio.h中有函数extern int printf   (const char *, ...);说明printf是外部的函数,怎么找到它的函数体,虽然它是通过putchar()实现的。

2-------putchar.c文件中有3个一样的函数体char putchar (char c) {},那printf是怎么区分调用这些函数的


还有一问题就是putchar.c中定义的
#define XON0x11
#define XOFF 0x13
代表什么意思


以上的问题让我觉得关于标准C语言的用法,还是什么也不会。。。。


希望能指点一下!

techbaby 发表于 2014-5-27 22:09:31

printf()是库函数,你是找不到他的函数体的,有的只是一个原型声明。

你将putchar()函数的实现包含在自己的源程序中,这样编译器会优先使用你改写的putchar()函数,而不会去使用其他地方的putchar()函数。

XON、XOFF是流控制字符,你可以查一下ASCII码表,其实这两个宏定义的值就是退格和回车,只是接收到这两个字符做一下特殊处理而已

techbaby 发表于 2014-5-27 22:14:06


以前项目中使用的代码,MCU貌似是C8051F520A

/*
***************************************************************************************************
*
*                                           上海有限公司
*                                              研    发    部
*                                    ShanghaiCo.,Ltd
*                                           All Rights Reserved
*
*------------------------------------------------文件信息------------------------------------------
* 文   件        名:        uart0.c
* 版                本:        v0.0
* 日                期:        2012.06.06
* 作      者:
* 描                述:        uart0串口通信
***************************************************************************************************
*/

/*
***************************************************************************************************
*                                        include files
***************************************************************************************************
*/
// #pragma src
#include "cpu.h"
#include "uart0.h"
#include "flash.h"
#include "adc0.h"

/*
***************************************************************************************************
*                                       predefinition
***************************************************************************************************
*/
/*
***************************************************************************************************
*                                 constants &macros & variables
***************************************************************************************************
*/
#define BAUDRATE    (9600)        // Baud rate of UART in bps

FRAME frame;

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//-----------------------------------------------------------------------------
static void _UART0_Init (void)
{
   SCON0 = 0x10;         // SCON0: 8-bit variable bit rate
                        //      level of STOP bit is ignored
                            //      RX enabled
                          //      ninth bits are zeros
                          //      clear RI0 and TI0 bits
#if (SYSCLK/BAUDRATE/2/256 < 1)
        TH1 = -(SYSCLK/BAUDRATE/2);
        CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
        CKCON |=0x08;
#elif (SYSCLK/BAUDRATE/2/256 < 4)
        TH1 = -(SYSCLK/BAUDRATE/2/4);
        CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
        CKCON |=0x01;
#elif (SYSCLK/BAUDRATE/2/256 < 12)
        TH1 = -(SYSCLK/BAUDRATE/2/12);
        CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
#else
        TH1 = -(SYSCLK/BAUDRATE/2/48);
        CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
        CKCON |=0x02;
#endif

   TL1 = TH1;                          // Init Timer1
   TMOD &= ~0xf0;                   // TMOD: timer 1 in 8-bit autoreload
   TMOD |=0x20;
   TR1 = 1;                              // START Timer1
   TI0 = 1;                                // Indicate TX0 ready

        ET1= 1;                         // Timer1 interrupt enabled
       
//    ES0 = 1;                               // Enable UART0 interrupt
}

/*
***************************************************************************************************
* 函数名称: uart0_init()
* 输 入:
* 输 出:
* 作 者:
* 日 期: 2012.06.15
* 功能描述: uart0 init
***************************************************************************************************
*/
void uart0_init(void)
{
        _UART0_Init();
        frame.flag = FALSE;
}

/*
* putchar (basic version): expands '\n' into CR LF
*/
char putchar (char c)
{
        if (c == '\n')
        {
            while (!TI0);
            TI0 = 0;
            SBUF0 = 0x0d;         /* output CR*/
        }

        while (!TI0);

        TI0 = 0;
        return (SBUF0 = c);
}

/*
***************************************************************************************************
* 函数名称: uart0_init()
* 输 入:
* 输 出:
* 作 者:
* 日 期: 2012.06.15
* 功能描述: uart0 init
***************************************************************************************************
*/
void frame_scan(void)
{
        if (frame.flag == TRUE)
        {
                if ((FRAME_START == frame.buf)         /* 帧开始 */
               && (FRAME_STOP == frame.buf))        /* 帧结束 */
                {
                        if (FRAME_TYPE_V == frame.buf)        /* 帧类型:电压V */
                        {
                                if (FRAME_TYPE_INC == frame.buf)        /* 修改类型:增加 */
                                {
                                        flash_change(TYPE_VOLTAGE, flash_voltage_value + ADC_VOLTAGE_MAX/2500);
                                        printf("SV+P\r\n");
                                }
                                else if (FRAME_TYPE_DEC == frame.buf)         /* 修改类型:减少 */
                                {
                                        flash_change(TYPE_VOLTAGE, flash_voltage_value - ADC_VOLTAGE_MAX/2500);       
                                        printf("SV-P\r\n");
                                }
                        }
                        else if (FRAME_TYPE_I == frame.buf)        /* 帧类型:电流I */
                        {
                                if (FRAME_TYPE_INC == frame.buf)        /* 修改类型:增加 */
                                {
                                        flash_change(TYPE_CURRENT, flash_current_value + 2);
                                        printf("SI+P\r\n");
                                }
                                else if (FRAME_TYPE_DEC == frame.buf)         /* 修改类型:减少 */
                                {
                                        flash_change(TYPE_CURRENT, flash_current_value - 2);
                                        printf("SI-P\r\n");
                                }
                        }       
                }
               
                frame.flag = FALSE;
        }
}

/*
***************************************************************************************************
* 函数名称: uart0_init()
* 输 入:
* 输 出:
* 作 者:
* 日 期: 2012.06.15
* 功能描述: uart0 init
***************************************************************************************************
*/
// static void uart0_isr(void) interrupt INTERRUPT_UART0
// {
//         static bool flag = FALSE;
//         static int8u cnt;

//         if (RI0)
//         {
//                 if (frame.flag == FALSE)
//                 {
//                         if (flag == TRUE)
//                         {
//                                 frame.buf = SBUF0;

//                                 if (cnt > FRAME_BUF_MAX - 1)
//                                 {
//                                         cnt = 0;
//                                         frame.flag = TRUE;       
//                                         flag = FALSE;
//                                 }
//                         }
//                         else
//                         {
//                                 frame.buf = SBUF0;
//                                
//                                 if (FRAME_START == frame.buf)
//                                 {
//                                         cnt = 1;
//                                         flag = TRUE;
//                                 }               
//                         }       
//                 }                       
//         }
//        
//         RI0 = 0;
//         TI0 = 0;       
// }

tigeroser 发表于 2014-5-27 22:37:03

techbaby 发表于 2014-5-27 22:09
printf()是库函数,你是找不到他的函数体的,有的只是一个原型声明。

你将putchar()函数的实现包含在自 ...

懂了一步,但是putchar.c中的3个程序是一样的(我没看错吧)它是怎么有区分的调用的,这些和流控制、计算机语言之类的有关吧
要关门了,明天研究一下

tigeroser 发表于 2014-5-28 08:17:03

techbaby 发表于 2014-5-27 22:14
以前项目中使用的代码,MCU貌似是C8051F520A

近楼主的意思
这段程序中的Putchar();用的应该是keil目录下的库函数,这样printf就直接用程序中的putchar();了

流控制是通信协议,协调速率匹配问题。。。。。。这些东西属于计算机的知识吧,不容易真正理解

煮酒fu 发表于 2014-6-5 20:21:44

techbaby 发表于 2012-6-19 11:52
要学会查找keil帮助文件!




学习了。
页: [1]
查看完整版本: C8051f中用keil编程,printf()这个函数是不是直接向串口输?