8571|26

7815

帖子

57

TA的资源

裸片初长成(中级)

楼主
 

一步一步完善LC测量小工具(即日起,持续更新) [复制链接]

这个帖子发好后,那个 后传即被删除,因为我不喜欢重复,但是因为耽搁时间久了,我也没办法修改题目,为了让大家伙知道这个帖子还在”成长中“,我决定移一个新帖,一个更简洁的新帖。

闲话少说,为了激励一下自己,首先把目前的 丑态 摆上来......
首先是图片:




此帖出自51单片机论坛

最新回复

贴程序。。。。总感觉误差有点大,而且更让人蛋疼的是我还不知道。。哈哈 #include #define uchar unsigned char #define uint unsigned int #define ulong unsigned long #define c2 1000 sbit bep=P3^7;     //蜂鸣器 sbit rel=P3^2;           //继电器 sbit chk=P3^3;           //测试按钮 sbit c_l=P3^4;           //c_l测试切换 sbit frq=P3^5;           //T1计数输入 ulong f1=0; ulong f2=0; ulong cnt_t0=0; ulong cnt_t1=0; uint ge,shi,bai,qian,wan,shiwan; ulong c1; ulong l1; code uchar table[]={0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x3f}; //延时函数 void delay(uint z) {         uint x,y;         for(x=z;x>0;x--)                 for(y=110;y>0;y--); } //led初始化函数 void init_led() {         P2=0;         P0=0;         delay(5); } //定时器计数器初始化函数 void init_inter() {         TMOD=0X51;     //定时器0工作方式1;计时器1工作方式1         TH0=-(50000/256);         TL0=-(50000%256);         TH1=0;         TL1=0;         TR0=1;         TR1=1;         ET0=1;         ET1=1;         delay(5); } //数码管计算 void calc_smg(uint f) {         shiwan=f/100000;         wan=f%100000/10000;         qian=f%100000/1000;         bai=f%1000/100;         shi=f%100/10;         ge=f%10; } //显示函数 void disp(uint ge,uint shi,uint bai,uint qian,uint wan,uint shiwan) {         P0=0X01;         P2=table[shiwan];         delay(5);         P0=0X02;         P2=table[wan];         delay(5);         P0=0X04;         P2=table[qian];         delay(5);         P0=0X08;         P2=table[bai];         delay(5);         P0=0X10;         P2=table[shi];         delay(5);         P0=0X20;         P2=table[ge];         delay(5); } //测量电路频率(采用一秒定时法) ulong freq() {         ulong f;         EA=1;         while(cnt_t0  详情 回复 发表于 2011-10-16 23:22
点赞 关注
个人签名

强者为尊,弱者,死无葬身之地

 

回复
举报

7815

帖子

57

TA的资源

裸片初长成(中级)

沙发
 

当前的问题,不仅是丑那么简单

当时它的不足之处表现在:
软件方面:
1 尚未能修改到适用于不同型号51芯片;(2011.08.08已解决)
2 原作者最终生成的可以在2K的2051上跑,我生成的HEX却将近4K。

硬件方面:
1 说它丑,那是因为没有规划好接口——假如非要采取两部分分开的话,当然,也完全可以考虑做到一体;
2 这个新做的单片机系统,可能是接触或者什么地方考虑不周,1602的显示情况非常不稳定,基本认为是硬件问题,而非软件问题,因为在开发板上很正常。
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

板凳
 

Step1:让它能在任何51上跑(新版本程序见附件)

把所有包含STC头文件换成标准的REG52以后,编译出了问题。
分析了一下:
LCD1602.h这个头文件,严格来说不是真正的头文件,因为它里面包含了几个函数定义,这是因为对于Keil还是不会多源文件的编译方法。
这里,包含了两个头文件,
一个是intrins.h这是标准头文件,没影响,所以问题出在那个Delay_12M.h上。
但实际上,这个头文件并没有使用任何与STC有关的特殊包含和定义

到底怎么回事呢?如果我早点仔细分析错误信息,而不是瞎猜那可能早发现了:
太脑残了,太脑残了,我居然一直没发现
sbit LCD_RW = P0^6;
sbit LCD_EN = P0^5;

位定义本该这么写,可是在原来的程序里,对方却是这样写的。
#define LCD_EN P0^5
更改好后,编译通过了。

昨天编译好后还有一些其他的问题,不过其实是同一个问题,所以,这一步完成了!

