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

[复制链接]
11641|26
 楼主| 幻阁 发表于 2009-12-24 15:35 | 显示全部楼层 |阅读模式
想把一部分函数封装成lib文件,而lib里又有单片机引脚的定义,怎么做可以让用户随意改变引脚呢?
例如:
sbit _cs=P1^0;
sbit _cs=P1^1;
void lib(void)
{
 _cs=0;
.....
_dat=1;

_cs=1;

}
古道热肠 发表于 2009-12-24 16:14 | 显示全部楼层
是不太好办,俺想到的是将控制管脚电平的部分做成函数,库是中间件。调用底层硬件驱动层实现相应的功能。
因特网用户 发表于 2009-12-24 17:53 | 显示全部楼层
这个问题之前讨论过
因特网用户 发表于 2009-12-24 17:55 | 显示全部楼层
使用回调函数,控制IO引脚的函数指针传给库函数
 楼主| 幻阁 发表于 2009-12-25 10:08 | 显示全部楼层
4# 因特网用户
我看过之前的贴子,只是我在一个lib文件中有N个函数要调用那两个定义的那两个引脚
冷漠 发表于 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

查看全部评分

zhuyulk 发表于 2009-12-25 13:55 | 显示全部楼层
古道热肠 发表于 2009-12-25 15:28 | 显示全部楼层
楼主试试冷漠网友的办法吧。
因特网用户 发表于 2009-12-25 18:20 | 显示全部楼层
你重新生成库当然可以了
问题是如何在不修改库的情况下达到lz的要求
冷漠 发表于 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,拿来分析?有那个本事和时间,早就自己重新做了。
zyok 发表于 2009-12-25 20:41 | 显示全部楼层
学习。。
冷漠 发表于 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 内容重新定位端口地址。
因特网用户 发表于 2009-12-26 11:19 | 显示全部楼层
冷漠看这个帖子
https://bbs.21ic.com/icview-44905-2-1.html
你的方法是不可行的  你试试看吧
上面那个贴子给出了两种方法
1.使用回调函数
2.把端口值赋值给一个变量,lib中对变量进行操作
 楼主| 幻阁 发表于 2009-12-27 14:28 | 显示全部楼层
按冷漠的方法,我试了,不行
在port.h里改端口是不起作用的,说明在生成的lib里端口已被定死了。
可是之前贴子里的方法太不实用了啊
冷漠 发表于 2009-12-27 17:51 | 显示全部楼层
确实不行。没事,挺好的问题,问题即课题,一定有一个简单的方法。以前的贴子2种方法觉得都不规范,只是技巧型;好像“我可以这样,我可以那样。”没有章法。——曹冲10岁知道称象方法,却一辈子都没能想到总结出个“阿基米德浮力定律”。虽然早生了几百年。

有一个标准方法......
 楼主| 幻阁 发表于 2009-12-27 19:05 | 显示全部楼层
最好能有更好的方法,大家探讨
因特网用户 发表于 2009-12-27 19:34 | 显示全部楼层
冷漠研究研究吧
我觉得使用回调函数是比较好的方法
 楼主| 幻阁 发表于 2009-12-27 21:27 | 显示全部楼层
可是回调函数,小弟不是太懂
放眼无尽 发表于 2009-12-27 22:35 | 显示全部楼层
学习。。。
古道热肠 发表于 2009-12-27 23:58 | 显示全部楼层
呵呵,这个与编译器的特性有关,可能大家说的回调函数也就是库中文件调一个底层控制IO层的函数吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

25

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部