ORG 0000H (表示把下一条指令放在以0000H这个地址开始携樱大的的存储空间ROM里,也就是把SJMP START这条指令存在0000H,0001H里,SJMP START长度是2个字节!!在使用中要注意SJMP的转移范围。ORG是伪指令,单片机不运行,它不产生机器码,是为汇编也就是将汇编语言翻译成机器码时服务的。它告诉汇编软件下条指令放在哪个存储空间。汇编程序开头都会有这句,因为单片机复位后,PC=0000H,也就是单片机复位后,程序都是从0000H开始执行的,因为单片机的0003H开始到002BH是中断入口地址,所以我们在0000H~0002H处存储跳转指令,直接跳到主程序。)
SJMP START(程序跳转到START处,SJMP的转移范围是当前PC的+127B~-128B)
ORG 0030H(将START开始的程序依次存在以0030H开始的存颂腊储空间里)
START: MOV P3,#0FFH (P3口输出高电平,因为没电路图,所以只能从后面的程序推断:所有的灯灭!!也就是电路图的灯的一端接电源,另一端接P3口。下面的程序以全灭处理(当然也可能所有灯亮,具体看电路图是怎么样的))
MOV A,#0FEH (A置初值,只有最左边或最右边灯亮)
JNB P1.2,LOOP (判断P1.2是否为0,为0跳转到LOOP,推测接按键,按键按下就跳转)
JNB P1.3,LOOP1 (同上)
JNB P1.4,LOOP2 (同上)
JNB P1.5,LOOP3 (同上)
SJMP START (跳转回STRAT,上面这段程序的作用是不停的判断有没有哪个按键按下,有按键按下就跳转去做相应的处理)
LOOP: MOV P3,A (P3=A,因为A刚已经置初值了,所以P3口的灯有一盏亮)
LCALL DEL (调用子程序,用来延迟,让人眼可以看到灯亮)
JNB P1.3,LOOP1 (判断P1.3是否为0,为0跳转到LOOP1)
RL A(左移A)
SJMP LOOP (跳去执行LOOP)
LOOP1: MOV P3,#0FFH (P3口输出高电平,也就是所有灯灭)
上面这段程序的作用是如果P1.2的按键有按下,那就让等向左轮流亮,直到P1.3的按键按下才停止,并且把灯都关了。
JNB P1.4,LOOP2 (判断P1.4是否为0,为0跳转到LOOP2)
JNB P1.5,LOOP3 (判断P1.5是否为0,为0跳转到LOOP3)
SJMP LOOP1 (如果P1.4和1.5都不为0,继续等待直到他们有一个为0,也就是
P1.4和1.5接的按键有被按下)
LOOP2: JNB P1.0,LOOP (判断P1.0按键是否被按下,如果被按下跳往LOOP)
JNB P1.3,LOOP1 ( 同上)
JNB P1.5,LOOP3( 同上)
MOV P3,A (P3=A,因为A刚已经置初值了辩竖,所以P3口的灯有一盏亮)
LCALL DEL (调用子程序,用来延迟,让人眼可以看到灯亮)
RL A(左移A)
SJMP LOOP2
上面这段程序的作用是如果P1.4的按键有按下,那就让等向左轮流亮,直到P1.3或P1.5的按键按下跳转
LOOP3: JNB P1.2,LOOP
JNB P1.3,LOOP1
JNB P1.4,LOOP2
MOV P3,A
LCALL DEL
RR A
SJMP LOOP3
上面这段程序的作用是如果P1.5的按键有按下,那就让等向右轮流亮,直到P1.2,P1.3或P1.4的按键按下跳转
DEL: MOV R5,#02H
DEL1: MOV R6,#0F0H
DEL2: MOV R7,#0F0H
DEL3: DJNZ R7, DEL3
DJNZ R6, DEL2
DJNZ R5, DEL1
上面这段是延时程序(((15*16*2+3)*15*16+3)*2+1)机器周期
RET (延迟程序返回)
END (告诉汇编软件,程序到此结束,同ORG一样,单片机不执行这句)
有错请指正!!!!
ORG 0000H// 表示搭梁举程序从0000H这个单元开始执行MOV 20H,#02H//表示,02H移到 20H这个单元,完了之后,20H中的内容就是 02H (20H)=02H
MOV 21H,#03H这个同上 完了之后,21H中的内容就是 03H (21H)=03H
MOV A,20H //这渣尺个与上边两个不同,就是少了个# 所以表示的也不同,这个是把 20H中的内容移到A,上边20H中的内容是 02H 所以,执行完后,(A)=02H
SWAP A//就是把A中的高字节与低字节交换,结果是 (A)= 20H (上边A的内知碧容已经是02H)
ADD A,21H//这个是把 21H中的内容 加上 A中的内容,结果放在A 上边的(21H)=03H,(A)=
20H,所以,结果是(A)=23H
MOV 22H,A //这个是把A中的内容移到 22H单元中,执行完后,(22H)=23H,A中还是23H
END就是结束程序的意思
#include<reg51.h> //51单片机头文件#include<stdio.h> //标准输入输出头文件
unsigned char speed = 5//定义一个字符变量,并赋值为5
//(想知道5代表什么可以查ASCII码,也可以当数字用)
unsigned char rec_buf[5]//定义一个可以存5个字符的数组
unsigned char rec_idx = 0//定义一个字符变量,并赋值为0
char putchar (char c) //实现一个名为putchar的方法,传入一个字符,返回一个字符
{ //{}括起来的是方法体,代表这里面的内容属于这个方法的
ES=0 //ES应该是一个寄存器吧,这里是把里面清0,单片机我懂不多
SBUF = c //把传入的字符写到SBUF寄存器,
while(TI==0) //当TI寄存器里值非0时继续,这里是一个条件等待
TI=0 //把TI 寄存器清0重置
ES=1 //向ES寄存器写入1
return 0 //返回0,结束本方法
}
void delay100ms(unsigned char n)//定义一个无返回值的方法,并需要传入一个字符
{ //char字符型是可以当成数字来用的
unsigned char i,j //定义两个字符变量
TMOD = 0x20 //把寄存器置为 0010 0000 状态
for (j = 0j < n++j) //作n(n是方法传入的字符)次循环
{ //{}里面的东内容都进行n次循环
for(i = 0i < 20i++) //作20次循环,因为他在n次循环内,实际上是n乘以20次
{ 谈亮租 //外层进行1次,这里就这进行20次
THO=0x63 //把TH0寄存器置为 0110 0011状态
TL0=0x18 //把TLO寄存器置为 0001 0100状态
TRO=1 //把TRO寄存器置为 0000 0001状态
while(!TF0) //当TFO寄存器不为0时继续
TF0=0 //把TFO重置为0
}
}
}
void init_com() //一个无返回值,也不需要传入值的方法
{
TMOD=0x20 //TMOD寄存器设为 0010 0000状态
TH1=0xfd //TH1寄存器设为 1111 1101状态
TL1=0xfd //TL1寄存器设为 1111 1101状态
SM0=0 //SM0寄存器设为 0000 0000状态
SM1=1 //SM1寄存器设为 0000 0001状态
REN=1 //REN寄存器设为 0000 0001状态
EA=1 //EA寄存器设为 0000 0001状态
TR1=1 //TR1寄存器设为 0000 0001状态
ES=1 //ES寄存器设为 0000 0001状态
}
void main()
{
unsigned char lsd_dat, i, j//定义四个字符变量
char buf[15] //定义一个可以存放15个字符的字符数组
i = 0 //给变量i赋值为数字0
init_com() //执行上面定义过的init_com()方法;
while(1) //一个键肆死循环,不断的执行后面{}里的代码
{
delay100ms(speed) //执行前面定义过的void delay100ms(unsigned char n)方法
//首次执行时,speed是开始时定义的5
lsd_dat = 0x01 << i//变量lsd_dat赋值为1,也就是二进制的0000 0001
P1 = lsd_dat //把P1寄存器置为 lsd_dat的值的二进制状态
buf[0] = 'D' //把buf字符数组的首个值赋值为字符D,ascii码为68
含兆 //等同于十进制数字68,二进制 0100 1000
for (j = 0 j < 8++j)//进行8次循环,每次循环j的值加1
buf[j + 1] = '0' + ((lsd_dat & (0x01 << j)) ? 1 : 0)//这段有点麻烦
//给buf数组的第j+1个存储单元赋值,这个值是不确定的
//如果(lsd_dat & (0x01 << j))的运算结果不是0
//那么他就等于‘O'+1,否则就等于‘0’+0;
//这里,我不知道‘0’是字母o的大写,还是数字0,应该是数字0
//下面说(lsd_dat & (0x01 << j))的运算
//lsd_dat就是上面定义的变量,他第一次执行时的值是0000 0001
//他会不会变取决与以后的代码有没有改变他
//(0x01 << j)这个作用是,把0000 0001 向左移动j个位,右边补0
//比如说j的值是2,就是左移两位,那么(0x01 << j)的值就是0000 0100
//j是每次循环都在变,所以这个值也在变
//现在我们就当j的值运行到等于2的时候来看(lsd_dat & (0x01 << j))
//可以看成(0x01&0x04)这是一个与运算,结果看下面
// 0x01 0000 0001
// 0x04 0000 0100
// & 0000 0000 结果就是0
//j=2的话,((lsd_dat & (0x01 << j)) ? 1 : 0)=0;
//'0' 是数字的话,值是十进制48,
//'0' + ((lsd_dat & (0x01 << j)) ? 1 : 0)=48,还是字符‘0’
//也就是说((lsd_dat & (0x01 << j)) ? 1 : 0)的值,不是0,就是1
//那么,'0' + ((lsd_dat & (0x01 << j)) ? 1 : 0)他的值
//不是48,就是49,也就是字符面的'0'或者‘1’,
buf[9] = '\r'//buf字符数组的第10个存储空间赋值为换行符 ‘\r’
buf[10] = '\n'//buf字符数组的第11个存储空间赋值为换行符 ‘\n’
buf[11] = 0 //buf字符数组的第10个存储空间赋值为0
printf(buf) //输出字符数组
++i //i的值自增1
if (i >=8) //如果i大于或者等于8
i=0 //把i重置为0
}
}
void es () interrupt 4 //定义一个给51单片机发送数据的方法
{
unsigned char dat //定义一个字符变量
if(RI) //如果RI寄存器非空,执行后面{}里面的内容
{
RI = 0 //把RI寄存器清空
dat = SBUF //把SBUF寄存器的值赋给dat变量
SBUF = dat //再把SBUF寄存器设置成dat变量表示的内容
while(TI == 0) //等待到TI寄存器非空的时候继续下面的代码
TI = 0 //把TI寄存器重置清空 (时间有限,简单说了)
if (dat == 'L' //如果dat变量的值等与字符‘L’,执行后面{}内的代码
{
rec_idx = 0 //把rec_idx变量赋值为0(此处不是字符‘0’,而是内码);
rec_buf[rec_idx++] = dat//给数组rec_buf[0]赋值为dat变量的值,
//并且rec_idx的值自增1
}
else if (rec_idx > 0)//如果上面那个条件不成立,并且rec_idx大于0,
//则执行后面{}里的内容
{
rec_buf[rec_idx++] = dat//给数组rec_buf的第rec_idx个赋值为dat变量的值,
//并且rec_idx的值自增1
if (dat > '0' && dat <= '9')//如果dat大于‘0’(48)并且小于等于‘9’(57)
//则执行下条代码,否则跳过下行代码
speed = 10 - (dat - '0')//给变量speed赋值为10-(dat-48)
rec_idx = 0 //给变量rec_idx赋值为0
}
}
}
看在这么精细,字又多的份上,分给我吧,虽然,我也是半瓶水,应该这些是没错的。现在时间都0:58了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)