![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
alex Guest
|
variable pic16f628a |
Posted: Sat Feb 16, 2008 1:20 pm |
|
|
Hi, i need help for a little problem.
My source code:
Code: |
#include<16f628a.h>
#fuses NOWDT,NOPROTECT,PUT,NOLVP,MCLR,INTRC_IO
#use delay(clock=48000)
#use fast_io(b)
#use fast_io(a)
void main()
{
int duty;
duty= 1;
setup_oscillator(OSC_48KHZ);
set_tris_b(0xF7);
output_low(PIN_b3);
while(1)
{
output_high(pin_b3);
delay_ms(duty);
output_low(pin_b3);
delay_ms(20);
}
}
|
Easy? No, because I have a problem. when I use duty=1 I have a rectangular wave of 1.5 ms Hi and 20 ms low.
If i use delay_ms(1) I have 1ms Hi, if I use delay_ms(2) I have 2ms Hi., but with delay_ms(duty) I can´t create the same value of duty=x.
So, a variable int is wrong? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Feb 16, 2008 3:26 pm |
|
|
The problem is likely caused by your very low clock speed of 48 KHz.
The instruction cycle frequency is 1/4 of that, which is only 12 kHz.
CCS uses software delay loops to create the delays in the delay_ms()
function. With a 12 KHz instruction clock, there are 12 instructions per
millisecond. "Branch" instructions take two cycles. I haven't looked at
the .LST file, but I suspect that the CCS library code for delay_ms() just
doesn't work very well at low clock speeds. |
|
![](templates/subSilver/images/spacer.gif) |
alex Guest
|
|
Posted: Sat Feb 16, 2008 3:50 pm |
|
|
But, PCM programmer, the instructions delay_ms(1) e delay_ms(2) are working well. I see 1.1 ms hi e 2.1 hi.
The instruction delay_ms(duty) , where duty is a variable int that is not working.
Is it not possible that i am using a wrong variable? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sat Feb 16, 2008 4:00 pm |
|
|
The problem is that the delay_ms, using a _variable_, is much more complex code, than that using a fixed value. For the constant, the compiler inserts the instructions needed to get as close as it can the the specified time. For the variable version, it has to have a loop, and count down the variable. The minimum loop time is about 10 instruction times, and the 'step size', is about 15 instruction times. The delay_ms code, for variables, is just not able to cope with times where there are so few instructions per loop. I suspect you will find that the arithmetic, actually goes 'haywire' internally, if one mSec, is less than the shortest available loop time...
At this clock rate, a variable loop, is beyond the ability of the code to deal with.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
alex Guest
|
|
Posted: Mon Feb 18, 2008 8:29 am |
|
|
Well, I gave up of delay. I used a instruction "for" and I did 1ms hi and 20ms low.
The problem is that I can´t change the values of duty cycle.
The variable int of instruction "for" doesn't increase in decimal.. I can´t increase or decrease the duty cycle.
Are there solutions for that? |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Mon Feb 18, 2008 10:46 am |
|
|
Something like
Code: |
#include<16f628a.h>
#fuses NOWDT,NOPROTECT,PUT,NOLVP,MCLR,INTRC_IO
#use delay(clock=48000)
#use fast_io(b)
#use fast_io(a)
#define PERIOD 20
void main()
{
int duty;
duty= 1;
setup_oscillator(OSC_48KHZ);
set_tris_b(0xF7);
output_low(PIN_b3);
int n,i;
while(1)
{
output_high(pin_b3);
for(n=0; n<duty; n++) {
// Insert dummy code to create required delay or use another loop
for(i=0; i<10; i++) {}
}
output_low(pin_b3);
for(n=0; n<(PERIOD - duty); n++) {
// Insert dummy code to create required delay or use another loop
for(i=0; i<10; i++) {}
}
}
}
|
duty = 0 to PERIOD
the low period will be slightly out due to the PERIOD - duty calculation. This can be corrected by changing the internal for(i= loop.
There is still a problem with this.
If duty = 0 you will still get a low pulse.
If duty = PERIOD you will still get a high pulse.
If the delay (for) routines are too slow then you will not be able to get the desired 1ms duty. You do the math. |
|
![](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
|