ImageVerifierCode 换一换
格式:DOCX , 页数:11 ,大小:20.46KB ,
资源ID:2944288      下载积分:2 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/2944288.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(第七章 单片机混合编程.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

第七章 单片机混合编程.docx

1、第七章 单片机混合编程第七章 单片机与C语言的混合编程一、混合编程的原则对于一个程序,整体程序框架,大部分的程序用c语言编写,有些要求严格定时等要求的用汇编语言编写,有时可以达到较好的效果。C51函数声明转换后的函数名说 明void func1(void)FUNC1无参数传递,函数名不改变type func2(args)_FUNC2有参数传递,前加“_”,通过寄存器传递type func3(args) reentrant-?FUNC3重入函数,有参数传递,前加“_?”,通过堆栈传递(在调用时也用寄存器传递,在函数中再转存入堆栈中)混合编程最关键的问题是参数传递,也就是在连接时,不同语言编写的程

2、序,参数是如何传递的。已经知道,c51有一套严格的参数传递规定,一般来说用汇编编写的程序变量的传递参数所使用的寄存器是无规律的,汇编语言较随便。因此混合编程中,汇编语言服从c51的规定。按照C51 的参数传递标准可让你的程序有很好的可读性,并有利于维护。编写出来的函数很容易和C 编写的函数进行连接,如果你用汇编编写的函数和C编译器编译出来的代码风格一样的话,连接器将能够对你的数据段进行覆盖、分析。二、编译、连接的规则1、 C51中函数名的转换规则2、几个概念:1) 编译将源程序翻译成单片机可以执行的目标代码,产生一个目标文件(.OBJ)。源文件编译时只能得到相对地址。列表文件是编译后生成的含源

3、程序、目标代码和错误信息的可打印文件。2) 段的概念段是程序存储器或数据存储器的单位。分为绝对段和可重新定位段。绝对段是不能重新定位的,如主程序的开始,必然在0000H,中断矢量入口也不能变。绝对段没有段名。可以重新定位的段,例如函数,库函数等。要有段名、类型及属性。可以重新定位的段位置由连接时确定。3) 模块模块是包含一个或多个段的文件,由编程者命名。4) 连接与定位将各模块中所以具有相同段名及类型的段连接起来,连接以后各段都分配了绝对地址。生成一个完整的程序。例如在几个函数中都调用了sin(x),连接时就会合并到一起,在整个程序中计算sin(x)的段只有1个。产生一个可以固化到单片机中的文

4、件(.HEX)。3.文件处理过程: 编辑:用编辑器分别编辑C源代码和汇编源代码。编译:用户编写的c语言源程序经过c51编译器编译后,生成浮动地址的目标代码文件。这种浮动地址的目标代码是不能直接装入805l单片机的EPROM中运行的,必须经过连接定位器L51的连接和定位,生成具有绝对地址的目标代码,才能在8051单片机中运行。连接:L51能将各个模块中具有相同名字的再定位部分段组合到个单一的再定位段中,同时产生个段表(MAP)。段表中包含了每个段的类型、基地址、长度和段名。在进行段组合时要求所有具有相同名字的部分段都有相同的存储器类型(CODE、DATA、IDATA、XDATA或BIT),如果类

5、型不同则会发生错误。组合段的长度不能超过存储器的实际长度。L51能够进行多程序模块的连接,它具有静态覆盖功能,可使8051单片机中有限的存储器资源得到允分利用。在连接定位的过程中能自动加入运行库中必要的库函数。L51连接定位器生成绝对目标输出文件。L5l采用静态覆盖技术来操作数据存储器,使8051系列单片机中有限的内部RAM得到充分的利用。对于由c51编译器或A51汇编器生成的目标模块中没有相互调用的参数和局部变量,将在存储器中覆盖,从而可产牛非常紧凑的数据区。转换成 *.HEX文件:通过符号转换器0HS51转换成Inte1HEX文件,该文件可以固化到EPROM4、C51编译器的段名规则 1)

6、段名 段名包含源程序文件名、存储类型和名字,名字就相当与C程序中的函数名。注意:所有的段名都被转换为大写字符保存,因此混合编程时,用汇编语言编写段名要用大写。 存储类型用前缀表示:段名前缀存储区类型说 明?PR?code可执行程序段?CO?code程序存储器中的常数数据段?BI?bit内部数据存储区的位类型数据段?BA?bdata内部数据存储区的可位寻址的数据段?DT?data内部数据存储区的数据段?FD?far外部数据存储区的far型数据段?FC?const far程序存储器中的far型常数数据段?ID?idata内部数据存储区的间接寻址的数据段?PD?pdata外部数据存储区的分页数据段?

7、XD?xdata外部数据存储区的一般数据段?C?库文件 C源程序编译后,段名的形式如下:?PR?XIAOYAN?SHUIL ?C?LIB_CODE 其中:XIAOYAN?为名称,SHUIL为文件名,?PR?为段名前缀 ,含义如下: 5、设置变量地址有时候我们希望把变量存储在指定的地点,特别是在主控制器初始化SRAM之后,从8051系统才开始工作的情况,在这种情况下两个系统必须在存储器分配上达成一致。如果你不想在编译时才给变量分配地址,Keil C可以让你指定变量的存储地址。例如你想定义一个整型变量并把它初始化为0x4050, 用C是不能够把变量指定在某个地址的,另外你也不能指定位变量的地址,但

