Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

MCLR as digital input is resetting the device

HighTechPower

Member level 2
Joined
Jul 10, 2020
Messages
52
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
425
Hi. I'm using PIC12F683 in a circuit. I'm using it's pin 4, MCLR as digital input by adjusting the configuration bits accordingly. I have connected a SPDT switch to pin 4 whose level can be either 3.3 V or 0 V, however whenever there is a change in input voltage level at pin 4 (low to high or high to low) by changing switch position, it resets pin 7 (perhaps the whole device). Any idea why this is happening and how to avoid that.
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
19,284
Helped
4,272
Reputation
8,547
Reaction score
4,236
Trophy points
1,393
Activity points
127,990
Hi,
Show your code and setup.
Otherwise we can just guess.

Klaus
 

andre_teprom

Super Moderator
Staff member
Joined
Nov 7, 2006
Messages
9,222
Helped
1,148
Reputation
2,315
Reaction score
1,124
Trophy points
1,403
Location
Brazil
Activity points
53,693
Read previous reply.

Provide the settings witch are being programmed into device.
Or, show the code, if these configurations are there as pre-proprocessor directives.
 

HighTechPower

Member level 2
Joined
Jul 10, 2020
Messages
52
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
425
Hi,
Show your code and setup.
Otherwise we can just guess.

Klaus

Please attached here find the full schematic and code as well.

Code:
#include <xc.h>

#define _XTAL_FREQ 4000000

void init_micro (void);
void init_timer (void);
void init_adc (void);
void init_pwm (void);
void read_adc(void);
void pwm_dr (unsigned int dr);
void status (void);
int abval (int);

static int dr = 0, counter_a = 0, counter_b = 0, counter_c = 0, counter_d = 0, adc = 0, flag_c = 0, buzzer_flag = 0;
//static signed long sample_fresh = 0, sample_previous = 0, filtered_previous = 0, filtered_fresh = 0, temp_sample = 0, temp_filtered = 0;

#define SBIT_LED_CHARGING GP4
#define SBIT_LED_CHARGED GP5
#define SBIT_BUZZER GP2
#define TRUE 1
#define FALSE 1
//#define PB_SWITCH GP0
#define PB_SWITCH GP3
#define POWER_GOOD GP0

void main (void)
{
    init_micro();
    init_adc();
    init_timer();
//    init_pwm();
    do
    {
    }
    while(TRUE);
}

void init_micro (void)
{
    OSCCON = 0b01100111;
    TRISIO = 0b00001010;
    CMCON0 = CMCON0 | 0b00000100;
    ANSEL = 0b01010010;
    GPIO = 0b00000000;
    POWER_GOOD = TRUE;
    __delay_ms(100);
}

void interrupt team_isr()
{
    if(TMR1IF)
    {
        counter_b++;
        if(adc >= 820)
        counter_c++;
        if(counter_b >= 300)
        {
            if(counter_c >= 299)
            flag_c = 1;
            else if(counter_c < 299)
            flag_c = 0;
            counter_b = 0;
            counter_c = 0;
        }
        counter_a++;
        if(!PB_SWITCH)
        {
            SBIT_BUZZER = 0;
            if(adc >= 820)
            {
                SBIT_BUZZER = 0;
                if(flag_c)
                {
                    SBIT_LED_CHARGED  = 1;
                    SBIT_LED_CHARGING = 0;
                    if(counter_a >= 10)
                    {
                        counter_a = 0;
                    }
                }
                else if(!flag_c)
                {
                    SBIT_LED_CHARGED = 0;
                    if(counter_a >= 10)
                    {
                        SBIT_LED_CHARGING ^= 1;
                        counter_a = 0;
                    }
                }
            }
            else if(adc < 820)
            {
                if(counter_a >= 10)
                {
                    SBIT_LED_CHARGING ^= 1;
                    counter_a = 0;
                }
                SBIT_BUZZER = 0;
                SBIT_LED_CHARGED = 0;
            }
        }
        else if(PB_SWITCH)
        {
            if(adc >= 820)
            {
                if(flag_c)
                {
                    if(counter_a >= 10)
                    {
                        SBIT_BUZZER ^= 1;
                        counter_a = 0;
                    }
                    SBIT_LED_CHARGED  = 1;
                    SBIT_LED_CHARGING = 0;
                }
                else if(!flag_c)
                {
                    SBIT_LED_CHARGED = 0;
                    SBIT_BUZZER = 0;
                    if(counter_a >= 10)
                    {
                        SBIT_LED_CHARGING ^= 1;
                        counter_a = 0;
                    }
                }      
            }
            else if(adc < 820)
            {
                if(counter_a >= 10)
                {
                    SBIT_LED_CHARGING ^= 1;
                    counter_a = 0;
                }
                SBIT_BUZZER = 0;
                SBIT_LED_CHARGED = 0;
            }
        }
        TMR1IF = 0;
        TMR1H = 0xCF;
        TMR1L = 0x2C;
        TMR1IE = 1;
        PEIE = 1;
        GIE = 1;
        TMR1ON = 1;
    }
   
    if(ADIF)
    {
        read_adc();
        ADIF = 0;
        ADON = 1;
        ADIE = 1;
        PEIE = 1;
        GIE = 1;
    //    __delay_us(4);
        GO_nDONE = 1;
    }
}

