历史上的今天
返回首页

历史上的今天

今天是:2024年08月26日(星期一)

正在发生

2021年08月26日 | 51单片机-串口printf系列函数

2021-08-26 来源:eefocus

1.printf系列的函数实现


懂得了单片机通过串口传输数据给电脑端窗口查看,那么,有时我们需要发送字符串,有时需要发送一个变量的数值是多少,以及还要发送回车换行这三种情况。所以我们把这三个功能函数封装起来,方便后续的串口使用。


首先笔者写的“void printf_str(u8 *str)”函数就是专门用来发送字符串给电脑端的。


其次“void printf_num(u32 num)”发送的变量的数值只支持显示十进制数0~4294967295,也就是参数是u32类型。


最后“void printf_rn()”就是发送回车换行符了。


关于这三部分的代码大家可以尝试去阅读一下是怎么实现的,如果有很多地方看不懂那么可以不用深究,往下学,笔者会在后面的知识点中讲解其中的运用。


我们希望串口这部分功能模块也能像定时器那样封装一个单独文件来使用。


所以创建好“uart.c”和“uart.h”文件,复制以下代码


2.uart.c的代码


#include

#include //详见第六章第8讲

   

void ConfigUART(u16 baud)

{

    SCON  = 0x50;  //配置串口为模式1

    TMOD &= 0x0F;  //清零T1的控制位

    TMOD |= 0x20;  //配置T1为模式2

    TH1 = 256 - (11059200/12/32)/baud;//计算T1重载值

    TL1 = TH1;     //初值等于重载值

    ET1 = 0;       //禁止T1中断

    ES  = 1;       //使能串口中断

    TR1 = 1;       //启动T1

    

void printf_str(u8 *str)

    while(*str != '')//连续发送字符串数据,直到检测到结束符

    {

        SBUF=*str++;

        while(!TI);    //等待字节发送完成TI被置1就退出这个while循环

        TI = 0;        //清0标志位

    }  

}

   

void printf_num(u32 num)

{

    u8 buf[10];

    char i;//取值范围为-128~127

    

    for (i=0; i<10; i++)       //把长整型数转换为10位十进制的数组

    {

        buf[i] = num % 10;

        num = num / 10;        //舍掉个位数,重新装载

    }

    

    for (i=9; i>=1; i--)  

    {

        if (buf[i] != 0)break; //从最高位起,遇到0不理会,遇到非0则退出循环

    }

    

    while(i>=0)          //剩余低位都如实发送出去

    {   

        SBUF='0'+buf[i]; //如果此时的buf[i]的值是1,那么电脑端窗口在“字符格式”模式下要想显示字符“1”,只需'0'+1,因为‘0’就是ASCII码值48

        while(!TI);      //等待字节发送完成TI被置1就退出这个while循环

        TI = 0;          //清0标志位

        i--;   

    }

}

   

void printf_rn() //发送回车换行符

{

    SBUF='r';

    while(!TI);  //等待字节发送完成TI被置1就退出这个while循环

    TI = 0;      //清0标志位

    

    SBUF='n';

    while(!TI);  //等待字节发送完成TI被置1就退出这个while循环

    TI = 0;      //清0标志位

}


3.uart.h的代码


#ifndef __UART_H__

#define __UART_H__

   

void ConfigUART(u16 baud);

void printf_str(u8 *str);//发送字符串

void printf_num(u32 num);//发送参数的数值

void printf_rn();        //发送回车换行符

   

#endif


4.main.c的代码


#include  

#include //详见第六章第8讲

#include

 

void main()

{  

    u8 key;

    u32 value=65535;

    LED_Init();//初始化LED硬件模块

    KEY_Init();//初始化按键模块

    EA = 1;    //闭合总中断开关

    ConfigUART(9600);

   

    while(1)

    {  

        key=KEY_Scan(0,1000);

        if(key==4)

        {

            printf_str("value=");//发送字符串

            printf_num(value);   //发送变量的数值

            printf_rn();         //发送回车换行符

            value++;

        }

    } 

}

  

