背景
有个项目使用需要使用库,将代码封装起来,仅仅留下调试接口,给用户使用,调试一些参数。这样工程看起来更简单,也方便客户维护。
也有一些使用场景,需要把自己的代码封装起来,这个是怕被别人窃取,自己的功夫白费了,也可以提供库的形式。
当然也有如下场景
当公司或者个人需要提供自己的编写的代码供他人调用时,而你或提供方并不想提供源代码(.c源代码),只想提供头文件.h(在头文件中申明函数)供他人调用,他人在调用时只需要知道调用的函数功能是什么,传递的参数是什么等,无需了解函数是怎样具体实现的。 此时就需要静态链接库(当然还有动态链接库,这里先讲解静态链接库的生成和使用)
关键步骤
实际使用效果
我这里提供的例程是使用STC(宏晶)的单片机实现stc15w404as
这也是客户选的,原理给出来,只需要负责代码实现即可。
最终的实际库函数调用为234.LIB
这里正常添加 234.LIB ,使用的函数在头文件如下
代码,头文件中告诉客户,哪些参数是可以调整的,其他是不能动的
对于客户来说就简单了,只需要了解这个头文件相关的几个宏定义即可。
/******************************************************************************
* 文件名称: stc15w404as.h
* 功能描述: stc15w404as补充寄存器头文件
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其它说明:
* 修改日期 版本号 修改人 修改内容
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 2013/02/22 V1.0.0.0
******************************************************************************/
#ifndef STC15W404AS_H
#define STC15W404AS_H
#include <reg51.h>
#include "intrins.h"
/*
*
* 请不要修改以下内容,多谢!!!
*
*
*/
#define FOSC 33177600L
/* STC15W404AS寄存器补充 */
sfr AUXR1 = 0XA2;
sfr AUXR = 0X8E;
sfr TH2 = 0XD6;
sfr TL2 = 0XD7;
sfr P4 = 0xc0;
sfr P5 = 0xc8;
sfr SPSTAT = 0xCD; //
sfr SPCTL = 0xCE; //
sfr SPDAT = 0xCF; //
/*************************/
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define uchar unsigned char
#define uint unsigned int
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
sfr P4M1 = 0xB3;
sfr P4M0 = 0xB4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
//sbit led_1 = P1^2;
//sbit led_11 = P3^2;
//sbit led_12 = P3^3;
//sbit led_13 = P3^6;
sbit led_14 = P3^6; /* 红灯 */
sbit led_13 = P3^7; /* 绿灯 */
sbit led_2 = P1^3;
sbit key_1 = P1^2;
#define STEP_1_TOLG 5 /* 5 * 50 = 250ms */
#define STEP_2_TOLG 10 /* 10 * 50 = 500ms */
#define STEP_3_TOLG 20 /* 20 * 50 = 1000ms */
#define STEP_4_TOLG 10 /* 10 * 50 = 500ms */
#define STEP_5_TOLG 20 /* 20 * 50 = 1000ms */
#define STEP_1_MAX_TIME 14400 /* 14400 * 250ms = 1 hour*/
#define STEP_2_MAX_TIME 36000 /* 36000 * 500ms = 5 hour*/
#define STEP_3_MAX_TIME 10800 /* 10800 * 1000ms = 3 hour*/
#define STEP_4_MAX_TIME 14400 /* 14400 * 500ms = 2 hour*/
#define STEP_5_MAX_TIME 7200 /* 7200 * 1000ms = 2 hour*/
#define STEP_1_JUMP_VOLTAGE 102 /* 2V */
#define STEP_2_JUMP_VOLTAGE 189 /* 3.7V */
#define STEP_3_JUMP_VOLTAGE 26 /* 0.5V */
#define STEP_JUMP_ABNORMAL 20 /* 0.4V */
#define NO_KEY_DOWN 0x00
#define KEY_9_DOWN 0x01
#define KEY_10_DOWN 0x02
#define KEY_9_10_DOWN 0x03
sbit key_9 = P3^0;
sbit key_10 = P3^1;
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC高8位结果
sfr ADC_LOW2 = 0xBE; //ADC低2位结果
sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540个时钟
#define ADC_SPEEDL 0x20 //360个时钟
#define ADC_SPEEDH 0x40 //180个时钟
#define ADC_SPEEDHH 0x60 //90个时钟
//sfr AUXR1 = 0XA2;
sfr CCON = 0XD8;
sfr CMOD = 0XD9;
sfr CCAPM0 = 0XDA;
sfr CCAPM1 = 0XDB;
sfr CCAPM2 = 0XDC;
sfr CL = 0xE9;
sfr CCAP0L = 0xEA;
sfr CCAP1L = 0xEB;
sfr CCAP2L = 0xEC;
sfr CH = 0xF9;
sfr CCAP0H = 0xFA;
sfr CCAP1H = 0xFB;
sfr CCAP2H = 0xFC;
sbit CF = CCON^7;
sbit CR = CCON^6;
sbit CCF2 = CCON^2;
sbit CCF1 = CCON^1;
sbit CCF0 = CCON^0;
sbit PPCA = IP^7;
sfr CMPCR1 = 0XE6;
sfr CMPCR2 = 0XE7;
//sfr AUXR = 0X8E;
//sfr TH2 = 0XD6;
//sfr TL2 = 0XD7;
//sfr P4 = 0xc0;
//sfr P5 = 0xc8;
sfr PCA_PWM0 = 0XF2;
sfr PCA_PWM1 = 0XF3;
sfr PCA_PWM2 = 0XF4;
//sfr P1ASF = 0X9D;
//sfr ADC_CONTR = 0XBC;
//sfr PCON2 = 0X97;
//
//sfr SPSTAT = 0xCD; //
//sfr SPCTL = 0xCE; //
//sfr SPDAT = 0xCF; //
//sbit ADD = P1^2;
//sbit DEL = P5^5;
//sbit PWM2_L = P3^2;
//sbit PWM1_L = P3^3;
//sbit PWM0_L = P3^6;
extern void delay_ms(unsigned int ms);
//extern void Delay50ms(void);
extern unsigned char ReadKey(void);
extern void InitADC();
extern BYTE GetADCResult(BYTE ch);
extern void serial_open(void);
extern void senddata(uchar data_buf);
extern void pwm_init(void);
extern void set_pin16_pwm_value(unsigned char pwm_value);
extern void set_pin15_pwm_value(unsigned char pwm_value);
extern void timer0_init();
//-----------------------------------------------
sfr IAP_DATA = 0xC2; //IAP数据寄存器
sfr IAP_ADDRH = 0xC3; //IAP地址寄存器高字节
sfr IAP_ADDRL = 0xC4; //IAP地址寄存器低字节
sfr IAP_CMD = 0xC5; //IAP命令寄存器
sfr IAP_TRIG = 0xC6; //IAP命令触发寄存器
sfr IAP_CONTR = 0xC7; //IAP控制寄存器
#define CMD_IDLE 0 //空闲模式
#define CMD_READ 1 //IAP字节读命令
#define CMD_PROGRAM 2 //IAP字节编程命令
#define CMD_ERASE 3 //IAP扇区擦除命令
//#define ENABLE_IAP 0x80 //if SYSCLK<30MHz
//#define ENABLE_IAP 0x81 //if SYSCLK<24MHz
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
//#define ENABLE_IAP 0x83 //if SYSCLK<12MHz
//#define ENABLE_IAP 0x84 //if SYSCLK<6MHz
//#define ENABLE_IAP 0x85 //if SYSCLK<3MHz
//#define ENABLE_IAP 0x86 //if SYSCLK<2MHz
//#define ENABLE_IAP 0x87 //if SYSCLK<1MHz
//测试地址
//#define IAP_ADDRESS 0x0400
#define IAP_ADDRESS 0x0000
extern void Delay(BYTE n);
extern void IapIdle();
extern BYTE IapReadByte(WORD addr);
extern void IapProgramByte(WORD addr, BYTE dat);
extern void IapEraseSector(WORD addr);
//extern void eeprom_tst_main(void);
uchar eeprom_save_para(uchar *pscr, uchar len);
uchar eeprom_read_para(uchar *pdst, uchar len);
#define V_SIG_VALUE_30V 77 /* 30v == 1.5v == 76 changeVlotVal[0]*/
#define V_SIG_VALUE_60V 153 /* 60v == 3v == 153 changeVlotVal[1]*/
#define V_SIG_VALUE_70V 179 /* 70v == 3.5v == 179 changeVlotVal[2]*/
#define V_SIG_VALUE_74V 189 /* 74v == 3.7v == 189 changeVlotVal[3]*/
#define V_SIG_VALUE_76V 194 /* 76v == 3.8v == 194 changeVlotVal[4]*/
#define V_SIG_VALUE_80V 204 /* 80v == 4v == 204 changeVlotVal[5]*/
#define A_SIG_VALUE_0A 3 /* 0.225A == 0.06v == 3*/
#define V_SIG_VALUE_30V_0025 (478 / 1000) /* changeVlotVal[0]*/
#define V_SIG_VALUE_60V_0025 (956 / 1000) /* changeVlotVal[1]*/
#define V_SIG_VALUE_70V_0025 (1116 / 1000) /* changeVlotVal[2]*/
#define V_SIG_VALUE_74V_0025 (1179 / 1000) /* changeVlotVal[3]*/
#define V_SIG_VALUE_76V_0025 (1211 / 1000) /* changeVlotVal[4]*/
#define V_SIG_VALUE_80V_0025 (1275 / 1000) /* changeVlotVal[5]*/
//void getTableDat(unsigned char index);
//void getTableDatInit(unsigned char index);
void getTableDat0025(unsigned char index);
void getTableDatInit0025(unsigned char index);
#define EEPROM_SAVE_DAT_LEN 2
void mainBody(void);
void timerBody(void);
extern unsigned int g_stepTime1;
extern unsigned int g_stepTime2;
extern unsigned int g_stepTime3;
extern unsigned int g_stepTime4;
extern unsigned char g_stepCurrent1;
extern unsigned char g_stepCurrent2;
extern unsigned char g_stepCurrent3;
extern unsigned char g_step3JumpCurrent;
extern unsigned char g_stepCurrent4;
#endif
库的工程如下图所示
把使用数据都打包到库函数中
编译后的结果如下图所示,这里可以看到,成功编译234.LIB
"eeprom.obj",
"keyscan.obj",
"mainBody.obj",
"pwm.obj",
"timer.obj",
"vlottable.obj"
TO "234.LIB"
LIB51 LIBRARY MANAGER V4.24
COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 2002
"234.LIB" - 0 Error(s), 0 Warning(s).
关键配置如下图所示: