矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 11730|回复: 6

【DIY参赛】AT89C2051制作的节拍器

 关闭 [复制链接]
     
发表于 2009-7-24 14:54:18 | 显示全部楼层 |阅读模式
  本人偶尔弹一下吉它,有一个节拍器还是挺有帮助练习的。曾经想过用555振荡,CD4017指示做节拍器,却未付诸实施。但认识了单片机之后,很多想法都更容易实现了。最开始学习了51系列,用的是AT89S52——因为可以ISP,编程容易。2051/4051体积更小,但需要编程器。后来用AT89S52做了个2051的编程器,才把早前买的那芯片用起来。 当然,现在我喜欢用AVR系列了,这是题外话。
  节拍器的任务就是按照既定的延时提供声、光指示,2051完全可以胜任。我用4位共阳数码管(每个8字的阳极是连在一起的)来进行动态扫描显示,引脚正好够用。外围电路也没有独特的地方,四个按键是利用动态扫描的时候进行检测的。

  还是洞洞板制作,用了一点贴片电阻。那时候还没有用贴片电容。虽然AT89C2051手册说需要3V电压以上,实际我用两节镍氢电池完全可以工作(6MHz),电流也不大,数码管不用限流电阻。

  先前做的了一个送给朋友了,现在这个额外加了一点功能,跟节拍器无关,所以上面多了几个元件。这个芯片是4051,ROM大一点。

  复位过后节拍器进入设置模式,第一个数字显示每小节几拍子(2/3/4/6/8),后三个数字显示每分钟多少拍(24-240调节)。三个按钮是设定这两参数用的。另一个按钮是进入节拍显示模式和蜂鸣开关。我这个板子上面多出来的一个按钮与节拍器无关。

  2/3/4拍子利用数码管笔划中间那一横来指示,6/8拍子则用下面的两个竖笔划。在每小节第一拍,绿色LED闪亮和蜂鸣的声音都要长一点。



  最后附上程序。我没用过C语言写51程序,也不打算用C来写51的程序,所以是汇编的。
;  tempo.asm   version 0.2,  (Dec. 23rd, 2006)
;
;  for AT89C2051/4051 with 6MHz crystal

led1  equ 33h
led2  equ 32h
led3  equ 31h
led4  equ 30h

display  equ 34h
tempo   equ 35h
rlskey  equ 36h
tlong1  equ 37h
tlong2  equ 38h
rdelay  equ 39h
tdelayL equ 3Ah
tdelayH equ 3Bh
beat    equ 3Ch
bb  equ 3Dh
dummy   equ 3Eh

keydown equ 20h.7       ; bit flag
fastkey equ 20h.6

mmode   equ 20h.5
bdark   equ 20h.4
beep    equ 20h.3

keypad  equ 21h

mute    equ 22h.2
pri     equ 22h.1
indoff  equ 22h.0

p0H     equ 5Ah
p0L     equ 28h
p1H     equ 2Fh
p1L     equ 53h

  ORG 0
  AJMP start

  ORG 0Bh          ; interrupt TF0
  XCH  A,display
  JMP @A+DPTR

  ORG 30h
start:
  
    MOV SP, #60h
    MOV display,#0
    MOV keypad,#0Fh

    MOV 20h, #0     ; clear all flags
    MOV DPTR, #dispfunc
    MOV R4, #3
    MOV R3, #10

    MOV A, tdelayH
    CJNE A, p0H, resetmem
    CJNE A, p1H, resetmem
    MOV A, tdelayL
    CJNE A, p0L, resetmem
    CJNE A, p1L, resetmem
    AJMP rmem
resetmem:
    MOV tdelayH, #03h
    MOV tdelayL, #0E8h  ; 1000 for 120 bpm
    MOV tempo, #120
    MOV beat, #4
    MOV 22H, #2
rmem:   
    MOV R7, tdelayH
    MOV R6, tdelayL
    INC R7
    MOV A, tempo
    ACALL showtempo
    ACALL showbeat


    MOV TMOD, #02h      ; Timer 0, 8bit auto reload mode
    MOV TH0, #6         ; preset 250 counts, 0.5 ms for 6MHz crystal
    MOV TL0, #6
    MOV IE, #82h          ; enable interrupts, set EA and ET0
    SETB TR0          ; start timer 0

main:                           ;The main loop
    ORL PCON,#1                 ;Enter IDLE mode and wait for Timer interrupt

    JNB beep, a1
    CPL P3.0                    ; generate 1000Hz square wave

a1: MOV A, keypad
    CJNE A, #0Fh, chkkey

    DJNZ rlskey, meter          ; wait for 50ms before read next key
                                ; auto exec every 256 cycles, when no key
    MOV tlong1, #30
    MOV tlong2, #40
    CLR fastkey
    CLR keydown                 ; reset key states

    JB mmode, meter             ; skip when in meter mode

    DJNZ R4, meter              ; R4 controls the freqency of blinking
    JBC bdark, a2
    SETB bdark                  ; next time it will go dark
    MOV A, #0FFh
    MOV led1, A
    MOV led2, A
    MOV led3, A
    MOV led4, A                 ; clear digital display
    MOV R4, #4
    DJNZ R3, meter              ; R3 controls the idle time of setting mode
    MOV 22h, #4                 ; initially muted
    AJMP chmm                   ; auto change to beat mode, to save power
