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

variable pic16f628a

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







variable pic16f628a
PostPosted: Sat Feb 16, 2008 1:20 pm     Reply with quote

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?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Feb 16, 2008 3:26 pm     Reply with quote

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.
alex
Guest







PostPosted: Sat Feb 16, 2008 3:50 pm     Reply with quote

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?
Ttelmah
Guest







PostPosted: Sat Feb 16, 2008 4:00 pm     Reply with quote

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
alex
Guest







PostPosted: Mon Feb 18, 2008 8:29 am     Reply with quote

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?
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Mon Feb 18, 2008 10:46 am     Reply with quote

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.
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