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 CCS Technical Support

32Khz Ext XTAL and delay_us() problem?

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



Joined: 21 Oct 2011
Posts: 17

View user's profile Send private message

32Khz Ext XTAL and delay_us() problem?
PostPosted: Fri Oct 21, 2011 9:20 pm     Reply with quote

The snippet of code below is designed to vary the duty cycle servo motor along with some hysteresis based in an ADC reading (error) on an PIC16F616.

It works fine using #fuse INTRC and #use delay(clock = 8000000). I do however need to lower the overall power consumption of INTRC and use the #fuse LP and #use delay (clock=32768, xtal) and of course, I'm using a tuning fork xtal and 22pf caps on OSC1 and OSC2 as per the data sheet.

The problem appears only when using the 32768Hz xtal and in the delay_us() directives. However, the "delay_ms(xxx)" appear properly timing but, when program enters into "delay_us(xxx)", the controller/program basically stops.

I'm using PCM compiler and a http://cfm.citizen.co.jp/english/product/pdf/CFS-CFV.pdf xtal.

The xtal appears to be running properly (amplitude maybe a little low but my scope does load it down slightly, freq is right on) and again, the program seems to run fine until it runs the "delay_us()" section/s.

Any idea's?

Code:

#include <16F616.h>
#device adc=10;
#fuses LP, NOWDT, NOPROTECT, BROWNOUT, PUT
#use delay(clock=32768, xtal)

if((error >= 1) && (error <= 1024))
{
   if(error >= error_previous_high)
   {
   output_high(PIN_C2);//red light on,  enable servo FET, wait 2 secs
   delay_ms(2000);
            
      for(y = (error_previous_high - 10) ; y <= error; y++)
         {         
         output_high(PIN_C0); //start pulse
         delay_us(y + 1360); //delay on
         output_low(PIN_C0); //end pulse
         delay_us(20000-(y + 1360));//delay off      
         }

   error_previous_high = (error + 10);
   error_previous_low = (error - 10);
   output_low(PIN_C2);//red off, FET off
            
   }
   else if(error <= error_previous_low)
   {
   output_high(PIN_C2);//red light on,  enable servo FET, wait 2 secs
   delay_ms(2000);
            
      for(y = (error_previous_low + 10); y >= error; y--)
      {            
      output_high(PIN_C0);
      delay_us(y + 1360);
      output_low(PIN_C0);
      delay_us(20000-(y + 1360));         
      }
   error_previous_high = (error + 10);
   error_previous_low = (error - 10);
   output_low(PIN_C2);//red off, FET off
   }
         
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Sat Oct 22, 2011 3:57 am     Reply with quote

There are a number of things to realise.
First, the simple addition maths in your delay_us call, is going to take nearly 2mSec to run at 32KHz.....
Second the delay_us loop, takes a _minimum_ of several instructions to execute. and more if using an int16 loop variable (which you will be doing, though you don't show us the declaration of y). Say perhaps 12 instructions, giving a loop resolution of 400uSec, at your clock. 90% of loop values will simply be impossible at this loop frequency....
The internal count, is probably just going 'underscale' and failing.
It is a bit like asking a cricketer to catch a bullet. Just not possible.

Best Wishes
temtronic



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

View user's profile Send private message

PostPosted: Sat Oct 22, 2011 5:08 am     Reply with quote

It looks like you're trying to control an RC hobby type servo.If this is true, changing the type of oscillator to reduce power is NOT worth the effort.You are either powering the project from either a 'pluged into the wall' PSU or batteries.In either case the PIC uses very,very little power compared to the servo.
Also your code snippet also shows power hungry LED,again it'll take more energy to light than the PIC needs to run !
So I'm confused as to WHY you want to reduce PIC power when the 'perpipherals'(LEDs, servo) consume 100s of times the energy ?
Sam_63



Joined: 21 Oct 2011
Posts: 17

View user's profile Send private message

PostPosted: Sat Oct 22, 2011 8:37 am     Reply with quote

Thanks temt and Ttel,

Ttel, you nailed it...thank you. I Just wasn't thinking, although after I posted 1/32khz = 32us, it occurred to me....doh.

temt, Yes you're correct but.....the led is just a diagnostic used that is removed and replaced by a FET. The servo doesn't run all the time.......the micro servo only comes on when needed...ie., short bursts when needed to correct errors in positions. The duty cycle is about 2% at a freq of around .001hz with off/idle currents around 1.6ma. The PIC is using about 90% of this 1.6ma while just spinning on data collections.

The AA are lasting about 30-60 some days at an overall idle current of around 1.6ma, I'd like the idle current down in the 10's-50's ua.
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Sun Oct 23, 2011 2:39 am     Reply with quote

The first obvious thing is to 'not go so far'. Take the CPU frequency down to perhaps 1MHz, and though timing resolution will go down, things will still be possible. Your consumption is a little high at 8MHz. This will obviously depend on what lines you are changing/driving though. Typical consumption at 1MHz, is 345uA.
If you can change PICs, one possibility would be to go for one that support oscillator switching. Then on the delays between pulses, switch the oscillator down, and perform these at a low clock rate. Devices like the 16F1503, support an internal clock, that might be accurate enough for your application (servos are not that accurate), and offer switching between the rates from this 'on the fly'. It's baseline consumption is already about 50% lower than the chip you are using....

Best Wishes
Sam_63



Joined: 21 Oct 2011
Posts: 17

View user's profile Send private message

PostPosted: Sun Oct 23, 2011 9:29 am     Reply with quote

Yes totally agreed Ttel, that was is what i was just considering.

As slow as the data collection is, I could switch on the fly between the LP 32Khz ext. clk. mode for data acquisition and over to 8/4/1Mhz int. clk. for servo commands.

You say the 16F616 doesn't support that INT/EXT clock switch over? Bummer

If not, yes, I'll have to switch PIC's then.
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