Next Step:向缩小HEX大小迈进,关于这一点,本来没什么信心,多亏xuchanghua老师在 后传 里的怀疑和他给我的短消息建议:
不要把单片机当成PC用。
少用函数调用
合适选择数据类型。

下一步,我将采取他的建议,从反汇编的手段去实际看看这些带来了多大的CODE空间浪费。

[ 本帖最后由 辛昕 于 2011-8-8 15:00 编辑 ]

适用任何51版本.rar

37.48 KB, 下载次数: 33

此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

1469

帖子

0

TA的资源

五彩晶圆(中级)

4
 
嘿嘿,来给老大顶一下
话说辛昕有时间了啊,又把这个捡起来了,倒是我彻底的忙疯了....

不过有一点不太明白,那个位定义的地方两种方法应该是一样的吧,我一直是用的define,网上也说两种方法是一样的
从原理上分析也都没问题啊,一个是把地址赋给变量,一个是直接把字符替换成地址,都说得通啊...
此帖出自51单片机论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

5
 

回复 4楼 anqi90 的帖子

完全不一样啊!!
#Define那货,绝对不是叫 位定义!!
那个#define是预定义,确切的说,它就是翻译,直接把一句话一个表达式直接替换。
你说对了,本来也没什么问题,问题就出在,KEIL的汇编器对于P1.1口只认P1^1这样的写法(当然,这是标准的写法),很可惜的是,当我们真这样写的时候,编译就会出问题.......你可以试试,你在C代码里直接这么写看会不会错,至于它为什么会错,我没仔细追究过。不过从我最近看的书来猜,我猜测是 在 KEIL的语法分析器里,没有 “P1^1”这种模式的语句?它存在的意义是直接借由位定义在反汇编时,对应回汇编里的写法而已。
那为啥,STC的片子里这么写就没问题呢?
很简单,答案在STC的头文件里,因为它已经把P10这样写法的IO口 位定义了。
里头有N多这样的语句:
sbit P11 = P1^1
ps:我是极不喜欢这种写法的,理由之一正是这个帖子引发的故事。
不通用。

而sbit它是一个位定义关键字,当然是绝对不会有问题。

同样的道理,很多地方#define都被滥用了,这点需要小心

PS:俺不是有时间了,俺是这些天看书看腻了。

[ 本帖最后由 辛昕 于 2011-8-9 09:31 编辑 ]
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

6
 

更合理的组织项目文件

这个修改版本采用了更合理更一般的组织方式。
把一些外设比如1602的子函数做成一个单独的源程序,与原来极不规范的声明定义都放在头文件里相比,算是一个规范化吧。
名字也修改了,主源程序叫main.c而不是原来的1602.c(这是因为最开始我是在anqi90给我的1602函数的基础上一点一点增加修改出来的。所以保留了这个名字)

由于我自己开始使用KEIL 4,为了大家都能打开。
压缩包里包含了两个文件夹,一个是KEIL 4的,一个是KEIL 2的,这样, KEIL2 3 4都能打开了。

//--------------------------------------------------------------------------------------------------
说起来,在上班搞STM32以前,从来没试过多个源文件在一个项目文件里——那时候甚至没有这个概念。
上班以后,用IAR的时候,很惊奇,咦?为什么不用我设置,它自己好想知道多个源文件之间怎么链接似的?
但是当时我以为KEIL不能这样——也许是因为在不太懂声明的时候,试过一次结果失败了,很是费劲,所以也没有往下仔细看。
做LC测量小工具的时候,anqi90和我谈过这事,我很遗憾的说,额,我也不会耶,于是我们俩就决定用一种很不规范的方法,把定义和声明都放在头文件里。

这两天,本来一直想想办法参照xu_changhua大叔说的,把程序改小,但一直没成功。
倒是51放下一阵子过后。重新捡起来,又折腾了一会KEIL。
现在换用了KEIL 4.
忽然想试一下,结果发现,嗨,它就是自动的,不需要设置。
这样,就把程序项目文件修改好了,按照更合理的组织方式。

声明在相应的头文件里,定义在相应的源文件里里。
只有一个主函数,在主源程序里。
很感慨的一点是:很多东西我们开始可能不懂所以做不成功,但不意味着一定做不了,所以我们要时不时回头再试试。

[ 本帖最后由 辛昕 于 2011-8-10 16:04 编辑 ]

LC_meter(更合理的组织方式).rar

98.77 KB, 下载次数: 30

此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

547

帖子

0