void InterruptUART() interrupt 4

{

    if (RI)    //接收到字节

    {

        RI = 0;//手动清零接收中断标志位                     

    }

}


在串口中断函数中我们没有再写“if(TI){ TI = 0; }”,那是因为我们在所有的发送函数中都做了TI的清0处理,所以可以在串口中断函数中不用再书写TI。


大家别忘了创建好“uart.c”和“uart.h”之后要添加到工程文件中

10.9.png?imageView2/2/w/550


打开串口,选择“字符格式显示”模式,不断按K4,不停打印出如下内容

10.10.png?imageView2/2/w/550

推荐阅读

史海拾趣

Greatbatch-Sierra Inc公司的发展小趣事

机顶盒,全称为数字视频变换盒,是连接电视机与外部信号源的重要设备,其专业性与科普性并重。从广义上讲,机顶盒泛指一切与电视机连接的网络终端设备,能够接收并转换多种信号源,包括有线电缆、卫星天线、宽带网络及地面广播等,为观众提供丰富多样的视听体验。

在数字电视时代,机顶盒扮演了至关重要的角色。它不仅能够接收并解码高清乃至4K超高清的数字电视信号,将其转换为电视机可识别的视频和音频流,还具备网络交互功能,使用户能够享受在线购物、观看网络视频、玩游戏等多元化服务。此外,机顶盒还提供了电子节目指南、因特网网页浏览等增值服务,极大地丰富了用户的娱乐生活。

从技术分类上看,机顶盒可分为多种类型,如DVB-S(数字卫星机顶盒)、DVB-T(数字地面机顶盒)、DVB-C(有线电视数字机顶盒)以及IPTV机顶盒等。每种类型在信号接收和解码方面各有特点,但共同之处在于它们都是连接电视机与外部世界的桥梁,为用户带来更加便捷、丰富的视听享受。

随着智能电视的快速发展,机顶盒的形态也在不断变化。一些智能电视已经内置了机顶盒的功能,实现了电视机与机顶盒的一体化。然而,机顶盒作为独立的设备,在灵活性、扩展性等方面仍具有独特的优势,将继续在数字电视领域发挥重要作用。

E-tec Interconnect Ltd公司的发展小趣事

为了满足全球客户的需求,E-tec开始在全球范围内进行布局。他们在亚洲、欧洲和北美等地设立了生产基地和研发中心,实现了全球范围内的生产和销售。同时,E-tec还注重供应链的整合和优化,与多家原材料供应商建立了长期稳定的合作关系,确保原材料的稳定供应和成本控制。

Altitude Technology公司的发展小趣事

Altitude Technology公司成立于一个科技迅猛发展的时代,创始人李华怀揣着对电子技术的热爱和对未来科技的憧憬,决定创立一家专注于高度集成和智能化电子产品研发的公司。初期,公司面临着资金短缺、人才匮乏等重重困难,但李华凭借对技术的深刻理解和敏锐的市场洞察力,带领团队开发出了一款具有划时代意义的智能手环,这款产品以其出色的性能和人性化的设计迅速在市场上获得了认可,为Altitude Technology公司赢得了第一桶金。

Bergquist Company公司的发展小趣事

在60年代,Bergquist Company作为一家私人拥有的美国公司,在明尼苏达州的一个小城市诞生。创立初期,公司面临着资金短缺、市场竞争激烈等诸多困难。然而,创始人凭借着对导热材料行业的深刻洞察和坚定信念,带领公司一步步走过了创业初期的艰难岁月。他们不断研发新产品,提升产品质量,逐渐在市场上获得了一席之地。

Apacer公司的发展小趣事

除了产品创新,Apacer宇瞻科技还注重为客户提供量身定制的解决方案。在某次客户系统升级中,宇瞻科技的技术团队发现原有SD卡无法满足大量随机小数据的存取应用,甚至可能缩短SSD使用寿命。于是,宇瞻科技建议客户导入Page Mapping技术,并搭配Smart Read Refresh技术的SD卡,成功解决了客户的存储问题。这一技术突破不仅帮助客户实现了系统升级,也为宇瞻科技赢得了更多的信任和赞誉。

Chemtronics公司的发展小趣事

为满足电子行业对无铅应用的需求,Chemtronics专门设计了完整的无铅产品线,并成为业内第一个向市场提供此类产品的公司。这一创新不仅满足了市场对环保和高效产品的需求,也进一步巩固了Chemtronics在电子行业的领先地位。

问答坊 | AI 解惑

关于TI 6000系列DSP优化经验(转帖)

看到网上很多网友对TI 6000系列DSP优化工作感到苦恼,在此我总结下我的优化经验,希望对大家有帮助。 一、首先考虑从系统结构上优化,比如尽量减少待处理数据的无谓搬移,考虑你DSP片内存储量和每次处理数据量对系统结构优化,这部分的优化应该最 ...…

查看全部问答>

【ATMEL技术问题】关于KEIL下AT91R40008启动代码问题

用KEIL 软件建立一个工程,自动生成一个启动代码STartup.S ; 但是问题来了,这个代码有点不知所云,编译出错哦啊,请大侠指点!下面是代码 /*****************************************************************************/;/* STARTUP.S: Start ...…

查看全部问答>

菜鸟提问:SHBrowseForForlder()不能用,怎么代替

我是个初学者,我这个平台不能使用SHBrowseForForlder()这个方法,想找另外一个方法来代替SHBrowseForFolder,达到相同的效果, 或者可以不用打开浏览文件夹着个对话框,直接可以保存文件到指定目录也可以。劳驾各位帮忙啊…

查看全部问答>

求助:蓝牙和WIFI共存的问题

关于BT与WIFI共存时的设计,小弟有些问题,实在是不太明白,请教各位高手。 1. 我在网上看到有人说如果蓝牙和WIFI的物理隔离达到30dB以上,则两者之间的相互影响可以基本忽略。请问如果才能做到物理隔离达到30dB以上呢?是否天线距离远一些就可以 ...…

查看全部问答>

关于pc104总线驱动的制作

小弟刚刚做了一块基于pc104总线的DA板卡,但是现在要与基于pc104总线的3350主板进行交互,主要是对pc104总线的数据进行读取,需要制作驱动,小弟第一次开发,有那位大侠能够给一个例子或其他的资料,多谢…

查看全部问答>

螺纹的检测技术

各位大虾,有什么方法可以检测孔内的螺纹?只要检测孔内是否有螺纹就可以了。…

查看全部问答>

向大家请教一下uc/os-II多任务的运行机制?

有一个如下的uc/os-II源代码,就是采用信号量机制使两个任务共享一个串口com1,去打印一条字符串。 [code] #include \"config.h\" #define        Task0StkLengh        64       ...…

查看全部问答>

【课后练习】LaunchPad课后练习七之定时器

课后练习七之定时器   (定时器看起来简单,却搞了好久,和之前的430定时器不太一样,看了很多次,还有很多没弄出来的地方,有几个地方还是没懂) 1.TIMER_A由以下部分组成 [1] 计数器部分 输入的时钟源具有4种选择,所选择的时钟源又可 ...…

查看全部问答>

4位半的AD达到5位半分辨率的讨论,欢迎跟进一起探讨。

5位半的数字万用表没有一千块RMB是拿不下来的,本帖想讨论能否设计一种廉价的方案实施一个5位半表呢? ICL7135是4位半AD转换器,价格低廉,才4块钱多些,如果采用过采样编程技术,是否可以做出一个5位半分辨率的万用表呢? 欢迎讨论。 如果经研 ...…

查看全部问答>