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

Delay_us not precise ?

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



Joined: 19 Dec 2014
Posts: 23

View user's profile Send private message

Delay_us not precise ?
PostPosted: Tue Jan 13, 2015 10:30 am     Reply with quote

Hi all,
I am using a PIC16F1704 to control a stepper motor.
The problem I am having is with the Delay_us function.
Setup:
Code:

#INCLUDE "16f1704.h"
#DEVICE PIC16F1704
#FUSES HS,NOWDT,NOPROTECT,NOMCLR,NOPLLEN   //,PUT
#USE delay(clock=20000000)
#DEFINE DIR      PIN_C2


My test/debug function:
Code:

while(1)
   {
      output_high(DIR);
      delay_us(50);
      output_low(DIR);
      delay_us(5);      
   }


Now when a look at PIN_C2 on an oscilloscope I get High for 84us !!!
I was expecting something a bit better than that...
Am I setting up the oscillator options wrong or something?
(I have a 20MHz crystal connected between OSC1 and OSC2)

Thanks,
RNR
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 13, 2015 11:52 am     Reply with quote

Always post your compiler version on a question like this. The version
number is given at the top of the .LST file after a successful compilation.
It will be a number like 4.141 or 5.028 or 5.036, etc.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Wed Jan 14, 2015 1:43 am     Reply with quote

Also, what you post, should be compilable. You don't show a 'main' for your 'test' function.

As a comment there is no point in setting the device, the processor include file already does this for you.

The normal reason for this to be slow, will be that you are executing an interrupt. The delays are calculated in processor cycles. If your processor is going off and doing something else (executing an interrupt), then 'of course', delay_us will look slow. It'll still count exactly the same number of processor cycles, but your processor will be going off and executing interrupt code for part of the count, so the 'main loop' will not be what is executing all the time....

If you want 'absolute times', then you have (instead), to use a timer. Look at the 'tick' functionality (#use timer, and get_ticks), which allows you to read a 'tick' which is in a time unit dependant on the clock you select for it, which will reflect the real passage of time, even if interrupts are called.
RNR107



Joined: 19 Dec 2014
Posts: 23

View user's profile Send private message

PostPosted: Wed Jan 14, 2015 3:17 am     Reply with quote

@PCM programmer:
CCS PCM C Compiler, Version 5.034, 21281

@Ttelmah
I have no interrupts enabled... The test function is all it does right now. :-)

Code:

/****************************************************************************************/
/*   Pre Processor Commands                                                             */
/****************************************************************************************/
#INCLUDE "16f1704.h"
#DEVICE PIC16F1704
#FUSES HS,NOWDT,NOPROTECT,NOMCLR,NOPLLEN

#USE delay(clock=20000000)
#USE rs232(baud=9600,xmit=PIN_C4,rcv=PIN_C5, stream=COM1)

/****************************************************************************************/
/*   Global Variables / constants                                                       */
/****************************************************************************************/
#DEFINE DIR      PIN_C2
#DEFINE STP      PIN_C3

#BYTE OSCSTAT = 0x09A   // Oscillator status register

short PIC_ready = FALSE;

// Total number of pulse for the traveller in 1/2 steps: 3749
/****************************************************************************************/
/*   Function Prototypes                                                   */
/****************************************************************************************/
void init_PIC(void);
void debug123(void);

/****************************************************************************************/
/*   Main Loop...                                                                       */
/****************************************************************************************/
void main(void)
{
   init_PIC();
   printf("\n\rready\n\r");

   while(TRUE)
   {
      debug123();
   }
}

/****************************************************************************************/
/*      PIC setup                                                                       */
/****************************************************************************************/
void init_PIC()
{
   setup_adc_ports(NO_ANALOGS);
   set_tris_a(0b11111111);  // all pins on Port A set to Inputs
   output_low(DIR);
   output_low(STP);

   PIC_ready = TRUE;
}

/****************************************************************************************/
/*      Debug                                                                          */
/****************************************************************************************/
void debug123()
{
   while(1)
   {
      output_high(DIR);
      delay_cycles(250);
      output_low(DIR);
      delay_cycles(25);      
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Wed Jan 14, 2015 3:45 am     Reply with quote

So, you have changed it significantly, and are now using cycles, not times.

The output instructions, each take four instruction times. The loop takes three, so as posted, total time is:

loop 3
I/O 8
delays 275
Total 286

Master clock = 5MIPS
Time = 57.2uSec

Now, that assumes your clock is actually running at the frequency you think. Does your serial output work?. Are you actually testing this on a chip? (Remember 'simulators', such as MPLAB, and Proteus, will 'accept what you tell them' about the clock, so may be running at a different speed).

You are still naming the chip a second time, and then doing unnecessary things (TRIS is controlled for you as standard, it wakes set to input, so why change it, then you 'deslect ' the analog multiplexer, but don't turn the ADC itself off. then you have an infinite loop calling another infinite loop).

Just for the sake of it, this is a typical test program:
Code:

#INCLUDE "16f1704.h"
#FUSES HS,NOWDT,NOPROTECT,NOMCLR,NOPLLEN

#USE delay(clock=20000000)
#USE rs232(baud=9600,xmit=PIN_C4,rcv=PIN_C5, ERRORS, stream=COM1)
//You _must_ always have the ERRORS directive with a hardware UART,
//unless _you_ are handling errors yourself. Repeat [u]must[/u].

void main(void)
{
    while (TRUE)
    {
        output_toggle(DIR);
        delay_ms(1);
    }
}

Expect a frequency of 498.4Hz (1mSec, plus 8 instruction times 3 for loop, then since the processor doesn't have a toggle - on the PIC16, it has to read, modify, write to do the toggle - 5 instructions) repeated twice for each full cycle.
RNR107



Joined: 19 Dec 2014
Posts: 23

View user's profile Send private message

PostPosted: Wed Jan 14, 2015 5:45 am     Reply with quote

@Ttelmah
I updated the compiler to V5.36 and the problem went away!

I still took your advice and add the "ERROR" in the serial port definition, Disable the ADC, remove the TRIS settings, remove the #DEVICE...

Thank you for your time mate!
Well apreciated.

RNR
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