Darrels interrupts and multiple SOUND statements, will it work?


Results 1 to 32 of 32

Threaded View

  1. #23
    Join Date
    May 2013
    Location
    australia
    Posts
    2,644


    Did you find this post helpful? Yes | No

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

    any pic without auto context save will need the wsave psave vars added


    this compiles ok for a 12f1822 watch the define OSC not sure how fast a 12f1822 is

    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 20
    DEFINE INTHAND _Generate         ' We're treating the interrupt as an ASM routine (see notes!)   did not like asm label not sure why
    '-------------------------------------------------------------------------------------------
    ' These variables and alises are needed by the sound generator and needs to be
    ' accessed by the user.
    Channel_1       VAR Porta.0     ' Output for sound channel 1
    Channel_2       VAR Porta.1     ' Output for sound channel 2
    Channel_3       VAR Porta.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 :                       made this a pbp label
    @ 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                           ; '    no fast
    
    Last edited by richard; - 15th January 2015 at 10:06. Reason: osc

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