Time delay on with 2 second pulse output diagram

dannyf

Joined Sep 13, 2015
2,197
here is what I put together quickly, based on my understanding of your tasks.

Code:
//timer examples
//output asserted after a 30-second trigger, and stays on for 2 seconds;
//blocking
//http://forum.allaboutcircuits.com/threads/time-delay-on-with-2-second-pulse-output-diagram.126929/

//fuse settings
//configuration bits for 12f675 - internal oscillator (4Mhz)
#pragma config BOREN = OFF
#pragma config CPD = OFF
#pragma config FOSC = INTRCIO
#pragma config MCLRE = OFF
#pragma config WDTE = OFF
#pragma config CP = OFF
#pragma config PWRTE = OFF
//end fuse configuration

#include <xc.h>                        //we use xc8 compiler

//hardware configuration
#define TRG_PORT        GPIO
#define TRG_DDR         TRISIO
#define TRG             (1<<0)      //trigger input pin
#define TRG_DUR         30           //trigger duration, in TRG_PR
#define TRG_ON          5             //on duration, in TRG_PR
#define TRG_PR          10          //timer unit, in ms
#define TRG_ACTIVE()    IO_GET(TRG_PORT, TRG)   //input is on, active high

#define OUT_PORT        GPIO
#define OUT_DDR         TRISIO
#define OUT             (1<<1)      //output pin(s)
#define OUT_OFF()       IO_CLR(OUT_PORT, OUT)   //output is active high
#define OUT_ON()        IO_SET(OUT_PORT, OUT)

#define DLY_1ms            65        //delay for 1ms - compiler / mode specific
//end hardware configuration

//global defines
#define IO_SET(port, pins)   port |= (pins)
#define IO_CLR(port, pins)   port &=~(pins)
#define IO_FLP(port, pins)   port ^= (pins)
#define IO_GET(port, pins)   ((port) & (pins))
#define IO_OUT(port, pins)   IO_CLR(port, pins)
#define IO_IN(port, pins)    IO_SET(port, pins)
//#define NOP()                nop()

//global variables
int trg_cnt=0;

//initialize the timer
void tmr_init(void) {
    IO_IN(TRG_DDR, TRG);               //TRG as input
   
    OUT_OFF(); IO_OUT(OUT_DDR, OUT);    //turn off output, as output
   
    trg_cnt=0;                          //initialize trigger counter
}

//delay
void delay(unsigned int dly) {
    while (dly--) NOP();
}

//delay ms
void delay_ms(unsigned int ms) {
    while (ms--) delay(DLY_1ms);      //waste time
}

//reset the mcu
void mcu_init(void) {
    //initiation code
    //specific to 12f675
    CMCON = 0x07;                        //turn off analog comparator
    ANSEL = 0x00;                        //all pins gpio

}

void main(void) {
   
    mcu_init();
    tmr_init();
    while (1) {
        delay_ms(TRG_PR);               //waste some time
        //IO_FLP(OUT_PORT, OUT);            //flip output pin - for debugging
        //scan the trigger input
        if (TRG_ACTIVE()) trg_cnt+=1;   //increment trg_count if trg is active
        else trg_cnt=0;                 //otherwise, reset trg_counter
        //test to see if trigger has been asserted
       if (trg_cnt>=TRG_DUR) {         //trg remained on long-enough
            OUT_ON();                   //turn on the output
            trg_cnt = TRG_ON;            //reuse trg counter
            while (trg_cnt--) delay_ms(TRG_PR);  //keep the output on for enough time, and blocking the trigger input
            OUT_OFF();                  //turn off the ouptut
            trg_cnt = 0;                //reset trg counter
        }
    }
    return;
}
It runs on a 12f675.

Basic operations: the mcu waits for the trigger pin (TRG) to be asserted (in this case, steady active high after TRG_DUR * TRG_PR, or 300ms). After that, the output pin (OUT) goes high for TRG_ON * TRG_PR, or 50ms. and the cycle starts again.

Customization:
1) if you change compiler (XC8 1.12 for me) or mode, you will need to change DLY_1ms to achieve the right timing;
2) if you change chips, you will need to change the fuse settings as well initialization section of the code;
3) if you want different pin / port combination, you will need to change the TRG and OUT macros to point to the right port / pin. The code can drive multiple output pins as is;
4) if you need different timing, change TRG_PR, TRG_DUR and TRG_ON;
5) if you need different logic, change the code.
6) the code should compile relatively easily for 10f200 as well.
7) the way it is implemented, the code is naturally anti-debouncing.

Here is a quick simulation of it.

So it may not do exactly what you want but it should get you started.
12f675 timer.PNG
 

Thread Starter

RodneyB

Joined Apr 28, 2012
697
here is what I put together quickly, based on my understanding of your tasks.

Code:
//timer examples
//output asserted after a 30-second trigger, and stays on for 2 seconds;
//blocking
//http://forum.allaboutcircuits.com/threads/time-delay-on-with-2-second-pulse-output-diagram.126929/

//fuse settings
//configuration bits for 12f675 - internal oscillator (4Mhz)
#pragma config BOREN = OFF
#pragma config CPD = OFF
#pragma config FOSC = INTRCIO
#pragma config MCLRE = OFF
#pragma config WDTE = OFF
#pragma config CP = OFF
#pragma config PWRTE = OFF
//end fuse configuration

#include <xc.h>                        //we use xc8 compiler

//hardware configuration
#define TRG_PORT        GPIO
#define TRG_DDR         TRISIO
#define TRG             (1<<0)      //trigger input pin
#define TRG_DUR         30           //trigger duration, in TRG_PR
#define TRG_ON          5             //on duration, in TRG_PR
#define TRG_PR          10          //timer unit, in ms
#define TRG_ACTIVE()    IO_GET(TRG_PORT, TRG)   //input is on, active high

#define OUT_PORT        GPIO
#define OUT_DDR         TRISIO
#define OUT             (1<<1)      //output pin(s)
#define OUT_OFF()       IO_CLR(OUT_PORT, OUT)   //output is active high
#define OUT_ON()        IO_SET(OUT_PORT, OUT)

#define DLY_1ms            65        //delay for 1ms - compiler / mode specific
//end hardware configuration

//global defines
#define IO_SET(port, pins)   port |= (pins)
#define IO_CLR(port, pins)   port &=~(pins)
#define IO_FLP(port, pins)   port ^= (pins)
#define IO_GET(port, pins)   ((port) & (pins))
#define IO_OUT(port, pins)   IO_CLR(port, pins)
#define IO_IN(port, pins)    IO_SET(port, pins)
//#define NOP()                nop()

//global variables
int trg_cnt=0;

//initialize the timer
void tmr_init(void) {
    IO_IN(TRG_DDR, TRG);               //TRG as input
  
    OUT_OFF(); IO_OUT(OUT_DDR, OUT);    //turn off output, as output
  
    trg_cnt=0;                          //initialize trigger counter
}

//delay
void delay(unsigned int dly) {
    while (dly--) NOP();
}

//delay ms
void delay_ms(unsigned int ms) {
    while (ms--) delay(DLY_1ms);      //waste time
}

//reset the mcu
void mcu_init(void) {
    //initiation code
    //specific to 12f675
    CMCON = 0x07;                        //turn off analog comparator
    ANSEL = 0x00;                        //all pins gpio

}

void main(void) {
  
    mcu_init();
    tmr_init();
    while (1) {
        delay_ms(TRG_PR);               //waste some time
        //IO_FLP(OUT_PORT, OUT);            //flip output pin - for debugging
        //scan the trigger input
        if (TRG_ACTIVE()) trg_cnt+=1;   //increment trg_count if trg is active
        else trg_cnt=0;                 //otherwise, reset trg_counter
        //test to see if trigger has been asserted
       if (trg_cnt>=TRG_DUR) {         //trg remained on long-enough
            OUT_ON();                   //turn on the output
            trg_cnt = TRG_ON;            //reuse trg counter
            while (trg_cnt--) delay_ms(TRG_PR);  //keep the output on for enough time, and blocking the trigger input
            OUT_OFF();                  //turn off the ouptut
            trg_cnt = 0;                //reset trg counter
        }
    }
    return;
}
It runs on a 12f675.

Basic operations: the mcu waits for the trigger pin (TRG) to be asserted (in this case, steady active high after TRG_DUR * TRG_PR, or 300ms). After that, the output pin (OUT) goes high for TRG_ON * TRG_PR, or 50ms. and the cycle starts again.

Customization:
1) if you change compiler (XC8 1.12 for me) or mode, you will need to change DLY_1ms to achieve the right timing;
2) if you change chips, you will need to change the fuse settings as well initialization section of the code;
3) if you want different pin / port combination, you will need to change the TRG and OUT macros to point to the right port / pin. The code can drive multiple output pins as is;
4) if you need different timing, change TRG_PR, TRG_DUR and TRG_ON;
5) if you need different logic, change the code.
6) the code should compile relatively easily for 10f200 as well.
7) the way it is implemented, the code is naturally anti-debouncing.

Here is a quick simulation of it.

So it may not do exactly what you want but it should get you started.
View attachment 111223

Thank you very much. I am going to try this its all totally new. So immediately I will try and learn how to copy it into MPLAB and then into the PIC.

This is such a big help because whilst I understand nothing yet at least I have something in front of me that I can try and learn from.

Thank you
 

Thread Starter

RodneyB

Joined Apr 28, 2012
697
This is a little embarrassing

1. I cut and pasted the code into MPLAB IDE v 8.92 and realized I could do nothing with that.
2. I then went to the project wizard, selected Device PIC12F675; Create project file,Browse saved file as delay on timer.mcp;
3. Then it came to add existing file to your project, didn't know what to do there so just clicked next
4 Summary Project Parameters Device PIC12F675, Toolsuite Microchip XC8 Toolsuite

I then tried to build the project and it asked to include a file which i canceled, then got a message " Build Failed"

I am certain I am skipping a step, please can you direct me to somewhere to learn how to set this up
 

dannyf

Joined Sep 13, 2015
2,197
A project will have at least one source file. You didn't add the source file to your project.

Right click on source file and go from there. Or read the user guide.
 
Top