void init_timer (void)
{
    T1CON = 0b00110100;
    TMR1H = 0xCF;
    TMR1L = 0x2C;
    TMR1IE = 1;
    PEIE = 1;
    GIE = 1;
    TMR1ON = 1;
    TMR1IF = 0;
}

void init_pwm (void)
{
    PR2 = 255;
//    if(filtered_fresh < 4)
//    if(adc < 4)
//    pwm_dr((adc + 94));
//    pwm_dr((filtered_fresh + 4));
//    pwm_dr((adc + 4));
//    else
//    pwm_dr(adc);
//    pwm_dr(filtered_fresh);
//    pwm_dr(adc);
    pwm_dr(4);
    TRISIO = 0b00001011;
    CCP1CON = 0b00001100;
    T2CON = 0b00000101;
}

void init_adc (void)
{
    ADCON0 = 0b10000100;
    ADON = 1;
    ADIF = 0;
    ADIE = 1;
    PEIE = 1;
    GIE = 1;
//    __delay_us(4);
    GO_nDONE = 1;
}

void pwm_dr (unsigned int dr)
{
    CCPR1L = (dr >> 2);
    CCP1CON = ((CCP1CON & 0x3F) + ((dr << 4) & 0x30));
}

void read_adc (void)
{
    adc = (((unsigned)ADRESH << 8) | ADRESL);
/*    filtered_previous = filtered_fresh;
    temp_filtered = 255 * filtered_previous;
    temp_filtered = temp_filtered >> 8;
    sample_previous = sample_fresh;
    sample_fresh = adc;
    temp_sample = 255 * abval((sample_fresh - sample_previous));
    temp_sample = temp_sample >> 8;
    filtered_fresh = temp_filtered + temp_sample;   */
//    run_pwm();
//    status();
}

void status (void)
{
    if(adc < 820)
    SBIT_LED_CHARGING = 0;
    else
    SBIT_LED_CHARGED = 1;
}

int abval (int val)
{
    return (val<0 ? (-val) : val);
}

Also attached here find the settings preview.
--- Updated ---

Please also reply for the thread in link below which belongs to same schematic and code.

(5) CMCON0 and ANSEL registers | Forum for Electronics (edaboard.com)
 

Attachments

  • Charger Front.PDF
    362.7 KB · Views: 3
  • 1615104213866.png
    1615104213866.png
    111.8 KB · Views: 7
Last edited:

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
19,284
Helped
4,272
Reputation
8,547
Reaction score
4,236
Trophy points
1,393
Activity points
127,990
Hi,

Schematic. Nothing that explains the behaviour.
But U2 capacitors...the bulk (bigger one) needs to be at the input side.

