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.

PIC10F206: my 30 sec delay doesn't function well

Status
Not open for further replies.

R&DElec

Newbie level 5
Newbie level 5
Joined
Aug 1, 2023
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
79
Hello, I'm trying to program PIC10F206 to :
when IN is High :1) the out is high 2) 30 sec delay or timer starts
while in the time (or delay) : when IN goes high again I want it to reset the time
when IN low: Out low
my problem is when in is high and timer starts no matter how many times In goes high again it still waits for 30 Second to be over instead of restarting my timer.
I am using MPLab v6.05 and C8 compile and Pickit3
I'm not sure why it doesn't like the way that I'm asking it to reset the timer

#pragma config WDTE = OFF // Watchdog Timer (WDT disabled)
#pragma config CP = OFF // Code Protect (Code protection off)
#pragma config MCLRE = OFF // Master Clear Enable (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)

#include <xc.h>
#define _XTAL_FREQ 4000000
#define IN GP0
#define OUT GP1

void main(void) {
// Set IN as input and OUT as output
TRISGPIO = 0b01;
CMCON0 = 0b1000001;

while(1) {
// Check if IN is high
if(IN) {
// Set OUT high
OUT = 1;

// Start 30-second timer
int i = 0;
while(i < 30) { // 30 * 1 second = 30 seconds
__delay_ms(1000); // 1 second delay
if(IN) {
// If IN goes high again, restart the timer
i = 0;
} else {
i++;
}
}
} else {
// Set OUT low
OUT = 0;
}
}
}
 

Hi,

Please use code tags when posting code in the forum.

Use TABs in your source code.

please mind the expressions:
* "when IN is High" is a level oriented condition: if (IN)
* "when IN goes high" is a edge oriented condition: if(IN & !IN_last)
* "when IN goes high again" is a repeated edge. But it´s not clear from what condition it repeats. It´s not clear whether the first (level oriented) is included in the "again" or not.

so your code says:
If it detects the level of IN= 1, then it
{sets OUT = 1
starts a timer
restarts the timer on IN = 1 level
}

so basically
it times out when IN = 0 continously for 30 seconds.

Klaus
 

Thank you now its working:
Code:
#include <xc.h>
#define _XTAL_FREQ 4000000
#define IN GP0
#define OUT GP1

void main(void) {
    // Set IN as input and OUT as output
    TRISGPIO = 0b01;
    CMCON0 = 0b1000001;
  
    while(1) {
        // Check if IN is high
        if(IN) {
            // Set OUT high
            OUT = 1;
        
            // Start 30-second timer
            int i = 0;
            while(i < 30) {  // 30 * 1 second = 30 seconds
                for(int j = 0; j < 1000; j++) { // Check IN 1000 times in 1 second
                    if(IN) {
                        i = 0; // If IN goes high, restart the timer
                        break; // Exit the inner loop
                    }
                    __delay_ms(1); // 1 millisecond delay
                }
                if(!IN) {
                    i++; // Increment the counter only if IN is low for the entire second
                }
            }
        } else {
            // Set OUT low
            OUT = 0;
        }
    }
}
 
Last edited by a moderator:

Generally if you want a timer that can be "topped up" to make it run longer it is better to use a 'while' loop than an 'if' loop.

while(i != 0)
{
do something
i--;
}

that way you can change 'i' to make the delay as long as you want and change 'i' on the fly if you need to change the delay time. Unfortunately, delay loops are what we call 'blocking' routines because they stop everything else until they finish. This is one of the advantages of MCUs with interrupt capability (PIC10 series does not have interrupts) because you can make the delay work in the background while continuing to do other things.

You can also use TMR0 to create accurate delays but without interrupts you have to check its value by reading it in your loop.

Remember ints are usually 16 bits wide so they can hold values +/- 32767. If you use an 'unsigned int' it can hold zero to 65535.

Brian.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top