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

How to make precisely pulses

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



Joined: 29 Sep 2010
Posts: 73
Location: Brazil

View user's profile Send private message MSN Messenger

How to make precisely pulses
PostPosted: Mon Dec 09, 2013 5:12 pm     Reply with quote

Hello, I am trying to make just some pulses with a 16F877A.

For now I am using a 4Mhz crystal.

Is it possible to make pulses like this?

Code:
ON        OFF
2ms      398ms
1ms      149ms
1ms      59ms
1ms      39ms
16us     29.8ms


I can use a higher crystal if necessary.

I will use some buttons to choose my ON and OFF time. But I am trying with timer0 and the time I am getting is wrong.

I think that if I have a resolution of 4 or 4us, I can cover all my pulses possibilities.

bye

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Dec 09, 2013 5:53 pm     Reply with quote

What is the purpose of the project ? What are the pulses used for ?

Are these individual pulses, with several seconds between each pulse ?
In other words, press one button and get a pulse. Wait a few seconds,
press another button and make a different pulse (but only one instance of
the pulse) ?

Or, do the pulses occur continuously ?

If so, are the pulses constantly the same type, until a button is pushed,
and then the pulse is changed to a different type ?

Please explain what you want.
matheuslps



Joined: 29 Sep 2010
Posts: 73
Location: Brazil

View user's profile Send private message MSN Messenger

PostPosted: Mon Dec 09, 2013 7:10 pm     Reply with quote

The project is to test diesel engines.

The pulses will be continuously. I will use some buttons and a LCD to set up the ON and OFF times.

I tried with:

Code:
setup_counters(RTCC_INTERNAL, RTCC_DIV_1);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   set_timer0(255);


I thought that I could get 1us resolution with the code above.

bye
Ttelmah



Joined: 11 Mar 2010
Posts: 19360

View user's profile Send private message

PostPosted: Tue Dec 10, 2013 2:00 am     Reply with quote

Not easily.

When you think that it takes about three instruction cycles just to turn a line on or off, and at 4Mhz, the cycle is 1uSec, there is no time left to so anything else at all.
Using an interrupt, it takes typically about 30 instructions to get into an interrupt handler.

So, lets assume much higher speed.

30 instructions to get into the interrupt handler, and then perhaps another handful to do anything. To give 4uSec as minimum pulse width, you'd need to be clocking at perhaps 40Mhz. The 877A does not go that fast. So you'd need to switch to something like a PIC18F.

