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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

汇编语言混合编程对Keil的设置.docx

1、汇编语言混合编程对Keil的设置在keil C语言与汇编语言的混合编程中曾经遇到过的一些问题,写下来留作以后参考。(本文写于11.04.10,在8.18日加入了第4点的内容)1、C语言中加入汇编语言模块的方法:例子:void func() C语言代码#pragma asm MOV R6,#23DELAY2: MOV R7,#191DELAY1: DJNZ R7,DELAY1DJNZ R6,DELAY2RET#pragma endasm C语言代码其中红色为C语言部分,绿色为嵌入的汇编语言部分。汇编部分需要用#pragma asm和#pragma endasm包起来2、Keil提示“asm/en

2、dasm”出错的解决方法如果只是像1中那样直接加入汇编代码的话,编译将会报错,错误如下:compiling sendata.c.sendata.c(81): error C272: asm/endasm requires src-control to be activesendata.c(87): error C272: asm/endasm requires src-control to be activeTarget not created解决方法如下:首先右键单击包含有汇编部分的c语言文件名,然后在如上图所示的菜单中选择带有红色方框的选项在弹出的对话框中,将上图中红色方框选中的两项打上勾

3、(默认的情况下,前面的勾是灰色的,要让这两项前的勾变为黑色的),点击确定。3、?C_START等相关警告的处理按照2中的方法处理完之后,再编译不会出现错误信息了,但是会出现如下的警告信息:linking.* WARNING L1: UNRESOLVED EXTERNAL SYMBOLSYMBOL: ?C_STARTMODULE: STARTUP.obj (?C_STARTUP)* WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNALSYMBOL: ?C_STARTMODULE: STARTUP.obj (?C_STARTUP)ADDRESS: 00

4、0DH处理方法如下:在如上图所示的“Source Group 1”上点右键,在菜单中选择 “Add Files to Group Source Group 1 ”找到你的KEIL安装目录,选择其中的“C51”目录下的“LIB”目录下的“C51S.LIB”文件,点击Add,然后Close即可。注意,上图所示的文件选择框进入LIB目录下后,默认只显示.c文件,需要在“文件类型”中选择“Library file (*.lib)”,即可显示LIB文件了。添加C51S.LIB到工程后,再次编译,警告信息消失。linking.Program Size: data=9.0 xdata=0 code=28cr

5、eating hex file from sendata.sendata - 0 Error(s), 0 Warning(s).4、寄存器冲突问题的解决汇编程序块中常常会使用到51的通用寄存器,比如R0-R7。这种情况下可能会和C语言程序中已经使用到的R0-R7产生冲突,以至于产生一些非常隐蔽和古怪的错误。虽然有人说KEIL可以自动分配寄存器组使之不产生冲突。但是在我这里具体测试时还是有冲突的(或者是我的KEIL设置有问题?),下面是测试小程序:/* 测试程序*/i ncludei ncludetypedef unsigned char uint8 ;uint8 buf16=0x55 ;uin

6、t8 i=0 ;/* 初始化单片机相关寄存器*/void UartInit()SCON=0x50 ;TMOD|=0x21 ;PCON|=0x80 ;TH1=0xE8 ;TL1=0xE8 ;IE|=0x90 ;TR1=1 ;/* 延时*/void delay()#pragma asm MOV R6,#19 DELAY2 : MOV R7,#18 DELAY1 : DJNZ R7,DELAY1 DJNZ R6,DELAY2 RET #pragma endasm /* 向COM1发送一个字符*/void SendChar(uint8 byteToSend)SBUF=byteToSend ;while

7、(!TI);TI=0 ;/* 读取一个字节*/uint8 read_byte()uint8 recvdata=8 ;delay(); /延时 return recvdata ;/* 主 程 序*/int main()UartInit();/串口初始化 while(1)bufi+=read_byte();/* 串口中断处理*/void chuankou()interrupt 4 if(RI)for(i=0;isizeof(buf);i+)SendChar(bufi);RI=0 ;程序本身非常简单,一目了然。main函数的作用就是不断把read_byte()的返回值读入buf中,再待有串口中断时,

8、将buf中的内容输出到串口。read_byte()函数也已经做了简化,返回值固定为8。将这个程序在KEIL中编译,下载运行。奇怪的情况出现了,buf中的内容输出到串口总是0(输出理所当然应该是8)。把delay();这一句注释掉后,程序就输出正常了。delay();不过起到了一个延时作用而已,怎么可能改变到函数返回值呢?看看read_byte()函数生成的汇编程序USING 0MOV R7,#08HACALL delayRET 才晓得,原来read_byte()函数将返回值放到R7中,然后调用delay函数,再返回。后面的程序调用read_byte()返回值时,直接从R7中取数。但是“ACAL

9、L delay”时,已经存放了#08H的R7,在延时中被递减到了0,这也是为什么buf中存放的内容都是0的缘故。知道了原因就好办一些了,由于本人是菜鸟,单片机水平很有限,目前只想到了如下4种解决方法:(1)避开C语言部分已经使用了的Rn编汇编模块时,看看C语言部分生成的汇编程序,把那些C语言已经使用到的,且可能对汇编部分构成冲突的Rn避开就好了。比如上面的延时程序中,把R6、R7换成R3、R4,程序就正常了。(2)用USING X + ARX的方式调用其他组Rn寄存器51单片机有4组R0-R7的寄存器,据说main中一般使用的都是第0组。那么在汇编部分中使用其他的组就可以了,delay函数的内

10、容可以改成如下这样:void delay()#pragma asm USING 2MOV AR6,#19DELAY2: MOV AR7,#18DELAY1: DJNZ AR7,DELAY1DJNZ AR6,DELAY2RET #pragma endasm 但是注意,如果这样用的话,delay延时的长度可能需要重新计算。因为AR6和R6有所不同,以下是在网上找到的两段英文描述:R0 R7 The eight 8 bit general purpose 8051 registers in the currently active register bank.A Maximum of four re

11、gister banks are available. AR0 AR7 Represent the absolute data addresses of R0 through R7 in the current register bank. The absolute address for these registers changes depending on the register bank that is currently selected. These symbols are only available when the USING assembler statement is

12、given. Refer to the USING assembler statement for more information on selecting the register bank. These representations are suppressed by the NOAREGS directive off the Cx51 compiler. 看这意思,似乎R0 R7是寄存器,而AR0 AR7是地址,所以“MOV AR6,#19”和“MOV R6,#19”所花的时钟周期数是不同的。我调一个采集数据的程序时,刚开始没有注意到这个问题,因此很奇怪为什么用AR6和R6,采集到的数据是不一样的,后来才反应过来它们延时不同。(关于51单片机的各条指令的时钟周期数可以在XX上搜到很多,这里就不列出了)(3)对汇编部分中使用到的寄存器采用入栈保护简单的说就是在汇编部分使用Rn之前,将它们的内容塞进栈中存起来,延时循环结束之后再从栈中取出来

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

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