5
CCS :: View topic - ADCless POT reading using a 16F628 http://ccsinfo.com/forum/viewtopic.php?t=27191&highlight=inte ... 1 от 5 01.3.2007 г. 10:37 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 Joined: 31 May 2006 Posts: 2 ADCless POT reading using a 16F628 Posted: Wed May 31, 2006 9:57 pm Hello, 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);

CCS _ View topic - ADCless POT reading using a 16F628

Embed Size (px)

Citation preview

Page 1: CCS _ View topic - ADCless POT reading using a 16F628

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

1 от 5 01.3.2007 г. 10:37

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

Joined: 31 May 2006Posts: 2

ADCless POT reading using a 16F628Posted: Wed May 31, 2006 9:57 pm

Hello,

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);

Page 2: CCS _ View topic - ADCless POT reading using a 16F628

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

2 от 5 01.3.2007 г. 10:37

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

Joined: 06 Sep 2003Posts: 6775

Posted: Wed May 31, 2006 11:16 pm

Look at the schematic for your board:

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

Page 3: CCS _ View topic - ADCless POT reading using a 16F628

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

3 от 5 01.3.2007 г. 10:37

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

Joined: 31 May 2006Posts: 2

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

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:

Page 4: CCS _ View topic - ADCless POT reading using a 16F628

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

4 от 5 01.3.2007 г. 10:37

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

Joined: 14 Mar 2006Posts: 10

Posted: Sat Jun 03, 2006 2:29 pm

>>Arlof said:

>>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);

Page 5: CCS _ View topic - ADCless POT reading using a 16F628

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

5 от 5 01.3.2007 г. 10:37

}

TtelmahGuest

Posted: Sat Jun 03, 2006 2:29 pm

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 PostsAll Posts Oldest FirstOldest First Go

CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours

Page 1 of 1

Jump to: General CCS C DiscussionGeneral CCS C Discussion Go

You can post new topics in this forumYou can reply to topics in this forum

You cannot edit your posts in this forumYou cannot delete your posts in this forum

You cannot vote in polls in this forum

Powered by phpBB © 2001, 2005 phpBB Group