Then the approach needs to change as well. It is the sheer 'range' that is difficult. A few uSec pulse is easily produced with accurate timings using the CCP or PWM. Doing it in software, the times needed to load things, and respond to events happening, will make the short times not work. Problem then is the the PWM, only allows the total pulse interval to be 1024* the minimum pulse resolution (unless one looks at chips with more sophisticated PWM's), so this is ruled out. Leaves CCP. This allows pulse interval to be up to 65536* the minimum resolution, so potentially with 4uSec, a maximum of 262mSec total interval. So again won't cover it....

Now it is difficult without knowing a lot more about the actual timings. What is the shortest 'interval' that could occur with a small pulse like 4 to 16uSec?. What is the shortest pulse that could be needed with a long interval like 398mSec?. What is the absolute longest interval?.
It is possible that it might be possible to cover the large range using two solutions. So the CCP to give the narrow pulses, and then switching to a timer based solution for the longer intervals, but you need to specify the problem in much more detail.
I must admit I find it hard to think of any 'good reason' to need both variation in period, and pulse width over such an enormous range.

Best Wishes
temtronic



Joined: 01 Jul 2010
Posts: 9170
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Dec 10, 2013 6:33 am     Reply with quote

comment.
I'm looking at this a bit differently. My view is that you're going to enter the on and off times then press a 'go' button to start the pulses. After a certain time, either automatically or manually stop the program.
If so, then use the delay_us() or delay_ms() functions. They are quite precise and easy to use. You can use an ISR to capture the keypresses like 'go' and 'stop'.
It would be a very good start to your overall project, easy to code and be 'up and running' in a day.

hth
jay
matheuslps



Joined: 29 Sep 2010
Posts: 73
Location: Brazil

View user's profile Send private message MSN Messenger

PostPosted: Tue Dec 10, 2013 11:46 am     Reply with quote

@temtronic

I thought about the ms and us functions, but the uC will be frozen all the time during this tasks.

@Ttelmah

For now, this is just a prototype to test fuel nozzle.

So, in this moment I am thinking pulses like:

02ms - 398ms >>> ON 1 to 3ms and OFF 396 to 400ms
01ms - 149ms >>> ON 1 to 3ms and OFF 147 to 151ms
01ms - 59ms >>> ON 1 to 3ms and OFF 57 to 61ms
01ms - 39ms>>>ON 1 to 3ms and OFF 37 to 41ms
16us - 29ms >>> ON 16us to 1ms and OFF 24 to 34ms

Longest time (ON+OFF ) 400ms (2.5HZ)

I am thinking about Ttelmah's idea and came with this:

Use the CCP module with PWM enabled to generate small pulses. For example configure Timer2 to generate a 125Khz square wave (On version 5 of the compiler, it does it for me :D). So I will get 4uS pulses. OK. Problem 1 solved.

When the CCP go from high to low, call an interrupt to generate the big OFF time. Inside the interrupt, I will disable the PWM and start counting.... when my OFF time ends, start the PWM again.. loop forever

What do you guys thing about this idea?

So, what is the best way to make my CCP pin call a timer interrupt?

bye
temtronic



Joined: 01 Jul 2010
Posts: 9170
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Dec 10, 2013 3:17 pm     Reply with quote

ok...from a 'design' viewpoint.

Need to know what else is the PIC supposed to do while pulsing the injectors?

Most 'test' setups I've used go for xx amount of time. It'd be simple to code a PIC with preset 'routines' using delay_us(). Press a button and it loops 'forever'. Another PIC could actually capture test data if required.
PICs are very cheap these days and frankly the 877A I think is now 'obsolete' or at least on the 'endangered species' list. Yes,I have a tube full of them but use the 18F46K22 for 99% of all new projects.

Also be sure to properly snub the injector drivers otherwise EMI can come back and kill the PIC!

cheers
jay
matheuslps



Joined: 29 Sep 2010
Posts: 73
Location: Brazil

View user's profile Send private message MSN Messenger

PostPosted: Wed Dec 11, 2013 6:25 am     Reply with quote

temtronic wrote:
ok...from a 'design' viewpoint.

Need to know what else is the PIC supposed to do while pulsing the injectors?


For now, nothing. To tell the true. I am already using the uS and mS function for initial tests. But I want to make it more robust.

temtronic wrote:
PICs are very cheap these days and frankly the 877A I think is now 'obsolete' or at least on the 'endangered species' list. Yes,I have a tube full of them but use the 18F46K22 for 99% of all new projects.


Agree!!! I personally only use 18F and up because it has a lot of features. But I help a lot of people on my country with cheaper chips. There is a lot of beginners and they always start with 16F family.

temtronic wrote:
Also be sure to properly snub the injector drivers otherwise EMI can come back and kill the PIC!


Already done.


I reviewed my calculations and realized that with a 125kz and 20Mhz crystal, I am getting just 7 ~ 8 bits of resolution.

So, another approach. Lets go to the opposite limit.

I I use a crystal of 4Mhz, I can calculate the frequency like this:

Code:
               Crystal Frequency
PWM Freq = -----------------------------------------
              (PR2 + 1) * (Timer2 Prescaler) * 4


Timer2 like:

Code:

                      4000000
PWM Freq  = -----------------------------------------
                  (255+ 1) * (16) * 4


Frequency output of 244,140625 Hz! Hn? Hum... lets continue....

Resolution:

Resol = LOG(Fosc/PWM_freq) / LOG(2)

Resol = LOG(4000000 / 244,140625) / 0,30103

Resol ~ 14 bits. This chips has a limit on 10bits.

If my frequency is 244,140625, my period is 1/244,140625 = 0,004096 seconds or 4.096 ms.

With 10 bits resolution:

4.096ms / 1024 = 4uS!!!!!!!!

Increments of 4uS of my duty cycle. With this I can go from my ON´s limits (16uS and 3mS).

Correct?

bye
matheuslps



Joined: 29 Sep 2010
Posts: 73
Location: Brazil

View user's profile Send private message MSN Messenger

PostPosted: Wed Dec 11, 2013 3:21 pm     Reply with quote

Well, after some testing, I came with this:

The commented lines is because some people do not have the CCS version 5. I think the commented lines will not work with older version, so I make the old fashion way.

I can now produce a 16uS ON time and a 30 ~ 32mS OFF time. Good, hun?

I do not have a oscilloscope right now. I am measuring with PICkit 3. Ow trying at least.

Code:
#include <16F877A.h>

#Fuses XT
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PUT                      //Power Up Timer
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(crystal=4MHz)

//#USE PWM(OUTPUT=PIN_C2, FREQUENCY=244, DUTY=75, STREAM=PWM1)

int16 cont;

#INT_TIMER1
void  TIMER1_isr(void)
{
   cont++;
   
   if (cont == 30)
   {
      cont = 0;
      setup_ccp1(CCP_PWM);
      disable_interrupts(INT_TIMER1);
   }
   set_timer1(65411);   
}

#INT_CCP2
void  CCP2_isr(void)
{
   //pwm_off();
   setup_ccp1(CCP_OFF);
   enable_interrupts(INT_TIMER1);
}

void main()
{
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);      //524 ms overflow
   setup_timer_2(T2_DIV_BY_16,255,1);           //4,0 ms overflow, 4,0 ms interrupt
   
   set_timer1(65411);

   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_CAPTURE_FE);
   set_pwm1_duty(4L);

   disable_interrupts(INT_TIMER1);
   enable_interrupts(INT_CCP2);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      //TODO: User Code
   }

}


bye
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Dec 11, 2013 8:50 pm     Reply with quote

If this was my task, i'd buy a crystal source with .5 or 1 usec clock period,
either with a single 82c54 OR
some 74HC/HCT4059 and hc573 addressable latch ics,
plus a tiny dab bit of discrete gate logic-
and control the parts with a 28 or 40 pin pic in simple digital port output mode.

That way the task can be set in some latches, and gated/triggered/repeated with the pic barely involved in the pulse
generation, and with superbly low timing jitter and perfect repeatbility.
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