org 00h ;mov 96h,#00111111b;p2M1 mov 8eh,#0 ;允许使用内部扩展的ram jmp cfg org 0bh jmp t0int org 1bh jmp t1int ;40保存设定时间,41保存A分数,42保存B分数,43保存当前时间(正在计时),44保存发声地址 cfg: mov 55h,#20 mov 40h,#30 ;开机时的初始分数 mov 41h,#00 ;左计分 mov 42h,#00 ;右计分 mov 43h,#30 ;读取初始时间从40读来 mov 5dh,#14;发开机声,可以分别查表不同的发声频率,不同的发声时间 mov r2,#1;工作模式,单机分别模式双机同时模式 mov tmod,#00100010b;t1工作方式二自动装入 mov th0,#245 ;12MHz时,1US*50=50us(20KHz,0.05ms)扫描一下转向记数 setb tr0 setb et0 setb ea main: call js call disp call key1 call key2 call key3 call run1 jb 10h, main call run2 call run3 jmp main key1:jb 09h,k1edd setb 09h jb p2.7,k1ed jb 08h,k1edd setb 08h mov r0,#15 mov a,40h cjne a,#90,rr10 mov 40h,#15 rr10:inc 40h djnz r0,rr10 mov 43h,40h clr 11h ;允许倒计时和加分 ret k1ed:clr 08h k1edd:ret key2: k2ed:ret key3: k3ed:ret run1:jb 0fh,r1ed setb 0fh dec 43h clr 10h ;允许计分 mov a,43h cjne a ,#0, rrrr setb 10h ;不许计分 setb 11h;还要加个不充再减 rrrr:mov a,#10 cjne a,43h,$+3 jc r1ed mov 5dh ,#0 ;发声 r1ed:ret run2: jb 0dh,r2ed setb 0dh jb p3.1,r3ed jb p3.0,r3ed inc 41h inc 41h mov 5dh ,#2 ;发声 mov a,#10 cjne a,43h,$+3 jc r2ed inc 41h r2ed:ret run3: jb 0bh,r3ed setb 0bh jb p3.2,r3ed jb p3.3,r3ed inc 42h inc 42h mov 5dh ,#4 ;发声 mov a,#10 cjne a,43h,$+3 jc r3ed inc 42h r3ed:ret t1int:jmp $ mov th0,#(65535-1000)/255 mov tl0,#(65535-1000) push acc push psw mov psw,#11000b mov a,p2 ;设p2.6/p2.7检测,r6记录123顺序,3dh记录上一次值,21h记录检测的桉键值 anl a,#11000000b ek0: cjne a,#00000000b,ek2 ;检查出现在的状态 cjne r6,#01000000b,ek1 ;查看上一次的状态 call inc1 ek1: cjne r6,#10000000b,ek2 ;查看上一次的状态 call dec1 ek2: cjne a,#01000000b,ek4 ;检查出现在的状态 cjne r6,#11000000b,ek3 ;查看上一次的状态 call inc1 ek3: cjne r6,#00000000b,ek4 ;查看上一次的状态 call dec1 ek4: cjne a,#11000000b,ek6 ;检查出现在的状态 cjne r6,#10000000b,ek5 ;查看上一次的状态 call inc1 ek5: cjne r6,#01000000b,ek6 ;查看上一次的状态 call dec1 ek6: cjne a,#10000000b,ek8 ;检查出现在的状态 cjne r6,#00000000b,ek7 ;查看上一次的状态 call inc1 ek7: cjne r6,#11000000b,ek8 ;查看上一次的状态 call dec1 ek8: mov r6,a ;将本次伯数据保存 mov a,42h cjne a,#0,ek9 setb p2.0 jmp t0d ek9: cpl p2.0 djnz 43h,t0d mov 43h,#100 dec 42h t0d: pop psw pop acc reti t0int: push acc push psw cpl p2.6 call su1 pop psw pop acc djnz 57h,t0end djnz 56h,t0end clr 0dh clr 0bh mov 56h,#20 clr 09h djnz 55h,t0end mov 55h,#20 jb 11h,t0int ;高电平不允许计时 clr 0fh t0end: reti su1:mov a,5dh ;8音播放程序,58/59延时,59是0就停,5a分频系数,5b步数,5c分频,5d是N首两倍,是1停止,高频固定调用 cjne a,#1,su6 ;查看1新声音标志,5e/5f为当前表,占用资源ACC/PSW/DPTR/58H-5AH mov a,59h cjne a,#0,su7 ;查看0声音结束标志, jmp su3 su2:mov a,5ah cjne a,#0,su4 ;查看是否需要静音 su3:setb p2.0 ret su4:djnz 5ch,su5 ;不需静音就分频发音 mov 5ch,5ah cpl p2.0 su5:ret su6:mov dptr,#sds ;查表看该唱哪一首歌 movc a,@a+dptr mov 5eh,a mov a,5dh inc a movc a,@a+dptr mov 5fh,a mov 5dh,#1 ;只查一次 mov 5bh,#0 ;从该首头开始放 jmp su8 su7:djnz 58h,su2 ;延时 mov 58h,#200 ;延时 djnz 59h,su2 ;发声时间减1到0后查下一步时间和音调 inc 5bh su8:mov a,5bh ;发声的查表程序 mov dph,5eh ;装入当前首表地址 mov dpl,5fh ;装入当前首表地址 movc a,@a+dptr ;查出当前步时间和音调,上半字节为时间0为结束,下半字节为音调D为静音 mov 59h,a ;发声时间,结束标志为0,最长时间为15个单位, anl a,#0fh ;进一步查出音调, mov dptr,#sbb ;查音阶分频表, movc a,@a+dptr mov 5ah,a ;音调分频系数 mov a,59h ;再求出发生时间 anl a,#0f0h ;删除音调数据 ret saa:db 255,227,203, 191,170,152,143,128,114,101, 96,85,76,0;高频晶振音阶分频数据,音准高 sbb:db 101,90, 81, 76, 67, 60, 57, 51, 45, 40, 38,34,30,0;低频晶振音阶分频数据,音准较差 ;sbb:db 10,9, 8, 7, 6, 5, 4, 3, 2, 1, 38,34,30,0;低频晶振音阶分频数据,音准较差 sds:db sd1/255,sd1,sd2/255,sd2,sd3/255,sd3,sd4/255,sd4,sd5/255,sd5,sd6/255,sd6,sd7/255,sd7,sd8/255,sd8 sd1:db 48h,0;声音数据:前面是时间,0结束,后面是音调,d静音. sd2:db 1ch,1dh,1ch,0 sd3:db 18h,1dh,18h,1dh,1ch,0 sd4:db 1ch,1dh,1ch,1dh,1ch,1dh,1ch,1dh,1ch,0 sd5:db 1ch,15h,1dh,1ch,15h,0 sd6:db 1ch,15h,1dh,1ch,15h,0 sd7:db 4ch,4bh,4ah,49h,48h,47h,46h,45h,44h,43h,42h,41h,40h,0 sd8:db 40h,41h,42h,43h,44h,45h,46h,47h,48h,49h,4ah,4bh,4ch,0;8音程序结束 inc1:mov 02h,#0 ;模式为0 inc 39h mov r4 ,39h cjne r4,#0,iend inc 38h iend:ret dec1:mov 02h,#0 ;模式为0 dec 39h mov r4 ,39h cjne r4,#255,dend dec 38h dend:ret d10ms:mov r7,#10 d1ms:djnz r6 ,$ djnz r7 ,d1ms ret js: mov a,41h mov b,#10 div ab mov 30h,a mov 31h,b mov a,30h mov b,#10 div ab mov 30h,b mov a,43h mov b,#10 div ab mov 32h,a mov 33h,b mov a,32h mov b,#10 div ab mov 32h,b mov a,42h mov b,#10 div ab mov 34h,a mov 35h,b mov a,34h mov b,#10 div ab mov 34h,b ret disp: djnz r7,$+4 mov r7,#6 mov a,r7 mov dptr,#tab1 movc a,@a+dptr ;mov p1,#0ffh orl p1,#11111011b ;anl p2,#11000000b anl a,#00111111b ;orl p2,a ;mov p2,a mov a,r7 add a,#2fh mov r0,a mov a,@r0 mov dptr,#tab2 movc a,@a+dptr mov c,p1.2 anl p1,a mov p1.2,c ret tab1: db 11000000b,11000001b,11000010b,11000100b,11001000b,11010000b,11100000b tab2: db 10000100b,11101110b,01000101b,01000110b,00101110b,00010110b,00010100b,11001110b,00000100b,00000110b,00001100b,00110100b,10010101b,01100100b,00010101b,00011101b,00000000b ys00:djnz 50h,$ mov 50h,#10 djnz 51h, ys00 ret TAB2b: DB 11H,0D7H,32H,92H,0D4H,98H,18H,0D3H,10H,90H,50H,1CH,39H,16H,38H,78H,0ffH,0ffh,0ffh,0ffh tab1b:db 10b,1b,100b,10000b,1000b,100000b,1000000b,10000000b;2a 1b 5c 7d 6e 3f 4g ;tab2:db 10000b,11011100b,101000b,01001000b,11000100b,01000010b,10b,11011000b,0b,1000000b,11111110b,9;2a 1b 5c 7d 6e 3f 4g tab3:db 0001000b,1101110b,0010100b,0100100b,1100010b,0100001b,0000001b,1101100b,0000000b,0100000b,1111111b tab4:db 00010001b,01111101b,00100011b,00101001b,01001101b,10001001b,10000001b,00111101b,00000001b,00001001b,11111111b end