• AVR Freaks

Hot!Pic10f320 adc interrupt

Page: 12 > Showing page 1 of 2
Author
wgenzo
New Member
  • Total Posts : 21
  • Reward points : 0
  • Joined: 2017/06/28 02:55:36
  • Location: Brescia, Italy
  • Status: offline
2017/06/29 05:29:38 (permalink)
0

Pic10f320 adc interrupt

Good day to all,
I'm new in the forum cause for the very first time I'm using a PIC uC...basically I'm an hardware designer, so I rarely manage bits...http://www.microchip.com/...es/smiley/bigSmile.gif and I'm not so good.
I have to use PIC10F320 because of its small size (SOT23-6 package) to monitor an analog input and produce a PWM output.
No problem with PWM output when analog input is not monitored: I obtain right frequency and duty cycle square wave on pin RA0 by means of timer2. Unfortunately (frankly speaking because I'm not able..) when I read analog input (on pin RA1) if I use polling tecnique, PWM output it's not stable because it's influenced by delay introduced waiting GO_nDONE.
I'm able only to program in C (I'm using MPLAB X IDE with XC8 compiler) and I'm searching for an example where it's used ADC interrupt.
I've tried with the code below but with no success:
//Function to Read ADC channel
unsigned int ADCRead()
{
GIE = 1; //Enable global interrupt
TMR0IE=1; // timer0 interrupt enable
PEIE = 1; //Enable peripheral interrupt
PIE1bits.ADIE = 1; //Enable ADC interrupt
ADIF = 1;
ADRES = 0x00;
//ADIF = 0; // clear AD interrupt flag

ADCON=0b00100101; //Fosc/8, AN1 setted as analog input,enable ADC
//OPTION_REG=0b10000100; // prescaler 1:32 assigned to timer0
//TMR0=256-62; // 16*62 = 992uS. Overflow interrupt will fire every 992uS

if (ADIF)
{
ADIF=0; // clear AD interrupt flag
advalue=ADRES;
//GO_nDONE = 1;
}
}

Could you please help me to read ADC with an interrupt tecnique (I could use timer0 for this aim).
Thanks
Have a nice day
Andrea
#1

34 Replies Related Threads

    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/06/29 06:57:48 (permalink)
    +1 (1)
    Do NOT set GIE and PEIE unless you have an interrupt service routine, which you don't appear to have.
    They don't need to be set to poll ADIF.
     
    How are you generating the PWM?
    Your PIC has a PWM module which can generate it for you with no user interaction once it is set up.
     
    #2
    NorthGuy
    Super Member
    • Total Posts : 6223
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: Pic10f320 adc interrupt 2017/06/29 07:02:20 (permalink)
    0
    Do you use a PWM module (controlled with PWMCON register) to generate your PWM output? Do you reload PWM duty-cycle on every TMR2 cycle?
     
    #3
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/06/29 07:05:22 (permalink)
    0
    Thanks for your fast reply and clarifications.
    I'm generating PWM in the following way:
     
    void InitPWM ()
    {

    PWM1CON = 0b00000000; // Clear PWM1CON
    PR2 = 0b01101110; // Configure the Timer2 period, decimal 110 --> 18kHz

    PWM1CON = 0b11000000; //Enable PWM Module, Module Output

    PWM1DCH = 0b00000000; // Clear duty cycle registers
    PWM1DCL = 0b00000000;

    TMR2IF = 0; //Clear the timer 2 interrupt flag
    T2CON = 0b00000000; //Set prescaler to 1

    TMR2ON = 1; //Enable timer 2

    TRISA =0b00001010; //RA0 & RA2 setted as output

    //Set duty cycle to 106
    PWM1DCH = 0b00011010;
    PWM1DCL = 0b10000000;

    return;

    }
    #4
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/06/29 13:12:05 (permalink)
    +1 (1)
    So you are using the PWM peripheral.
    That will be perfectly stable even if you don't touch it for long periods, so I don't understand what you mean by:

     when I read analog input (on pin RA1) if I use polling tecnique, PWM output it's not stable because it's influenced by delay introduced waiting GO_nDONE.

    Now you need to explain how you are testing, what you are expecting to see, and what you are seeing.
     
    This sounds more like you mis-interpreting what you are seeing, or a problem in how you are testing.
    #5
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/06/29 14:10:12 (permalink)
    0
    I'm testing RA0 measuring with an oscilloscope probe (100us/div) directly on the pin of the uController:
    when I comment, in the main, ADCRead function the output on RA0 pin is a perfect square wave, turning from 0 to 3,3V at 18kHz with 50% duty cycle. When ADCRead is uncommented, on RA0 I see an irregular square wave, that means that I don't see a new pulse every period, I miss some pulses and the duty cycle is less than 50%...without changing anything in the InitPWM function. For this reason I think that uController is working on ADC and misses PWM...
    Thanks
    Andrea
    #6
    NorthGuy
    Super Member
    • Total Posts : 6223
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: Pic10f320 adc interrupt 2017/06/29 14:34:49 (permalink)
    +1 (1)
    If  you use PWM module, the interference cannot be caused by ADC working. There must be some other cause.
     
    As qhb said, you should not enable interrupts if you don't handle them. Enabled interrupts can cause the problem you have - PIC tries to process the interrupt, but there's no handling, so it goes to a random place, most likely to the code which re-initializes the PWM.
    post edited by NorthGuy - 2017/06/29 14:44:55
    #7
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/06/29 14:40:04 (permalink)
    0
    Also if I use a delay,20us long, after starting adc conversion,to wait for the end of adc conversion (polling tecnique), without interrupt, I notice the same irregular pulses out of RA0 pin
    #8
    NorthGuy
    Super Member
    • Total Posts : 6223
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: Pic10f320 adc interrupt 2017/06/29 14:46:22 (permalink)
    0
    wgenzo
    Also if I use a delay,20us long, after starting adc conversion,to wait for the end of adc conversion (polling tecnique), without interrupt, I notice the same irregular pulses out of RA0 pin



    Have you removed these lines?
     

    GIE = 1; //Enable global interrupt
    PEIE = 1; //Enable peripheral interrupt

    #9
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/06/29 15:31:35 (permalink)
    +1 (1)
    Get rid of these lines altogether
    GIE = 1; //Enable global interrupt
    TMR0IE=1; // timer0 interrupt enable
    PEIE = 1; //Enable peripheral interrupt
    PIE1bits.ADIE = 1; //Enable ADC interrupt
    ADIF = 1; 
    ADRES = 0x00;


    Move this line out of your ADC read function, and do it only once at the start of your main function
    ADCON=0b00100101; //Fosc/8, AN1 setted as analog input,enable ADC

     
    All that should be left in your ADCRead function should be:
    unsigned int ADCRead()
    {
        GO_nDONE = 1;    // start conversion
        while (GO_nDONE);    // wait until conversion complete
        return ADRES;    //return 8 bit value
    }

     
     
    Edit: fixed return value. This chip only has an 8 bit ADC.
    For that reason, the function only needs to return an unsigned char, not an unsigned int.
     
    post edited by qhb - 2017/06/29 15:36:17
    #10
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/06/30 02:12:17 (permalink)
    0
    Ok, thanks for this council. I'm on a business trip till next thursday, then I'll test this suggestion and write back for a feedback
    Thanks again
    Andrea
    #11
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 02:53:21 (permalink)
    0
    I'm still experiencing problems with output on RA0 pin.
    I removed the 6 lines told and moved in the main the code
    ADCON=0b00100101; //Fosc/8, AN1 setted as analog input,enable ADC
     (removing from ADC Read function).
     
    PWM is still irregular, changing in frequency and duty cycle only when ADC Read in uncommented as you can see in the image....
     
    Thanks
    Andrea
     



    #12
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 02:54:24 (permalink)
    #13
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 03:02:07 (permalink)
    +1 (1)
    What is connected to RA1?
    Have you made sure you're not getting cross coupling of the PWM on RA0 into the RA1 pin?
     
    #14
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 03:09:12 (permalink)
    0
    RA1 is connected to a voltage divider made with a 120K resistor in series with a 5K36 resistor.
    The aim is having approx. 1V on RA1 pin when power supply of the system is 24V (so 24*5360/(120000+5360) gives 1.02V).
    Voltage on RA1 pin is quite stable, with little ripple and no cross coupling of the PWM into RA1 pin is evident
    #15
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 04:45:02 (permalink)
    0
    I add that I suppose I'm correctly reading ADC on RA1 because I made a function that checks voltage on resistor divider and blinks an LED (connected on RA2) under a certain threshold...and this is correctly working (under the threshold LED blinks, above the threshold LED is always on). Only PWM on RA0 is not stable....
    #16
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 04:59:39 (permalink)
    0
    Can we see how your entire program looks now please?
     
    #17
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 05:18:10 (permalink)
    0
    The entire program is as below:
     
    #include <htc.h>
    #define _XTAL_FREQ 8000000
    #define MINLEVEL 62 // 62/255 corrispondente a blink sotto i 19V, ovvero 0,8V sul partitore/3,3V

    #pragma config FOSC = INTOSC // Oscillator Selection bits (INTOSC oscillator: CLKIN function disabled)
    #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
    #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
    #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
    #pragma config MCLRE = ON // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
    #pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
    #pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
    #pragma config LPBOR = OFF // Brown-out Reset Selection bits (BOR disabled)
    #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)

    void InitPWM();
    void ADCInit();
    unsigned char ADCRead();
    void Interrupt();
    unsigned char advalue;

    void main()
    {
    TRISA =0b00001010; // TRISA=DATA DIRECTION RA1 input (deve diventare analog???). RA2 output , RA3 inputs . RA0 output later, even after PWM settings
    ANSELA=0b00000010; // only RA1 as analog input

    PORTA = 0b00000000;

    CLC1CON = 0b00000000;
    CWG1CON0 = 0b00000000;

    InitPWM();
    //Initialize the ADC Module

    ADCON=0b00100101; //Fosc/8, AN1 setted as analog input,enable ADC
    ADCRead ();

    advalue=ADRES; // AD conversion result
    if (advalue<MINLEVEL)
    {
    PORTA=0b0000000;
    __delay_ms(500);
    PORTA=0b00000100;
    __delay_ms(500);
    }
    else {
    PORTA=0b00000100;
    }

    }


    void InitPWM ()
    {

    PWM1CON = 0b00000000; // Clear PWM1CON
    PR2 = 0b01101110; // Configure the Timer2 period, decimal 110 --> 18kHz

    PWM1CON = 0b11000000; //Enable PWM Module, Module Output

    PWM1DCH = 0b00000000; // Clear duty cycle registers
    PWM1DCL = 0b00000000;

    TMR2IF = 0; //Clear the timer 2 interrupt flag
    T2CON = 0b00000000; //Set prescaler to 1

    TMR2ON = 1; //Enable timer 2

    TRISA =0b00001010; //RA0 & RA2 setted as output

    //Set duty cycle to 106
    PWM1DCH = 0b00011010;
    PWM1DCL = 0b10000000;

    return;

    }
    //Function to Initialise the ADC Module
    void ADCInit()
    {
    //Port Configuration
    ADCON=0b00100110;


    }
    //Function to Read ADC channel
    unsigned char ADCRead()
    {
    GO_nDONE = 1;

    while (GO_nDONE); // wait until conversion complete
    return ADRES; //return 8 bit value*/
    }
    #18
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 05:31:57 (permalink)
    +3 (3)
    You are letting your main() function exit.
    You shouldn't!
    Also, not your current problem, but you are discarding the return value from your ADCRead() function, and re-reading the ADC register.
    #19
    wgenzo
    New Member
    • Total Posts : 21
    • Reward points : 0
    • Joined: 2017/06/28 02:55:36
    • Location: Brescia, Italy
    • Status: offline
    Re: Pic10f320 adc interrupt 2017/07/06 23:50:35 (permalink)
    0
    I beg your pardon but I'm not able to understand your suggestion.
    What do you mean with "you are letting your main () function exit"?
     
    In any case, if I comment the line ADCRead (); in the main, PWM output on RA0 pin is ok.
    In my humble opinion, waiting for GO_nDONE with the line 
    while (GO_nDONE);  
    stops microcontroller doing other for a time longer than PWM period...so I need a way to have an interrupt from ADC, not polling it
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2020 APG vNext Commercial Version 4.5