历史上的今天
返回首页

历史上的今天

今天是:2025年02月18日(星期二)

正在发生

2019年02月18日 | 【单片机笔记】51串口printf的使用和变量循环问题

2019-02-18 来源:eefocus

串口printf的使用


每次在使用到51内核的MCU是总会很头疼,原因有很多,主要的就是仿真,串口打印调试等比较麻烦。但是没办法,这还必须要用到。所以没办法,把之前用过的串口打印程序重新温习了下,用过51和32的朋友一定会发现51简直弱爆了,在串口打印程序上还非常的不方便。以最好用的printf为例子。我今天就把这个函数给写出来了,当然依托了网上的大神们,函数原型如下:


void USART0_Printf(char *fmt,...)//这个是我们的printf函数


{


 char* ap;//typedef char *va_list; va_list是char型的指针


 charxdata string[128];//访问外部RAM 两字节对齐


 va_start(ap,fmt);//这个函数的功能是,找到第一个可变形参的地址,并把地址赋给ap


 vsprintf(string,fmt,ap);//其实这个函数才是核心函数,没研究。。。


 USART0_SendString(string);//这个函数就是发送字符串函数,通过上一个函数,就把该提取的东西都提取了


 va_end(ap);//结束函数


}


这个函数在51调试的时候还是非常好用的,特别是又用串口ISP下载的用户。接下来简述下函数的用法:


1、在编写函数之前,首先需要添加stdarg.h头文件,其中va_start和va_end函数就是这个里面的库。




2、其次就是需要分配一个空间,例如上面的char xdata string[128]; 因为空间有限,我这里给的是外部128字节。打印的长度超出了可能就会出问题了,根据情况,在空间充足的情况下可以分配大一点。




3、编写底层的串口打印字符串函数,在51的程序里我一般写成如下:


//串口0发送一个字节


void USART0_SendByte(u8 value)


{


       SBUF= value;  //发送一个字节                         


       while(!TI);   //等待TI置1              


              TI=0;                                 


}


//串口0发送字符串


void USART0_SendString(u8 *dat)


{


       while(*dat!='\0')


              USART0_SendByte(*dat++);


}


这是串口0的打印函数,如果换成串口1也是一样的。


在使用的过程中需要注意有数据的情况下,数据需要强转成int型不能直接用unsigned char,这个不是我今天所遇到的问题,在上学期间实践过,所以使用的时候我都加了强转,例如:


USART0_Printf("PWR_LEVEL=%d  MOD_LEVEL=%d  FAN_LEVEL=%d TIME_LEVEL=%d FUN_LEVEL=%d\n",


                           (int)PWR_LEVEL,(int)MOD_LEVEL,(int)FAN_LEVEL,(int)TIM_LEVEL,(int)FUN_LEVEL);


 


变量循环问题


在程序编程中往往会遇到一些奇怪的问题,今天调试的MCU就出现了个问题,问题是这样的,一个8位的变量(FAN_LEVEL),当我需要这个变量在1、2、3、4之前循环的时候,一开始没有别的想法直接写上简单的计算公式,如下:


                     FAN_LEVEL++;


                     FAN_LEVEL= FAN_LEVEL%4+1;


这是第一时间想到的方法,但是在调试的时候发现不对,一开始也没有发现,这还能出错吗?调到后面把变量值打出来才发先这个变量确实存在问题,以下是调试的串口打印结果:



很奇怪变量并不是按照设计的循环的,调试了很久,始终找不到问题,但是有一种情况是可以的,如下公式


                     FAN_LEVEL++;


                     FAN_LEVEL= FAN_LEVEL%4;


这样的结果确实是正确的,如下图:



那我就感觉很奇怪了,但是这个0-3循环不是1-4循环,不是想要的结果,到这里看到的朋友都会说再在后面递增一下不久可以了,加上之后的方法:


                     FAN_LEVEL++;


                     FAN_LEVEL= FAN_LEVEL%4;


                     FAN_LEVEL++;


经过实验,很幸运,结果还是错的,跟没有加递增是一样的结果。当然我到现在还是没有找到原因,但是总的结果不能不要啊,最后只能用个很笨的办法了,如下:


推荐阅读

史海拾趣

DUCATI公司的发展小趣事

在电子行业中,DUCATI公司(杜卡迪摩托控股公司)的发展历程尤为独特,它从一个无线电通信技术的研究和生产公司,逐渐发展成为享誉全球的摩托车生产商。以下是五个与DUCATI公司电子行业起源及其后来摩托车业务发展起来的相关故事:

  1. 无线电通信技术的奠基

1926年,DUCATI家族工程师Antonio Cavalieri Ducati与意大利波隆那地区的绅士合作,成立了杜卡迪无线电器材制造公司。公司专注于无线电通信技术的研究和生产,为后来的发展奠定了坚实的基础。尽管当时并未涉足摩托车行业,但这一技术积累为公司带来了重要的经验和资金储备。

  1. 战火中的坚持与转型

第二次世界大战期间,杜卡迪的工厂不幸毁于战火。然而,在战后的废墟中,公司看到了对车辆需求的逐渐增加。不久后,杜卡迪开始踏入其他工业领域,为后来的摩托车业务探索了新的道路。这种逆境中求生存、转型谋发展的精神,是杜卡迪文化中不可或缺的一部分。

  1. Cucciolo引擎的突破

1946年,杜卡迪推出了企业史上的第一具单汽缸引擎Cucciolo。这款引擎由当时的意大利工业振兴协会管理,设计者为都灵的SIATA公司。虽然最初只是装置在脚踏车上的小型引擎,但这一突破性的技术为杜卡迪进入机车制造领域打开了大门。Cucciolo引擎的成功研发,为杜卡迪摩托车部门的成立奠定了基础。

  1. Cruiser机车的问世

1952年,杜卡迪推出了第一部配备电动启动马达和自动变速系统、排气量175cc的机车Cruiser。这款机车标志着杜卡迪正式成为机车制造厂,并为其在摩托车行业的地位奠定了基础。Cruiser的成功问世,进一步巩固了杜卡迪在摩托车市场的地位。

  1. Monster与916的辉煌

进入90年代后,杜卡迪在摩托车设计和技术上取得了重大突破。1993年,阿根廷设计师Miguel Galluzzi设计的Monster为杜卡迪在财务危机的愁云惨雾中找到了曙光。而1994年推出的916更是杜卡迪划时代的革命性作品,这款车型获得了世界经典名车的殊荣。Monster和916的成功设计不仅展现了杜卡迪在摩托车设计上的独特魅力,也为其在全球市场上赢得了广泛的赞誉。

以上五个故事展示了DUCATI公司在电子行业中的起源以及后来摩托车业务的发展过程。这些故事不仅体现了公司的创新精神和技术实力,也展现了其在逆境中求生存、转型谋发展的坚定信念。

埃派克森微电子(Apexone)公司的发展小趣事

埃派克森微电子的创立可追溯到2002年,由高勇回国并带领一支团队创立。作为一家初创公司,埃派克森在创立初期就明确了以模拟系统级芯片为突破口的发展战略。通过不断的研发和创新,埃派克森成功开发了多款具有竞争力的芯片产品,逐渐在亚太与国际市场崭露头角。这一阶段,公司的创新精神和坚持不懈的努力为后来的发展奠定了坚实基础。

台湾稳态公司的发展小趣事

随着企业实力的增强和产品质量的提升,台湾稳态公司开始积极拓展市场。公司不仅在国内市场取得了良好的销售业绩,还积极开拓海外市场,将产品销往全球多个国家和地区。同时,稳态公司还制定了全球化战略,通过与国际知名企业的合作和交流,不断提升自身的国际竞争力。

福建国光公司的发展小趣事

随着企业实力的增强和产品质量的提升,台湾稳态公司开始积极拓展市场。公司不仅在国内市场取得了良好的销售业绩,还积极开拓海外市场,将产品销往全球多个国家和地区。同时,稳态公司还制定了全球化战略,通过与国际知名企业的合作和交流,不断提升自身的国际竞争力。

Adaptive Networks Inc公司的发展小趣事

