![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
RNR107
Joined: 19 Dec 2014 Posts: 23
|
Delay_us not precise ? |
Posted: Tue Jan 13, 2015 10:30 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 13, 2015 11:52 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Wed Jan 14, 2015 1:43 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
RNR107
Joined: 19 Dec 2014 Posts: 23
|
|
Posted: Wed Jan 14, 2015 3:17 am |
|
|
@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);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Wed Jan 14, 2015 3:45 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
RNR107
Joined: 19 Dec 2014 Posts: 23
|
|
Posted: Wed Jan 14, 2015 5:45 am |
|
|
@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 |
|
![](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
|