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 support@ccsinfo.com

Led flickering and functions ...

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







Led flickering and functions ...
PostPosted: Wed Aug 24, 2005 7:47 am     Reply with quote

Hello,

i am using a pic 18F458 with ccs 3.206.

What i wanted to do is to switch on and off a led to make it flicker that shows that a device is switched on.
But the device should wait for data and execute a command.

So i tried to do that with an interrupt but it is not working ...

Code:
#define HIGH_START 114
byte seconds, high_count;
#INT_RTCC
clock_isr() {
   if(--high_count==0) {
      output_high(PIN_B0);
      delay_us(5);
      output_low(PIN_B0);
      high_count=HIGH_START;
   }
}

main() {
   high_count=HIGH_START;
   set_rtcc(0);
   setup_counters(RTCC_INTERNAL, RTCC_DIV_64);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   
while(TRUE)
{
// do something;
}
}


where should i put this
Code:
high_count=HIGH_START;

to make an overflow ? Everywhere that i have a new while ? Because i have lots of while in my while :p

Any ideas ?

Thanks
sseidman



Joined: 14 Mar 2005
Posts: 159

View user's profile Send private message

PostPosted: Wed Aug 24, 2005 8:15 am     Reply with quote

Five microseconds is MUCH TOO SHORT to be able to see an LED flicker on. Try 100 milliseconds.

It's not a great idea to be hanging out in an interrupt routine for 100 ms, depending on what else you want your program to do. If you have a second timer available, its much better to use one timer, like you're doing, to set the frequency of the LED. That interrupt should turn the bit on, and start a second timer that controls the duration of the LED on time. When that interrupt triggers, turn the LED bit off, and stop the duration timer.

Scott
sseidman



Joined: 14 Mar 2005
Posts: 159

View user's profile Send private message

PostPosted: Wed Aug 24, 2005 8:27 am     Reply with quote

Aah--

I see what you're trying to do now. It doesn't make any sense the way you're looping. Pin B0 is going to go high for 5microseconds, and then low for a few instruction cycles, and then high again.

Also, somewhere in main, make sure you define pin B0 as an output.

Place HIGH_START into your counter
set_timer0(HIGH_START);


So:
Code:
#INT_RTCC
clock_isr() {
output_high(PIN_B0);
delay_ms(50);
output_low(PIN_B0);
set_timer0(HIGH_START);  //there are more accurate ways to do this
}



It's hard to know if the timing is right without knowing your clock frequency. You probably want to blink the LED for 50-100ms every 2 seconds or so.


But consider using one interrupt for frequency, and one for duration, as discussed before.
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Wed Aug 24, 2005 8:52 am     Reply with quote

Code:


#define HIGH_START 114
byte high_count;

#INT_RTCC
clock_isr() {
   high_count--;
   if(!high_count)
     {
      output_toggle(PIN_B0);
      high_count=HIGH_START;
     }
}

main() {
   high_count=HIGH_START;
   set_rtcc(0);
   setup_counters(RTCC_INTERNAL, RTCC_DIV_64);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   
 while(TRUE)
 {
  // do something;
 }
}


Humberto
Wouhou
Guest







PostPosted: Thu Aug 25, 2005 1:45 am     Reply with quote

Thanks for your responses :

could you tell me how to do this ? Using 2 interrupts please ?

I don't really sure to understand.

Humberto your programm is not working i don't know why ...
Wouhou
Guest







PostPosted: Thu Aug 25, 2005 3:06 am     Reply with quote

If i try to it this way in the interrupt :

Code:
counter =0;

#INT_RTCC
clock_isr() {
if(system_on)
      {
      if(counter == 0) {output_high(LED);}
      if(counter == 10) {output_low(LED); counter = 0;}
      counter++;
      }
}

It is better to not use a delay, so i tried this way but it is not accurate, could you tell me why ?
Wouhou
Guest







PostPosted: Thu Aug 25, 2005 3:07 am     Reply with quote

