View previous topic :: View next topic |
Author |
Message |
pvol
Joined: 10 Oct 2008 Posts: 46 Location: GREECE
|
conversion time of 16f877 |
Posted: Sun Nov 30, 2008 1:28 pm |
|
|
Hhi everybody!!!
I want to ask, how much time is required for 16f877
to do one conversion (A/D) ?
Datasheet says that it requires 12 TAD.
What is "TAD"?
On 20 MHz XT ,how much time is 1 TAD ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 30, 2008 1:42 pm |
|
|
The available Tad divisors are shown in the 16F877 data sheet:
Quote: | • 2TOSC
• 8TOSC
• 32TOSC
|
Divide your chosen divisor by the crystal frequency. The result will
be the Tad time. Example:
Code: |
32
-------- = 1.6 us Tad
20 MHz |
To choose the correct divisor, see the table in the A/D section of
the data sheet which shows the maximum recommended crystal
frequency for each divisor. |
|
|
pvol
Joined: 10 Oct 2008 Posts: 46 Location: GREECE
|
|
Posted: Sun Nov 30, 2008 3:15 pm |
|
|
thanks for answer!!
i'm doing a circuit right now.
i have two POTs on +5V
one POT connects in AN0
and the other in AN1
I wrote a simple code to see these two values
over hyperterminal but it seems not work very well!
When I increase-decrease AN0 the difference is very
little on c1. When I increase-decrease AN1, c1 and c2
change both!!!!!
Why is this happens? Could you explain me?
Code: |
#include <16F877.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#byte PORTA = 0x05
#byte PORTB = 0x06
#byte PORTC = 0x07
#use RS232(baud=115200, xmit=PIN_C6, rcv=PIN_C7)
int16 c1=0;
int16 c2 =0;
void main() {
setup_adc_ports( AN0_AN1_AN3 );
setup_adc(ADC_CLOCK_DIV_32);
set_tris_a(0xFF);
set_tris_c(0x80);
while(TRUE){
set_adc_channel( 0 );
c1 = read_ADC();
delay_us(4);
set_adc_channel(1);
c2=read_ADC();
printf ("%ld\n",c1);
printf("%ld\n",c2);
}
} |
|
|
|
Ttelmah Guest
|
|
Posted: Sun Nov 30, 2008 3:39 pm |
|
|
You have your delays in the wrong place, and they are too small.
The ADC, has a small capacitor internally. When you 'set_adc_channel', the multiplexor connects the capacitor to the selected external line. The capacitor then needs to _charge_ to the incoming voltage. This needs to happen _before_ you read the value. When you then read the ADC, the capacitor is disconnected from the outside world, and the reading is made of the voltage on this.
Now, in the data sheet, section '11.1' "A/D Acquisition requirements", you have an analysis of how long this charging takes. 19.72uSec. This for a source with an impedance of 10KR (the maximum recommended).
The calculation PCM has gven you, is the time then needed to actually perform the reading. This is 'hidden' in the read_adc function.
So, your sequence needs to be:
Select channel
Wait for the capacitor to charge (allow 20uSec)
Perform the reading (takes 12*1.6uSec)
Repeat for each channel you want to read.
Best Wishes |
|
|
pvol
Joined: 10 Oct 2008 Posts: 46 Location: GREECE
|
|
Posted: Sun Nov 30, 2008 4:01 pm |
|
|
I have done this, but the same problem.
Code: | delay_us(25);
set_adc_channel( 0 );
delay_us(25);
c1 = read_ADC();
set_adc_channel(1);
delay_us(25);
c2=read_ADC();
printf ("%ld\n",c1);
printf("%ld\n",c2); |
Does it matter that one is 100K and second is 47K?
47K affects in value of 100K!!!
When 47K goes 0 ...100K shows 962
and when 47K goes 1023... 100K shows 1003!!!
When I do this separate at 100K
does not affects at 47K but
values is the same 962-1003!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 30, 2008 4:53 pm |
|
|
Quote: | Does it matter that one is 100K and second is 47K? |
Look in the back of the 16F877 data sheet, in this section:
Quote: | TABLE 15-12:
A30 ZAIN Recommended impedance of analog voltage source: 10.0 k |
Try smaller pots, such as 10K and 4.7K ohms. |
|
|
pvol
Joined: 10 Oct 2008 Posts: 46 Location: GREECE
|
|
Posted: Mon Dec 01, 2008 5:35 am |
|
|
problem solved!!!
I change the 2 pots at 1K
and plays fine!!
thank you very much (all of you)!!!! |
|
|
pvol
Joined: 10 Oct 2008 Posts: 46 Location: GREECE
|
|
Posted: Wed Dec 03, 2008 3:52 pm |
|
|
hello again!!
today , i measure the time to convert 2 channels
with a osciloscope.
it was about 87us ,without delays was 37us/2=17.5us per ch
/////////////////////////////from here
set_adc_channel( 0 );/////
delay_us(25);/////
c1 = read_ADC();////
set_adc_channel(1);//////
delay_us(25);//////////
c2=read_ADC();///////to here =87us
/////////////////////////////////////////////////
these channels
i want to send them to PC (labview)
but i have a problem about the time to send!
also i measure exactly the time to send ,look.
////////////////////////////////////////from here
output_high(PIN_B7);//////////
printf("A %ld\n",c1);///////
printf("B %ld\n",c2);/////////
output_low(PIN_B7);////////////to here = 1.1ms
/////////////////////////////////////////
1.1ms/2=550us per channel
or almost 100us per character
i want to minimize this time as i can
let's say about 20us per character!
i know it is diffucult but i ask you
if there is some way to do this..
do you have any ideas??
my baud rate is 115200
is there any PIC that supports 230400??
p.s
A_ and B_ must exist in printf() is something like identity for these 2 channels
thank you again for your help |
|
|
pvol
Joined: 10 Oct 2008 Posts: 46 Location: GREECE
|
|
Posted: Thu Dec 04, 2008 1:30 am |
|
|
can i minimize time if i write in #ASM code???
do you know how much time need in #ASM code
to send one character via rs232??
baud 115200. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 04, 2008 1:48 am |
|
|
Quote: | My baud rate is 115200. I want to minimize this time as I can let's say about 20us per character! |
The limitation is the baud rate. ASM won't make any difference.
Here is the equation:
Code: |
10 bits/char
---------------- = 86.8 us/char
115200 bits/sec
|
|
|
|
pvol
Joined: 10 Oct 2008 Posts: 46 Location: GREECE
|
|
Posted: Thu Dec 04, 2008 2:06 am |
|
|
is there any PIC at 230400?
i didn't find anything
do you know something about that? |
|
|
Ttelmah Guest
|
|
Posted: Thu Dec 04, 2008 3:59 am |
|
|
What baud rates you can do, are dependant on the crystal chosen.
However, start with a PIC, that has a faster ADC, in terms of the internal capacitor charging. The 877, has one of the slowest (requires 20uSec), while (for example), the same circuit connected to a 4620, only requires 2.4uSec. A lot better.
The Tad for the 4620, is also much shorter 0.7uSec for the F4620, against 2uSec for the 877.
Put this together, and you can do a acquire/conversion in just under 11uSec, for the 4620, versus 44uSec for the 877.
Now, for the serial, the 877, at 20MHz, won't allow 234000 to be selected, but clock the 4620, at 10MHz, with the PLL, to give 40MHz operation, and 234000, becomes selectable. Remember though, that at the higher speed, the overall quality of your connection, becomes much more critical, and the maximum length allowed falls. It may seem strange, but in fact 234000, will be allowed, if you change the 877's crystal to 22464000Hz, or even the slower 14976000Hz. This is because it becomes an even integer division from these rates, while from 20MHz, the only possible divisions, give too much error.
Best Wishes |
|
|
Ttelmah Guest
|
|
Posted: Thu Dec 04, 2008 4:12 am |
|
|
As a futher comment, make your transmitted data shorter.
Send in hex, not decimal. Most standard languages at the PC end can receive hex, and it takes only 3 hex digits to send the largest possible value from the ADC, versus four for decimal text.
Best Wishes |
|
|
pvol
Joined: 10 Oct 2008 Posts: 46 Location: GREECE
|
|
Posted: Thu Dec 04, 2008 4:53 am |
|
|
when you say 22464000Hz crystal you
mean that i just disconnect 20MHz and put
this crystal
some changes at fuses?capacitors?
and directive #use rs232(230400.....)
is that correct?
can you give some example how to write
printf hex?//??
lets say number 325
printf(A_325...)
at hex how???
thanks for help!! |
|
|
Ttelmah Guest
|
|
Posted: Thu Dec 04, 2008 5:37 am |
|
|
Yes to the crystal.
Look at the list of supported formats for printf.
Best Wishes |
|
|
|