如何将.a文件如何将c语言程序导入单片机机中?

C51强大功能及其高效率的重要体现之一在于其丰富的可直接调用的库函数,多使用库函数使程序代码简单,结构清晰,易于调试和维护,下面介绍C51的库函数系统。

C51提供的本征函数是指编译时直接将固定的代码插入当前行,而不是用ACALL和LCALL语句来实现,这样就大大提供了函数访问的效率,而非本征函数则必须由ACALL及LCALL调用。C51的本征库函数只有9个,数目虽少,但都很是有用,列以下:_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回_iror_,_irol_:将int型变量循环向左(右)移动指定位数后返回_lrol_,_lror_:将long型变量循环向左(右)移动指定位数后返回_nop_:      至关于插入NOP_testbit_: 至关于JBC bitvar测试该位变量并跳转同时清除。_chkfloat_: 测试并返回源点数状态。使用时,必须包含#inclucle 一行。如不说明,下面谈到的库函数均指非本征库函数。

第二节 几类重要库函数

例如803一、8051均为REG51.h其中包括了全部8051的SFR及其位定义,通常系统都必须包括本文件。

该文件中实际只定义了几个宏,以肯定各存储空间的绝对地址。

3. 动态内存分配函数,位于stdlib.h中

4. 缓冲区处理函数位于“string.h”中

5. 输入输出流函数,位于“stdio.h”中

流函数通8051的串口或用户定义的I/O口读写数据,缺省为8051串口,如要修改,好比改成LCD显示,可修改lib目录中的getkey.c及putchar.c源文件,而后在库中替换它们便可。

第三节 Keil C51库函数原型列表

如程序有误修改源代码后没必要再translate或link了,只要一步Amake便可。若project中包括不止一个文件,在DOS的Ishell中不能用Translate编译,而应创建bat文件,直接在命令窗编译,而后link链接。如还需用Translate则只能多个文件分别编译,而后链接。

    C51程序编译生成汇编代码的效率,是由许多因素共同决定的,对于Keil C51,主要受如下两种因素影响:

第一节 存储模式的影响

    存储模式决定了缺省变量的存储空间,而访问各空间变量的汇编代码的繁简程度决定了代码率的高低。例如:一个整形变量i,如放于内存18H、19H空间,则++i的操做编译成四条语句:INC 0x19MOV A,0x19JNZ 0x272DINC 0x180x272D:而若是放于外存空间0000H、0001H则++i的操做编译成九条语句:MOV DPTR,A就汇编以后的语句而言,对外部存储器的操做较内部存储器操做代码率要低得多,生成的语句为内存的两倍以上,而程序中有大量的这种操做,可见存储模式对代码率的响了。所以程序设计的原则是一、存储模式从small-Compact-large依次选择,实在是变量太多,才选large模式。二、即便选择了large模式,对一些经常使用的局部的或者可放于内存中的变量,最好放于内存中,以尽可能提升程序的代码率。

第二节 程序结构的影响

程序的结构单元包括模块、函数等等。一样的功能,若是结构越复杂,其所涉及的操做、变量、功能模块函数等就越多,较之结构性好,代码简单的程序其代码率天然就低得多。此外程序的运行控制语句,也是影响代码率的关键因素,例如:switch -case语句,许多编译器都把它们译得很是复杂,Keil C51也不例外,相对较为简易的Switch-case语句,编译成跳转指令形式,代码率较高,但对较为复杂的Switch-Case,则要调用一个系统库函数?C?ICASE进行处理,很是复杂。再如if( ),while( ),等语句也是代码相对较低的语句,但编译之后比switch-case要高得多。所以建议设计者尽可能少用switch-case之类语句来控制程序结构,以提升代码率。除以上两点外,其它因素也会对代码率产生影响,例如:是否用寄存器传递参数 即NOAREGS选项是否有是否包括调试信息:即DEBUG选项是否包括扩展的调试信息:即BJECTEXTEND

可设置其它各类调试窗口,设置断点、观察点,修改地址空间,加载文件等等;

支持用户程序的各类显示方式,可连续运行,单步运行用户程序,并可在线 汇编;

可设置所要观察的变量、表达式等;

显示内部寄存器的内容,程序运行次数等;

显示串口接收和发送的数据;

显示所要观察的各程序段占用CPU的空间;

显示所选择的内存中的数据;

