51单片机实现scanf和printf函数

发布者:VelvetSoul最新更新时间:2016-05-31 来源: eefocus关键字:51单片机  scanf  printf函数 手机看文章 扫描二维码
随时随地手机看文章
最开始学习C语言时,使用printf和scanf进行格式化输入输出十分方便。

学习单片机有很长时间了,之前要再屏幕上显示一个变量或者通过串口传出一些变量值观测的话,需要进行一系列的取余取整运算,很是麻烦。

最近又研究了一下keil中针对printf和scanf的实现机理,做了一些改动,实现了标准格式化输入输出,共大家参考。

 

1.printf函数在格式化输出时,向下调用了char putchar(char c);这个函数,在“stdio.h”里可以发现有这个函数,所以我们需要自己构造一个这样的函数,即通过串口putchar(),代码如下:

 

char putchar(char c)
{
	hal_uart_putchar(c);
	return c;
}

 

其中hal_uart_putchar(c);函数是我们比较熟悉的了,是51单片机通过串口发送一个字节的函数,具体代码如下:

 

void hal_uart_putchar(char i)
{
	ES = 0;
	TI = 0; //清空发送完中断请求标志位
	SBUF = i;  //将数据放入寄存器发送
	while(TI == 0);//等待发送完毕,发送完毕 TI == 1
	TI = 0; //清空发送完中断请求标志位
	ES = 1;
}

 

有了这两个函数,在单片机启动后,首先进行串口初始化,接着就可以使用printf了……是不是很简单……

-------------------------------------------------------------------------------------------------------------------------------------

2.下面再看scanf的具体实现方法:

scanf函数在格式化输入时,向下掉用了char getkey(void);这个函数,在“stdio.h”里可以发现有这个函数,所以我们需要自己构造一个这样的函数,即通过串口getkey(),代码如下:

 

char _getkey (void)  
{
	return hal_uart_getchar();
}

 

其中hal_uart_getchar(); 稍稍复杂,但也很好理解,代码如下:

 

char hal_uart_getchar(void)
{
	uchar ch;
	//Wait until a character is available:
	while(uart_rx_cnt == 0);
	ES = 0;
	ch = uart_rx[uart_rx_rp];
	uart_rx_rp = (uart_rx_rp + 1) % UART_BUF_SIZE;
	uart_rx_cnt--;
	ES = 1;
	return ch;
}

 

这个函数是从串口接收队列中取出队尾的一个字节。uart_rx_cnt 表示现在串口队列中的已有字节数,uart_rx_rp 指向队尾。

最后要介绍的一个函数是串口接收中断函数,代码如下:

 

void UART1InterruptReceive(void) interrupt 4
{
	ES=0;//关串行口中断
	if(RI)
	{
		RI=0;//接收中断信号清零,表示将继续接收
		if(uart_rx_cnt < UART_BUF_SIZE)
		{
			uart_rx[uart_rx_wp] = SBUF;
			uart_rx_wp = (uart_rx_wp + 1) % UART_BUF_SIZE;
			uart_rx_cnt++;
		}
	} 
	ES=1;//开串行口中断 
}

 

该函数实现了串口的中断接收,收到的新的字节存放在队首,即uart_rx_wp指向队列的首地址,每次收到一个新的字节,uart_rx_cnt增1。

至此,scanf函数也可以实现了。

测试截图:

置顶
        51单片机实现scanf和printf函数
 

注:串口接收的队列没有溢出检测……

这篇文章里实现的是对于串口的格式化输入输出,实际上,我们同样可以对hal_uart_getchar();和hal_uart_putchar(c);函数进行更改,实现在屏幕上的格式化输出等,思路都是一样的……

关键字:51单片机  scanf  printf函数 引用地址:51单片机实现scanf和printf函数

上一篇:#51单片机#8位数码管(74HC595芯片)的使用方法
下一篇:51单片机 EEPROM AT24c02 存储\读取一个字节

推荐阅读最新更新时间:2024-03-16 14:55

