Generating a Sound with PIC - Assembly

Discussion in 'Embedded Systems and Microcontrollers' started by Sgt.Incontro, Oct 29, 2013.

  1. Sgt.Incontro

    Thread Starter Member

    Dec 5, 2012
    50
    1
    Hi all,

    So I need to generate a sound (tune) for a project I am doing now, using a PIC microcontroller (PIC16F84A) programmed in Assembly ONLY.

    A speaker will be attached to one of the ports in order to play the sound.

    I just need some guidance on how to start this, how exactly are sound tones generated in assembly?

    Thanks. :)

    EDIT: (I think you need to toggle a port on and off rapidly, but not quite sure how to proceed with this...)
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,441
    3,361
    A simple tone can be created using a digital square wave output.
    You can use an internal timer to set the frequency or you can use a PWM feature to set the duty cycle to 50% but vary the period of the PWM output.
     
    Sgt.Incontro likes this.
  3. Sgt.Incontro

    Thread Starter Member

    Dec 5, 2012
    50
    1
    Any idea how to get started on this?

    How exactly would I use the internal timer to set the frequency? Do you mean TMR0?

    I am still in the basic stages of learning PIC Assembly, so please excuse my questions if they are obvious.
     
  4. MrChips

    Moderator

    Oct 2, 2009
    12,441
    3,361
    I am not the most experienced user of PICs around here. But since you are now learning, here is something easy you can do.

    Set up TMR0 timer and get it running.
    Read the 8-bit value of TMR0 and output it to PORTB. Do this in a tight program loop.

    Now output the square wave signal from each of the PORTB pins to a loudspeaker or an audio amplifier (such as a PC audio amplifier). Try each of the PORTB pins in turn, starting with RB7 and working your way up to RB0.
     
  5. Sgt.Incontro

    Thread Starter Member

    Dec 5, 2012
    50
    1
    Last edited: Oct 29, 2013
  6. tracecom

    AAC Fanatic!

    Apr 16, 2010
    3,869
    1,393
    Although it's not the answer to your specific question, PICAXE chips have a built-in tune function, with several different tunes pre-defined. www.picaxe.com
     
  7. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Ignore the section in the code with:
    CNT dt 0
    etc.
    It doesn't clear the variables, which was probably his intention. It just creates some program instructions which never get executed.
    <ed>In fact the delay is wrong too, for 100kHz with 4Mhz PIC, a single cycle instruction is 1 microsecond, so you need 5 of them in between each toggle of the pin. It is indeed
    </ed>
     
    Last edited: Oct 29, 2013
  8. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    absf likes this.
  9. Sgt.Incontro

    Thread Starter Member

    Dec 5, 2012
    50
    1
    Thanks for the replies guys.

    Markd77 mentioned that accuracy of the page wasn't up to standard, so I found a new example that is easier to understand:

    ; Start Program ********************************************

    ; Initialize (Default  Input) .............................
    MOVLW b’00000000’ ;Define Port B outputs
    TRIS PORTB ; and set bit direction
    GOTO check

    ; Delay Subroutine ........................................
    delay MOVLW 0FF ; Standard Routine
    MOVWF Count
    down DECFSZ Count
    GOTO down
    RETURN

    ; Main Loop ...............................................
    check BTFSC PORTA,Input ;Check Input Button
    GOTO check ; and wait if not ‘on’
    BSF PORTB,Buzzer ; Output High
    CALL delay ; run delay subroutine
    BCF PORTB,Buzzer ; Output Low
    CALL delay ; run delay subroutine
    GOTO check ; repeat always

    END ; Terminate source code
     
  10. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    So you want to make musical notes using assembler code?

    Instead of nested delays (which are clunky in ASM) one good old technique was to use the 16bit timer.

    Here's the method;
    1. toggle the output pin
    2. load timer with value 65536-x (x is the period) and clr the timer overflow flag
    3. wait for timer roll (overflow flag is set)
    4. repeat

    This is easier to implement as there is just one value (x) which sets the note that is playing. x is the half-period of the frequency as it takes two "x" periods to make a full squarewave output cycle.

    If your code needs to do other things while the note is playing, you can do other (short) tasks during step 3, while the PIC is waiting for the timer overflow flag to be set.
     
    Sgt.Incontro likes this.
Loading...