Darrels interrupts and multiple SOUND statements, will it work?


Closed Thread
Results 1 to 32 of 32

Hybrid View

  1. #1
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,132


    Did you find this post helpful? Yes | No

    Default Re: Darrels interrupts and multiple SOUND statements, will it work?

    16F877 made that video game??

    Ioannis

  2. #2
    Join Date
    Feb 2013
    Posts
    1,124


    Did you find this post helpful? Yes | No

    Default Re: Darrels interrupts and multiple SOUND statements, will it work?

    No, that video game runs on 6502 or similar CPU. It is possible to emulate NES using PIC, using various models, check this link as example:


    For the my intended music playback, 877A uses DT-INTs, and for the easter egg moment, which will be achieved when user presses certain combo of keys, ther will be a small animation on 1602 display, and music should be playing, MCU won't be doing anything sophisticated that time.

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Darrels interrupts and multiple SOUND statements, will it work?

    Hi,
    So, I've played around some more.....
    It won't run at anything below 16MHz. Even at 16MHz the interrupt routine, executing at 10kHz cosumes 70% of the available CPU cycles.
    I've only tried it on an 18F25K20 @64MHz, you try it on a 16F or 12F1840 and see if it works.

    You can not cut'n'paste this into a program using DT-Ints. Try it stand-alone first and we'll see about DT-ints later - if needed.

    /Henrik.

    Code:
    '****************************************************************
    '*  Name    : 3xSound generator.pbp                             *
    '*  Author  : Henrik Olsson                                     *
    '*  Notice  : Written by Henrik Olsson 2015                     *
    '*          : Free software, use as you wish.                   *
    '*  Date    : 2015-01-14                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : Written in response to a thread on the PBP forum: *
    '*          : www.picbasic.co.uk/forum/showthread.php?t=19684   *
    '*                                                              *
    '*          : Tones are generated using the DDS tecnique with a *
    '*            simple 16bit accumulator to which a value gets    *
    '*            added once every interrupt (100us). When the      *
    '*            accumulator overflows the output is toggled.      *
    '*            Three generators are incorporated since that was  *
    '*            the request. More could be added if the PIC is    *
    '*            clocked fast enough. With three generators 16MHz  *
    '*            is the lowest you want to use. The interrupts     *
    '*            then uses ~70% of the available CPU cycles when   *
    '*            three tones are generated.                        *
    '*                                                              *
    '*            Version history:                                  *
    '*              v1.0 2015-01-14 - Initial version               *
    '*                                                              *
    '****************************************************************
    
    ' CONFIG's, TRIS's, ANSEL's CMCON's and anything device specific is not shown
    
    DEFINE OSC 64
    DEFINE INTHAND Generate         ' We're treating the interrupt as an ASM routine (see notes!)
    
    '-------------------------------------------------------------------------------------------
    ' These variables and alises are needed by the sound generator and needs to be
    ' accessed by the user.
    Channel_1       VAR PortC.0     ' Output for sound channel 1
    Channel_2       VAR PortC.1     ' Output for sound channel 2
    Channel_3       VAR PortC.2     ' Output for sound channel 3
    
    TMR2IF          VAR PIR1.1      ' Alias to TMR2 Interrupt Request Flag - verify against datasheet.
    
    Output_1        VAR WORD        ' Desired output frequency, Channel 1, 13.107 units per Hz
    Output_2        VAR WORD        ' Desired output frequency, Channel 2, 13.107 units per Hz
    Output_3        VAR WORD        ' Desired output frequency, Channel 3, 13.107 units per Hz
    
    Duration_1      VAR WORD        ' Duration of tone, Channel 1, 100us units.
    Duration_2      VAR WORD        ' Duration of tone, Channel 2, 100us units.
    Duration_3      VAR WORD        ' Duration of tone, Channel 3, 100us units.
    
    '-------------------------------------------------------------------------------------------
    ' These are variables used by the interrupt service routine.
    ' No user servicable parts inside......
    R0_SHADOW       VAR WORD        ' Variable used for saving PBP system variables in the ISR
    R1_SHADOW       VAR WORD        ' Variable used for saving PBP system variables in the ISR
    R4_SHADOW       VAR WORD        ' Variable used for saving PBP system variables in the ISR
    
    Accumulator_1   VAR WORD        ' DDS accumulator for sound generator 1
    Accumulator_2   VAR WORD        ' DDS accumulator for sound generator 2
    Accumulator_3   VAR WORD        ' DDS accumulator for sound generator 3
    
    old_1           VAR WORD        ' Used to detect overflow of accumulator 1
    old_2           VAR WORD        ' Used to detect overflow of accumulator 2
    old_3           VAR WORD        ' Used to detect overflow of accumulator 3
    '--------------------------------------------------------------------------------------------
    
    ' We want 10kHz interrupt rate, that's 100us between interrupts.
    ' The interrupt routine needs around ~280 instruction cycles when
    ' outputting on three channels.
    '
    ' At 16MHz that would be  400 instructions - 70% used by the generator. 
    ' At 20MHz that would be  500 instructions - 56% used by the generator
    ' At 40MHz that would be 1000 instructions - 28% used by the generator
    ' At 64MHz that would be 1600 instructions - 17.5% used by the generator
    '
    ' T2CON and PR2 needs to be setup so that an interrupt is triggered every 100us
    ' Use one of the follwing:
    ' PR2 =  99 : T2CON = %00000110   ' For 64MHz - 1:16 prescaler
    ' PR2 =  49 : T2CON = %00000110   ' For 32MHz - 1:16 prescaler
    ' PR2 = 124 : T2CON = %00000101   ' For 20MHz - 1:4 prescaler
    ' PR2 =  99 : T2CON = %00000101   ' For 16MHz - 1:4 prescaler
     
    PR2 = 99 : T2CON = %00000110  'TMR2 on, postscaler 1:1, prescaler 1:4
    
    IPR1.1   = 1        ' TMR2 high priority
    PIE1.1   = 1        ' TMR2 IE
    INTCON.6 = 1        ' PIE
    INTCON.7 = 1        ' GIE
    
    
    Main:
        ' All three notes will play simultanously for the specified duration.
        ' The sound is generated in the background so the PAUSE 1000 will
        ' execute at the same time as the notes are played. Remember though that
        ' the interrupt "steals" time so the PAUSE isn't correct. The slower the
        ' PIC clock is the more inacurate it gets.
    
        Output_1 = 857   : Duration_1 = 500    'Play C2 (65.4Hz) for 50ms
        Output_2 = 5767  : Duration_2 = 2500   'Play A4 (440.0Hz)for 250ms 
        Output_3 = 25893 : Duration_3 = 1000   'Play B6 (1975.5Hz) for 100ms
    
        Pause 1000
    
    Goto Main
    
    
    '-------------------------------------------------------------------------------
    ' Actual interrupt routine here. Please note that this is written in PBP but
    ' the interrupt is handled as if it were a ASM interrupt. As far as I can see
    ' it uses PBP system variables R0, R1, R4 so I'm saving/restoring those.
    ' If ANY code gets added here then the ASM-listning needs to be checked to 
    ' see of the added PBP code uses any more system variables and if so
    ' those needs to saved/restored as well.
    ' When all three channels produces output it needs ~280 instructions cycles.
    @ Generate:
    
    @ MOVE?WW R0, _R0_SHADOW                  ; Save PBP system variable R0 
    @ MOVE?WW R1, _R1_SHADOW                  ; Save PBP system variable R1 
    @ MOVE?WW R4, _R4_SHADOW                  ; Save PBP system variable R4   
        TMR2IF = 0
    
        IF Duration_1 > 0 THEN
            Accumulator_1 = Accumulator_1 + Output_1
            If Accumulator_1 < old_1 THEN Toggle Channel_1
            old_1 = Accumulator_1
            Duration_1 = Duration_1 - 1
        ELSE
            Channel_1 = 0
        ENDIF
        
        IF Duration_2 > 0 THEN
            Accumulator_2 = Accumulator_2 + Output_2
            If Accumulator_2 < old_2 THEN Toggle Channel_2
            old_2 = Accumulator_2
            Duration_2 = Duration_2 - 1
        ELSE
            Channel_2 = 0
        ENDIF
        
        If Duration_3 > 0 THEN
            Accumulator_3 = Accumulator_3 + Output_3
            If Accumulator_3 < old_3 THEN Toggle Channel_3
            old_3 = Accumulator_3
            Duration_3 = Duration_3 - 1
        ELSE
            Channel_3 = 0
        ENDIF
    
    
    @ MOVE?WW _R0_SHADOW, R0                    ; Restore PBP system variable R0
    @ MOVE?WW _R1_SHADOW, R1                    ; Restore PBP system variable R1 
    @ MOVE?WW _R4_SHADOW, R4                    ; Restore PBP system variable R4    
     
    @ retfie FAST
    '-------------------------------------------------------------------------------
    END

  4. #4
    Join Date
    Feb 2013
    Posts
    1,124


    Did you find this post helpful? Yes | No

    Default Re: Darrels interrupts and multiple SOUND statements, will it work?

    WOW, so fast!

    It's my fault, I forgot to mention, we only need high frequencies for SFX synthesis, for music playback, 5 octave range is enough, which means roughly 440*5=2.2khz

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Darrels interrupts and multiple SOUND statements, will it work?

    Hi,
    2.2kHz (Output_x = 28835) should work. The higher you go the more jittery the output becomes.

    If you want to calculate the value to put in the Output_x variables at runtime (instead of using a lookup table or whatever) you can do it with Output_x = ( Frequency + ( Frequency ** 20353 ) ) where Frequency is a WORD containing the desired output frequency * 10, (4400 = 440.0Hz)

    It's not perfect but may be good enough.

    Let me know if you get around to trying it.

    /Henrik.

  6. #6
    Join Date
    Feb 2013
    Posts
    1,124


    Did you find this post helpful? Yes | No

    Default Re: Darrels interrupts and multiple SOUND statements, will it work?

    What happens if I run this code say at 4mhz 16F870 ? there will be no output, frequency wont match, or sound will be breaking up?

  7. #7
    Join Date
    Feb 2013
    Posts
    1,124


    Did you find this post helpful? Yes | No

    Default Re: Darrels interrupts and multiple SOUND statements, will it work?

    on 16F876A, gives error during compile on this:

    IPR1.1 = 1 ' TMR2 high priority

Similar Threads

  1. Multiple IF THEN Statements: PIC16F84A
    By bob425 in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 10th August 2012, 06:01
  2. Problem with multiple interrupts
    By aratti in forum General
    Replies: 7
    Last Post: - 2nd June 2009, 08:18
  3. Multiple IF-THEN statements
    By DavidK in forum mel PIC BASIC Pro
    Replies: 11
    Last Post: - 20th June 2007, 18:28
  4. Handeling multiple Interrupts
    By BobSpencerr in forum General
    Replies: 15
    Last Post: - 1st March 2007, 01:12
  5. Multiple HW Interrupts
    By Radiance in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 13th August 2003, 22:35

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts