|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
Simple C problem - Pls take a look ! |
Posted: Sat Jan 24, 2009 1:21 pm |
|
|
Hello 2 all !
Using pic18f452 @ 10 MHz and CCS C compiler vesrion 4.057 , i'm trying to achieve the following behaviour :
- after 4 ms have passed, pin e1 is low for 1 ms, high for 1ms, still high for 1 ms, low for 1ms.
This behaviour should be repeated once every 4 ms.
Here is the code :
Code: |
#include <18f452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
//=======================================
char gc_SLAVE_timer;
char gc_ZERO_timer;
char gc_ONE_timer;
char count0,count1,i,flag0,flag1;
short start0, start1;
//=======================================
#define SLAVE_TIMER_TICKS 4 // 4 ms
#define ZERO_TIMER_TICKS 1 // 1 ms
#define ONE_TIMER_TICKS 1 // 1 ms
//=======================================
#define RTCC_PRELOAD 246
//=======================================
//#use fast_io(b)
//======================ISR INTRERUPERE TIMER0=================================
#int_rtcc
void rtcc_isr(void)
{
// Reload the RTCC, so it will keep overflowing every 10 ms.
set_rtcc(RTCC_PRELOAD);
// Decrement any timers that are running.
if(gc_SLAVE_timer)
gc_SLAVE_timer--;
if(gc_ZERO_timer)
gc_ZERO_timer--;
if(gc_ONE_timer)
gc_ONE_timer--;
}
//=============================PREZENTA SLAVE==================================
void check_SLAVE()
{
if(gc_SLAVE_timer)
{
return;
}
else
{
gc_SLAVE_timer = SLAVE_TIMER_TICKS;
start0=true;
start1=true;
count0=0;
count1=0;
}
}
//=============================================================================
void check_ZERO()
{
while (start0)
{
if(gc_ZERO_timer )
{
return;
}
else
{
gc_ZERO_timer = ZERO_TIMER_TICKS;
count0++;
if ((count0%2==1)&& (count0<3))
output_high(pin_e1);
else
output_low(pin_e1);
}
}
}
//==========================================
void check_ONE()
{
while (start1)
{
if(gc_ONE_timer )
{
return;
}
else
{
gc_ONE_timer = ONE_TIMER_TICKS;
count1++;
if ((count1%2==1)&& (count1<3))
output_low(pin_e1);
else
output_high(pin_e1);
}
}
}
//=============================================================================
void main()
{
gc_SLAVE_timer = SLAVE_TIMER_TICKS;
gc_ZERO_timer = ZERO_TIMER_TICKS;
gc_ONE_timer = ONE_TIMER_TICKS;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_BIT);
set_timer0(RTCC_PRELOAD);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
start0=false;
start1=false;
while(1)
{
check_SLAVE();
for(i=0; i<2; i++)
{
if (i%2==1)
check_ZERO();
else
check_ONE();
}
}
}
|
Thank you all ! |
|
|
Guest
|
|
Posted: Sat Jan 24, 2009 1:22 pm |
|
|
P.S. : It isn't working at all !! |
|
|
tranz
Joined: 10 Feb 2007 Posts: 78
|
|
Posted: Sat Jan 24, 2009 1:32 pm |
|
|
You just want a continious loop for this? why are you not using
delay_ms(1000); //delay for 1 ms.
and
output_high( PIN_E1);// high PIN_E1
commands to do the job? It is far less complicated that way. |
|
|
Guest
|
|
Posted: Sun Jan 25, 2009 12:37 am |
|
|
Hello !
This is a state machine. Every 4 ms i have to do this action. For the rest of the time, i've got do to other things ?
Is there a way to do this ?
Thank you for your interest !! |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Sun Jan 25, 2009 3:29 am |
|
|
If your output is low for 1ms, high for 1ms, high for 1ms, low for 1ms, and that cycle repeats, then that's just a repeating cycle of low for 2ms, high for 2ms!
If you have timer 2 free, that is easy to do using the PWM module.
Lookup the CCS help for setup_ccp1() and set_pwm1_duty().
Once you set it up it just runs by itself and your code can do whatever other processing you need. You can reconfigure the settings at any time, to turn it off, tweak the duty cycle, period, etc. _________________ Andrew |
|
|
SimpleAsPossible
Joined: 19 Jun 2004 Posts: 21
|
"It's a state machine" |
Posted: Mon Jan 26, 2009 7:27 pm |
|
|
You said it: it's a state machine. Here's a rough summary of what I'd do in your timer ISR. Set your timer to overflow every 1 ms.
Code: |
static int state = 0; // only in ISR, init to zero
state++;
state %= 4; // easy since the total number of states is a power of two
switch (state)
{
default: // catch any errors and force valid
state = 0;
/*fallthru*/
case 0:
state = 1;
output_high(PIN_E1);
break;
case 1:
state = 2;
output_high(PIN_E1);
break;
case 2:
state = 3;
output_low(PIN_E1);
break;
case 3:
state = 0;
output_low(PIN_E1);
break;
}
|
|
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Tue Jan 27, 2009 2:13 pm |
|
|
Everything should be as simple as possible, but no simpler, eh?
I agree with the state machine approach, but you've incremented the state twice, once before the switch{} statement and again in each of the cases. |
|
|
|
|
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
|