打印

keil中生成lib文件的问题 求助

[复制链接]
10243|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
幻阁|  楼主 | 2009-12-24 15:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
古道热肠| | 2009-12-24 16:14 | 只看该作者
是不太好办,俺想到的是将控制管脚电平的部分做成函数,库是中间件。调用底层硬件驱动层实现相应的功能。

使用特权

评论回复
板凳
因特网用户| | 2009-12-24 17:53 | 只看该作者
这个问题之前讨论过

使用特权

评论回复
地板
因特网用户| | 2009-12-24 17:55 | 只看该作者
使用回调函数,控制IO引脚的函数指针传给库函数

使用特权

评论回复
5
幻阁|  楼主 | 2009-12-25 10:08 | 只看该作者
4# 因特网用户
我看过之前的贴子,只是我在一个lib文件中有N个函数要调用那两个定义的那两个引脚

使用特权

评论回复
6
冷漠| | 2009-12-25 11:14 | 只看该作者
本帖最后由 冷漠 于 2009-12-25 13:31 编辑

没那么复杂,很简单的事情。C51,L51早就考虑到了的事:

1、做一个端口头文件PORT.h
内容:PORT.H
/*
Port  Header file for generic 80C51 and 80C31 microcontroller.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/
sbit _cs=P0^7;
sbit _dat=P2^4;  


端口管脚PX^n对库函数来说是可修改的。(不修改就是默认值。)项目中所有模块的 PORT.h 跟着变化! 所以用户可以通过外部文件 PORT.h 修改_cs,_data 管脚。例如修改为:

sbit _cs=P1^2;
sbit _dat=P3^5;  


重新编译、连接,可以看到管脚编译结果跟着改变。

2、所以库函数应写为:
#include <reg51.h>
#include "PORT.h"

void lib( )
{
_cs=0;
//.....
_dat=1;

_cs=1;

}


主函数形式:
#include <reg51.h>
#include "PORT.h"


void  lib( void );  //这个应该在MAIN.h项目头文件里说明。

main()
{
lib( );

}

使用特权

评论回复
评分
参与人数 2威望 +3 收起 理由
lhj200304 + 1
古道热肠 + 2
7
zhuyulk| | 2009-12-25 13:55 | 只看该作者

使用特权

评论回复
8
古道热肠| | 2009-12-25 15:28 | 只看该作者
楼主试试冷漠网友的办法吧。

使用特权

评论回复
9
因特网用户| | 2009-12-25 18:20 | 只看该作者
你重新生成库当然可以了
问题是如何在不修改库的情况下达到lz的要求

使用特权

评论回复
10
冷漠| | 2009-12-25 20:32 | 只看该作者
本帖最后由 冷漠 于 2009-12-25 20:41 编辑

9楼没理解其中道理。LZ交给用户的是固定不变的库文件,例如mylib.LIB。其内容形式为
#include <reg51.h>
#include "PORT.h"

void lib( )
{
_cs=0;
//.....
_dat=1;

_cs=1;

}

LZ交给用户的第2部分软件是主函数main.c。LZ交给用户的最终可执行软件是main.C和mylib.LIB 这两个文件在同一项目中共同编译、连接,生成的可执行文件(例如:main.hex或其它)。这里除了PORT.h以外,所有都是LZ不允许他人修改的。他之所以把自己的所有模块做成库文件,是对自己软件成果的一种保护。根本不可能由其他人重新生成mylib.LIB。
       库文件,他人可以拿来连接到自己的程序中重复使用,——谁要想修改别人库文件,也许你能从库中提出个*.OBJ,拿来分析?有那个本事和时间,早就自己重新做了。

使用特权

评论回复
11
zyok| | 2009-12-25 20:41 | 只看该作者
学习。。

使用特权

评论回复
12
冷漠| | 2009-12-25 21:00 | 只看该作者
本帖最后由 冷漠 于 2009-12-25 22:17 编辑

再谈端口文件的作用。其实6楼说的方法是C语言移植技术所采用的一般方法。——所有C模块都是为了做出来重复使用或者可以移植到其他51内核处理器上重复使用的。如果仅仅因为2个处理器管脚不一致,就使得移植变得非常麻烦,甚至要使用那些很少有人会用的回调函数,那这种编译、连接器就做得太差了。
    其实想象的出,库函数中关于端口部分的代码使用的是端口变量名字标识符 _cs /_dat  而不是固定地址。例如_cs=1;  编译为SETB   _cs 。至于_cs 的地址具体是什么,是由连接 / 定位器最后将所有可重定位的模块按照某种规则计算分配确定的。——不是在库文件中就固定不变的。否则怎么叫可重定位目标文件OBJ?所以,咱们的惯性思维总以为库文件中的OBJ模块是已经编译好的,内容固定不变的,但是忽略了一点:OBJ文件没有经过连接,那么其中的地址内容就是不定的、浮动、可重定位的。而端口地址部分在连接 / 定位的时候,当然就是依据PORT.h 里的用户定义内容确定。当移植库函数的时候,与其他应用程序所使用的新的main.C 再次连接/定位,从库中提出需要的OBJ 模块时,依据新的PORT.h 内容重新定位端口地址。

使用特权

评论回复
13
因特网用户| | 2009-12-26 11:19 | 只看该作者
冷漠看这个帖子
https://bbs.21ic.com/icview-44905-2-1.html
你的方法是不可行的  你试试看吧
上面那个贴子给出了两种方法
1.使用回调函数
2.把端口值赋值给一个变量,lib中对变量进行操作

使用特权

评论回复
14
幻阁|  楼主 | 2009-12-27 14:28 | 只看该作者
按冷漠的方法,我试了,不行
在port.h里改端口是不起作用的,说明在生成的lib里端口已被定死了。
可是之前贴子里的方法太不实用了啊

使用特权

评论回复
15
冷漠| | 2009-12-27 17:51 | 只看该作者
确实不行。没事,挺好的问题,问题即课题,一定有一个简单的方法。以前的贴子2种方法觉得都不规范,只是技巧型;好像“我可以这样,我可以那样。”没有章法。——曹冲10岁知道称象方法,却一辈子都没能想到总结出个“阿基米德浮力定律”。虽然早生了几百年。

有一个标准方法......

使用特权

评论回复
16
幻阁|  楼主 | 2009-12-27 19:05 | 只看该作者
最好能有更好的方法,大家探讨

使用特权

评论回复
17
因特网用户| | 2009-12-27 19:34 | 只看该作者
冷漠研究研究吧
我觉得使用回调函数是比较好的方法

使用特权

评论回复
18
幻阁|  楼主 | 2009-12-27 21:27 | 只看该作者
可是回调函数,小弟不是太懂

使用特权

评论回复
19
放眼无尽| | 2009-12-27 22:35 | 只看该作者
学习。。。

使用特权

评论回复
20
古道热肠| | 2009-12-27 23:58 | 只看该作者
呵呵,这个与编译器的特性有关,可能大家说的回调函数也就是库中文件调一个底层控制IO层的函数吧。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

25

帖子

0

粉丝