Vous êtes sur la page 1sur 5

CCS :: View topic - ADCless POT reading using a 16F628 http://ccsinfo.com/forum/viewtopic.php?t=27191&highlight=inte...

FAQ Forum Help Official CCS Support Search Register

Profile Log in to check your private messages Log in

ADCless POT reading using a 16F628

CCS Forum Index -> General CCS C Discussion

View previous topic :: View next topic

Author Message

Arlof ADCless POT reading using a 16F628


Posted: Wed May 31, 2006 9:57 pm

Joined: 31 May 2006 Hello,


Posts: 2

Long time lurker first time poster.....

I've been using higher end pics in the past, and now I'm playing with a MELABS x3 board. I've
gotten everything to work except for the pot measurement. It appears to use the RC time
constant to measure the change of resistence.

Circuit is a 5K pot in series with a .1 uF capacitor.

I've read in Myke Predko's book how to do it, but my code doesn't seem to work at all. The PIC
basic hex file works, using the POT command so I know the hardware is fine.

Code:

#case // case sensitive turned on


#include <16F628.h> // Include device header file
#use delay(clock = 4000000)// Make compiler aware of osc frequency 4 @ MHz External
#fuses XT,NOLVP, NOWDT, // Pre Directive of: External Oscil, No Low Voltage, No Watch Dog

#use rs232(baud = 9600, xmit = PIN_B2, rcv = PIN_B1) // Setup the on boards USART

#byte port_b = 0x06 // Register For Bit Level Port_B


#byte port_a = 0x05 // Register For Bit Level Port_A
#byte LCD_DATA = 0x05

#bit BUTSTAT = port_b.7 // Port_B PIN_B7 aka Push Botton


#bit POTPIN = port_b.0 // Port_B PIN_B0 aka POT

// Function Prototype

int pot_read(void);

int potval;

void main(void)
{

//int CharPresent;

port_b_pullups(TRUE);
set_tris_a(0x00);

1 от 5 01.3.2007 г. 10:37
CCS :: View topic - ADCless POT reading using a 16F628 http://ccsinfo.com/forum/viewtopic.php?t=27191&highlight=inte...

set_tris_b(0b10000010);

// set led's off


BUTSTAT = 1;
output_low(LED1);
output_low(LED2);

printf("TEST RS232\r\n");
lcd_init();
//enable_interrupts(INT_RB); // Enable Status Chang on B Interrupt
//enable_interrupts(GLOBAL); // Enable Interrupts to be used.

for (;;)
{

output_high(LED1);
delay_ms(250);
output_low(LED1);
output_high(LED2);
delay_ms(250);
output_high(LED1);
delay_ms(500);
output_low(LED1);
output_low(LED2);
delay_ms(500);
potval = pot_read();
printf(putc_lcd,"%x",potval);
}
}

int pot_read (void)