a2: MOV A, tempo
    ACALL showtempo
    ACALL showbeat
    MOV R4, #3

meter:
    DJNZ R5, a3                 ; R5 controls the time of sound/light
    SETB P3.1                   ; turn off the flash LED
    CLR beep
    SETB P3.0

a3: DJNZ R6, main
    MOV R6, #0
    DJNZ R7, main
    MOV R7, tdelayH
    MOV R6, tdelayL             ; reload values for R6 and R7
    CJNE R6, #0, a4
    DEC R7
a4: INC R7
    AJMP showtick


chkkey:
        JB keydown, keydelay
        MOV R3, #10
        SETB keydown
        MOV rlskey, #100
which:  CJNE A,#0Dh,key234
        JB mmode, chms              ; key 1
        MOV A, tempo
        CJNE A, #240, tinc
        AJMP meter
key234: CJNE A,#0Eh,key34
        JB mmode, chms              ; key 1
        MOV A, tempo
        CJNE A, #24, tdec
        AJMP meter
key34:  CJNE A,#0Bh,key4
        JB mmode, chms              ; key 3
        MOV A,beat
        INC A
        CJNE A,#5,sbn5
        INC A           ; 5 --> 6
sbn5:   CJNE A,#7,sbn7
        INC A           ; 7 --> 8
sbn7:   CJNE A,#9,sbn9
        MOV A, #2       ; 9 --> 2
sbn9:   MOV beat, A
        ACALL showbeat
        AJMP meter
key4:   CJNE A,#7h, lwait
        JNB fastkey, chls
        AJMP poweroff               ; turn off power if long hold this key

chms:   CLR mmode
        MOV A, tempo
        ACALL showtempo
        ACALL showbeat
        AJMP meter
chmm:   SETB mmode
        MOV bb, #0
        MOV R7,#1                   ; cause no delay
lwait:  AJMP meter

keydelay:
        JB fastkey, repeat
        DJNZ tlong1, lwait
        MOV tlong1, #30
        DJNZ tlong2, lwait
        MOV tlong2, #40
        SETB fastkey
        MOV rdelay, #1
repeat: DJNZ rdelay, lwait
        MOV rdelay, #30
        AJMP which

tinc:   MOV R0, A                   ; save the value
        CLR EA                      ; disable interrupt
        MOV DPTR, #(timetable-24)
        MOVC A,@A+DPTR
        MOV DPTR, #dispfunc
        SETB EA
        XCH A,tdelayL
        CLR C
        SUBB A,tdelayL
        MOV tdelayL,A
        JNC a10
        DEC tdelayH
a10:    MOV A, R0
        INC A
        MOV tempo, A
        ACALL showtempo
        AJMP meter
tdec:   DEC A
        MOV tempo, A
        MOV R0, A
        CLR EA                      ; disable interrupt
        MOV DPTR, #(timetable-24)
        MOVC A,@A+DPTR
        MOV DPTR, #dispfunc
        SETB EA
        ADD A,tdelayL
        MOV tdelayL,A
        JNC a11
        INC tdelayH
a11:    MOV A, R0
        ACALL showtempo
        AJMP meter

chls:   JNB mmode,chmm
        MOV A,22H
        INC A
        ANL A, #7
        CJNE A, #6, a12
        CLR A
a12:    MOV 22H, A
        AJMP chmm



showtempo:
  CLR EA        ; disable interrupt
  MOV DPTR,#ledtable
  MOV B, #100
  DIV AB
  MOVC A,@A+DPTR
  MOV led3, A
  MOV A, #10
  XCH A,B
  DIV AB
  MOVC A,@A+DPTR
  MOV led2, A
  XCH A,B
  MOVC A,@A+DPTR
  MOV led1, A
  MOV DPTR,#dispfunc
  SETB EA       ; enable interrupt
  RET

showbeat:
  CLR EA        ; disable interrupt
  MOV DPTR,#ledtable
  MOV A, beat
  MOVC A,@A+DPTR
  ANL A,#0DFh       ; enable the "dot"
  MOV led4, A
  MOV DPTR,#dispfunc
  SETB EA       ; enable interrupt
  RET

showtick:
    CLR P3.1                    ; turn on the flash LED
    JB mmode, a5
    MOV R5, #2                  ; in setting mode, light 1 ms
    AJMP main
tickone:
    MOV R5, #200                ; light 100 ms, for the 1st tick
    AJMP a6
a5: MOV A, bb
    JZ tickone
    MOV R5, #20                 ; except the first tick, light 10 ms
    JB pri, a7
a6: JB mute, a7
    SETB beep
    CLR P3.0                    ; enable sound