TA的资源

纯净的硅(初级)

7
 
 谢谢楼猪
此帖出自51单片机论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

8
 

发一份统计:对于如何缩小HEX代码,感觉束手无策

首先我决定对子函数进行分析。
在Debug状态下,点开SourceWindow,可以查看所有子函数的使用次数——严格来说是子函数名字字样出现次数,但这里,我们可以变通得到其使用次数。
同时,我们计算出它们在反汇编中占用的ROM空间长度,换算成十进制

函数名        占用空间(B)        使用次数
test                                          39               1
calculate                           17                1
transfer                                   128        1
Get_Frequency                    73        3
Key_Div                                   168        4
Show_float                           205        2
Lcd_Ini                                    60        1
Lcd_Clear_Line                    31        11
Lcd_Write_String            96        15
Lcd_Write_Command    18        3
Lcd_Write_Command_Nocheck        15        1
Lcd_Write_Data                    21        1
Lcd_Check_Busy            43        2
Delay_s                                     33        1
Delay_um                              7        1
Delay_ms                              23        9

同时,我又做了一个实验,得到一个这样的事实:
就是说一个函数被多次调用,在反汇编里,只是在调用处引用一个LCALL指令,而函数的实现只有一次。

基于这样一个事实,我们往下分析:
首先,说说我为什么做这样一个实验。
因为我看到1602部分的函数个数较多,而且从名字看,容易让人猜测很多是类似的。

观察1602的函数,的确可以发现,只有两个函数的使用次数较多,而且差别很大,绝大多数函数使用次数只有1次,而另两个也不过是两次和三次。
这说明,这里有好几个函数(定义)很浪费。
但是,正如我先前去掉两个从未被使用过的1602函数一样,由于这些函数本身占用的ROM空间也不大,因此,对于节省ROM空间,意义不大。
就算我们能费尽心思,这5个函数总共也就150B左右。
怎么省撑死也就剩下150B,意义不大。
事实上,修改了函数,合并的一个方法把同类型函数增加一个参数来改变功能,先不说这过程带来多余的反汇编代码,也可能会让RAM增加,不划算。

所以说,真正能带来显著性变化的部分还是在我后来自己增加上去的那几个主源程序里的子函数。

回想起来,我最初抱着“引用的少的函数尽量不写成函数”的想法,于是我直接把test等的实现扔进代码里,但是效果不明显,如今看来是可以理解的,因为它总共才39B啊,而且只用了一次,就那么一次。

我试过把Key_Div这个函数一次一次地往引用的地方复制,结果引发编译不通过,我猜测这是由于中间产生的变量过多造成的,这个问题下一个阶段再分析。

现在我引出一个新问题:
单从反汇编出来的代码考虑。
假如一个代码段被多次引用,写成函数被调用相比于直接把实现写在代码里,是不是更加节省ROM空间?

以transfer为例,我试图把他变成转换int类型的,其实变化不大
从128变到108

现在,试一下,运算带来的差异。
实际上也不大。
只是从208下降到180多

这个变化很少,跟我想象的变化相差太远。
也许,实际改变以后,情形会有更大变化?只是有我所不熟悉的部分?

就算我们把所有涉及运算的全部关掉,那也才不到1K啊。
难道真的是此路不通?
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

1469

帖子

0

TA的资源

五彩晶圆(中级)

9
 
如果真的想大幅度减少代码体积的话,感觉还是得直接上汇编,而且这个工程不算很复杂,除了中间计算的部分汇编不是很容易实现
有时候很简单的一个语句C语言会绕很大一圈,而且汇编的话估计RAM占用也会少一点
此帖出自51单片机论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

10
 

回复 9楼 anqi90 的帖子

假如是这样,那我会就此停步。
因为拿汇编换体积,不是我的本意。
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

21

帖子

0

TA的资源

一粒金砂(中级)

11
 

也发个我做好的(数码管版)

 

STC89C52 + 74HC04 + LM311P

 

 

 

因为只有6位数码管,所以电容只能测到1U以内,结果还是很满意的。至于测电感有些偏小。

 

[ 本帖最后由 卫星狂 于 2011-8-26 21:46 编辑 ]
此帖出自51单片机论坛

赞赏

1

查看全部赞赏

 
 
 

回复

30

帖子

0

TA的资源

一粒金砂(中级)

12
 
楼上板子布局挺好,还用上古董电容,很不一般哦,可否分享下程序。
此帖出自51单片机论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

