sairfan1
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.
I'm using internal OSC and I tried to calibrate OSC by using register OSCCAL but no luck. Please note that datasheet is attached.
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.