a7: MOV A,#0FFh
    MOV led1,A
    MOV led2,A
    MOV led3,A
    MOV led4,A                  ; clear all LEDs
    JB indoff, bbq              ; skip display index
    MOV A,beat
    ADD A,#2
    JB ACC.3, beat_68
    ANL A, #3
    JZ beat_2
                                ; beat_34
    MOV A, bb
    ADD A, #led4
    MOV R0, A
    MOV @R0, #0F7h
    AJMP bbq
beat_68:
    MOV A,bb
    JB ACC.0, ddot
    MOV dummy, #07Fh
    AJMP divby2
ddot:
    MOV dummy, #0EFh
divby2:
    RRC A                       ; C=0 since "ADD A,#2 will not overflow"
    ADD A, #led4
    MOV R0, A
    MOV @R0, dummy
    AJMP bbq
beat_2:
    MOV A,bb
    JZ bb2_0
    MOV led2, #0F7h
    AJMP bbq
bb2_0:
    MOV led4, #0F7h
bbq:MOV A,bb
    INC A
    CJNE A, beat, bbx
    CLR A
bbx:MOV bb,A
    AJMP main


dispfunc:
    SETB P3.3
    MOV P1, led1
    CLR P3.7
    MOV A,#(show2-dispfunc)
    XCH A,display
    MOV C, P3.2
    MOV keypad.0, C
    RETI
show2:  SETB P3.7
    MOV P1, led2
    CLR P3.5
    MOV A,#(show3-dispfunc)
    XCH A,display
    MOV C, P3.2
    MOV keypad.1, C
    RETI
show3:  SETB P3.5
    MOV P1, led3
    CLR P3.4
    MOV A,#(show4-dispfunc)
    XCH A,display
    MOV C, P3.2
    MOV keypad.2, C
    RETI
show4:  SETB P3.4
    MOV P1, led4
    CLR P3.3
    MOV A,#0
    XCH A,display
    MOV C, P3.2
    MOV keypad.3, C
    RETI


poweroff:
    MOV p0H, tdelayH
    MOV p1H, tdelayH
    MOV p0L, tdelayL
    MOV p1L, tdelayL
    MOV A, 22H
    JNZ a30
    MOV A, #6
a30:DEC A
    MOV 22H, A
    MOV led3, #28h
    MOV led2, #71h
    MOV led1, #71h
    SETB P3.0
    SETB P3.1
    MOV R7, #6
a31:ORL PCON,#1
    DJNZ R6, a31
    MOV R6, #200
    DJNZ R7, a31
    MOV P1, #0FFh
    MOV P3, #0FFh
    ORL PCON, #2h   ; power down mode
    AJMP main       ; no effect , powered down
   

ledtable:
  DB 28h, 0EEh, 32h, 0A2h, 0E4h, 0A1h, 21h, 0EAh, 20h, 0A0h

timetable:
DB 200, 185, 171, 158, 148, 138, 129, 121, 114, 107, 100, 96, 90, 85, 81, 77,
DB 73, 70, 66, 64, 60, 58, 56, 53, 51, 49, 47, 45, 44, 42, 40, 39, 38, 36, 35,
DB 34, 33, 32, 30, 30, 29, 28, 27, 26, 26, 25, 24, 23, 23, 22, 22, 21, 21, 20,
DB 19, 19, 19, 18, 17, 17, 17, 17, 16, 15, 16, 15, 14, 15, 14, 13, 14, 13, 13,
DB 13, 12, 12, 12, 12, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 10, 9, 8,
DB 9, 9, 8, 8, 8, 8, 8, 8, 8, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 6, 6, 7, 6, 6, 6,
DB 6, 6, 5, 6, 6, 5, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 4, 5, 5, 4, 5, 4, 5, 4, 4,
DB 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 3, 4, 3, 4, 3, 4, 3, 3, 4, 3,
DB 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 2, 3, 2, 3,
DB 3, 2, 3, 2, 2, 3, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2

END

[ 本帖最后由 d3b7 于 2009-7-24 14:56 编辑 ]

评分

1

查看全部评分

     
发表于 2009-7-24 15:04:56 | 显示全部楼层
能整单片机的在我眼里都很NB
貌似70年代《无线电》也有个节拍器电路 不知作用是不是一样的?
     
发表于 2009-7-24 17:04:29 | 显示全部楼层
相当不错.
     
发表于 2009-7-25 18:18:27 | 显示全部楼层
有注释就好了。
发表于 2009-7-25 22:53:50 | 显示全部楼层
有一个时期雅马哈琴的节拍显示是用数码管的小数点显示
     
发表于 2009-7-26 20:37:10 | 显示全部楼层

请问一下2051这个芯片的内部资源

俺好奇,在长汀购了几个,但现在没有电脑看不了它的文档,不知道它能用来干吗。
俺想请问有它的图片形式的资料文档吗,俺用手机也只能看到图片。
     
发表于 2011-2-24 21:29:48 | 显示全部楼层
楼主上个原理图好吧
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-4-18 13:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表