• AVR Freaks

Hot!Synchronize ADC readings with PWM signal in PIC16F1824

Author
Ferocactus
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2021/02/22 16:01:08
  • Location: 0
  • Status: offline
2021/02/23 10:36:37 (permalink)
0

Synchronize ADC readings with PWM signal in PIC16F1824

Hello, everyone!
I want to read an analog voltage, but it needs to do be done only when a PWM signal is low. The chip is a PIC16F1824.
The only way I image it would be possible is to connect a spare input to the PWM pin, and use a interrupt on change to trigger the ADC everytime signal goes from high to low. 
Is there a better way to do it, without using an extra I/O?
 
Thank you !
#1

14 Replies Related Threads

    ric
    Super Member
    • Total Posts : 29915
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/23 14:27:05 (permalink)
    0
    The CCP can generate an interrupt when the PWM signal goes low.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    Ferocactus
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2021/02/22 16:01:08
    • Location: 0
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/23 18:12:39 (permalink)
    0
    Thank you Ric.
    I feel really dumb, but I couldn´t find anything in datasheet that indicates how to generate the interrupt.
    What register should I look for?
    #3
    davea
    Super Member
    • Total Posts : 628
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: Tampa Bay FL USA
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/23 19:33:34 (permalink)
    +1 (1)
    I couldn´t find anything in datasheet that indicates how to generate the interrupt.

    I can't eater
    only on the rising edge TMRx = PRx
     
    #4
    ric
    Super Member
    • Total Posts : 29915
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/23 19:45:12 (permalink)
    +1 (1)
    Just set the CCP1IE flag in PIE1.
    I agree, the datasheet does not spell out that an interrupt is generated, but I'm sure I've used it in the past.
     
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    davea
    Super Member
    • Total Posts : 628
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: Tampa Bay FL USA
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/23 20:11:54 (permalink)
    0
    is there any pic data sheets that show that in the block diagram
    this is the only thing I found
    31014a.pdf
    Answer 5:
    The CCP1IF flag will be set on the match condition. TMR1IF is set when Timer1 overflows
    this is not good :(
    #6
    ric
    Super Member
    • Total Posts : 29915
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/23 20:22:16 (permalink)
    0
    That's in compare mode, which uses Timer 1.
    Best just try it on a real chip.
     
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #7
    Ferocactus
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2021/02/22 16:01:08
    • Location: 0
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/24 12:34:06 (permalink)
    0
    Just to update you guys, it didn´t work. Setting CCP3IE bit had no effect, at least not in the PIC16F1824.pink
    #8
    ric
    Super Member
    • Total Posts : 29915
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/24 12:37:08 (permalink)
    0
    So you had GIE and PEIE set, and it never jumped to the ISR?
    Or were you just polling to see if CCP3IF got set?
    It's useful to explain exactly HOW you checked to make sure you didn't miss something.
    It may well be that it doesn't work, but don't give up too easily. :)
     
    post edited by ric - 2021/02/24 12:38:27

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #9
    Ferocactus
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2021/02/22 16:01:08
    • Location: 0
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/24 18:56:17 (permalink)
    0
    Here is the test code I wrote. It generates a 250 Hz PWM with CCP3 output (this is working fine).
    The interrupt never happens,  though.

    /*
     * File: PWM interrupt test
     * Author: 0xFF
     * Processor: PIC16F1824
     * OSC: 8 MHz (internal)
     * Compiler: XC8
     *
     * OBJECTIVE: Outputs a 250 Hz PWM signal in CCP3 pin.
     * A CCP3 interrupt is enabled to generate a 1 uS pulse on RC3 pin
     * everytime PWM signal transitions from high to low
     * (I´m not sure PIC16F1824 is capable of generating an interrupt in such
     * circunstances.)
     */

    // CONFIG1
    #pragma config FOSC = INTOSC
    #pragma config WDTE = OFF
    #pragma config PWRTE = ON
    #pragma config MCLRE = ON
    #pragma config CP = OFF
    #pragma config CPD = OFF
    #pragma config BOREN = OFF
    #pragma config CLKOUTEN = OFF
    #pragma config IESO = ON
    #pragma config FCMEN = ON
    // CONFIG2
    #pragma config WRT = OFF
    #pragma config PLLEN = OFF
    #pragma config STVREN = ON
    #pragma config BORV = LO
    #pragma config LVP = OFF

    // Includes
    #include <xc.h>
    #include "stdint.h"

    #define _XTAL_FREQ 8000000

    // Duty CYcle adjust variable
    uint16_t pwm_dut = 0;

    //Prototype
    // changes PWM duty cycle
    // valid range is 0 to 500
    void reg_pwm(uint16_t val);

    /***** --- MAIN LOOP --- *****/
    void main(void)
    {
        // Int. Osc at 8 MHz
        OSCCON = 0b01110000;

        // Port settings
        ANSELA = 0;
        ANSELC = 0;
        TRISA = 0;
        TRISC = 0;
        
        // ****** Config PWM ******
        /* Config timer2 prescale to 64
         and load PR2 register to make
         PWM run at 250 Hz */
        T2CONbits.T2CKPS = 0b11;
        T2CONbits.TMR2ON = 1;
        PR2 = 0x7C;
        //Config CCP in PWM mode
        CCP3CONbits.CCP3M = 0b1100;
     
        // using timer2
        CCPTMRS0bits.C3TSEL = 0b00;

        // Enable CCP3 interrupt
        INTCONbits.PEIE = 1;
        PIE3bits.CCP3IE = 1;
        INTCONbits.GIE = 1;
        
        // set PWM duty cycle to 50%
        pwm_dut = 250;
        reg_pwm(pwm_dut);
           
        /***** --- FOR LOOP --- *****/
        for (;;)
        {
           
        }
    }

    // Changes PWM duty cycle
    // Allowed range is 0 (0%) to 500 (100%)
    void reg_pwm(uint16_t val)
    {
        uint8_t temp;
        temp = val & 0b11;
        temp = temp << 4;
        CCP3CON &= 0b1100;
        CCP3CON |= temp;
        temp = val >> 2;
        CCPR3L = temp;
    }

    // Handles CCP3 interrupts
    // Create a 1 uS pulse on RC3 pin
    // whenever (if) a CCP3 int happens
    void interrupt isr(void)
    {
        if (PIR3bits.CCP3IF)
        {
            LATCbits.LATC3 = 1;
            __delay_us(1);
            LATCbits.LATC3 = 0;

            PIR3bits.CCP3IF = 0;
        }
    }

    post edited by Ferocactus - 2021/02/24 19:14:41
    #10
    ric
    Super Member
    • Total Posts : 29915
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/24 19:12:33 (permalink)
    +1 (1)
    Your code looks pretty good.
    The last thing worth trying is using one of the enhanced CCP modules, i.e. 1 or 2.
    It's strange that the "Register used by PWM" table shows the IE and IF flags as unshaded in PWM mode, but Microchip are not known for absolute consistency in their datasheets, particularly the newer ones...
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #11
    Ferocactus
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2021/02/22 16:01:08
    • Location: 0
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/24 19:27:42 (permalink)
    0
    Thank you, ric!  I´ll try the enhanced CCP. If this also fails, I will use an extra I/O to watch the state of the PWM.
    #12
    davea
    Super Member
    • Total Posts : 628
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: Tampa Bay FL USA
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/24 20:40:03 (permalink)
    0
    It's strange that the "Register used by PWM" table shows the CCP IE and IF flags as unshaded in PWM mode

    and all timer ISR flags are shaded
    something got to generate a ISR...
    @Ferocactus if you find that TIMER ISR does work and CCP ISR does not work
    you could start a different timer to timeout just after the pin goes low (+2 LSB of 10 bit PWM value)
    zero the 2nd timer at the PWM ISR and set PR as need for PWM value to start ADC
    post edited by davea - 2021/02/24 20:41:36
    #13
    1and0
    Access is Denied
    • Total Posts : 12095
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/25 08:25:13 (permalink)
    0
    As I understand it, there is a TMRxIF interrupt when TMRx matches PRx.  For PWM mode, there's a CCPyIF interrupt when TMRx:Q-cycle matches CCPRyH:CCPyCON<5:4> that seems to occur in some PIC devices and not others; but I have to admit that I've never used this before.
     
    post edited by 1and0 - 2021/02/25 08:45:26
    #14
    Ferocactus
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2021/02/22 16:01:08
    • Location: 0
    • Status: offline
    Re: Synchronize ADC readings with PWM signal in PIC16F1824 2021/02/26 05:48:18 (permalink)
    0
    davea
    @Ferocactus if you find that TIMER ISR does work and CCP ISR does not work
    you could start a different timer to timeout just after the pin goes low (+2 LSB of 10 bit PWM value)
    zero the 2nd timer at the PWM ISR and set PR as need for PWM value to start ADC


    Thank you, davea! I´m I little short on time right now, but I´ll definitely try yours and ric´s suggestions.
    #15
    Jump to:
    © 2021 APG vNext Commercial Version 4.5