简易电子琴的设计
本次设计中单片机晶振为12MHZ,那么定时器的计数周期为1MHZ,假如选择工作方式1,那T值便为T= 216--5﹡105/相应的频率 ,那么根据不同的频率计算出应该赋给定时器的计数值,列出不同音符与单片机计数T0相关的计数值如下表所示:
音符 | 频率(HZ) | 简谱码(T值) |
中 1 DO | 523 | 64580 |
中 2 RE | 587 | 64684 |
中 3 M | 659 | 64777 |
中 4 FA | 698 | 64820 |
中 5 SO | 784 | 64898 |
中 6 LA | 880 | 64968 |
中 7 SI | 988 | 65030 |
采用查表程序进行查表时,可以为这个音符建立一个表格,有助于单片机通过查表的方式来获得相应的数据:
TABLE DW 64580,64684,64777,64820,64898,64968,65030
源程序:
方案一:产生按键音符
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP BREAK
MAIN: MOV TMOD,#01H ;设置定时器0的工作方式
SETB EA
SETB ET0 ; 设置定时器0中断
SETB TR0 ; 启动定时器0
WAIT1: LCALL KEY ; 调用KEY子程序,判断有键按下否?第几个键?
CLR EA ;屏蔽中断
CJNE R3,#00H,WAIT1 ;如果R3=0,表示有键按下
MOV A,22H ;将22H里存放的按键号送给A
RL A ; 因为查表里都是字,所以得乘2查得数据
MOV DPTR,#TABLE ;指向表头
MOVC A,@A+DPTR ; 查表
MOV TH0,A ;将数据高位送TH0
MOV 21H,A ; 将高位备份
MOV A,22H ;将22H里存放的按键号送给A
RL A ;因为查表里都是字,所以得乘2查得数据
INC A ;取低位数据
MOVC A,@A+DPTR
MOV TL0,A
MOV 20H,A
WAIT2: LCALL KEY
SETB EA
CJNE R3,#00H,WAIT1
JMP WAIT2
KEY: MOV R3,#00H ; KEY子程序,判断有键按下否?第几个键?
MOV R1,#0FFH
MOV R0,#00H
MOV A,R1
MOV P2,A
MOV A,P2
CLR C
CPL C ;利用标志位CY来判断是哪个键按下
MOV R2,#08H
WAIT3: RLC A ;移位判断
JNC STORE
INC R0
DJNZ R2,WAIT3
STORE: MOV 22H,R0 ; 将按键号存22H,R3=0有键按下
MOV R3,#00H
RET
BREAK: PUSH ACC ; 中断产生方波,从P1.0口输出
PUSH PSW
MOV TL0,20H
MOV TH0,21H
CPL P1.0
POP PSW
POP ACC
RETI
TABLE: DW 65030,64968,64898,64820,64777,64684,64580 ; 7,6,5,4,3,2,1
END
方案二:产生按键音符
ORG 0000H
SJMP START
ORG 000BH
AJMP INT_0
ORG 0030H
START: MOV P1,#00H
SETB EA
SETB ET0 ;计数器0
MOV TMOD,#02H
MOV TH1,#09CH
MOV TL1,#09CH ;定时器初植
CLR TR0 ;定时器不允许
SCAN: ;键盘扫描
MOV A,P2 ;判断键盘按下,跳到SCAN_1,若未按,继续扫描
CJNE A,#0FFH,SCAN_1
NOP
SJMP SCAN
SCAN_1:ACALL DELAY ;是不是真的要按下?如果是,则跳转SU_KEY查询是哪个按下?
MOV A,P2
CJNE A,#0FFH,SU_KEY
NOP
SJMP SCAN
SU_KEY:JNB P2.1,MU_1 ;判断是哪个键按下?
JNB P2.2,MU_2
JNB P2.3,MU_3
JNB P2.4,MU_4
JNB P2.5,MU_5
JNB P2.6,MU_6
JNB P2.7,MU_7
SJMP SCAN
;R1信号周期
MU_1: MOV R1,#19 ;如果第一个按键按下,则R1=19,同时程序转NEXT
SJMP NEXT
MU_2: MOV R1,#17
SJMP NEXT
MU_3: MOV R1,#15
SJMP NEXT
MU_4: MOV R1,#14
SJMP NEXT
MU_5: MOV R1,#13
SJMP NEXT
MU_6: MOV R1,#11
SJMP NEXT
MU_7: MOV R1,#10
SJMP NEXT
NEXT: MOV A,R1
MOV R0,A
SETB TR0 ;启动定时器0
NEXT_1:MOV A,P2 ; 没键按下继续执行,有键按下,返回读引脚
CJNE A,#0FFH,NEXT_1
ACALL DELAY
MOV A,P2 ;真的没键按下?
CJNE A,#0FFH,NEXT_1
CLR TR0 ;不响
相关推荐
-
taxigo | 2005-04-28
-
-
-
hpnet | 2003-05-20
-
younghuang | 2004-08-12
-
-
-
-
-
武松打虎 | 2004-03-27
-
-
-
hwenlong | 2005-03-20
评论