8、是对于不需要初始化的变量你可以使用关键字_at_来指定地址。你的变量将分配在DATA段中下面是一个指定地址的例子unsigned char data byteval _at_ 0x32;关键字_at_的另一个功能是能通过给I/O器件指定变量名,为你的输入输出器件指定变量名。例如你在XDATA段的地址0x4500处有一个输入寄存器,你可以通过下面的代码为它指定变量名:unsigned char xdata inpreg _at_ 0x4500;以后在读该输入寄存器的时候只要使用变量名inpreg就可以了。三、 C51项目中汇编语言文件的格式 1、声明部分 1)模块名定义格式(在文件开始) NAM

9、E 模块名用关键字NAME说明模块名 2)子程序代码段声明格式(在模块名定义之后)如: ?PR?_|_?函数名1(子程序名1)?模块名 SEGMENT CODE ?PR?_|_?函数名2(子程序名2)?模块名 SEGMENT CODE : ?PR?_|_?函数名n(子程序名n)?模块名 SEGMENT CODE主要说明符号类型,分配空间。 3)子程序被调用属性声明格式(紧接前面)如: PUBLIC _|_?函数名1(子程序名1) PUBLIC _|_?函数名2(子程序名2) : PUBLIC _|_?函数名n(子程序名n)用PUBLIC说明该模块可以与其他子程序、模块共享。调用它的模块必须在模

10、块开头包含外部函数说明EXTERN3、 用汇编语言编程时段声明格式设汇编文件名字为Delay.asmNAME Delay;给该模块一个名字PUBLIC _DELAY;表示有参数传递?PR?_DELAY?Delay SEGMENT CODE;代码段声明RSEG ?PR?_DELAY?Delay ;RSEG表示可重定位_DELAY:(程序段)RET上面是用汇编编程,用c调用时汇编程序段的一个框架模式。汇编文件的格式化是很简单的,给存放功能函数的段一个段名,因为是在代码区内,所以段名的开头为PR ,在编程时,“?PR?”是可以省略的。对于传递参数的功能函数,必须符合参数的传递规则。下面看一个用c调用

11、汇编的例子。例:(混合编程2)dpjc.c(文件名)#define uchar unsigned char uchar add1(uchar x,uchar y);void main(void) uchar x,y,z;x=0x10;y=0x20;z=add1(x,y); 汇编语言源程序:(注意汇编的格式,文件名用字母)huib.asm(文件名)PUBLIC _ADD1_ADD1?HUIB SEGMENT CODERSEG _ADD1?HUIB_ADD1: MOV A,R7 ADD A,R5 MOV R7,A RET END上面分别是两个文件,按下列步骤进行编辑、编译和连接:1)建立工程文件,

12、然后建立C源文件dpjc.c和汇编源文件huibian.a51,建立方法相同。2、编译:将光标放在要编译的文件(如huibian.a51)右击,弹出浮动菜单。将光标移到“Translate”上单击(或用工具栏按钮)对该程序进行编译。将两个文件全部编译无误后,方可进行连接。3、连接:单击“Build target”工具栏按钮即可连接。4、运行:运行时要打开汇编窗口“Disassembly Window”和”Watch & Call Stack Window”窗口,观察汇编语言中的变量是如何传递的,注意变量是如何变化的。编译、连接以后产生的汇编代码如下: 3: void main(void) 4:

13、 5: uchar x,y,z; 6: x=0x10; C:0x000F 7F10 MOV R7,#0x10 7: y=0x20; C:0x0011 7D20 MOV R5,#0x20 8: z=add1(x,y); C:0x0013 120019 LCALL ADD1(C:0019)C:0x0016 8F08 MOV 0x08,R7 9: C:0x0018 22 RET 5: _ADD1: MOV A,R7 C:0x0019 EF MOV A,R7 6: ADD A,R5 C:0x001A 2D ADD A,R5 7: MOV R7,A C:0x001B FF MOV R7,A 8: RET

14、注意数据传递过程。4、用空函数编译查看汇编格式与数据传递将add1函数编写一个空函数:#define uchar unsigned char uchar add1(uchar a,uchar b) void main(void) uchar x,y,z; x=0x10; y=0x20; z=add1(x,y); 编译时,文件选项要选择“Generate Assembler SRC File”和“Assembler SRC File”,产生一个后缀为.SRC的文件。方法:在源程序名上右击鼠标,出现浮动菜单,将鼠标移到“options for File 文件名.c”,左击鼠标,在弹出窗口中选择即可

15、,注意原来是灰色的,选择使其变为黑色。打开hunhebc3.SRC文件如下:; .hunhebc3.SRC generated from: hunhebc3.c; COMPILER INVOKED BY:; E:keilC51BINC51.EXE hunhebc3.c BROWSE DEBUG OBJECTEXTEND SRC(.hunhebc3.SRC)NAME HUNHEBC3?PR?_add1?HUNHEBC3 SEGMENT CODE ?DT?_add1?HUNHEBC3 SEGMENT DATA OVERLAYABLE ?PR?main?HUNHEBC3 SEGMENT CODE ?DT?main?HUNHEBC3 SEGMENT DATA OVERLAYABLE EXTRN CODE (?C_STARTUP) P

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1