{
int i = 0;
output_low(LED1);
output_low(LED2);
port_b_pullups(FALSE);
output_high(POT);
delay_us(5);
set_tris_b(0b10000011); // Set port b0 to input.
//output_low(POT);
while (POTPIN == 1)
i++;

printf("Pot Val = %x",i);


return (i);

So basically it just hangs in the while loop I assume. Now that I look at the code is it because I
don't have a roll over for my int i? I thought it would automatically roll over....

Anyway, the way I coded the pot_read() function was that it put out a high on the B0 pin and
delay 5 us for charging of the cap. Then I change my tris to make it an input, the capacitor
should start to discharge to ground, then wait for the trigger point on the high to low transition.
approx 2.5 or 1.5 V.

Any ideas? I'm sorta stumped.

Regards,

David.

PCM programmer Posted: Wed May 31, 2006 11:16 pm

Look at the schematic for your board:


Joined: 06 Sep 2003
Posts: 6775 http://www.melabs.com/downloads/labx3sch.pdf
The trimpot and capacitor are in the top center of the schematic.
Note the values.

Now go to this explanation of the POT command, on the Piclist website:


http://www.piclist.com/techref/microchip/seepicsrc/psbpix/pot.htm
Near the top of the article, they explain how they calculate the

2 от 5 01.3.2007 г. 10:37
CCS :: View topic - ADCless POT reading using a 16F628 http://ccsinfo.com/forum/viewtopic.php?t=27191&highlight=inte...

charging time for the capacitor. Compare the amount of time that
they charge the capacitor to the amount of time that you're using.
Plug the values of the cap and trimpot from the labx3 schematic
into their equation. What time value do you get ?

Also, do you have the trimpot set at some reasonable value ?


Make sure it's not set at 0. Initially, it's best to set it at max resistance.

Besides that problem, the rest of your pot_read() routine doesn't work
the way the Pot command does in PicBasic. If you want to translate
the PicBasic Pot command to C, one good way to do it is to compile
a Picbasic program which uses that command, and then look at the .LST
file. They put comments in there which explain what the ASM code is
doing. You may not understand all of it, but I think you should be
able to get the idea of how they do the measurement. Example:
Code:

POT
call CONVPIN ; Convert pin to FSR and bit mask
POTT
movwf RM1 ; Save bit mask
call HIGHT ; Set pin high to charge cap

movlw 10 ; Charge cap for 10ms


call PAUSE
movf RM1, W ; Get bit mask
iorwf INDF, F ; Set pin to input
bcf FSR, 7 ; Point to port
xorwf INDF, F ; Flip bit to low
clrf R0 ; Zero counter
clrf R0 + 1
potloop
bsf FSR, 7 ; Point to TRIS
movf RM1, W ; Get bit mask
xorwf INDF, F ; Set pin to output
; Discharge a little (& clear Watchdog timer)
clrwdt
nop ; Short delay
nop

xorwf INDF, F ; Set pin back to input


bcf FSR, 7 ; Point back to port
andwf INDF, W ; Read pin
btfsc STATUS, Z ; Still high?
goto potdone ; No
movf R2, W ; Get scale factor
addwf R0, F ; Increase count by scale
btfsc STATUS, C ; Check for roll to high
incfsz R0 + 1, F
goto potloop ; Do some more
decf R0 + 1, F ; Overflow so set to max
potdone
movf R0 + 1, W ; Get result to W
DONE

Arlof Posted: Sat Jun 03, 2006 12:58 pm

Hey, Great help thanks. Apprently the guy in the that wrote that book forgot to mention you
Joined: 31 May 2006
Posts: 2 needed to discharge the capacitor.

So if anyone else has this question the coded solution was:

Now I've got another question I did a delay_ms(2.5) ; And it put a delay of about 9.28 seconds.
Whats the deal with that is that a bug or something? I've got compiler 3.42.

Thanks,

David

Code:

3 от 5 01.3.2007 г. 10:37
CCS :: View topic - ADCless POT reading using a 16F628 http://ccsinfo.com/forum/viewtopic.php?t=27191&highlight=inte...

int pot_read (void) // instruction = 1uS


{
int i = 0;
output_high(POT);
delay_ms(3); // Charge time 5x.1e-6x5k = 2.5 mS
set_tris_b(0b10000011); // Set port b0 to input.

while (POTPIN == 1) // Do loop will the storge charge is more than 2.5 Vdc
{
i++; // Increment Counter 0hms = 01 hex
output_low(POT); // Set ouput to discharge cap a bit
set_tris_b(0b10000010); // set the i/o port to output
delay_us(10); // wait a bit for it to discharge some.
set_tris_b(0b10000011); // I/O to input to check for the switch point
}

set_tris_b(0b10000010); // Set the i/o to output


return (i); // return time it took to pull the RC to a 0.

Leef_me Posted: Sat Jun 03, 2006 2:29 pm

>>Arlof said:
Joined: 14 Mar 2006
Posts: 10 >>Now I've got another question I did a delay_ms(2.5) ; And it put a >>delay of about 9.28
seconds. Whats the deal with that is that a bug or >>something? I've got compiler 3.42.
>>Thanks,
>>David

Hmm, according to the "Compiler Updates" webpage the latest versions are Version 3.249 &
Version 3.236 . Perhaps you have a typo.

Check the parameter value for delay_ms() again; 2.5 is not within the allowed parameter
ranges.

I did try 2.1, 2.2 ... 3.5 and only 2.5, 3 and 3.5 gave any ASM result.
I did not try to decipher the resulting delay. The values 2.1 and others caused the compiler to
not generate any code.
------------------------------------------------------------------------------

Quoting from the help file:

Syntax:
delay_ms (time)

Parameters:
time - a variable 0-255 or a constant 0-65535

HTH,
Leef_me

Code:
#include "C:\Documents and Settings\Lee\My Documents\rc_signal\rc.h"

void main()
{
delay_ms(100);

output_float (PIN_A3);

delay_ms(2.5);

output_float (PIN_A3);

4 от 5 01.3.2007 г. 10:37
CCS :: View topic - ADCless POT reading using a 16F628 http://ccsinfo.com/forum/viewtopic.php?t=27191&highlight=inte...

Ttelmah Posted: Sat Jun 03, 2006 2:29 pm


Guest

The 'delay' functions, accept _integer_ values only. My guess would be that 2.5, gets encoded by
the compiler to a float, and then the first two bytes of this get taken and treated as an integer.
This would be '0x2080', allowing for the byte order used in the float, which ought to give 8.32
seconds. However the behaviour with a float is completely undefined, so this is only a guess.
If you want to delay for 2.5mSec, then code this as delay_us(2500).

Best Wishes

Display posts from previous: All Posts Oldest First Go

All times are GMT - 6 Hours


CCS Forum Index -> General CCS C Discussion

Page 1 of 1

Jump to: General CCS C Discussion Go

You can post new topics in this forum


You can 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

5 от 5 01.3.2007 г. 10:37

Vous aimerez peut-être aussi