Please help configure 16F616


Closed Thread
Results 1 to 16 of 16
  1. #1

    Default Please help configure 16F616

    I'm having trouble getting a 16F616 to work correctly, and I'm pretty sure the problem is with how I am configuring the various registers.

    These are my peripheral connections:
    A0 - push button (digital input)
    A1 - potentiometer (analog input)
    A2 - potentiometer (analog input)
    A3 - push button (digital input/MCLRE is off)
    A4 - relay (digital output)
    A5 - SPI connection (digital output)
    C0 - LED (digital output)
    C1 - SPI connection (digital output)
    C2 - SPI connection (digital output)
    C3 - relay (digital output)
    C4 - LED (digital output)
    C5 - relay (digital output)

    I am also using the TRM0 interrupt. What am I doing wrong?


    Code:
    #config 
        __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF
    #endconfig
    
    
    ADCON0 = %00000000
    ANSEL = %00000110
    CM1CON0 = %00000000
    CM2CON0 = %00000000                 
    
    TRISA = %00001111
    TRISC = %00000000
    
    ' Set TMR0 to interrupt every 16.384 milliseconds
       OPTION_REG = %10000101        ' Set TMR0 configuration
       INTCON = %10100000           ' Enable TMR0 interrupts
       On Interrupt Goto tickint

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,388


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    #config
    __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF
    #endconfig
    is only setting a partial number of config bits for that chip ,the bits that are omitted will revert to their default state , it may cause your [totally unspecified] problem, or it may be in the unposted code or both




    this is the device info file from your ?:\PBP3\DEVICE_REFERENCE folder

    Code:
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;
    ;  File:    PIC16F616.INFO
    ;  Date:    05/18/16
    ;  Generated by melabs File Manager
    ;
    ;  PICBASIC PRO(tm) Compiler version: 3.0.9
    ;
    ;  Copyright 2016 microEngineering Labs, Inc.   All Rights Reserved
    ;  The content herein is intended to facilitate embedded development using
    ;  PICBASIC PRO Compiler.  Reproduction or utilization for other purposes
    ;  is prohibited without written permission from microEngineering Labs, Inc..
    ;  
    ;  microEngineering Labs, Inc.
    ;  2845 Ore Mill Road STE 4
    ;  Colorado Springs, CO  80904
    ;  719-520-5323
    ;  fax: 719-520-1867
    ;  http://melabs.com
    ;  [email protected]
    ;
    ;  Modifications to this file in the \DEVICE_REFERENCE folder will be
    ;  overwritten when you install future upgrades.
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;MPASM __CONFIG Directive Options
    ;
    ;  The PBP default configuration for the PIC16F616 is:
    ;
    ;  #CONFIG
    ;    __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_ON & _IOSCFS_4MHZ & _CP_OFF
    ;  #ENDCONFIG
    ;
    ;  You may use the information below to construct your own configuration
    ;  directives for the PIC16F616.  Please note that ALL DEFAULT
    ;  CONFIGURATION SETTINGS WILL BE OVERWRITTEN when you include a #CONFIG
    ;  block in your program.
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;
    ; Available __CONFIG labels for PIC16F616:
    ;
    ;CONFIG Options
    ;
    ;  Oscillator Selection bits
    ;    _FOSC_EXTRCCLK     ;RC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
    ;    _EXTRC_OSC_CLKOUT     ;RC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
    ;    _EXTRC     ;RC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
    ;    _FOSC_EXTRCIO     ;RCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
    ;    _EXTRC_OSC_NOCLKOUT     ;RCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
    ;    _EXTRCIO     ;RCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
    ;    _FOSC_INTOSCCLK     ;INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
    ;    _INTRC_OSC_CLKOUT     ;INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
    ;    _INTOSC     ;INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
    ;    _FOSC_INTOSCIO     ;INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
    ;    _INTRC_OSC_NOCLKOUT     ;INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
    ;    _INTOSCIO     ;INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
    ;    _FOSC_EC     ;EC: I/O function on RA4/OSC2/CLKOUT pin, CLKIN on RA5/OSC1/CLKIN
    ;    _EC_OSC     ;EC: I/O function on RA4/OSC2/CLKOUT pin, CLKIN on RA5/OSC1/CLKIN
    ;    _FOSC_HS     ;HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
    ;    _HS_OSC     ;HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
    ;    _FOSC_XT     ;XT oscillator: Crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
    ;    _XT_OSC     ;XT oscillator: Crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
    ;    _FOSC_LP     ;LP oscillator: Low-power crystal on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
    ;    _LP_OSC     ;LP oscillator: Low-power crystal on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
    ;
    ;  Watchdog Timer Enable bit
    ;    _WDTE_ON     ;WDT enabled
    ;    _WDT_ON     ;WDT enabled
    ;    _WDTE_OFF     ;WDT disabled and can be enabled by SWDTEN bit of the WDTCON register
    ;    _WDT_OFF     ;WDT disabled and can be enabled by SWDTEN bit of the WDTCON register
    ;
    ;  Power-up Timer Enable bit
    ;    _PWRTE_OFF     ;PWRT disabled
    ;    _PWRTE_ON     ;PWRT enabled
    ;
    ;  MCLR Pin Function Select bit
    ;    _MCLRE_ON     ;MCLR pin function is MCLR
    ;    _MCLRE_OFF     ;MCLR pin function is digital input, MCLR internally tied to VDD
    ;
    ;  Code Protection bit
    ;    _CP_OFF     ;Program memory code protection is disabled
    ;    _CP_ON     ;Program memory code protection is enabled
    ;
    ;  Internal Oscillator Frequency Select bit
    ;    _IOSCFS_8MHZ     ;8 MHz
    ;    _IOSCFS8     ;8 MHz
    ;    _IOSCFS_4MHZ     ;4 MHz
    ;    _IOSCFS4     ;4 MHz
    ;
    ;  Brown-out Reset Selection bits
    ;    _BOREN_ON     ;BOR enabled
    ;    _BOD_ON     ;BOR enabled
    ;    _BOR_ON     ;BOR enabled
    ;    _BOREN_NSLEEP     ;BOR enabled during operation and disabled in Sleep
    ;    _BOD_NSLEEP     ;BOR enabled during operation and disabled in Sleep
    ;    _BOR_NSLEEP     ;BOR enabled during operation and disabled in Sleep
    ;    _BOREN_OFF     ;BOR Disabled
    ;    _BOREN_OFF     ;BOR Disabled
    ;    _BOD_OFF     ;BOR Disabled
    ;    _BOR_OFF     ;BOR Disabled
    ;
    ;
    ;/MPASM
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    Warning I'm not a teacher

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    Quote Originally Posted by richard View Post
    is only setting a partial number of config bits for that chip ,the bits that are omitted will revert to their default state , it may cause your [totally unspecified] problem, or it may be in the unposted code or both


    this is the device info file from your ?:\PBP3\DEVICE_REFERENCE folder
    Thanks for your help, Richard. Yes, that's the device. I'll post the code and a schematic. I was reluctant to because it's pretty long and I'm not sure I can fully explain all the things I'm trying to do.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    Here's the schematic. PDF is attached as well.
    Name:  EchoRoyal.bmp