13
 

回复 11楼 卫星狂 的帖子

如果可以的话,希望你能分享一下你的源程序哦
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

14
 

说说我的进展

前阵子,折腾程序,后来除了把它的文件组织改得规范一些以外,最初欲减小HEX的体积,无果。

然后拖了好一阵子,这阵子,开始做板子。

为了避免之前的遗憾,即使是在洞洞板上焊接,我也依然先在PROTEL上画图,考虑一下如何布局。
这一次,做出来的板子,倒真的是看起来顺眼很多。

之所以没有 很兴奋的说,完成了!!

是因为,很可惜,东西做出来了,却没能正常工作。

单片机和LCD1602部分,没太大问题。

从程序看,它卡在测量频率的哪一个子程序哪里,是压根没往下进行,而不是出错。
(有一次无意万用表笔触及3脚的什么地方的时候,忽然看到显示500HZ,心想这肯定是无意起振了。于是确定,问题出在没起振。)

折腾了一个多小时,后来发现,是LM311的测量电路部分,根本没起振。
表现为,用万用表测 电压,居然可以看到变化——正常情况下可以看到才怪,几百K的方波,能看到的应该是二分之一电源电压,也就是2.5V左右。

但是,仔细检查了线路,一再检查了两三次,连接没错。
还换了一个LM311。
还是没有找到问题。

于是只好先放下。
回想此前的乱折腾,这次一定不会再乱来,瞎折腾的。
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

15
 
今天上班,搞定了做了两三天的一个活——其实这东西不复杂,只是我在理解上有较大偏差,所以走了很多弯路。
然后解决一个中断的串口也挺简单。

这个LC到了这一步可以歇歇了,虽然我也不知道到底怎么解决这次突然冒出来的不起振的问题......

水浒看到了82集,方腊打了两集了,琼英给张清娶了......
突然不知道干嘛好。
稍微整理了一下上星期焊这个板子,但觉得尽是些废话,还是写了,大家忍不住要扔鸡蛋的话,请不要挑臭的扔,最多我给钱你买

作伴字的时候,经常有些要查的东西老忘,幸好可以上网,不过呢,只要保存下来,就不用那么费劲了。
比如说LCD1602的引脚图,还有51的引脚图。
不知为什么,我对51内部的寄存器和指令记得还挺熟的,反倒那简简单单的几组管脚,我总是记不得。

还有一件事情,这次倒是记得,不过上次做毕业设计的时候——是帮人做的那个,可把我害得够惨
就是老忘记P0口是需要外部上拉的——其实那次也不是我忘了。而是STC的,从来就没说它不是,我以为它是——不过想想,谁让我程序不把它拉高捏?
额,当时我好像就是忘了吧,因为我想起来了,当时我用的其实是AT,我只是一时忘了。

//==========================================
看了看一张电路图,上面写了一行字,提醒自己,当时忽然想到。
之前那个东东,频率计老乱跳乱闪,显示乱码,我想这跟我没有锁住LCD1602有关,我应该等到它转换成功数值以后就锁了——很可惜,这次没啥机会试验一下了。因为压根就没测频。

有点可惜和教训的是,其实我不该把之前的版本,我是说那个电路给拆了,不然我至少可以试试。

[ 本帖最后由 辛昕 于 2011-9-26 19:56 编辑 ]
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

4008

帖子

0

TA的资源

版主

16
 

回复 15楼 辛昕 的帖子

我觉得你要想办法去除浮点运算才有可能缩小到2K
此帖出自51单片机论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

17
 

回复 16楼 huo_hu 的帖子

其实浮点运算带来的影响并没有想象的那么大。
也就200B左右。
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

4008

帖子

0

TA的资源

版主

18
 

回复 17楼 辛昕 的帖子

有原理图吗?我也做一个,以前写的1602库可以用上

定时器测频率那里用中断好些吧

[ 本帖最后由 huo_hu 于 2011-9-28 11:15 编辑 ]
此帖出自51单片机论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

19
 

回复 18楼 huo_hu 的帖子

俺就是这么干的。
你等等。我找找
https://bbs.eeworld.com.cn/thread-248597-1-1.html
这是我们活动的第一个规整帖,主题就是那个LM311测量电路。原理图就在里面,至于1602和单片机的是常规的,你的话不说应该也知道。
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

4008

帖子

0

TA的资源

版主

20
 

回复 19楼 辛昕 的帖子

测频率为什么不用计数方式呢?
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表