CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Please Help me to create delay's by timers

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
vismay



Joined: 13 Dec 2009
Posts: 3

View user's profile Send private message

Please Help me to create delay's by timers
PostPosted: Sun Dec 13, 2009 10:04 am     Reply with quote

Hello sir, I am new to CCS , This is my first time in Embbeded C.

I've been reading forums for the past two years. And I've learned a lot of information about programming. I take this opportunity to convey my heartiest wishes to Mr. PCM Programmer & Mr.Ttelmah for their great contribution.Mr.Ttelmah always used a proverb " walk before trying to run". I belive that I'm trying to walk.Definitely you could find foolish ideas in my code. Still I'm learning C.With all of your support I can grow.

I created a new project for Automatic Mains Failure Panel and this is my first code.I'm using some existing code from the posts, and compiled it.
I'm using delay_ms() in many areas, which affects total operation.Still I've to add Low Fuel, Low oil pressure, Temperature protections to this unit.

Functions of my project

If the Mains failure ,Genset should start automatically by Three attempts to Self Motor. If the 1,2,3 attempt success,Generated power must connected to load by Contactor. If the 3rd attempts fails a warning alarm must activated and go to stop mode. If we press Reset Switch then again start to run the Generator. If the Mains resume, the change over must triggered after 30seconds from Generator to Mains and a stop solenoid must activated to stop the generator.

Please kindly help me to create delay's by using Timers. I read few posts about Timer and still I'm facing difficulty. For Mains sensing delay 20 seconds ok. But I can't add to other functions.

Friends as I am a beginner, I need your help.

I Will be very grateful to you. Thanks

My Compiler Version is 4.013. I'm using PIC KIT 2 and Proteus

Code:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

#define INTS_PER_SECOND 76     // (20000000/(4*256*256))
#define START_RLY PIN_C0      //  GENSET START RELAY
#define ALARM_RLY PIN_C1
#define FUEL_RLY PIN_C2
#define STOP_RLY PIN_C3
#define MAINS_CB_RLY PIN_C4
#define DG_CB_RLY PIN_C5
#define CRANK_RLY PIN_C6
#define DG_SENSE PIN_B3
#define MODE_SW PIN_B6

#include <flex_lcd.c>

int8 acin,genin;   
int8 start;
int8 stop;
int8 aa;
int8 seconds;
int8 int_count;   
int1 ext_int_flag = false;

#int_ext
void PB0_isr (void)
{
  ext_int_flag = true;
}

#INT_RB
void portchange_isr ()
{
  start = input(PIN_B4);
  stop = input(PIN_B5);
 }

#int_rtcc
void clock_isr()
{                 
                                 
 if(--int_count==0)           
    {
     ++seconds;
     int_count=INTS_PER_SECOND;
    }
}

void pinread()
{
    genin=input(PIN_B1);  // Genset sense
    acin=input(PIN_B2);   // Mains sense
}

void acon()
{
   output_low(DG_CB_RLY);
   clear_interrupt(INT_RTCC);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   lcd_gotoxy(1,1);
   lcd_putc("     EB ON      ");

   if(seconds == 20)                  // <==== Delay Function OK here.
        {
            output_high(MAINS_CB_RLY); // Mains Circuit Breaker On
            seconds = 0;
         }

}


void manual()
{
   EXT_INT_EDGE(H_TO_L);
   enable_interrupts(INT_RB);
   enable_interrupts(GLOBAL);

   output_low(MAINS_CB_RLY);

   lcd_gotoxy(1,1);
   lcd_putc("  MANUAL MODE   ");

if(!start)
    {
      ext_int_flag = TRUE;

      lcd_gotoxy(1,1);
      lcd_putc("\f  MANUAL START  ");
      output_high(CRANK_RLY);
      delay_ms(5000);          // <====  Please help here
      output_low(CRANK_RLY);

     }

pinread();

 if(!genin)

   {
      output_high(DG_CB_RLY);
   }

 else if(genin)
   {
      output_low(DG_CB_RLY);
    }


 if(!stop)
   {
      ext_int_flag = TRUE;
      lcd_gotoxy(1,1);
      lcd_putc("  MANUAL STOP   ");
      output_high(STOP_RLY);
      delay_ms(10000);          //  <====  Please help here
      output_low(STOP_RLY);

 pinread();

  if(genin)
      {
         output_low(DG_CB_RLY);
      }
   }

}


 void crank()

 {
    output_low(MAINS_CB_RLY);
    output_low(DG_CB_RLY);
    aa=0;
    pinread();
    delay_ms(100);

  if(genin)

    {
      lcd_gotoxy(1,1);
      lcd_putc("\fCRANK 1ST ATM  "); // 1st try Generator Crank Motor
      output_high(crank_rly);
      delay_ms(5000);         //    <====  Please help here. How do i put delay without using this?
      output_low(crank_rly);
     }

  delay_ms(1000);

  pinread();

  if(genin)

    {
      aa++;
      lcd_gotoxy(1,1);
      lcd_putc("\f CRANK 2ND ATM  ");
      output_high(crank_rly);
      delay_ms(5000);            // <====  Please help here
      output_low(crank_rly);

     }

 delay_ms(1000);

  pinread();

  if(genin)

    {
       aa++;
       lcd_gotoxy(1,2);
       lcd_putc("\f CRANK 3RD ATM   ");
       output_high(crank_rly);
       delay_ms(5000);            // <====  Please help here
       output_low(crank_rly);
     }

  delay_ms(1000);

  pinread();

  if(genin)

     {
       aa++;

       delay_ms(250);

       if(aa>=3)

           {
             lcd_gotoxy(1,1);
             lcd_putc("\f CRANK FAILURE  ");
             output_high(ALARM_RLY);
             delay_ms(2000);              // <====  Please help here
             output_low(ALARM_RLY);
             delay_ms(2000);              // <====  Please help here
             output_high(ALARM_RLY);
             delay_ms(2000);              // <====  Please help here
             output_low(ALARM_RLY);
             output_high(ALARM_RLY);
             delay_ms(2000);              // <====  Please help here
             output_low(ALARM_RLY);
             sleep();
           }

        }

   }


void genon()

  {
    crank();
    output_low(MAINS_CB_RLY);
    output_high(DG_CB_RLY);
    lcd_gotoxy(1,1);
    lcd_putc("   GENSET ON    ");

  }

void autom()

 {
   pinread();

   if(!acin && genin ) // EB On ,Gen off.

     {
       acon();
     }

  if (!acin && !genin) //EB On ,Gen On

     {
       acon();
     }

  if (acin && genin)   // EB off , Gen Off
     {
       genon();
     }

  }


void main()

  {
    int_count=INTS_PER_SECOND;
    set_timer0(0);
    setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
    ext_int_edge(H_TO_L);
    enable_interrupts(INT_RTCC);
    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);

    port_b_pullups(TRUE);
    set_tris_a(0x00);
    set_tris_c(0xFF);


    lcd_init();
    delay_ms(50);
    lcd_gotoxy(1,1);
    lcd_putc(" AMF CONTROLLER ");
    delay_ms(1000);

    seconds = 0;

while(TRUE)

 {

   if (input(mode_sw))

    {
       autom();  // Automatic mode
    }

   if (!input(mode_sw))
     {
       manual();  // Manual Mode
     }
  }

}



Sorry for my poor english. Best wishes to all of the members
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Sun Dec 13, 2009 11:04 am     Reply with quote

You could add additional variable to your RTCC ISR. So you would have so called delay variable. Then you can write a custom delay function that will count the seconds.

Snippets of code:
Code:
#int_rtcc
void clock_isr()
{                 
                                 
 if(--int_count==0)           
    {
     ++seconds;
     ++delay_seconds;
     int_count=INTS_PER_SECOND;
    }
}


delay_seconds is global variable.



Code:


void custom_delay(int delay)
{
     delay_seconds=0;
     while (delay!=delay_seconds)
     {
      delay_cycles(1);    // <---- this is equal to NOP in assembler
      }
}


Now you just put this to your code. I hope that I understand your question. I still don't know why you need to replace the compiler delay function.
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

View user's profile Send private message Visit poster's website

PostPosted: Sun Dec 13, 2009 9:15 pm     Reply with quote

As with bungee, I can't seem to figure out why you would like to replace the built-in compiler delay functions.
vismay wrote:
create delay's by using Timers
Would you also like to multitask? It doesn't appear so in your code. But usually when someone wants to use a timer to create delays it means he wants to include multitasking ability (more correctly - 'time sharing' ability); sort of like a stripped down Real Time Operating System. In such a situation they are not so much 'delays' as they are a 'heartbeat', or a 'tick'.

If all you want to achieve is turning on and off a genset (and checking temperature, oil, etc), you need not use an RTOS. The longest delay you have used creates a 10 second wait. Do you need to perform other tasks during this period? Or can you wait until after the delay has finished? This is the question you must ask yourself before using a time-sharing scheme.

Rohit
vismay



Joined: 13 Dec 2009
Posts: 3

View user's profile Send private message

PostPosted: Sun Dec 13, 2009 10:51 pm     Reply with quote

Thanks Mr. Bungee for your quick response.

I will follow your advice. There will be multitask functions running in my hardware. We have to monitor Diesel Generator Belt cut, Oil pressure, Temperature, Mains sensing, Fuel level. For an example, if the belt cut was detected during the delay_ms() functions, how do I get out of the delay and perform the other task? Please kindly guide me.

Thanks Mr. Rohit de Sa, for your detailed explanation. As you said, I want to perform other tasks during that period. That's why I need an alternative. You are right. And I don't know much about RTOS. As a beginner I don't know how to do time sharing.

And my longest delay will be 30 seconds (when Mains resumes and hold for 30 seconds the change over function will be happened, if it is not the load will be connected to generator only).

Sorry, I am new to C. Don't know how to manage this. Is it possible? If it is not please give me your suggestion.

Thank you very much Mr. Bungee, Mr.Rohit de Sa for spending your precious time for my problem. Thanks for your good support.

My best wishes to all.
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun Dec 13, 2009 11:25 pm     Reply with quote

Take a look at this thread for some ideas that will do what you want...

http://www.ccsinfo.com/forum/viewtopic.php?t=40866

I rarely use delay routines (i.e. delay_us() or delay_ms()) in my code. My delays are all based off the real time interrupt timer and I use direct H/W interrupts where immediate response is required so I spend 98% of the time looping in Main.
_________________
Google and Forum Search are some of your best tools!!!!
vismay



Joined: 13 Dec 2009
Posts: 3

View user's profile Send private message

PostPosted: Sun Dec 13, 2009 11:56 pm     Reply with quote

Thanks Mr.dyeatman for pointing me in the right direction.

Quote:
I rarely use delay routines (i.e. delay_us() or delay_ms()) in my code. My delays are all based off the real time interrupt timer and I use direct H/W interrupts where immediate response is required so I spend 98% of the time looping in Main.


This is what I want to do. Thanks for your great help. I will try to alter my code and I will post flow chart and modified code very shortly.

Thank you very much Mr. dyeatman for spending your precious time for my problem. Thanks for your good support.
Best wishes.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group