Views: 722
Size:  552.3 KB
    Attached Images Attached Images

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    So I've started a new program that does not have all the features I want. I figured it's best to start with the base and then add things once I get those working properly. The schematic is for an echo/delay sound effects unit. Right now, I'm just trying to get the on/off (bypass/trails) switch and the "DELAY TIME" potentiometer to work.

    The 2 x PT2399 ICs are the delay chips. They are in series. Their delay time is controlled by the MCP4251 digital potentiometer, which is controlled by the 16F616 (note that the schematic says 16F676, but I am using the 16F616), which interfaces with the user via an analog potentiometer.

    The on/off feature has two modes of operation - normal bypass and trails bypass. Normal bypass is just an on/off switch for the effect. When "ON", junction A and B are set high to allow signal to pass through the switching JFETs and junction C is low to block signal. When "OFF", junction A and B are low and junction C is high. "Trails mode" is a feature that allows the echoes to continue repeating after you turn the effect "off", but doesn't allow any new echoes to be created. So when the effect is on, it is the same as when in normal mode, but when the effect is off, junction A is low, cancelling new signal that feeds into the delay chips and the dry side of the crossfader, but junction B and C are high allowing the complete dry signal to pass and any signal that is already in the feedback loop of the delay chip.

    The user can toggle between normal and trails modes by pressing and holding the bypass switch for 3 seconds. The tempo LED will blink 5 times to let the user know that the mode has changed. When the effect is on, the bypass LED is high. When it is off, the bypass LED is low.

    In the code below, the bypass feature seems to work just fine. It is the delay time control that I'm having problems with. The analog potentiometer does control the delay time as it should. However, it modulates wildly, i.e., the digital potentiometer will not settle into one position once you stop turning the analog potentiometer. I have a feeling the way I've done the config or set the registers has something to do with it.

    Code:
    #config 
        __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _IOSCFS_4MHZ
    #endconfig
    
    ADCON0 = %00000000
    ADCON1 = %01100000
    ANSEL = %00000110
    
    
    CM1CON0 = %00000000
    CM2CON0 = %00000000  
    
    TRISA = %00001111
    TRISC = %00000000
    
        
        '                      
        '    Hardware connection
        '    ===================
        CS          VAR PORTA.5
        SCK         VAR PORTC.2
        SDI          VAR PORTC.1
        tempoLED var PORTC.0
        tempobutton var PORTA.0
        bypassbutton var PORTA.3
        bypassLED var PORTC.4
        fetA var PORTC.5
        fetB var PORTA.4
        fetC var PORTC.3
        
        
        
        '   
        '    Variables definition 
        '    ===================
        w var word                          ' division toggle switch
        x var word                          ' delay time knob
        xprevious var word
        z var word
        binaryvalue var word
        
        ticks var word
        tapcount var word
        LEDcounter var word
        LEDcounterlimit var word
        LEDrate var word
        
        trailsmode var byte
        trailsmodecounter var word 
        LEDon var byte
        LEDoff var byte
        
        LEDon = 1
        LEDoff = 0
                                 
        '
        '    begin in bypass
        '    ===============
        
        tempoLED = 0
        fetA = 0
        fetB = 0
        fetC = 1
        bypassLED = LEDoff
        trailsmode = 0
        
        
    main:       
            gosub readpot
            if bypassBUTTON = 0 then
                gosub bypasspress
                gosub bypassbuttonrelease
            ENDif
            pause 100
            gosub movedigipot 
    goto main
    
    
    bypasspress:                                                  ' subroutine that occurs when bypass button is pressed
        trailsmodecounter = 0                                      ' waits to see if you want to switch between normal or trails mode
        do until trailsmodecounter = 400
            if bypassbutton = 1 then exit
            pause 10       
            trailsmodecounter = trailsmodecounter + 1
        loop
        
        if trailsmodecounter = 400 then                         ' if bypass button was held long enough then change mode
            goto trailmodechange
        endif 
        
        if trailsmode = 1 then                       ' if bypass button was not held long enough go to sub to toggle between on/off
            gosub trailsbypass
        elseif trailsmode = 0 then
            gosub normalbypass
        endif
    return
    
    trailmodechange:                ' subroutine that occurs when bypass button is held long enough to change between normal or trails mode
        if trailsmode = 1 then
            trailsmode =  0
        elseif trailsmode = 0 then
            trailsmode = 1
        endif
        
        for z = 1 to 5
        tempoLED = 1
            pause 100
        tempoLED = 0
            pause 100
        next z
        
    goto main    
    
    normalbypass:                        ' subroutine for normal bypass
        if bypassLED = 0 then
            fetA = 1
            fetB = 1
            fetC = 0
            bypassLED = LEDon
        elseif bypassLED = 1 then
            fetA = 0
            fetB = 0
            fetC = 1
            bypassLED = 0
        endif
    return
    
    trailsbypass:                       'subroutine for trails bypass
        if bypassLED = 0 then
            fetA = 1
            fetB = 1
            fetC = 0
            bypassLED = LEDon
        elseif bypassLED = 1 then
            fetA = 0
            fetB = 1
            fetC = 1
            bypassLED = LEDoff
        endif
    return
    
    bypassbuttonrelease:             ' debounce subroutine when bypass button is pressed
        do until bypassbutton = 1
            pause 10
        loop
    return
           
    movedigipot:
    
        CS=0                                        
        shiftout SDI, SCK, 1, [00000000,x]                 ' move wiper A
        shiftout SDI, SCK, 1, [00010000,x]                   'move wiper B
        CS=1   
    return
    
    
    readpot:    
        adcin 2,x                                       'read voltage of "delay time" pot                                                                          
    return
    
    
    end

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    Haven't checked anything in detail but I see you're using ADCIN to read the pot but you're not telling the compiler anything about how you want it read.

    I suspect you're either sample time is way to low or you have mismatch between the expected number of bits and the left/right justification. I don't know what PBP defaults to when you don't tell it anything with the DEFINEs.

    Check the manual for the DEFINEs belonging to ADCIN.

    You have x decalred as a WORD which makes me Think you WANT 10 bits from the ADC but the digipot you're using expects 8bits only. From memory I don't know how SHIFTOUT handles WORD variables like in this case. Is it actually shifting out 16 bits or is it only shifting out 8 of the 16bits and if that's the case is it the lower or higher byte.

    /Henrik.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    Quote Originally Posted by HenrikOlsson View Post
    Haven't checked anything in detail but I see you're using ADCIN to read the pot but you're not telling the compiler anything about how you want it read.

    I suspect you're either sample time is way to low or you have mismatch between the expected number of bits and the left/right justification. I don't know what PBP defaults to when you don't tell it anything with the DEFINEs.

    Check the manual for the DEFINEs belonging to ADCIN.

    You have x decalred as a WORD which makes me Think you WANT 10 bits from the ADC but the digipot you're using expects 8bits only. From memory I don't know how SHIFTOUT handles WORD variables like in this case. Is it actually shifting out 16 bits or is it only shifting out 8 of the 16bits and if that's the case is it the lower or higher byte.

    /Henrik.
    Thanks, Henrik. I added "define ADC_SAMPLEUS 100" and "define ADC_BITS 8". That didn't seem to help any.

    How do my ADCONx and CMxCON0 registers look?

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    Hi,
    CMxCON looks fine to me, bit 7 = 0 which means the comparator is disabled (which it is by default on this device so no real need to add that but can't hurt).
    ANSEL sets RA1 and RA2 to analog, I suppose that's what you want.
    ADCON0 looks fine except possibly for bit 7 (I can NEVER remember when to use which setting). It should be in one state when using 8 bits and the other when usign 10 bits.
    ADCON1 sets the ADC clock to FOsc/64 which makes it run REALLY slow if the oscillator is 4MHz, try the RC mode instead.

    I checked the manual, if not told otherwise SHIFTOUT sends 8 bits even if the variable is of another size. You have mode 1 selected (MSB first) so my question then is if it shifts out the high byte of your word, MSB first or the low byte of your word, MSB first?

    I don't know, perhaps you've already done this, but I would make sure I had full control over that pot-chip first and THEN focus on the ADC.

    /Henrik.

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    I think I've got it working well now. FWIW, tweaking the CONFIG or registers didn't really help much. Neither did setting the ADC sample rate to ridiculously long times. What seems to have fixed it was adding a "buffer" or tolerance limit. Subroutine movedigipot sets xprevious to the ADC reading that was used to last move the digital pot. Subroutine checkpot checks to see if the current ADC reading is within +/- 2.56% of xprevious. If it is, it doesn't allow the digital pot to move. I made it so that x could never equal zero because that causes trouble further down the road. There's no obvious reason at the moment.

    Now it's time to implement the interrupt.....ugh.

    Code:
    #config 
        __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _IOSCFS_8MHZ
    #endconfig
    
    ADCON0 = %00000000
    ADCON1 = %00110000
    ANSEL = %00000110
    define ADC_SAMPLEUS 50
    define ADC_BITS 8
    
    
    CM1CON0 = %00000000
    CM2CON0 = %00000000  
    
    TRISA = %00001111
    TRISC = %00000000
    
        
        '                      
        '    Hardware connection
        '    ===================
        CS          VAR PORTA.5
        SCK         VAR PORTC.2
        SDI          VAR PORTC.1
        tempoLED var PORTC.0
        tempobutton var PORTA.0
        bypassbutton var PORTA.3
        bypassLED var PORTC.4
        fetA var PORTC.5
        fetB var PORTA.4
        fetC var PORTC.3
        
        
        
        '   
        '    Variables definition 
        '    ===================
        w var byte                          ' division toggle switch
        x var byte                          ' delay time knob
        xprevious var byte
        z var byte
        
        ticks var word
        tapcount var word
        LEDcounter var word
        LEDcounterlimit var word
        LEDrate var word
        
        trailsmode var byte
        trailsmodecounter var word 
        LEDon var byte
        LEDoff var byte
        
        LEDon = 1
        LEDoff = 0
                                 
        '
        '    begin in bypass
        '    ===============
        
        tempoLED = 0
        fetA = 0
        fetB = 0
        fetC = 1
        bypassLED = LEDoff
        trailsmode = 0
        gosub readpot
        gosub movepot
        if xprevious <= 0 then
            xprevious = 1
        endif
        
    main: 
            if bypassBUTTON = 0 then
                gosub bypasspress
                gosub bypassbuttonrelease
            ENDif
            gosub potcheck
    goto main
                                                                  ' subroutine that occurs when bypass button is pressed
    bypasspress:
        trailsmodecounter = 0                                      ' waits to see if you want to switch between normal or trails mode
        do until trailsmodecounter = 400
            if bypassbutton = 1 then exit
            pause 10       
            trailsmodecounter = trailsmodecounter + 1
        loop
        
        if trailsmodecounter = 400 then
            goto trailmodechange
        endif 
        
        if trailsmode = 1 then 
            gosub trailsbypass
        elseif trailsmode = 0 then
            gosub normalbypass
        endif
    return
    
    trailmodechange:                                                ' subroutine that occurs when bypass button is held long enough to change between normal or trails mode
        if trailsmode = 1 then
            trailsmode =  0
        elseif trailsmode = 0 then
            trailsmode = 1
        endif
        
        for z = 1 to 5
        tempoLED = 1
            pause 100
        tempoLED = 0
            pause 100
        next z
        
    goto main    
    
    normalbypass:                                                       ' subroutine for normal bypass
        if bypassLED = 0 then
            fetA = 1
            fetB = 1
            fetC = 0
            bypassLED = LEDon
        elseif bypassLED = 1 then
            fetA = 0
            fetB = 0
            fetC = 1
            bypassLED = 0
        endif
    return
    
    trailsbypass:                                                       'subroutine for trails bypass
        if bypassLED = 0 then
            fetA = 1
            fetB = 1
            fetC = 0
            bypassLED = LEDon
        elseif bypassLED = 1 then
            fetA = 0
            fetB = 1
            fetC = 1
            bypassLED = LEDoff
        endif
    return
    
    bypassbuttonrelease:                                               '  debounce subroutine when bypass button is pressed
        do until bypassbutton = 1
            pause 10
        loop
    return    
    potcheck:       
            gosub readpot
            if x <= 0 then
                x = 1
            endif
            if x >= xprevious + 5 or x <= xprevious - 5 then
                gosub movepot
            endif
    return        
    
    movepot:        
            CS = 0
            shiftout SDI, SCK, 1, [00000000,x]
            shiftout SDI, SCK, 1, [00010000,x]
            CS = 1
            xprevious = x
    return
             
    readpot
        adcin 2,x
        pause 100
    return
    
    end
    Last edited by keithv; - 9th September 2016 at 19:46.

  10. #10


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    So I added the interrupt. The idea is to make the tempo LED blink in time with the echoes, so that if you turn the delay time knob clockwise, the echoes go slower and the LED blinks slower, and if you turn the delay time knob counter clockwise, the echoes go faster and the LED blinks faster. It's working pretty well but there is one thing it is doing that is weird, and I can't figure out why.

    If you have the delay time pot full turn counter clockwise when you power on, the tempo LED gets stuck. If you turn the delay time knob full turn counter clockwise quickly, the tempo LED gets stuck and does not blink. However, if you turn the delay time knob full turn counter clockwise slowly, it works OK.

    I'm sure the problem is in my code. Probably has something to do with the potentiometer debounce, but I can't figure out what I'm doing wrong. I remove the code that pertains to the bypass switching to make it easier to read.


    Code:
    #config 
        __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _IOSCFS_8MHZ
    #endconfig
    
    ADCON0 = %00000000
    ADCON1 = %00110000
    ANSEL = %00000110
    define ADC_SAMPLEUS 50
    define ADC_BITS 8
    
    
    CM1CON0 = %00000000
    CM2CON0 = %00000000  
    
    TRISA = %00001111
    TRISC = %00000000
    
    ' Set TMR0 interrupt prescaler to 1:64
       OPTION_REG = %10000101        ' Set TMR0 configuration and enable PORTB pullups
       INTCON = %10100000           ' Enable TMR0 interrupts
       On Interrupt Goto tickint
    
        
        '                      
        '    Hardware connection
        '    ===================
        CS          VAR PORTA.5
        SCK         VAR PORTC.2
        SDI          VAR PORTC.1
        tempoLED var PORTC.0
        tempobutton var PORTA.0
        bypassbutton var PORTA.3
        bypassLED var PORTC.4
        fetA var PORTC.5
        fetB var PORTA.4
        fetC var PORTC.3
        
        
        
        '   
        '    Variables definition 
        '    ===================
        w var byte                          ' division toggle switch
        x var byte                          ' delay time knob
        xprevious var byte
        z var byte
        
        ticks var word
        tapcount var word
        LEDcounter var word
        LEDcounterlimit var word
        LEDrate var word
        
        trailsmode var byte
        trailsmodecounter var word 
        LEDon var byte
        LEDoff var byte
        
        LEDon = 1
        LEDoff = 0
                                 
        '
        '    begin in bypass
        '    ===============
        
        tempoLED = 0
        fetA = 0
        fetB = 0
        fetC = 1
        bypassLED = LEDoff
        trailsmode = 0
        gosub readpot
        gosub movepot
        if xprevious <= 0 then
            xprevious = 1
        endif
        
    main: 
            if LEDcounter > LEDrate then
                tempoLED = 1
                pause 5
                tempoLED = 0
            endif
            gosub potcheck
    goto main
    
    
    potcheck:       
            gosub readpot
            if x <= 0 then
                x = 1
            endif
            if x >= xprevious + 5 or x <= xprevious - 5 then               ' analog potentiometer debounce tolerance
                gosub movepot
            endif
    return        
    
    movepot:        
            CS = 0
            shiftout SDI, SCK, 1, [00000000,x]
            shiftout SDI, SCK, 1, [00010000,x]
            CS = 1
            xprevious = x
            gosub tempoLEDadjust
    return
             
    readpot
        adcin 2,x
        pause 10
    return
    
    tempoLEDadjust:                                           '  compensate for TMR0 not being 1:1 with actual delay time
        LEDrate = x + 10
        LEDcounterlimit = LEDrate + 1                       'counterlimit must always be 1 greater than rate
        LEDcounter = 0                                       ' reset LED counter
    return 
      
    Disable                                 ' Disable interrupts during interrupt handler
    tickint:                                    ' Interrupt routine to handle each timer tick   
        
        LEDcounter = LEDcounter + 1            ' add 1 to LEDcounter on every interrupt
       if LEDcounter > LEDcounterlimit then      ' prevent LEDcounter from overflowing
            LEDcounter = 0
       endif
    tiexit: 
       INTCON.2 = 0                             ' Reset timer interrupt flag
       Resume
    enable
    end

  11. #11
    Join Date
    May 2013
    Location
    australia
    Posts
    2,388


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    try something like this

    slightly altered for a pic16f1825




    Code:
    ;pic16f1825
    #CONFIG
                 __config        _CONFIG1,    _FOSC_INTOSC & _CP_OFF & _WDTE_OFF &  _PWRTE_ON  &  _MCLRE_ON  & _CLKOUTEN_OFF
                  __config      _CONFIG2, _PLLEN_OFF & _LVP_OFF
    #ENDCONFIG
    ADCON0 = %00000000
    ADCON1 = %00110000
    'ANSEL = %00000110       ;pic16f1825
    ANSELA = %00000100        ;pot is on   porta.2  an2
    define ADC_SAMPLEUS 50
    define ADC_BITS 8
    DEFINE ADC_CLOCK 3
    'CM1CON0 = %00000000     ;pic16f1825
    'CM2CON0 = %00000000     ;pic16f1825
    TRISA = %00001110        ;porta.0 used for debug
    TRISC = %00000000
    
        porta.0=1              ;porta.0 used for debug
        DEFINE DEBUG_REG PORTA
        DEFINE DEBUG_BIT 0      ;  if not used for pwr  
        DEFINE DEBUG_BAUD 9600
        DEFINE DEBUG_MODE 0     
       
        
        ' Set TMR0 interrupt prescaler to 1:128
        OPTION_REG = %10000110        ' Set TMR0 configuration and enable PORTB pullups
        INTCON = %10100000           ' Enable TMR0 interrupts
        osccon=$68   ;pic16f1825
        On Interrupt Goto tickint
        
        '                      
        '    Hardware connection
        '    ===================
        CS          VAR PORTA.5
        SCK         VAR PORTC.2
        SDI          VAR PORTC.1
        tempoLED var PORTC.0
    '    tempobutton var PORTA.0      ;porta.0 used for debug
    '    bypassbutton var PORTA.3     ;mclr used on pic16f1825
        bypassLED var PORTC.4
        fetA var PORTC.5
        fetB var PORTA.4
        fetC var PORTC.3
        ;pot is on   porta.2  an2
        
        
        '   
        '    Variables definition 
        '    ===================
    '    w var byte                          ' division toggle switch
        x var byte                          ' delay time knob
        xprevious var byte
    '    z var byte
        
    '    ticks var word
        tapcount var word
        LEDcounter var word
    '    LEDcounterlimit var word       
        LEDrate var byte
        
    '    trailsmode var byte
    '    trailsmodecounter var word 
    '    LEDon var byte
    '    LEDoff var byte
        
       
         pause 2000
        Debug "Start",13 ,10                         
        '
        '    begin in bypass
        '    ===============
        
        tempoLED = 0
        fetA = 0
        fetB = 0
        fetC = 1
        bypassLED = 0
    '    trailsmode = 0
        gosub readpot
        gosub movepot
        if xprevious <= 0 then
            xprevious = 1
        endif
        
    main: 
            if (LEDcounter // LEDrate) > (LEDrate>>1)   then
                tempoLED = 1
            else
                tempoLED = 0
            endif
            gosub potcheck
    if !  LEDcounter//4==0 then
           Debug 13 ,10 , #LEDcounter ,9,#(LEDcounter // LEDrate),9,#LEDrate
    endif        
            
    goto main
    
    potcheck:       
            gosub readpot
    '        if x <= 0 then     why ??????????????????????????????????
    '            x = 1
    '        endif
           ;if x >= xprevious + 5 or x <= xprevious - 5 then               ' analog potentiometer debounce tolerance
           if abs ( xprevious-x) > 4 then
                gosub movepot
           endif
    return        
    movepot:        
            CS = 0
            shiftout SDI, SCK, 1, [00000000,x]
            shiftout SDI, SCK, 1, [00010000,x]
            CS = 1
            xprevious = x
            gosub tempoLEDadjust
    return
             
    readpot
        adcin 2,x
        x = 8 max x      ;stop led from shutting down  completely
    '    pause 10     why ??????
    return
    tempoLEDadjust:                                           '  compensate for TMR0 not being 1:1 with actual delay time
        LEDrate = x/2
    '    LEDcounterlimit = LEDrate + 1                       'counterlimit must always be 1 greater than rate
    '    LEDcounter = 0                                       ' reset LED counter
    return 
      
    Disable                                 ' Disable interrupts during interrupt handler
    tickint:                                    ' Interrupt routine to handle each timer tick   
        
        LEDcounter = LEDcounter + 1            ' add 1 to LEDcounter on every interrupt
    '   if LEDcounter > LEDcounterlimit then      ' prevent LEDcounter from overflowing
    '        LEDcounter = 0
    '   endif
    tiexit: 
       INTCON.2 = 0                             ' Reset timer interrupt flag
       Resume
    enable
    end
    Warning I'm not a teacher

  12. #12


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    Richard,

    Thanks so much! That helped a lot. I made a few tweaks. I changed x = 8 max x to x = 1 max x in the readpot sub because that gave it a shorter minimum delay time. I added 7 to the LEDrate variable in the LEDtempoadjust sub because it was blinking just a slightly faster than the echoes. Then, of course I added back some of the variables and subs that pertain to the bypass switching.

    So now everything works perfectly with the switching, the delay time pot, and the blinking tempo LED. There is still another hurdle for me (and hopefully, this is the last one). The last feature I need to implement is the tap tempo button. This allows the user to tap out the rate of the echoes with the button rather than using the delay time knob. So that when the end user taps out the rate with the tempo button, it overrides the delay time pot....until the pot is actually moved again. That might be why some of the things in my previous code seemed weird.

    As it is now in the code below, the checkpot sub is constantly writing to the digital potentiometer. If I use the tap tempo button, it will change the tempo for a split second, but then the analog potentiometer immediately overwrites it. The checkpot sub is only supposed to check and see if the pot has been moved. I thought that by adding the if xprevious != to x and abs (xprevious - x) > 4 statement would do the trick, but it doesn't.

    The way your code handles the pot is obviously way more efficient since you've pared what used to take up 1024+ words to down to 682, but it's also a little over my head. How would I make the check pot sub just check the pot to see if the pot has been moved, and move the digital pot only when the pot has been moved?

    Code:
    #config 
        __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _IOSCFS_8MHZ
    #endconfig
    
    ADCON0 = %00000000
    ADCON1 = %00110000
    ANSEL = %00000110
    define ADC_SAMPLEUS 50
    define ADC_BITS 8
    DEFINE ADC_CLOCK 3
    CM1CON0 = %00000000     
    CM2CON0 = %00000000     
    TRISA = %00001111        
    TRISC = %00000000
       
        
        ' Set TMR0 interrupt prescaler to 1:128
        OPTION_REG = %10000110        ' Set TMR0 configuration and enable PORTB pullups
        INTCON = %10100000           ' Enable TMR0 interrupts
        On Interrupt Goto tickint
        
        '                      
        '    Hardware connection
        '    ===================
        CS          VAR PORTA.5
        SCK         VAR PORTC.2
        SDI          VAR PORTC.1
        tempoLED var PORTC.0
        tempobutton var PORTA.0      
        bypassbutton var PORTA.3     
        bypassLED var PORTC.4
        fetA var PORTC.5
        fetB var PORTA.4
        fetC var PORTC.3
        ;pot is on   porta.2  an2
        
        
        '   
        '    Variables definition 
        '    ===================
        w var byte                          ' division toggle switch
        x var byte                          ' delay time knob
        xprevious var byte
        z var byte
        
        ticks var word
        tapcount var word
        LEDcounter var word      
        LEDrate var byte
        
        trailsmode var byte
        trailsmodecounter var word 
        LEDon var byte
        LEDoff var byte
        
       
                               
        '
        '    begin in bypass
        '    ===============
        
        tempoLED = 0
        fetA = 0
        fetB = 0
        fetC = 1
        bypassLED = 0
        trailsmode = 0
        gosub readpot
        gosub movepot
        
    main: 
            tapcount = ticks
            if (LEDcounter // LEDrate) > (LEDrate>>1)   then
                tempoLED = 1
            else
                tempoLED = 0
            endif
            gosub potcheck
            if bypassBUTTON = 0 then
                gosub bypasspress
                gosub bypassbuttonrelease
            ENDif
            if tempobutton = 0 then
                goto tempopress
            endif               
    goto main
    
    tempopress:                                                       ' subroutine that occurs when tempo button is tapped
        if tapcount > 180 then                                        ' if longer than 3 seconds between taps, ignore the previous tap.
            ticks = 0
            gosub tempobuttonrelease
        else
            x = tapcount
            gosub movepot
            ticks = 0
            gosub tempobuttonrelease
        endif    
    goto main
    
    tempobuttonrelease:                                          ' debounce subroutine for tempo button
        tempoLED = 1
        do until tempobutton = 1
            pause 10
        loop
        tempoLED = 0
    return
    
    potcheck:       
            gosub readpot
           if xprevious != x and abs (xprevious-x) > 4 then
                gosub movepot
           endif
    return
    
    movepot:        
            CS = 0
            shiftout SDI, SCK, 1, [00000000,x]
            shiftout SDI, SCK, 1, [00010000,x]
            CS = 1
            xprevious = x
            gosub tempoLEDadjust
    return
             
    readpot
        adcin 2,x
        x = 1 max x      ;stop led from shutting down  completely
    return
    
    tempoLEDadjust:                                           '  compensate for TMR0 not being 1:1 with actual delay time
        LEDrate = (x/2) + 7
    return 
    
    bypasspress:
        trailsmodecounter = 0                                      ' waits to see if you want to switch between normal or trails mode
        do until trailsmodecounter = 400
            if bypassbutton = 1 then exit
            pause 10       
            trailsmodecounter = trailsmodecounter + 1
        loop
        
        if trailsmodecounter = 400 then
            goto trailmodechange
        endif 
        
        if trailsmode = 1 then 
            gosub trailsbypass
        elseif trailsmode = 0 then
            gosub normalbypass
        endif
    return
    
    trailmodechange:                                                ' subroutine that occurs when bypass button is held long enough to change between normal or trails mode
        if trailsmode = 1 then
            trailsmode =  0
        elseif trailsmode = 0 then
            trailsmode = 1
        endif
        
        for z = 1 to 5
        tempoLED = 1
            pause 100
        tempoLED = 0
            pause 100
        next z
        
    goto main    
    
    normalbypass:                                                       ' subroutine for normal bypass
        if bypassLED = 0 then
            fetA = 1
            fetB = 1
            fetC = 0
            bypassLED = LEDon
        elseif bypassLED = 1 then
            fetA = 0
            fetB = 0
            fetC = 1
            bypassLED = 0
        endif
    return
    
    trailsbypass:                                                       'subroutine for trails bypass
        if bypassLED = 0 then
            fetA = 1
            fetB = 1
            fetC = 0
            bypassLED = LEDon
        elseif bypassLED = 1 then
            fetA = 0
            fetB = 1
            fetC = 1
            bypassLED = LEDoff
        endif
    return
    
    bypassbuttonrelease:                                               '  debounce subroutine when bypass button is pressed
        do until bypassbutton = 1
            pause 10
        loop
    return    
      
    Disable                                 ' Disable interrupts during interrupt handler
    tickint:                                    ' Interrupt routine to handle each timer tick      
        LEDcounter = LEDcounter + 1            ' add 1 to LEDcounter on every interrupt
        ticks = ticks + 1
        if ticks > 300 then                     'prevent overflow when long periods of time pass between taps
            ticks = 240
       endif
    tiexit: 
       INTCON.2 = 0                             ' Reset timer interrupt flag
       Resume
    enable
    end

  13. #13


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    I realized what the problem was. xprevious =x was in the movepot subroutine, so anytime either the analog pot or tempo button changed x, xprevious would change.

    This seems to have fixed it.
    Code:
    #config 
        __CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _IOSCFS_8MHZ
    #endconfig
    
    ADCON0 = %00000000
    ADCON1 = %00110000
    ANSEL = %00000110
    define ADC_SAMPLEUS 50
    define ADC_BITS 8
    DEFINE ADC_CLOCK 3
    CM1CON0 = %00000000     
    CM2CON0 = %00000000     
    TRISA = %00001111        
    TRISC = %00000000
       
        
        ' Set TMR0 interrupt prescaler to 1:128
        OPTION_REG = %10000110        ' Set TMR0 configuration and enable PORTB pullups
        INTCON = %10100000           ' Enable TMR0 interrupts
        On Interrupt Goto tickint
        
        '                      
        '    Hardware connection
        '    ===================
        CS          VAR PORTA.5
        SCK         VAR PORTC.2
        SDI          VAR PORTC.1
        tempoLED var PORTC.0
        tempobutton var PORTA.0      
        bypassbutton var PORTA.3     
        bypassLED var PORTC.4
        fetA var PORTC.5
        fetB var PORTA.4
        fetC var PORTC.3
        ;pot is on   porta.2  an2
        
        
        '   
        '    Variables definition 
        '    ===================
        w var byte                          ' division toggle switch
        x var byte                          ' delay time knob
        xprevious var byte
        z var byte
        
        ticks var word
        tapcount var word
        LEDcounter var word      
        LEDrate var byte
        
        trailsmode var byte
        trailsmodecounter var word 
        LEDon var byte
        LEDoff var byte
        override var bit
        analogpot var bit
        footswitch var bit
        analogpot = 1
        footswitch = 0
        
       
                               
        '
        '    begin in bypass
        '    ===============
        
        tempoLED = 0
        fetA = 0
        fetB = 0
        fetC = 1
        bypassLED = 0
        trailsmode = 0
        gosub readpot
        gosub movepot
        pause 100
        
    main: 
            tapcount = ticks
             gosub potcheck
            
            if LEDcounter < 1  then
                tempoLED = 1
            else
                tempoLED = 0
            endif
            if bypassBUTTON = 0 then
                gosub bypasspress
                gosub bypassbuttonrelease
            ENDif
            if tempobutton = 0 then
                goto tempopress
            endif
                        
    goto main
    
    potcheck:       
           gosub readpot
           if abs (xprevious-x) > 4 then
                override = analogpot
                gosub movepot
           endif
    return
    
    tempopress:                                                       ' subroutine that occurs when tempo button is tapped
        if tapcount > 180 then                                        ' if longer than 3 seconds between taps, ignore the previous tap.
            ticks = 0
            gosub tempobuttonrelease
        else
            x = tapcount + 10
            override = footswitch
            gosub movepot
            ticks = 0
            gosub tempobuttonrelease
        endif    
    goto main
    
    tempobuttonrelease:                                          ' debounce subroutine for tempo button
        tempoLED = 1
        do until tempobutton = 1
            pause 10
        loop
        tempoLED = 0
    return
    
    movepot:        
            CS = 0
            shiftout SDI, SCK, 1, [00000000,x]
            shiftout SDI, SCK, 1, [00010000,x]
            CS = 1
            if override = analogpot then
                xprevious = x
            endif
            gosub tempoLEDadjust
    return
             
    readpot
        adcin 2,x
        x = 1 max x      ;stop led from shutting down  completely
    return
    
    tempoLEDadjust:                                           '  compensate for TMR0 not being 1:1 with actual delay time
        LEDrate = (x/2) + 6
    return 
    
    bypasspress:
        trailsmodecounter = 0                                      ' waits to see if you want to switch between normal or trails mode
        do until trailsmodecounter = 400
            if bypassbutton = 1 then exit
            pause 10       
            trailsmodecounter = trailsmodecounter + 1
        loop
        
        if trailsmodecounter = 400 then
            goto trailmodechange
        endif 
        
        if trailsmode = 1 then 
            gosub trailsbypass
        elseif trailsmode = 0 then
            gosub normalbypass
        endif
    return
    
    trailmodechange:                                                ' subroutine that occurs when bypass button is held long enough to change between normal or trails mode
        if trailsmode = 1 then
            trailsmode =  0
        elseif trailsmode = 0 then
            trailsmode = 1
        endif
        
        for z = 1 to 5
        tempoLED = 1
            pause 100
        tempoLED = 0
            pause 100
        next z
        
    goto main    
    
    normalbypass:                                                       ' subroutine for normal bypass
        if bypassLED = 0 then
            fetA = 1
            fetB = 1
            fetC = 0
            bypassLED = LEDon
        elseif bypassLED = 1 then
            fetA = 0
            fetB = 0
            fetC = 1
            bypassLED = 0
        endif
    return
    
    trailsbypass:                                                       'subroutine for trails bypass
        if bypassLED = 0 then
            fetA = 1
            fetB = 1
            fetC = 0
            bypassLED = LEDon
        elseif bypassLED = 1 then
            fetA = 0
            fetB = 1
            fetC = 1
            bypassLED = LEDoff
        endif
    return
    
    bypassbuttonrelease:                                               '  debounce subroutine when bypass button is pressed
        do until bypassbutton = 1
            pause 10
        loop
    return    
      
    Disable                                 ' Disable interrupts during interrupt handler
    tickint:                                    ' Interrupt routine to handle each timer tick      
        LEDcounter = LEDcounter + 1            ' add 1 to LEDcounter on every interrupt
        if LEDcounter > LEDrate then
            LEDcounter = 0
        endif
        ticks = ticks + 1
        if ticks > 300 then                     'prevent overflow when long periods of time pass between taps
            ticks = 240
       endif
    tiexit: 
       INTCON.2 = 0                             ' Reset timer interrupt flag
       Resume
    enable
    end
    Now I just need to make some fine adjustments so that the tempopress subroutine changes x so that the echoes are actually in time with the tempo that is tapped out. And I also need to add the division toggle switch. That's pretty simple though. It just divides x in half for double time or thirds for triplets.

  14. #14


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    I'm having one weird problem now that I can't figure out. The tap tempo works well except when the delay time pot is at about 20% of its rotation or less. If it's at 20% or less, the tempo button still works, but it makes the echoes go too fast....about 4 echoes for every one tap. If I have the delay time pot at 25% or higher, the tempo button works as expected with a 1 to 1 ratio.

    The way it's supposed to work is 2 is added to the tapcount variable upon each interrupt. It's supposed to be irrelevant as to whether or not you tap twice, 3, 4, or however many times. It just looks at the interval between the last to taps. It determines what the "first" tap is by looking at how long it was since your last tap. At the beginning of the tempopress subroutine, if it's been longer than 3 seconds, it assumes that this is your first tap, so it clears the tapcount variable. The interrupt then starts counting by adding 2 to the tapcount variable. On the second tap, it looks at the tapcount variable and uses that to set the delay time in the movepot subroutine. It then clears the tapcount variable and starts again.

    I can't figure out why the delay time pot is having an effect on this only when it is below a certain threshold.

  15. #15


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    I figured out what my biggest problem was. It was a hardware problem. It was SW3. The on-off-on toggle switch. I should have had the pole connected to a voltage divide. For some reason, it worked the way it was supposed to until the pot was below 20%. I don't know why the position of the pot made a difference, but it did. Anyhow....added a voltage divide and it works perfectly.

    The missing voltage divide aside, the pot still needed to be "debounced". Thank you so much, Richard for the massive improvement you made to the way the ADC reads the pot. Thanks for your help too, Henrik.

  16. #16
    Join Date
    Aug 2016
    Posts
    22


    Did you find this post helpful? Yes | No

    Default Re: Please help configure 16F616

    See below discussion to configure 16F616.
    http://electronics.stackexchange.com...in-a-pic16f616

Similar Threads

  1. Replies: 11
    Last Post: - 5th March 2012, 20:40
  2. CONFIGURE & OSCCON & meProg configure
    By SUNFLOWER in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 19th February 2011, 21:25
  3. PIC 16F616 Interrupt Enable/Disable?
    By Tobias in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 17th May 2009, 08:17
  4. 16F616 A to D
    By Tobias in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 1st May 2009, 16:37
  5. Configuring 16F616
    By Tobias in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 16th February 2009, 16:28

Members who have read this thread : 3

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