Imagine the regulator act as a water level control.
In your case the input (reservoir) is just 1/1000 of the output.
It's like you want to control the level of a 1000 liter box (output) with the input of 1 liter reservoir.
In most cases this may not lead to immedate fail, but on input power fail or big load variations it will.

An example.
In your case the capacitor voltage is 3.3V (Vn) and your circuit safely works with voltage down to 2.7V (Vm).
This is a voltage drop in the capacitor of just 0.6V.
The backup time 100uF × 0.6 V / Iload (for 50mA just 1.2 milliseconds)

In opposite when the capacitor is at the input side.
It's normally at 12V ...and with a regulator dropout of 2V your system will work with input voltages down to 2.7V + 2.0V =4.7V
So the capacitor difference is 12V - 4.7V = 7.3V.
This is about 12 times more ... and means 12 × 1.2ms 14.4ms backup time

When you use a switching regulator instead of a linear regulator:
It is about 1.2ms vs 35ms = a factor of 30.

Need some time to reviev the rest..

Klaus
 

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,823
Helped
4,839
Reputation
9,696
Reaction score
4,628
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
126,175
I'm quite surprised it works at all. Such a long ISR which includes subroutines and instructions to enable and disable interrupts is highly inadvisable.
I strongly suspect that closing the switch causes a software crash rather than a reset but they show the same symptoms.

I would start afresh but follow a flow normal ISR rules, treating each source of interrupt as a function. At the moment the code structure doesn't lend itself to an easy fix.

Brian.
 

HighTechPower

Member level 2
Joined
Jul 10, 2020
Messages
52
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
425
I'm quite surprised it works at all. Such a long ISR which includes subroutines and instructions to enable and disable interrupts is highly inadvisable.
I strongly suspect that closing the switch causes a software crash rather than a reset but they show the same symptoms.

I would start afresh but follow a flow normal ISR rules, treating each source of interrupt as a function. At the moment the code structure doesn't lend itself to an easy fix.

Brian.

You mean I don't write any code routines inside ISR?
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
19,284
Helped
4,272
Reputation
8,547
Reaction score
4,236
Trophy points
1,393
Activity points
127,990
Hi,

One (of several) rules for ISRs is: keep it as short (in time) as possible. A function call is not forbidden but it is additiinal processing power overhead for pushing data on the stack and back. An inline function could be an improvement..

Klaus
 

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,823
Helped
4,839
Reputation
9,696
Reaction score
4,628
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
126,175
You mean I don't write any code routines inside ISR?
Read the data sheet about interrupts!

---- while initializing ------
1. enable the interrupt sources
2. enable GIE. NEVER CHANGE GIE INSIDE THE ISR!!, it is automatically disabled as the ISR is entered and restored as you leave the ISR.

---- inside the ISR routine -----
3. PIC16 devices only have one level of interrupt so in the ISR check which peripheral caused it, set a flag for that source then clear the interrupt bit.
4. leave the ISR but do not change the GIE bit!

---- in the main code ------
5. in the main() loop, check the flag you set in step 3 and do whatever is necessary to handle the condition that caused the interrupt.
6. reset the flag you used in step 5 so the process doesn't repeat until another interrupt occurs.

ALWAYS do the work inside the main() loop, get out of ISRs as quickly as possible because while you are in the ISR you could miss subsequent interrupt events.

Brian.
 

HighTechPower

Member level 2
Joined
Jul 10, 2020
Messages
52
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
425
Is the following message normal?

1615201784457.png
--- Updated ---

Finally I found the culprit.
I just attached oscilloscope probe to the output of 78L33 of 3.3 V and when pressed the switch it created 0 V on that line for very short duration. Thus switch itself was creating short while changing it's position.
 
Last edited:

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
19,284
Helped
4,272
Reputation
8,547
Reaction score
4,236
Trophy points
1,393
Activity points
127,990
Hi,

You mean the DPDT switch?
There are "break before make" (this what you need) and "make before break" (that does not work).

But to avoid the problem at all the usual way is to use a SPST and a pullup.

Klaus
 

LaTeX Commands Quick-Menu:

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top