60-基于51单片机简易电子琴设计
具体实现功能 系统由STC89C52单片机+数码管+电源电路+音符按键+乐曲切换按键+蜂鸣器构成。 具体功能: 1、数码管显示所按的音符 2、从左到右的按键实现的音符分别是:do、re、mi、fa、so、la、si、do(高音); 3、三个按键可实现三首歌的切换:A是《挥着翅膀的女孩》,B是《同一首歌》,C是《两只蝴蝶》。 设计背景 单片微型计算机是大规模集成电路技术发展的产物,属第四代电子计算机,它具有高性能、高速度、体积小、价格低廉、稳定可靠、应用广泛的特点。它的应用必定导致传统的控制技术从根本上发生变革。因此,单片机的开发应用已成为高科技和工程领域的一项重大课题。 电子琴是现代电子科技与音乐结合的
[单片机]
60-基于<font color='red'>51单片机</font>简易电子琴设计
51单片机学习:静态数码管实验
实验名称:静态数码管实验 接线说明: 实验现象:下载程序后“数码管模块”最左边数码管显示数字0 注意事项: ***************************************************************************************/ #include reg52.h typedef unsigned int u16; //对系统默认数据类型进行重定义 typedef unsigned char u8; #define SMG_A_DP_PORT P0 //使用宏定义数码管段码口 //共阴极数码管显示0~F的段码数据 u8 gsmg_code ={0x3f,0x06,0x5b,0
[单片机]
89C51单片机内部结构深度解析二
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。一个TTL门电流为16mA,当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的低八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。 P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为低八位地址接收。 P2口:P2口为一个内部上拉电阻的8位双向I/O
[单片机]
51单片机入门教程上(保姆级指南)
前言 一、入门学习路线 1.《电路基础》 2.C语言基础 3.单片机基础 4.Altium Designer 二、前期准备工作 1.所需要的软件 (1)Keil 5 (2)STC-ISP (3)Proteus Professional 8 2.所需的硬件 (1)普中A2开发板 (2)其他开发板 正文 一、单片机的最小系统 1.复位电路 2.晶振电路 3.单片机IO口 (1)基本工作条件引脚 (2)输入输出引脚 (3)控制引脚 二、单片机的内部架构 三、单片机可控制的外设 1.LED流水灯 2.矩阵键盘和数码管显示 3.LCD1602和DS18B20 总结 前言 提示:以下是本篇文
[单片机]
<font color='red'>51单片机</font>入门教程上(保姆级指南)
51单片机点亮一盏LED灯的原理解析
首先应该了解51单片机最小系统:51最小系统也称为51最小应用系统,是指用最少的元件组成的51单片机可以工作的系统。如图2.1.1所示,51最小系统一般应该包括:单片机、晶振电路、复位电路。 晶振电路的原理及组成,作用: 在单片机系统里晶振的作用非常大,他结合单片机内部的电路,产生单片机所必须的时钟频率,单片机的一切指令的执行都是建立在这个基础上的,晶振的提供的时钟频率越高,那单片机的运行速度也就越快。简单地说,没有晶振,就没有时钟周期,没有时钟周期,就无法执行程序代码,单片机就无法工作。单片机工作时,是一条一条地从RoM中取指令,然后一步一步地执行。单片机访问一次存储器的时间,称之为一个机器周期,这是一个时间基准。—个机器周
[单片机]
51单片机串行口速率设置
/* 51单片机速率设置公式 波特率=SYSclk/(32*12*(256-TH1) */ #ifndef MONITOR51 SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */ TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */ TH1 = 221; /* TH1: reload value for 1200 baud @ 16MHz */ TR1 = 1; /* TR1: timer 1 run
[单片机]
51单片机外围模块——LCD1602液晶模块
LCD1602简介 1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号的点阵型液晶模块。它是由若干个5x7或者5x10的点阵字符位组成,每个点阵字符位都可以用显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此,所以它不能很好的显示图片。 1602的引脚 操作步骤 初始化(写命令) 写地址 写数据 时序图及时序参数 LCD1602关键性的指令设置 1.清屏指令 功能: 清除液晶显示器,即将 DDRAM 的内容全部填入 空白 的 ASCII码 20H; 光标归位,即将光标撤回液晶显示屏的左上方; 将地址计数器(AC)的值设为 0。 2.进
[单片机]
<font color='red'>51单片机</font>外围模块——LCD1602液晶模块
51单片机之C语言-4.5基本语句之条件选择语句
1. 条件选择语句之if 语句 前面我们讲了数据类型,运算符及表达式。C语言也是一种语言,既然是语言,一定有连接词。这些连接词可以用来表示假设,循环等等。我们先来看看假设if语句。这些连接词有一定的规则,我们只能按照这些规则来编写,否则编译器无法理解,就出错了。 第一种形式为基本形式: if if(表达式)语句 其语义是:如果表达式的值为真,则执行后面的语句,否则不执行该语句。 这个很好理解,if就是 如果 的意思,如果外面下雨,就带雨伞。在这里 外面下雨 ,就是表达式,如果这个表达式是对的,就执行后面的 带雨伞 这个动作。 第二种形式为: if-else if(表达式) 语句1; else 语句2; 其
[单片机]
<font color='red'>51单片机</font>之C语言-4.5基本语句之条件选择语句
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved