注意:访问本站需要Cookie和JavaScript支持!请设置您的浏览器! 打开购物车 查看留言付款方式联系我们
初中电子 单片机教材一 单片机教材二
搜索上次看见的商品或文章:
商品名、介绍 文章名、内容
首页 电子入门 学单片机 免费资源 下载中心 商品列表 象棋在线 在线绘图 加盟五一 加入收藏 设为首页
本站推荐:
正则表达式
文章长度[11727] 加入时间[2007/3/19] 更新时间[2021/9/18 3:54:48] 级别[0] [评论] [收藏]

org 00h
mov p1,#00000000b ;让输出口全部为高电平,p3口的状态根据本寄存器变化
mov 92h,#11111111b ;让输出口全部为高电平,p3口的状态根据本寄存器变化

mov r6,#0;设定工作在正常模式
mov r0,#80h
mov r1,#0h
sta:mov 0e3h,#10h;从FLASH中读出已前学习存储到的代码,放到内存中,从80h-0ffh共64字节,
mov 0e4h,r1
mov 0e7h,#0
orl 0e7h,#10000000b
mov 0e5h,#1
mov 0e6h,#46h
mov 0e6h,#0b9h
nop
mov 0e7h,#0
mov 0e5h,#0
mov 0e6h,#0
mov @r0,0e2h
inc r0
inc r1
cjne r0,#0h, sta;全部读到内存中,以便和收到的代码进行比较,确定开关灯

main:
jb p3.7,bgao;有信号时往下延时进入记录状态
djnz 3ah,bdi;
call rec

bgao:mov 3ah,#60;始终在3ah放入信号初始时的低电平时间
bdi:call key
call run


fs2:cjne r6,#4,fs3   ;表示正在学习模式,5dh是闪动的,让当前要学习的IO口也根着闪动
mov r7,39h;取出当前路数

fs0:cjne r7,#1,san1
mov c,5dh
mov p1.0,c
san1:cjne r7,#2,san2
mov c,5dh
mov p1.1,c
san2:cjne r7,#3,san3
mov c,5dh
mov p1.2,c
san3:cjne r7,#4,san4
mov c,5dh
mov p1.3,c
san4:cjne r7,#5,san5
mov c,5dh
mov p1.4,c
san5:cjne r7,#6,san6
mov c,5dh
mov p1.5,c
san6:cjne r7,#7,san7
mov c,5dh
mov p1.6,c
san7:cjne r7,#8,fs3
mov c,5dh
mov p1.7,c


fs3:cjne r6,#8,fsend   ;表示清除模式,删除当前按键以前学习过的内容,
setb 4eh
call clea              ;调用删除程序
fsend:djnz 3ch,main


mov 3ch,#100
djnz 3bh,main
mov 3bh,#30
clr 3dh        ;延时状态位   
clr 4dh        ;延时状态位  
cpl 5dh              ;大循环时延时后让5dh会高低电平变化,产生闪亮的感觉
jmp main


key:mov r7,#0   ;按键值先清零


orl p3,#00111100b
anl p3,#11111100b
mov a,p3
orl p3,#00000011b
anl p3,#11000011b
orl a,p3
orl a,#11000000b
ky0:cjne a,#11111001b,ky1
mov r7,#1
ky1:cjne a,#11110101b,ky2
mov r7,#2
ky2:cjne a,#11101101b,ky3
mov r7,#3
ky3:cjne a,#11011101b,ky4
mov r7,#4
ky4:cjne a,#11110110b,ky5
mov r7,#5
ky5:cjne a,#11111010b,ky6
mov r7,#6
ky6:cjne a,#11101110b,ky7
mov r7,#7
ky7:cjne a,#11011110b,ky8
mov r7,#8


ky8:cjne r7,#0,ky ;有键的情况,跳到ky

mov 3eh,#20
jb 3dh,rkend
setb 3dh
djnz 3fh,rkend
mov r6,#0    ;长期无键按下就将正常工作模式置为0,4是学习模式,8是清除模式。(后面可以看出,一旦某些工作完成了,模式就会设为0)
rkend:ret

ky:mov 3dh,r7
mov 39h,r7 ;按过第几路键,当前路数就是第几,长期保存
mov 3fh,#100
jb 3dh,rkend
setb 3dh
djnz 3eh,rkend
cjne r6,#4,mm1  
mov r6,#8            ;学习模式4还在长按键时,就进入清除模式8,
mm1:cjne r6,#0,mm2 
mov r6,#4           ;如果是正常工作模式0时长按键的话,就进入学习模式4
ret
mm2:mov r6,#8
ret

run:cjne r7,#0,rkend  ;功能执行程序,r7内装的是键盘扫描的数据,等于0说明按键已经松开,可以执行按键程序

run0:mov r7,3dh;
     mov 3dh,#0;以免下次再次执行
     cjne r7,#1,run1
cpl p1.0          ;改变输出状态,以后相同
run1:cjne r7,#2,run2
cpl p1.1
run2:cjne r7,#3,run3
cpl p1.2
run3:cjne r7,#4,run4
cpl p1.3
run4:cjne r7,#5,run5
cpl p1.4
run5:cjne r7,#6,run6
cpl p1.5
run6:cjne r7,#7,run7
cpl p1.6
run7:cjne r7,#8,rkend
cpl p1.7

r35:mov r3,#2;设定延时时间,不同晶振和不同振荡电阻时需要更改不同的值,用示波器看波形宽度大致相当即可
    mov r5,#180
   ;cpl p1.0;这句是输出一个信号用示波器测量波形宽度用的,大家要学习这种方法,程序运行可以通过观查IO口
;程序完全调试成功后,就必须删除这句(确实有多的IO口不删留空也可以)。
ret

 

rec:mov 20h,#0;按照信号规律记录信号
mov 21h,#0
mov 22h,#0
call r35;装入延时值
mov r3,#10
rec0s:jb p3.7,rec0n;现在进入一个延时程序,一边延时一边检查p3.7的状态,
djnz r5,rec0s
djnz r3,rec0s
ret;如果超过时间都没有变化,说明信号是无效的,程序返回

rec0n:call r35;装入延时值
rec0x:jnb p3.7,rec1
djnz r5,rec0x
setb 00h;在r5的这个合适的延时时间,定为高电平,将第1字节的第一位写入高电平(这里用了位地址),否则是低电平,都有效
djnz r3,rec0x
ret;如果超过时间都没有变化,说明信号是无效的,程序返回


rec1:call r35;装入延时值
rec1s:jb p3.7,rec1n
djnz r5,rec1s
djnz r3,rec1s
ret;如果超过时间都没有变化,说明信号是无效的,程序返回

rec1n:call r35;装入延时值
rec1x:jnb p3.7,rec2
djnz r5,rec1x
setb 01h;在r5的这个合适的延时时间,定为高电平,将第1字节的第一位写入高电平(这里用了位地址),否则是低电平,都有效
djnz r3,rec1x
ret;如果超过时间都没有变化,说明信号是无效的,程序返回,以后相同

rec2:call r35;装入延时值
rec2s:jb p3.7,rec2n
djnz r5,rec2s
djnz r3,rec2s
ret

rec2n:call r35;装入延时值
rec2x:jnb p3.7,rec3
djnz r5,rec2x
setb 02h;在r5的这个合适的延时时间,定为高电平,否则是低电平,以后相同
djnz r3,rec2x
ret

rec3:call r35;装入延时值
rec3s:jb p3.7,rec3n
djnz r5,rec3s
djnz r3,rec3s
ret
rec3n:call r35;装入延时值
rec3x:jnb p3.7,rec4
djnz r5,rec3x
setb 03h
djnz r3,rec3x
ret

rec4:call r35;装入延时值
rec4s:jb p3.7,rec4n
djnz r5,rec4s
djnz r3,rec4s
ret
rec4n:call r35;装入延时值
rec4x:jnb p3.7,rec5
djnz r5,rec4x
setb 04h
djnz r3,rec4x
ret
rec5:call r35;装入延时值
rec5s:jb p3.7,rec5n
djnz r5,rec5s
djnz r3,rec5s
ret
rec5n:call r35;装入延时值
rec5x:jnb p3.7,rec6
djnz r5,rec5x
setb 05h
djnz r3,rec5x
ret
rec6:call r35;装入延时值
rec6s:jb p3.7,rec6n
djnz r5,rec6s
djnz r3,rec6s
ret
rec6n:call r35;装入延时值
rec6x:jnb p3.7,rec7
djnz r5,rec6x
setb 06h

djnz r3,rec6x
ret
rec7:call r35;装入延时值
rec7s:jb p3.7,rec7n
djnz r5,rec7s
djnz r3,rec7s
ret
rec7n:call r35;装入延时值
rec7x:jnb p3.7,rec8
djnz r5,rec7x
setb 07h

djnz r3,rec7x
ret
rec8:call r35;装入延时值
rec8s:jb p3.7,rec8n
djnz r5,rec8s
djnz r3,rec8s
ret
rec8n:call r35;装入延时值
rec8x:jnb p3.7,rec9
djnz r5,rec8x
setb 08h

djnz r3,rec8x
ret
rec9:call r35;装入延时值
rec9s:jb p3.7,rec9n
djnz r5,rec9s
djnz r3,rec9s
ret
rec9n:call r35;装入延时值
rec9x:jnb p3.7,rec10
djnz r5,rec9x
setb 09h