显示各类符号名称,包括专有符号,用户自定义符号(函数名、变量、标号)等;

动态显示当前执行的程序段的函数调用关系;

提供当前模块内各程序段中被执行代码的比率;。

可显示I/O口,定时器,中断,串口等外围设备状态;

5. 中断处理程序调试

Serial:串口中断状态设置相应的中断请求标志位便可产生中断。

PA用来分析一段代码执行占用CPU的百分比。定义:命令行 PA func_name

dScope除了用命令行的方式进行调试之外,还可将各类调试命令聚集于一个调试文件中,而后调用该文件,就可达到自动测试用户源代码的目的。dScope的命令文件支持C/PL/M的格式,于是编制调试命令文件与编制C语言程序有些相似。

1. 地址空间及地址空间类型

C:代码空间D:内部直接寻址空间I: 内部间接寻址空间X:外部数据空间B:位寻址空间P:I/O口EB:扩展的位寻址空间(MCS251专有)ED:扩展的数据空间(MCS251专有)CO:常数空间(MCS251专有)HC:正常数空间(MCS251专有)

dScope支持十六进制、八进制、十进制、二进制常数,其后缀分别为H、Q(O)、T(或无)、Y;dScope不区分常量的大、小写。

分为整型(int),无符号整型(uint,00rd),长整型(long),无符号长整型(Wlong、Word)。

分为字符型(Char)和无符号字符型(Uchar)一种。

指用户程序中的行号,其实是个地址

地址常数的种类不少,地址常数不一样于行号常数,行号常数就是一个地址,而地址数被引用时,其实是取该地址中的数据。C:代码地址常数,如C:0X0012或0XFF:0X0012D:内部直接寻址地址常数,如D:0X0068或0X00:0X0068I:内部间按寻址地址常数,如I:0X0010或0X00:0X0010X:外部数据空间地址常数,如X:0X0028或0X01:0X0028B:位地址常数,如B:0X20或B:0X24.0EB:扩展的位地址常数(MCS251专有), ED:扩展的数据空间地址常数(MCS251专有)CO:常数空间地址常数(MCS251专有)HC:正常数空间地址常数(MCS251专有)

即用户源程序中的标号、函数名等,实际上表明某一地址。

(9) 用户源程序中定义的常数

dScope所支持的变量名或标识符最多可由31个字符组成,第一个字母为A~Z,a~z,下划线或问号,后续字符可为字母、数字、下划线和问号。除CPU变量和系统变量外,dScope不支持全局变量,但可视“define”命令定义的变量为全局变量。Dscope所, 支持的变量分为如下几种(变量名称不区分大、小写),支持类型转换:

分为整型变量(int)、无符号整型变量(uint/word),长整型(Long) 、无符号长整型(Ulong/dword)。

分为字符型(char)变量和无符号字符型(Uchar)

即R0~R七、A、C(位变量)、B、DPTR及特殊功能寄存器变量,对这些变量都可进行读、写操做。

(7) 用户源程序中定义的变量、数组、结构等

dScope支持ANSI C的运算符,包括算术运算符,逻辑运算符,关系运算符。

以运算符将dScope所支持的常量、变量、函数等链接在一块儿,就构成了dScope的表达式。

dScope不支持在命令文件中定义数组,但可引用用户程序中的数组,引用方式如同C。

dScope不支持在命令文件中定义结构和联合,但可引用用户程序中的结构和联合,引用方式如同C,但如要输出整个结构或联合的结果,就要用命令“OBJ”。

不可自定义指针,但支持用户源程序中的指针变量。

dScope提供了一系列调试命令。在命令文件中,dScope只支持这些语句及前述定义的表达式,C语言的语句均不被支持,但在命令文件所包含的用户自定义函数(非用户源程序中的函数)中支持C语句,但用户自定义函数中一样不支持数组、结构、联合和指针。

用户自定义变量指令,格式以下:Define <类型> <变量名>类型一为如前所述的变量类型,Define指令定义的变量可能为全局变量,可为用户自定义函数所引用。

内存显示命令,格式以下二:D   起始地址,结束地址地址如前所述的地址常数,标识符常量。

内存修改指令,格式以下:E 类型地址=表达式 [表达式2],[……]类型如前所述,地址如前所述的地址常数。表达式如前所述,但若是是函数名称(含标号、指针变量),则关键字E→EP