在电子行业中,品质是企业生存和发展的关键。台湾稳态公司深知这一点,因此从创业之初就坚持品质至上的原则。公司不仅严格把控原材料采购和生产流程,还建立了完善的品质管理体系和售后服务体系。通过不断提升产品品质和服务水平,稳态公司赢得了客户的信赖和口碑,为公司的长远发展奠定了坚实的基础。

粤翔(FlyWin)公司的发展小趣事
明确需要保护的设备和数据的重要性,以及系统对掉电保护的具体要求。

问答坊 | AI 解惑

整理下裁员/倒闭行业类别~有个快消招聘,找工作的来~ 奢侈品行业的情况有谁知道?

最近裁员倒闭的一片片,实在看的太多了,整理下下,有补充的可以跟贴,一并列举上。 也给要找的在找的将要找工作的人一点点参考。 申明: 本来的确打算一直做,因为都是大家提供的消息,但是似乎现在有些不同的“凡响”,我无意争什么,所以, ...…

查看全部问答>

一个学长的感言:转载 从C语言到FPGA高手,我是怎么炼成的

这些日子我一直在写一个实时操作系统内核,已有小成了,等写完我会全部公开,希望能够为 国内IT的发展尽自己一份微薄的力量。最近看到很多学生朋友和我当年一样没有方向 ,所以把我的经历写出来与大家共勉,希望能给刚入行的朋友们一点点帮助。一转 ...…

查看全部问答>

xip变大后下载问题

2440的板1gnandflash 32m sdram xip变大后,从13,531,423 字节到14,145,815 字节 原来的bootloader下载后断电不能自启动 Launch 0x30201000 后就不工作了。 是还需要改bootloader吗?…

查看全部问答>

在移植linux是遇到的问题.大家帮忙看看.

我在把linux的zImage文件和miniroot.cramfs烧进板子后,linux解压出错.错误信息如下: VIVI version 0.1.4 (root@localhost.localdomain) (gcc version 2.95.2 20000516 (re lease) [Rebel.com]) #0.1.4 五 5月 6 16:07:30 CST 2005 MMU table bas ...…

查看全部问答>

汽车电子整车方案

在前面的一个月里,我们一起温习了2008年~2009年上海汽车电子论坛有关技术方面的演讲资料,希望各位网友有所收获。最后一期汽车电子论坛精彩回顾 将与你分享有关零件供应商的演讲资料,了解他们的核心市场及技术优势,这对于研发和采购工程师们来 ...…

查看全部问答>

关于多驱动源的问题

一个FPGA初学者容易出差错的地方:多驱动源的问题 例如: 一个主模块M,这个主模块包含3个子模块,M1,M2,M3。Module M(clk, rst, din, cs, we,dout)   input             clk, rst;  ...…

查看全部问答>

TI LM3S811 DIY之【数控电源】讨论

目标板是基本最小系统+JTAG部分,所以很多部分都要自己动手来完成了!     数控电源人机界面   1、数码管+键盘;  2、LCD+键盘; 3、PC小工具;   预留PWM,ADC,COMP功能的外围脚       [ ...…

查看全部问答>

今天把OK6410超频到了800M,但速度并没有显著提高,请教大神们。

琢磨了半天,把OK6410超频到了800M,主要是修改文件s3c6410.inc和soc_cfg.h OK6410运行正常,跑的还很欢实。 改动如下: Windows CE Kernel for ARM (Thumb Enabled) Built on Sep 25 2009& ...…

查看全部问答>

[已售]20几天前刚买的stm32f103vc火牛开发板 转让

本帖最后由 ddllxxrr 于 2014-12-17 09:00 编辑 9月30日刚在淘宝网上买的,本来是买来做毕业设计的,可是毕业设计换了另一个题目,所以不需要再使用了。原价320 ,现在打9折,真的是全新的,刚买,没用过,光盘,配件,保修单什么的都是全的,可以 ...…

查看全部问答>

有谁能把STM32库函数这三句TIM1_TimeBaseStructInit最基本的通俗解释一下

TIM1_TimeBaseInitTypeDef  TIM1_TimeBaseStructure;TIM1_OCInitTypeDef  TIM1_OCInitStructure;TIM1_BDTRInitTypeDef TIM1_BDTRInitStructure; 我知道是初始化操作  …

查看全部问答>