Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics 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.

PIC12F629 not working if internal weak pull ups used

Status
Not open for further replies.

sairfan1

Full Member level 1
Full Member level 1
Joined
Jun 12, 2010
Messages
97
Helped
4
Reputation
8
Reaction score
7
Trophy points
1,288
Location
Regina, Canada
Activity points
2,384
Its my first time using internal weak pull ups I gone through some threads on this forum and I believe my understanding is good I can use internal weal pull up for buttons.

I have this small project to turn on relay after some delay, Problem is that when I use exrernal pull up resistors it works all goodd but when I use internal pull up it got held (stuck) on __delay_,ms statement when it reach there for second time.

When I run the program it works fine after 5 second delay it turns on RELAY, when i press button on GPIO2 it turns OFF RELAY and get in to loop flag == 1, now when I press button on GPIO 1 it comes out the 2nd loop (flag == 1) and reach to wait function, where it enters the loop statement and at reaching the line __delay_ms(1000) it gets halt, and never reaches to the line after this function. If I use external resistors it all works good. Please also note that at this point nGPPU bit is not set that means internal pull up are set but disabled.

When i set register OPTION_REG = 0b00000000; LED on GPIO 2 lit in half strength and I can see its like a PWM effect looks like TMR0 kicks in? to overcome this issue I separately set bit on option register to activate internal pull up OPTION_REGbits.nGPPU = 0; by setting nGPPU bit outcome is same.

C:
// CONFIG
//#pragma config FOSC = INTRCCLK  // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

 // Definitions 4MHZ internal
#define _XTAL_FREQ 4000000

#define RELAY GPIObits.GP4
#define SW GPIObits.GP5

#include <xc.h>

volatile uint8_t flag = 0;

void __interrupt() isr(void){
    if (INTCONbits.INTF == 1) {
        INTCONbits.INTF = 0;
        //RELAY = 1;       
        flag = 1;       
    }
    
    // GP1 is internally pulled up, if pressed it will be zero
    if (INTCONbits.GPIF == 1 && GPIObits.GP1 == 0) {     
        INTCONbits.GPIF = 0;
        flag = 0;
        //SW = !SW;
    }
}

void wait(uint8_t w);

void main(void) {
    
    // OSCCAL = 0b10000000;
        
    // Comparator register       
    CMCON = 0b00000111;     // disable comparator
    
    // Interrupt config reg.
    // GIE,
    // PEIE Peripheral int,
    // T0IE,
    // INTE (PORT2),
    // GPIE (Change Port),
    // T0IF,
    // INTF (External Int Flag),
    // GPIG (Port change flag)
    INTCON = 0b11011000;
    
    TRISIObits.TRISIO0 = 1;   //relay reset
    TRISIObits.TRISIO1 = 1;   // extra
    TRISIObits.TRISIO2 = 1;   // emergency stop
    //TRISIObits.TRISIO3 = 1;   // MCLRE
    TRISIObits.TRISIO4 = 0;   // Relay
    TRISIObits.TRISIO5 = 0;   //
    //GPIO = 0;
    
    // internal weak pull ups
    WPU = 0b00000111;
    
    // IOC Interrupt On Change
    IOC = 0b00000011;
    
    // OPTION_REG reg
    // GPPU' pull up enable
    // INTEDG intrrupt edge
    // T0CS TMR0 clock source
    // T0SE TMR0 source edge
    // PSA prescaler assignment
    // PS<2:0> prescaler rate bits
    //OPTION_REG = 0b00000000;
    
    //OPTION_REGbits.nGPPU = 0;
    
    
    while(1) {
        
        //GPIObits.GP4 = !GPIObits.GP4;
        //GPIObits.GP5 = !GPIObits.GP5;

        wait(5);           // wait for 5 sec       
        RELAY = 1;         // turn on relay after 5 sec
 
        
        while(flag == 0) {
            __delay_ms(10);
        }
        
        while(flag == 1) {
            __delay_ms(10);
        }       

    }

    
    return;
}

void wait(uint8_t w){
    
    for(uint8_t c = 0; c < w; c++) {
        __delay_ms(1000);
    }
}

I'm using internal OSC and I tried to calibrate OSC by using register OSCCAL but no luck. Please note that datasheet is attached.
 

Attachments

  • 12F629.pdf
    1.4 MB · Views: 173

First figure out whether your "weak pullup" is
(a) in fact the problem,
(b) a final-DC-high-level problem or
(c) a rise-too-slow, miss the schoolbus" loading problem.
(d) a "chatter" problem that musses up your algorithm
(e) still a mystery

(b)-(d) want a 'scope and some bench time. (a), (e)
you hope will fall out of that poking if they're it.
 

    sairfan1

    Points: 2
    Helpful Answer Positive Rating
Hi,

We don't have your schematic, thus we don't know how your buttons are connected.
So I guess it is connected between port and GND.
If so, then you need a pull up. It may be internal or external ... and because the PIC provides internal pull ups it makes sense to use them.
They are rather high ohmic, thus it is still prone to pick up noise. I recommend to connect a capacitor in parallel to the button.
"Noise" can be from external sources, but also coupled from other signals, like the port that switches the relay.

A button is no timing critical input, and button contacts are known for bouncing, thus I don't use interrupts at these ports. I rather poll them regularily (10ms) in an ISR and do simple software debouncing. (Usually it's sufficient to rely on two identical consecutive port readings).

Port interrupt react on any short glitch - even in the nanoseconds.
While with the simple polling method the glith need to be at exactly the poll point. Way less likely.

For a detailed discussion we need to know the resistor values, the PCB layout and the button/relay wiring.

Klaus
 
Last edited:

    sairfan1

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top