Welcome to the N1IR Electronics Website. Totally off the cuff, one take, unrehearsed video projects for anyone interested in amateur radio, electronic design, makers, hardware hackers and science.

Get off your duff and build something!
Training the hand and mind since 1982.

Friday, October 25, 2013

Replacement Project, Musical PIC PART 1

Well one of our staple project for our fresmen bit the dust. It was called the Musical PIC. The problem was I had a invalid HEX file, checksum error for some reason.

Back 5 years ago it was great project but it had a few drawbacks. First it used a PIC12C508 OTP. Yep One Time Programmable, what a pain in the a$$ if you need to change code. Burn change, burn change and rinse and repeat till you get it right, meanwhile at $0.50 a chip development of anything got expensive. Second I only had a couple of songs, I'm not musically inclined so figuring out songs to assembly language (ASM) was a real pain.

Well here is the original article with the 12C508.

A very simple PIC project to try. With the basic program available to download below you can insert any tune you like. My three year old son likes this Teletubbies tune. With a little more circuitry I wired it to the door of the car. Everytime he closed the door the car plays the Teletubbies tune. It was wired from the 0V of the car body to the wire that connects to the door switch. When the door is opened the supply to the PIC is shorted. When the door is closed the supply is reinstated and the PIC restarts its program again. Alternately it could be powered off batteries and hidden inside a childs toy.
 Hex code

ASM File
; FILE            TUNE.ASM
; FOR            12C508A
; CLOCK       Internal

    TITLE "TUNE Program"
    LIST P=12c508a
    include p12c508a.inc

    ;config settings for PICSTART Programmer

    constant noteLG    =.159        ;G note constants
    constant noteA    =.141        ;A
    constant noteB    =.127        ;B
    constant noteC    =.119        ;C
     constant noteD    =.104        ;D
    constant noteE    =.94        ;E
    constant noteFS    =.84        ;F#
    constant noteG    =.80        ;G

    constant MINIM =.250000        ;note length constants
    constant SEMIN =MINIM/2
    constant CROTCH =SEMIN/2
    constant QUAVER =CROTCH/2
    constant SEMIQV =QUAVER/2

NOTE    macro freq,length
    retlw freq
    retlw low ((length) / freq)
    retlw high ((length) / freq)

    ;File registers
    org 7
freq    res 1
len    res 1
lenh    res 1
frq    res 1
tabpos    res 1

    org 0
    movwf OSCCAL
    goto start

    retlw 'T'    ;chip identification
    retlw 'U'
    retlw 'N'
    retlw 'E'
    retlw ' '
    retlw 'V'
    retlw '1'
    retlw '.'
    retlw '0'

tune    movf tabpos,w
    addwf PCL,f

    ;example tune
    NOTE noteC,CROTCH    ;1

    NOTE noteD,CROTCH    ;2

    NOTE noteF,QUAVER    ;3

    NOTE noteE,QUAVER    ;4

    NOTE noteD,QUAVER    ;5

    NOTE noteC,CROTCH    ;6

    NOTE noteG,CROTCH    ;7
    NOTE noteF,QUAVER    ;8

    NOTE noteE,QUAVER    ;9

    NOTE noteD,QUAVER    ;10
    NOTE noteC,CROTCH    ;11

    NOTE noteG,CROTCH    ;12
    NOTE noteF,QUAVER    ;13

    NOTE noteE,QUAVER    ;14

    NOTE noteF,QUAVER    ;15
    NOTE noteD,QUAVER    ;16

endtab                ;end of tune

start    movlw b'00101010'    ;set outputs
    movwf GPIO
    tris GPIO        ;GPIO all outputs
    clrf tabpos        ;reset table position
nxtnote    call getnote         ;get note from table
    call play        ;play note
    movlw endtab - tunest    ;check if at end
    subwf tabpos,w        ;of table
    btfss STATUS,Z
    goto nxtnote        ;no then get next note
    movlw b'11111111'    ;set outputs to high
    tris GPIO        ;impedence input mode
    sleep            ;put PIC in low power mode
    goto start        ;re-start if woken up

getnote    call tune        ;get note from table
    movwf freq
    incf tabpos,f
    call tune        ;get length lower byte
    movwf len
    incf tabpos,f
    call tune        ;get length high byte
    movwf lenh
    incf tabpos,f

play    incf lenh,f
play2    movf freq,w
    call note        ;wait 1/2 frequency
    comf GPIO,f        ;toggle sounder
    decfsz len,f
    goto play2        ;keep looping until
    decfsz lenh,f        ;note finished
    goto play2

note    movwf frq        ;wait 1/2 of frequency
wait    nop                     
        decfsz frq,f
        goto wait