主程序中的bit位变量,子程序模块中如何声明

主程序中的bit位变量,子程序模块中如何声明,第1张

为了这个问题,浪费好长时间,挤进了脑汁,伤透了脑筋,曾一度有个现在看来应该是挺好笑的想法——怀疑keil不向标准c一样,不能很好的支持多c文件工程,在多c文件共享变量时,尚无法很好处理。

不过就在要点发送帖子按的一瞬间,偶却有了灵感,并通过验证,知道如何解决了。然后再接着想下去,通过实验,有个更多收获:

1)如果两个或更多c文件都需要使用某非bit型变量,那么声明是应将相应存储类型同时注明,即如果定义“uchar idata cntembuf”,那么应声明为“extern uchar idata cntembuf”或者“extern idata cntembuf”;

2)如果是bit型变量,则数据类型“bit”必须注明,而存储类型可以省略;

LN认为,keil里之所以将bit变量和其他类型变量分开处理,是keil面向的处理器都是51内核的,而51内核bit变量只存在于特殊功能寄存器和内存的位寻址区(bdata区),而特殊功能寄存器中的位变量若在两个以上文件中使用各各文件都只能用类似于sbit abcd = P1^6的形式进行声明,并且keil不检测abcd这个位变量在不同文件中是否代替相同位(例如,可以在另一个c文件中声明为:sbit abcd = P0^5等),这样一来,用extern声明的bit变量就只有在bdata区了,所以,允许在在一个c文件中定义位变量后,在其它c文件中省略“bdata”这个存储类型;

而非bit型变量则可以在特殊功能寄存器,内存,外存,所以声明时要使存储类型与定义时的存储类型相同(也可以在定义和声明时都不规定存储类型,而又编译器根据编译模式自动分配)。

感觉今天这事真有点搞笑,不过说明:交流是非常有用的。因为尽管帖子未能发出,但是在要跟他人交流时,人会不自觉的将所要描述给他人的问题屡一下头绪,而往往就这么一屡,可能就让自己有了办法。当然很多时候怎么屡也不行,这时候就要靠别人直接教了

在keil中新建工程,先用汇编编写主体程序,在主体程序中要对要调用的子程序进行声明,如EXTRN CODE (function)

EXTRN DATA (DATT0,DATT1,DATT2) ,然后,另建立一个c语言的文件,(千万不要把汇编和c放到一个文件中)并加入到新的工程中,进行编译。下面给一个在网上搜的,有空我编一个例子。

汇编语言调用C语言 

  这是我刚开始学硬件时做过的一个项目,刚开始是从汇编开始的,从下位机采集上来的数据是浮点数(4字节)我要用接收下来,然后再送到数码管去显示这个浮点数,这首先要把接收到的数(4字节数)再变成浮点数,虽然有浮点数的变换原理但要是用汇编程序来实现非常的繁琐,我想到用C语言来自动实现,如把4字节数赋给一个浮点变量后,这个变量就是一个浮点数然后再一位位分开送到数码管去显示根据这个原理理解下面的两段程序。

-------------------------------------------------

三位数带有一位小数的程式(例如显示“15.2”)

SLAVE EQU 26

FLAG BIT 2EH

REV0 EQU 30H

REV1 EQU 31H 存放收到的字符

REV2 EQU 32H

REV3 EQU 33H

DAT0 EQU 34H

DAT1 EQU 35H 要显示的字符

DAT2 EQU 36H

EXTRN CODE (function)

EXTRN DATA (DATT0,DATT1,DATT2)

ORG 0023H

AJMP RECV

ORG 0000H

AJMP START

ORG 0040H

START: NOP

MOV SP,#60H

SETB EA

SETB ES

MOV TMOD,#20H

MOV SCON,#0F4H

MOV TH1,#0FDH

MOV TL1,#0FDH

MOV PCON,#00H

SETB TR1

MOV R6,#4

CLR FLAG

MOV DAT0,#0

MOV DAT1,#0

MOV DAT2,#0

MOV DPTR,#NUM

MOV R1,#REV0

LOOP: MOV R0,#DAT0

MOV A,@R0

MOVC A,@A+DPTR

CLR P3.4

MOV P1,A

ACALL DELAY

ACALL DELAY

SETB P3.4

CLR P3.3

INC R0

MOV A,@R0

MOVC A,@A+DPTR

ANL A,#7FH

MOV P1,A

ACALL DELAY

ACALL DELAY

SETB P3.3

CLR P3.2

INC R0

MOV A,@R0

MOVC A,@A+DPTR

MOV P1,A

ACALL DELAY

ACALL DELAY

SETB P3.2

JNB FLAG,GGG

MOV DAT0,DATT0

MOV DAT1,DATT1

MOV DAT2,DATT2

CLR FLAG

GGG: SJMP LOOP

DELAY: MOV R7,#0FFH

DJNZ R7,$

RET

----------------------------------

从机接收程序

RECV: PUSH ACC

PUSH PSW

CLR RI

MOV A,SBUF

XRL A,#SLAVE

JZ TORECV

OUT: POP PSW

POP ACC

RETI

TORECV: CLR SM2

RECVNEXT:JNB RI,$

CLR RI

JNB RB8,ISNUM

SJMP OUT

ISNUM: MOV A,SBUF

MOV @R1,A

INC R1

DJNZ R6,RECVNEXT

LCALL function 调用C语言函数

SETB FLAG

MOV R6,#4

MOV R1,#REV0

SETB SM2

SJMP OUT

NUM: DB 0C0H,0F9H,0A4H,0B0H,99H

DB 92H,82H,0F8H,80H,98H

DB 86HEND

//C语言被调用部分

char data DATT0,DATT1,DATT2

void function()

{

float data *good=0x30

int data *gg=0x3a

// *good=(*good)*100

*gg=(int)*good

if(*gg>=0)

{

DATT0=(*gg)%10

*gg=(*gg)/10

DATT1=(*gg)%10

DATT2=(*gg)/10

}

else

{

DATT0=10

DATT1=10

DATT2=10

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11225741.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存