Map为内存段修改指令,Reset map将内存段复位或缺省值。

用以引用用户源程序中的结构(联合)、数组、格式以下:Obj表达式 [n,],[Line]表达式为用户源程序中的数组,结构(联合)名称。当Line缺省时,数目、结构(联合)的内容按n行输出;若有Line,则单行输出。

反汇编命令,格式以下:    U [地址]地址包括地址常 数及标识符常量,指明反汇编的起始地址。

观察点设置命令,格式以下:WS 表达式[,n][LINE]关键字LINE存在时,观察点表达式单行输出LINE缺省时,观察点表达式n行输出。

连续运行命令,格式以下:   G [起始地址],[终止地址]地址为标识符常量或地址常数,地址缺省时,为连续运行。

性能分析操做指令,其分如下几种:PA显示当前所设置的性能分析程度段PA Kill *删除当前所设置的全部性能分析程序段PA Kill n1 [,n2],[……]删除指定的性能分析程序段PA 地址范围设置性能分析程序段,地址范围能够起始地址和结束地址的方式给出,也可给出函数名,行号范围。PA Reset复位性能分析窗口(PA Windows),清除全部的记录。

断点显示指令,显示全部被定义的断点。

图标定义指令,用于当窗口(Toolbox)

DOS窗口Open命令,以“EXIT”命令退出DOS窗口。

文件包含命令,格式以下:Include [路径] 文件名dScope支持以文件包含的方式调入并执行调试命令文件,用户自定义函数文件,调试命令文件能够有后缀,也可无后缀。

完成输出操做并开闭该文件LOG指令只将LOG>或LOG>>与LOG OFF指令之间的操做命令存入该指定文件。

该指令将一段内存映象以19EX386/HEX的格式存盘,具体格式以下:Save 路径 文件名:地址一、地址2地址一、地址2指所要保存的空间范围,既但是标识符,也但是址常数。

变量=“字符串”SET 变量

dScope支持三种函数,即dScope预约义函数,用户自定义函数和信号函数,分别详述以下:

用于产生一个信号波形,该函数必须用于信号函数中。

(2) 用户自定义函数

这类函数不一样于用户源程序中的数函,其定义格式为Func 返回类型 函数名(参数序列) {    语句}返回类型如前所述的变量类型用户自定义函数中的语句与ANSI C类似,只是不支持数组结构、联合、指针,可引用dScope系统变量,define语句定义的变量和用户源程序变量,不支持dScope命令,如想在函数中执行dScope命令,要借助于exec(“Command__String”)函数,可引用dScope预约义的函数(除了twatch ( )函数),不支持ANSI C的库函数。

① 不支持条件汇编② 不支持头文件③ 无变量的初始化④ 不支持数组、结构、指针⑤ 调用方式不一样,自定义函数和信号函数首先要包含一个函数文件之中,然而在测试命令文件中以Inclule指令调用该函数文件,最后才能以函数名调用之。⑥ 函数调用只支持传值方式。

一般来说,一个单片机程序是有很多的部分构成每一个模块来实现某一个特定的功能,比如AD转换程序模块、timer定时器程序模块、PWM程序模块等。单片机开发过程中我们将这些程序模块用函数的方法来实现。这样一个单片机程序就可以由一个main函数和若干和函数模块来构成,同一个函数模块可以被一个或者多个函数调用任意多次。基于这种思想很多的单片机厂家设计了单片机的固件库文件(其库文件是和硬件的资源相配套的,比如timer/counter模块、PWM模块、UART模块等)来驱动设备的内部和外设资源。

下图为STC15标准库文件的函数库的函数和文件。

每个文件都以函数的形式保存为文件,比如GPIO的文件打开如下:

  1. // 返回: 成功返回0, 空操作返回1,错误返回2.

显然这是一个GPIO初始化的程序。由此可以看出,运用函数的方法可以有利于维护程序,也使得开发变得更模块化,在介绍函数之前我们先介绍一下程序的组成以及函数与文件的关系。

(1)    一个单片机程序由一个或者多个程序模块组成,每一个程序模块可以作为一个程序源文件。

(2)    一个程序源文件可以由一个或者多个函数构成。

(3)    单片机C程序和只能有一和main函数,并且执行是从main函数开始的。

