谁能帮我解释一下这个avr单片机的程序?

unsignedcharkeyboard(){unsignedcharkey_value,status;unsignedchardelay;//KEY0=1;//KEY1... unsigned char keyboard()
{
unsigned char key_value,status;
unsigned char delay;
// KEY0=1;
// KEY1=1;
// timeover&=0;
asm("CBI 0x11, 4");
key_value=0;
if((PIND&0x10)!=0&&(PIND&0x10)!=0)return 0;

//KEY0=0;//产生中断
asm("CBI 0x12, 4");
delay=20;
while(delay)
{
delay--;
}
asm("SBI 0x18,7");

delay=20;
while(delay)
{
delay--;
}
status=0;

while(1)
{
switch(status)
{
case 0:
if(KEY1!=0)
key_value+=0x80;
asm("CBI 0x18,7");
delay=0;
status=1;
break;
case 1:
if(delay>JIANGE)
{
asm("SBI 0x18,7");
status=2;
delay=0;
}
break;
case 2:
if(delay>JIANGE)
{
if(KEY1!=0)
key_value+=0x40;

asm("CBI 0x18,7");
status=3;
delay=0;
}
break;
case 3:
if(delay>JIANGE)
{
asm("SBI 0x18,7");
status=4;
delay=0;
}
break;
case 4:
if(delay>JIANGE)
{
if(KEY1!=0)
key_value+=0x20;
asm("CBI 0x18,7");
status=5;
delay=0;
}
break;
case 5:
if(delay>JIANGE)
{
asm("SBI 0x18,7");
status=6;
delay=0;
}
break;
case 6:
if(delay>JIANGE)
{
if(KEY1!=0)
key_value+=0x10;
asm("CBI 0x18,7");
status=7;
delay=0;
}
break;
case 7:
if(delay>JIANGE)
{
asm("SBI 0x18,7");
status=8;
delay=0;
}
break;
case 8:
if(delay>JIANGE)
{
if(KEY1!=0)
key_value+=0x08;
asm("CBI 0x18,7");
status=9;
delay=0;
}
break;
case 9:
if(delay>JIANGE)
{
asm("SBI 0x18,7");
status=10;
delay=0;
}
break;
case 10:
if(delay>JIANGE)
{
if(KEY1!=0)
key_value+=0x04;
asm("CBI 0x18,7");
status=11;
delay=0;
}
break;
case 11:
if(delay>JIANGE)
{
asm("SBI 0x18,7");
status=12;
delay=0;
}
break;
case 12:
if(delay>JIANGE)
{
if(KEY1!=0)
key_value+=0x02;
asm("CBI 0x18,7");
status=13;
delay=0;
}
break;
case 13:
if(delay>JIANGE)
{
asm("SBI 0x18,7");
status=14;
delay=0;
}
break;
case 14:
if(delay>JIANGE)
{
if(KEY1!=0)
key_value+=0x01;
asm("CBI 0x18,7");
status=15;
delay=0;
}
break;
case 15:
if(delay>JIANGE)
{
asm("SBI 0x18,7");
status=16;
delay=0;
}
break;
case 16:
if(delay>100)
{
if(key_value>32)key_value=0;
return key_value;
}
}
delay++;

}
return 0;
补充一下:#define KEY1 (PIND&0x10)
#define JIANGE 40

特别是这样的句子asm("SBI 0x18,7");
请帮忙注释一些好吗?
这个程序的返回值是什么呢,是固定的吗?

我用的是ATMega64的型号,在头文件里端口地址是这样定义的:
请问这个程序是怎么返回按键的结果的?

谢谢你帮我看了这个程序,但是这个程序返回的不是key_value的值吗,是怎么返回status的值的呢?而key_value的值在status等于0时,他的第七位置1,这个时候的值就已经是128了,再往下加,等到status
等于16的时候肯定就大于32了,所以最后输出的不都是0吗?
展开
 我来答
百度网友ed1f7b0
2010-08-05 · TA获得超过561个赞
知道小有建树答主
回答量:606
采纳率:0%
帮助的人:271万
展开全部
汇编指令SBI 0x18,7
相当于PORTB.7=1
汇编指令CBI 0x18,7
相当于PORTB.7=0

头文件里应该有类似定义: .equ PORTB=0x18

0x10表示PIND,0x11表示DDRD,0x12表示PORTD,
0x13表示PINC,0x14表示DDRC,0x15表示PORTC,
0x16表示PINB,0x17表示DDRB,0x18表示PORTB,
0x19表示PINA,0x1A表示DDRA,0x1B表示PORTA。

AVR的IO有三个寄存器,DDRX,PORTX,PINX。
DDRX 方向,DDRX=1,输出;DDRX=0,输入。
PORTX 分两种情况
如果DDR=1,即在输出状态的话,那么通过设置PORTX的值改变IO端口的电平
如果DDR=0,即在输入状态的话,那么PORT=1则使能上拉电阻,否则不使能。
PINX 此寄存器表示了该端口的实际电平,所以读IO口的话,应该读PINX,而不是PORTX。

这样就好理解了吧???

你判断的是按键按下的时间长度?

这个程序应该是这样的,不知道我理解的对不对?

进入这个函数,如果没按键按下,返回0,退出。
asm("CBI 0x11, 4"); //PORTD.4设置为输入
key_value=0;
if((PIND&0x10)!=0&&(PIND&0x10)!=0)return 0;//如果PORTD.4(KEY1)=1,返回0。

如果有按键按下,执行下面的程序。
2个 while(delay) 延时,防抖动。

进入 while(1) 循环,我觉得最后一个 return 0; 应该是没机会执行到的。

然后switch判断status的值,刚开始是0.然后逐渐增加(每次延时40个delay),到16后,返回,退出。
当status==0时,判断按键是否按下,如果按下,PORTB.7置0,key_value+=0x80(key_value的第7位置1)
status==1,延时40个delay后,PORTB.7置1(这个估计是指示灯)。
status==2,延时40个delay后,判断按键是否按下,如果按下PORTB.7置0,key_value+=0x40(key_value的第6位置1)
status==1,延时40个delay后,PORTB.7置1。
就这样重复,直到status==16,只是key_value置1的位置不同。
最后,到16时,判断status的值,如果大于32,返回0,其他返回status的值。
顽健又通顺的小虎鲸
2010-08-03 · TA获得超过632个赞
知道小有建树答主
回答量:371
采纳率:0%
帮助的人:123万
展开全部
asm("SBI 0x18,7");
这个是汇编指令吧!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
cczm1
2010-08-04 · TA获得超过860个赞
知道小有建树答主
回答量:212
采纳率:0%
帮助的人:105万
展开全部
SBI:I/O 寄存器位置
CBI:I/O 寄存器位清零
地址为0x00 - 0x1F 的I/O 寄存器可用SBI 和CBI 指令直接进行位寻址 ,用SBI 或CBI 指令改变某些管脚的方向( 或者是端口电平、禁止/ 使能上拉电阻) 时不会无意地改变其他管脚的方向( 或者是端口电平、禁止/ 使能上拉电阻)。
return 0是正常退出。
返回值是按键检测结果,不是固定值。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式