djnz r3,rec9x
ret
rec10:call r35;装入延时值
rec10s:jb p3.7,rec10n
djnz r5,rec10s
djnz r3,rec10s
ret
rec10n:call r35;装入延时值
rec10x:jnb p3.7,rec11
djnz r5,rec10x
setb 0ah

djnz r3,rec10x
ret
rec11:call r35;装入延时值
rec11s:jb p3.7,rec11n
djnz r5,rec11s
djnz r3,rec11s
ret
rec11n:call r35;装入延时值
rec11x:jnb p3.7,rec12
djnz r5,rec11x
setb 0bh

djnz r3,rec11x
ret
rec12:call r35;装入延时值
rec12s:jb p3.7,rec12n
djnz r5,rec12s
djnz r3,rec12s
ret;ret
rec12n:call r35;装入延时值
rec12x:jnb p3.7,rec13
djnz r5,rec12x
setb 0ch

djnz r3,rec12x
ret
rec13:call r35;装入延时值
rec13s:jb p3.7,rec13n
djnz r5,rec13s
djnz r3,rec13s
ret
rec13n:call r35;装入延时值
rec13x:jnb p3.7,rec14
djnz r5,rec13x
setb 0dh

djnz r3,rec13x
ret
rec14:call r35;装入延时值
rec14s:jb p3.7,rec14n
djnz r5,rec14s
djnz r3,rec14s
ret
rec14n:call r35;装入延时值
rec14x:jnb p3.7,rec15
djnz r5,rec14x
setb 0eh
djnz r3,rec14x
ret

rec15:call r35;装入延时值
rec15s:jb p3.7,rec15n
djnz r5,rec15s
djnz r3,rec15s
ret
rec15n:call r35;装入延时值
rec15x:jnb p3.7,rec16
djnz r5,rec15x
setb 0fh
djnz r3,rec15x
ret

rec16:call r35;装入延时值
rec16s:jb p3.7,rec16n
djnz r5,rec16s
djnz r3,rec16s
ret
rec16n:call r35;装入延时值
rec16x:jnb p3.7,rec17
djnz r5,rec16x
setb 10h
djnz r3,rec16x
ret

rec17:call r35;装入延时值
rec17s:jb p3.7,rec17n
djnz r5,rec17s
djnz r3,rec17s
ret
rec17n:call r35;装入延时值
rec17x:jnb p3.7,rec18
djnz r5,rec17x
setb 11h
djnz r3,rec17x
ret

rec18:call r35;装入延时值
rec18s:jb p3.7,rec18n
djnz r5,rec18s
djnz r3,rec18s
ret
rec18n:call r35;装入延时值
rec18x:jnb p3.7,rec19
djnz r5,rec18x
setb 12h
djnz r3,rec18x
ret

rec19:call r35;装入延时值
rec19s:jb p3.7,rec19n
djnz r5,rec19s
djnz r3,rec19s
ret
rec19n:call r35;装入延时值
rec19x:jnb p3.7,rec20
djnz r5,rec19x
setb 13h
djnz r3,rec19x
ret

rec20:call r35;装入延时值
rec20s:jb p3.7,rec20n
djnz r5,rec20s
djnz r3,rec20s
ret
rec20n:call r35;装入延时值
rec20x:jnb p3.7,rec21
djnz r5,rec20x
setb 14h
djnz r3,rec20x
ret

rec21:call r35;装入延时值
rec21s:jb p3.7,rec21n
djnz r5,rec21s
djnz r3,rec21s
ret
rec21n:call r35;装入延时值
rec21x:jnb p3.7,rec22
djnz r5,rec21x
setb 15h
djnz r3,rec21x
ret

rec22:call r35;装入延时值
rec22s:jb p3.7,rec22n
djnz r5,rec22s
djnz r3,rec22s
ret
rec22n:call r35;装入延时值
rec22x:jnb p3.7,rec23
djnz r5,rec22x
setb 16h
djnz r3,rec22x
ret

rec23:call r35;装入延时值
rec23s:jb p3.7,rec23n
djnz r5,rec23s
djnz r3,rec23s
ret
rec23n:call r35;装入延时值
rec23x:jnb p3.7,rec24
djnz r5,rec23x
setb 17h          ;到此时为止,已经连续记录到了40次以上p3.7在合法的时间内高低电平的变化,这必须是有规律的信号才可能产生。
djnz r3,rec23x
ret               ;到此时为止,遥控器发送的信号也将重复下一个循环,进行下一轮记录。