函数可以分为有参数函数和无参数函数。有参数传递函数是指在调用函数的时候,通过参数相被调用的函数传递运算的参数;而无参函数一般指的是参数执行特性的操作(比如对硬件的初始化等)。

无参函数的一般定义如下:

类型标识符 函数名()

有参函数的定义一般如下:

类型标识符 函数名(形式参数列表)

其中形式参数列表中的参数可以是数字变量、字符变量、数组变量、结构体变量等。

在调用有参函数的时候,主函数要将传递的参数转到函数的形式参数中,其中主函数的参数就做实际参数,而函数中的变量(函数名后面跟的参数)属于形式变量,当函数讲将数据运算结束后,会释放函数中用到的变量单元,最后控制硬件操作或者通过传递参数的形式将运算后的结果传递给主函数。

函数的返回值用return来完成运算后参数的传递,同样rerun的出现位置也很重要,如果执行了return程序,其return后面的程序将不再运行。和break、continue的区别就在于使用的地方不同,一个是函数中,而另外两个是应用到循环体中。

函数的调用比较方便,直接是函数名来实现函数的调用。

注意在单片机C语言中,如果先声明函数那么函数可以写在任何的位置,如果事先没有声明的话,函数只能写在main()函数的前面,否则会报出错误和警告。

如果将函数作为一个整体文件保存起来,在其他的文件中调用其变量的时候,我们应该用extern来声明变量,同样函数也一样。

extern是在函数的外部来声明全局变量,他的作用域是从变量的定义开始,到本程序文件的结尾。主要用于扩展外部变量的作用域。他可以用于同一文件内声明的外部变量也可以用于多个文件的程序中声明外部变量。

A.同一文件中声明外部变量

运行程序后可以看到输出23;

因为变量A和B在main之前没有定义过,因此在使用A和B变量的时候要在main函数中不能引用外部变量,因此在main函数中声明外部变量,表示A和B变量在外部已经定义过,这样main函数才能合法的使用变量A和B。

B. 在多个文件的程序中声明外部变量

在很多情况下一个程序由多个源文件构成,那多在一个文件中想引用另一个文件中已经定义的外部变量怎么么办呢?那么如果在两个文件中同时定义变量的话就会出现重复定义的错误,正确的办法是在一个文件中定义变量,而在另一个文件中用extern来声明外部变量,从而引用外部变量。比如:

将此文件保存文main.c文件

在文件fun.c文件中要使用A则fun文件如下:

这样便可以使用不同文件中的变量了,但是在使用中非常值得慎重,因为在执行一个文件中的函数的时候,可能会改变了该全局变量的值,从而影响到两一个文件中的函数执行的结果。

这就是关于函数的部分的讲解,可能比较粗糙,希望大家仔细去分析并查阅相关文献来更充实完整函数的部分,同时也要多看优秀的程序代码,来加深对函数的理解。谢谢大家!

打开所要导入源文件的功能块

2、安装gcc工具,在这,我安装了mingw这个工具。
单片机中代码生成.a文件
1、首先要把.c文件生成.o文件

2、然后再把.o文件生成.a文件。

注:-c选项表示只编译生成.o目标文件.

注:ar命令可以用来创建、修改库,也可以从库中提出单个模块。

r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。
如果若干 模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。
默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。

v: 该选项用来显示执行操作选项的附加信息。

注:我们可以跳过第一步,直接使用VSGDB生成的.o文件执行第二步。
单片机,全称单片微型计算机,又称微控制器,是把中央处理器、存储器、定时/计数器、各种输入输出接口等都集成在一块集成电路芯片上的微型计算机。

单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等。单片微型计算机简称单片机,是典型的嵌入式微控制器(Microcontroller Unit), 常用英文字母的缩写MCU表示单片机,单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。单片机由运算器,控制器,存储器,输入输出设备构成,相当于一个微型的计算机(最小系统),和计算机相比,单片机缺少了外围设备等。概括的讲:一块芯片就成了一台计算机。它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。同时,学习使用单片机是了解计算机原理与结构的最佳选择。它最早是被用在工业控制领域。

  由于单片机在工业控制领域的广泛应用,单片机由仅有CPU的专用处理器芯片发展而来。最早的设计理念是通过将大量外围设备和CPU集成在一个芯片中,使计算机系统更小,更容易集成进复杂的而对体积要求严格的控制设备当中。

我要回帖

更多关于 如何将c语言程序导入单片机 的文章

 

随机推荐