单片机中,PIC汇编GOTO语句的问题。

PIC单片机中(PIC12F5048):
1> goto 语句后面可以加变量吗?如 goto $ + 3; 这里的$ +3 可以改为
变量吗?(不是标号,是变量).
2> 我用循环语句计时:
MOVLW 05H;
MOVWF TEMP1; TEMP1是变量。
LOOP:
DECFSZ TEMP1,1; 此语句1US,
GOTO LOOP; 此语句2US,
这样TEMP1每减少1,时间减少3US,
这里能不能用什么方法,让TEMP1每减少1,时间减少1US。

1.goto后面只能是个标签,其实你使用的伪指令loop也是个标签,不能是个地址,如果要使用$ + 3; 用JMP
2.你的意思是想在循环上加变量自减1,再延时时间自减1,是吗?
这样你可以这样做(当然,我比较习惯C,所以我用C写):
#include<reg51.h> //使用晶振11.0592
unsigned int k; //k为延迟时间,单位是US
unsigned int temp; //temp为中间变量
void dalay1us (unsigned int i) //晶振选用12.0,最大输出频率为6Hz
{
if(i==0)
i==65355; //这里是你自己设的一个变量k的初值,等k自减为0时候,会自动复位为初值65355(该值自由设,我设为最大值),本判断句根据你要求选择性使用
temp=i-1;
for(i;i>0;i--);
k=temp;
}
//以后main()调用的时候,可直接使用dalay1us (k);就可以了,本语句已经变量自减1,再延时时间自减1,满足你的要求追问

我不太会用C,问下,你的语句;
for(i;i>0;i--);
每次调用的时候,i可以少一,但是我想问下,这个i少1,时间是少1US吗?

(我这个用的是PIC12F508,最大的数也才能255)

追答

我原来给赋值的命令有问题,不用加全局变量,可以直接输入数字,调用局部变量
#include //选用的是12.0MHz的晶振
void dalay1us (unsigned int k) //晶振选用12.0,最大输出频率为6Hz
{
unsigned char i,j,temp; //局部变量i,j,temp定义
while(k) //k不等于0时候,会一直循环下面的内容
{
for(temp=k;temp>0;temp--)
for(i=4;i>0;i--) //执行周期为4X250=1000
for(j=250;j>0;j--); //如果选用的是12.0MHz的晶振,那1000个周期的时间,刚好是1us
k--; //循环结束后,k=k-1,再进入while(k) ,直至k=0后,结束循环
}
}
void main()
{
dalay1us (3); //调用void dalay1us (unsigned int k) ,并将k=3;
}
以上dalay1us (3); 执行的时间是3us+2us+1us=6us

追问

如果选用的是12.0MHz的晶振,那1000个周期的时间,刚好是1us?
不是一个周期1US吗?1000个周期就是1ms了吧。

追答

哦,对,单位错掉了,呵呵,真不好意思啊,那直接用下面的就可以了
void dalay1us (unsigned int k) //晶振选用12.0,最大输出频率为6Hz
{
unsigned char temp; //局部变量temp定义
while(k) //k不等于0时候,会一直循环下面的内容
{
for(temp=k;temp>0;temp--);
k--; //循环结束后,k=k-1,再进入while(k) ,直至k=0后,结束循环
}
}

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-08-08
嘲讽帅哥是以51来作解释的。51执行的时候是以12个振荡周期为一个机器周期。而您所说的PIC系列的是以4个振荡周期为一个机器周期。所以在做精确延时时要注意了。其实你将MOVWF TEMP1 中的TEMP一开始除以3不就可以了。
第2个回答  2011-08-01
绝对不行的,GOTO后面接的一定是一个已知的地址,这关系到PC指针的问题,一个程序怎么走可全看他了,我建议你可以不用那么怕麻烦,循环时间不一样你可以多写几个循环子程序。如果满意请采纳。