rec24:;现在将这个记录到的3个字节(20/21/22h)的数据和(24/25/26h)中的数据进行比较,如果不相等,就将这些数存到后面的寄存器
mov a,20h
cjne a,24h,bgbd
mov a,21h
cjne a,25h,bgbd
mov a,22h
cjne a,26h,bgbd
jb 4dh,bgbd
setb 4dh         ;经过最少两轮记录的信号数据相比较是完全相等的,这说明确实收到了一个有效的遥控信号,
mov r4,#0h
cjne r6,#4,cread ;根据r6中的值来确定做如何工作
mov r6,#0
call wir
cread:call read
ret
bgbd:mov 24h,20h
mov 25h,21h
mov 26h,22h
jmp rec


read:mov a,r4 ;读出内存中的数据并和收到记录的数据比较,相同就执行功能。r4表示当前是第几路的数据
rl a
rl a
add a,#80h
mov r0,a
mov a,@r0
mov 3dh,@r0
inc r0
mov a,@r0
cjne a,24h,readend
inc r0
mov a,@r0
cjne a,25h,readend
inc r0
mov a,@r0
cjne a,26h,readend
call run0           ;经过比较数据一样就去运行程序功能,3dh中的数表示要去控制哪一路开关
readend:inc r4
cjne r4,#32,read
mov 3dh,#0
ret


wir:mov a,r4 ;要先将接收到的数据保存到内存中,这必须先和内存中的数据进行比较,已经有了该数据了就不要保存,r4表示当前是保存的第几路数据,这里需要循环检查每一路,由于内存有限,本程序最多只记忆32路
rl a         ;rl a这是乘2的意思
rl a         ;rl a还是乘2,两次乘2就等于*4,因为用四个字节才保存一组开关数据,一个字节要表示是第几路开关,三个字节表示密码
add a,#80h
mov r0,a
mov a,@r0
wy0:cjne a,#0ffh,wend ;读出的数据是空白的才可以写入,否则会盖掉以前的有用数据


wing:
mov @r0,39h
inc r0
mov @r0,24h
inc r0
mov @r0,25h
inc r0
mov @r0,26h
call save
ret
wend:inc r4
cjne r4,#32,wir ;如果能运行到这里,说明每个存储区都已经保存了数据,下面关掉全部的LED表示提示,请删除一些记忆
mov p1,#0
ret

save:         ;要将收到数据即学习到的数据保存在FLASH中,防止停电后丢失数据。说明:以下这些操作是没有理由的,请查相关资料
mov 0e3h,#10h
mov 0e4h,#00h
mov 0e7h,#0
orl 0e7h,#10000000b
mov 0e5h,#3
mov 0e6h,#46h
mov 0e6h,#0b9h        ;为什么说这些操作没有理由?因为单片机的任何操作都是将数(指令或者数据)搬来搬去,芯片设计时就是只要放上这些命令,FLASH读写功能就自动完成了。(驱动液晶、18B20测试温度、串行通信等等都是一样,别公司型号的单片机等,都是一样,放上不同的指令就完成了不同的功能,而这些都是要查相关的资料的。)
nop
mov 0e7h,#0
mov 0e5h,#0
mov 0e6h,#0
mov r0,#80h
mov r1,#0
sav:mov 0e3h,#10h  ;重复进行写入FLASH
mov 0e4h,r1
mov 0e2h,@r0
mov 0e7h,#0
orl 0e7h,#10000000b
mov 0e5h,#2
mov 0e6h,#46h
mov 0e6h,#0b9h
nop
mov 0e7h,#0
mov 0e5h,#0
mov 0e6h,#0
inc r0
inc r1
cjne r0,#0h,sav   ;重复循环将全部数据保存到FLASH中
ret


clea:mov r4,#0    ;删除已经记忆在内存中的数据,并从FLASH中也删除(在内存中删除后再保存到FLASH中即可)
clea0:mov a,r4
rl a
rl a
add a,#80h
mov r0,a
mov a,@r0
cjne a,3dh,cleaend
mov @r0,#0ffh      ;填入0数据就表示删除
clr 4eh
cleaend:inc r4
cjne r4,#32,clea0
jb 4eh,clea1
call save      ;还要保存到FLASH中
clea1:mov 3dh,#0
mov r6,#0
ret

end

 

1、 本站不保证以上观点正确,就算是本站原创作品,本站也不保证内容正确。
2、如果您拥有本文版权,并且不想在本站转载,请书面通知本站立即删除并且向您公开道歉! 以上可能是本站收集或者转载的文章,本站可能没有文章中的元件或产品,如果您需要类似的商品请 点这里查看商品列表!
本站协议 | 版权信息 |  关于我们 |  本站地图 |  营业执照 |  发票说明 |  付款方式 |  联系方式
深圳市宝安区西乡五壹电子商行——粤ICP备16073394号-1;地址:深圳西乡河西四坊183号;邮编:518102
E-mail:51dz$163.com($改为@);Tel:(0755)27947428
工作时间:9:30-12:00和13:30-17:30和18:30-20:30,无人接听时可以再打手机13537585389