Maybe it is better if you could tell me how to use 2 interrupts i think it will be the better way to do it !

HELP !
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Aug 25, 2005 5:08 am     Reply with quote

Wouhou wrote:
If i try to it this way in the interrupt :

Code:
counter =0;

#INT_RTCC
clock_isr() {
if(system_on)
      {
      if(counter == 0) {output_high(LED);}
      if(counter == 10) {output_low(LED); counter = 0;}
      counter++;
      }
}

It is better to not use a delay, so i tried this way but it is not accurate, could you tell me why ?
What do you mean with 'not accurate'?
It will only work for the first cycle and then fail. When counter reaches 10 you reset counter to 0 but then immediately add 1, so the next times you enter the interrupt the test for 0 will always fail.
Wouhou
Guest







PostPosted: Thu Aug 25, 2005 5:42 am     Reply with quote

Ok ! Thanks for that !

I fixed it out but the led is switched on and off too long.

I tried this :

Code:
     
counter++;
if(counter == 1) {output_high(LED);}
if(counter == 2) {output_low(LED); counter = 0;}


Do ou know how i could do this but to have something like this for 50-100ms every 2 seconds or so ?

i putted counter as an int. How can i do ?

Many thanks.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Aug 25, 2005 6:51 am     Reply with quote

Given the clock frequency of your CPU you can calculate the timing for the timer0 interrupt:
Code:
interrupts per second = Clock freq. / (4 x prescaler x counter max.)


with
Code:
setup_counters(RTCC_INTERNAL, RTCC_DIV_64);
the timer is setup with a prescaler that divides by 64 and the interrupt fires when the counter overflows (at 256 for an 8 bit counter).

You didn't tell us your clock frequency, but let's assume it is 4MHz, then you get the following calculation:
Code:
interrupts per second = 4MHz / (4 x 64 x 256) = 61 times per second



Change your code then to
Code:
#define TWO_SECONDS (2 * 61)
#define MSEC_100   (6)

counter++;
if (counter == TWO_SECONDS) {output_high(LED);}
if (counter == (TWO_SECONDS + MSEC_100) {output_low(LED); counter = 0;}
Wouhou
Guest







PostPosted: Thu Aug 25, 2005 8:11 am     Reply with quote

Ok many thanks !
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Aug 25, 2005 12:07 pm     Reply with quote

Wouhou wrote:
Quote:

Humberto your programm is not working i don't know why ...


For your info the code I posted is right and tested.
The code is pretty simple. I used 16F628 and 8Mhz crystal and I get in the scope a
clear and symetrical toggling in PINB0 every 930ms.

Check your hardware, tools and test procedure. Evil or Very Mad

Humberto
Bart



Joined: 12 Jul 2005
Posts: 49

View user's profile Send private message

PostPosted: Thu Aug 25, 2005 2:38 pm     Reply with quote

Hello Humberto or Wouhou,

Can you explain me how you come to, our how you calculated, the 114 value ? (Can you eventualy use 20 Mhz as clockspeed as example calculation ?)
Thanks.

Code:

#define HIGH_START 114

_________________
I like Skype (www.skype.com), my username is BplotM
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Aug 25, 2005 3:33 pm     Reply with quote

Quote:

Can you explain me how you come to, our how you calculated, the 114 value ?


It doesn´t have any special meaning, it is a constant value assigned in compilation time
to the preprocessor identifier HIGH_START using the preprocessor directive #define

In the posted code it is used to reload a decremented counter when it reach zero.

In the statement
if(--high_count==0)
high_count
is decremented and tested if it is = 0.

If high_count==0 it is loaded with the value 114, wich is replaced
using the identifier HIGH_START to repeat the cycle.

high_count=HIGH_START;

Quote:

Can you eventualy use 20 Mhz as clockspeed as example calculation ?)


Yes of course. (assuming you are talking about ckielstra example calculation)

Read this excelent thread posted by newguy:
http://www.ccsinfo.com/forum/viewtopic.php?t=22467

Humberto
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