![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
How to make precisely pulses |
Posted: Mon Dec 09, 2013 5:12 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 09, 2013 5:53 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
|
Posted: Mon Dec 09, 2013 7:10 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19360
|
|
Posted: Tue Dec 10, 2013 2:00 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Tue Dec 10, 2013 6:33 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
|
Posted: Tue Dec 10, 2013 11:46 am |
|
|
@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 |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Tue Dec 10, 2013 3:17 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
|
Posted: Wed Dec 11, 2013 6:25 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
|
Posted: Wed Dec 11, 2013 3:21 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed Dec 11, 2013 8:50 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|