View previous topic :: View next topic |
Author |
Message |
SchimmelSchumi
Joined: 05 May 2018 Posts: 3
|
Restriction of "delay_us" when using return value |
Posted: Sat May 05, 2018 1:41 pm |
|
|
HI guys,
I came across a very challenging problem on my current project.
I am building some sort of frequency generator with the PIC12F863 utilizing the "delay_us" integrated function.
As per the functional description, 'delay_us' can be used with variables up to int16.
However, if I read an analog input (10 bit), do some easy math and put it into the 'delay_us' function as parameter, it seems not to respond to any changes on the analogue input.
I get the frequency pattern I am looking for, but I cant change the frequency with the help of the ADC.
Are they any restrictions on the "delay_us" function I am not aware of?
Here a sneak into my code.
Code: |
.......
setup_adc_ports (sAN0|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_oscillator(OSC_8MHZ);
int16 Frequency, HalfDelay;
.....
set_adc_channel (sAN0);
Frequency = read_adc (ADC_START_AND_READ);
HalfDelay=Frequency*5;
HalfDelay=HalfDelay+300;
FOR (i = 0;i < 24; i++)
{
output_bit(PIN5, 0);
delay_us(HalfDelay);
output_bit(PIN5, 1);
delay_us(HalfDelay);
}
delay_us(HalfDelay);
delay_us(HalfDelay);
FOR (i = 0;i < 35; i++)
{
output_bit(PIN5, 0);
delay_us(HalfDelay);
output_bit(PIN5, 1);
delay_us(HalfDelay);
}
.....
|
Many thanks in advance for any input.
Brdgs, Mike. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat May 05, 2018 4:40 pm |
|
|
You need to see what the ADC values are. If you had a larger PIC, you
could easily add printf capability. You can use the debugger to see the
values. Set a breakpoint and put a watch window on the variables.
Also, what is "PIN5" ? That's not a CCS pin number, and not the official
name of any pin.
There should be a delay between these two lines. In the 12F683 data sheet
it's listed as about 5 usec. Add a
Quote: | set_adc_channel (sAN0);
Frequency = read_adc (ADC_START_AND_READ);
|
Regarding restrictions or bugs for delay_us(), we need to know your CCS
version number. It's a 4-digit number given at the top of your .LST file,
which will be in your project directory after a successful compilation. |
|
|
SchimmelSchumi
Joined: 05 May 2018 Posts: 3
|
|
Posted: Sat May 05, 2018 4:45 pm |
|
|
Thank you for your reply.
I wasn't aware of the delay. I will try it out.
I have a bunch of bigger PICs laying around, will also try other chips.
I am using CCS PCM C Compiler, Version 5.008, 5967
The PIN5 I made up as my real pin definition was a bit "strange".
I will let you know if this solves the problem. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Sat May 05, 2018 5:54 pm |
|
|
this
setup_adc(ADC_CLOCK_INTERNAL);
is usually NOT correct for 99% of the PICs. Some say the 'wizard' tosses it in well the 'wizard' should read the datasheet !
PIC12F863 ? hmm should that be 12f683 ??
If so, the ADC section says '..for clocks >1MHz, adc_internal for sleep mode only...' or words to that effect.
Jay |
|
|
SchimmelSchumi
Joined: 05 May 2018 Posts: 3
|
|
Posted: Sat May 05, 2018 5:59 pm |
|
|
Hi Jay,
thanks for your comment.
Even if I use the internal oscillator? I always believed I have to use
Code: | setup_adc(ADC_CLOCK_INTERNAL); |
When using the internal osciliator of the PIC.
Using the PIC12F683, correct. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Sat May 05, 2018 6:07 pm |
|
|
yes ! It's in table 9-1, there's two notes (1,4) . #4 says if clock >1MHz ONLY use internal ADC clock while in sleep mode. I was going to copy/paste the PDF page but silly Acrobat version I have won't do that.
I just checked again as I'm using the 12F683 for a project and the PDF is on my screen ! Now you may get 'lucky' and have it work, say in the lab, buit in the real World where it gets HOT or k-k-k-kold, the ADC may given wrong or random results.
I never use the 'wizard' or any 'simulator', so I can only blame myself for any mistakes or typos !
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun May 06, 2018 12:30 am |
|
|
For your chip using the internal oscillator at 8MHz, the recommended ADC settings are Fosc/16 or Fosc/32. These are:
ADC_CLOCK_DIV_16 or ADC_CLOCK_DIV_32
The ADC_CLOCK_INTERNAL uses the separate RC oscillator for the ADC Except for 'modern' PIC 24's and similar chips, this is never recommended, unless you actually stop the CPU to do the conversion. It has a tendency to give 'beat' signals as it's frequency is not sychronised to the master oscillator. Result poor accuracy....
Now on your delays. There are some other problems:
Code: |
set_adc_channel (sAN0);
Frequency = read_adc (ADC_START_AND_READ);
|
Wrong. The ADC needs at least Tacq between the channel being selected, and the value being read. About 5uSec assuming your source has an impedance below 10KR.
Then you don't show the code ever going back to read the ADC?. 24 cycles based on the single reading, then another 35 cycles still based on this reading. Are you actually ever going to see the value change?.
There are limitations with a variable. There is a minimum delay of perhaps 30 cycles using a variable, but your +300 should avoid this, and some granularity, but you should see the value change fairly well. |
|
|
|