|
|
View previous topic :: View next topic |
Author |
Message |
vismay
Joined: 13 Dec 2009 Posts: 3
|
Please Help me to create delay's by timers |
Posted: Sun Dec 13, 2009 10:04 am |
|
|
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
|
|
Posted: Sun Dec 13, 2009 11:04 am |
|
|
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
|
|
Posted: Sun Dec 13, 2009 9:15 pm |
|
|
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
|
|
Posted: Sun Dec 13, 2009 10:51 pm |
|
|
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: 1934 Location: Norman, OK
|
|
Posted: Sun Dec 13, 2009 11:25 pm |
|
|
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
|
|
Posted: Sun Dec 13, 2009 11:56 pm |
|
|
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. |
|
|
|
|
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
|