Example of how to switch pin back and forth between open drain output and comparator Input LPC804?

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Example of how to switch pin back and forth between open drain output and comparator Input LPC804?

85件の閲覧回数
joeatrainamp
Contributor II

I am seeking some sample code showing how to switch a pin from floating input to open drain output and back very fast.

I have an application where I measure the time for a charge to rise from zero volts to a Comparator threshold such as 2.5V through a fixed resistor. I use this to approximate capacitance from a circuit containing a variable capacitor.     The way I have done this in Arduino and Rust is slightly different but I essentially have a pin wired from +3VDD  through a 10M resistor feeding  the comparator input.  Then I measure time/count it takes for the pin to rise from zero to the threshold voltage.   Once I detect the transition event has occurred I drain the variable capacitor through the openDrain pin and loop.  I use oversampling to improve overall reading stability. 

I can use two pins one as the sense pin and one as the drainPin but if I am willing to allow the drain cycle to take a  longer then I can use a single pin that switches back and forth.   The advantage of the two pin approach with one pin acting as open Drain is that it drains the circuit faster which means I can take more samples for averaging quickly with less CPU time draining the battery but it seems like I am always running short of pins so the 1 pin version can come in handy. 

The sample code below used a CPU without a analog comparator so it used logic transition levels but it is also on a much faster clock so I could detect smaller time variations.   For the LPC804 I want to use the analog comparator with a higher transition voltage so it takes longer to reach the transition voltage and gives the LPC804 a better chance of detecting sub 1% changes charge time. 

The key to make this work well with the LPC804 is being able to switch a single pin from open drain output mode to input for the analog comparator and back.

In the LPC804 datasheet I found: Pin direction bits can be toggled in 9.10.1   In the LPC804 users manual I found the following:  10.5.12 GPIO port direction toggle registers Direction bits can be set by writing ones to these write-only registers. Symbol Table 150. GPIO port direction toggle register (DIRNOT0), address 0xA000 2480 bit description.  I am hoping somebody can provide C sample code for using this feature.



The samples below are only to help clarify the approach.   I would like to write an example showing both approaches using the LPC804.  I am hoping that we find the LPC804 CPU that draws much less power can still deliver sub 1% resolution of capacitance changes even though it is running 16 times slower.  I am hoping to show that the LPC bare metal with the analog comparator yields more consistent results due to few things happening in the background and the  defined threshold of the analog comparator means we require fewer samples when averaging.   If I can get it working with basic C then my next step is to try it with the PLU.

- Rust example using 1 pin: https://github.com/joeatbayes/embedded-rust-examples/tree/main/ex-gpio-change-pin-direction-var-cap-...

- Arduino C example using 1 pin:  https://github.com/joeatbayes/embedded-rust-examples/blob/main/ex-gpio-change-pin-direction-var-cap-...

- Rust example using 2 pin and open drain: https://github.com/joeatbayes/embedded-rust-examples/tree/main/ex-gpio-measure-time-to-change-high-t...

 

ラベル(1)
タグ(1)
0 件の賞賛
2 返答(返信)

57件の閲覧回数
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

As you know that the LPC804 has ACMP module, and the ACMP input pin is multiplexed with GPIO. for example, PIO0_14/ACMP_I3/ADC_2, the pin can function as GPIO pin and ACMP_IN3 pin.

you connect a capacitor to the PIO0_4 pin, when the pin is configured as ACMP_IN3 function, the pin has high impedance, you can use a current source to charge the capacitor, when it is above a threshold which is programmable, the ACMP_OUT will become high and can trigger an interrupt.

If you want to discharge the capacitor, you can configure the pin as PIO0_4 and configure the pin as GPIO output and output LOW logic, which can sink the charge via a current limited resistor.

It appears you program with Arduino platform, unfortunately, I am not familiar with the platform.

You can use the code to configure the PIO0_14 as GPIO output

#define BOARD_LED_RED_POR 0

#define BOARD_LED_RED_PIN 4

void BOARD_InitPins(void)

{

/* Enables the clock for the GPIO0 module */

CLOCK_EnableClock(kCLOCK_Gpio0);

 

gpio_pin_config_t LED_RED_config = {

.pinDirection = kGPIO_DigitalOutput,

.outputLogic = 0U,

};

CLOCK_EnableClock(kCLOCK_Swm);

SWM_SetFixedPinSelect(SWM0, SWM_PINENABLE0_ACMP_I3_MASK, false);

/* Initialize GPIO functionality on pin PIO0_13 (pin 4) */

GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_PORT, BOARD_LED_RED_PIN, &LED_RED_config);

}

 

You can configure the pin as ACMP_IN3

 

void pinInit()

{

CLOCK_EnableClock(kCLOCK_Swm);

SWM_SetFixedPinSelect(SWM0, SWM_PINENABLE0_ACMP_I3_MASK, true);

 

}

 You can download SDK from the link:

https://mcuxpresso.nxp.com/en/welcome

 

You can use MCUXPresso tools to compile/debug

 

Hope it can help you

BR

XiangJun Rong

 

 

0 件の賞賛

47件の閲覧回数
joeatrainamp
Contributor II



Thanks for the response, You are right I like Rust, Python and Arduino but find myself wanting to switch over to ARM C just often enough to need to learn this stuff.

 I got a version of the capacitance sensor working  LPC804 using logic levels  but still want to try a
version with the Analog comparator just to see if it works better.   Here is the working version: https://community.nxp.com/t5/LPC-Microcontrollers/A-C-Example-for-measuring-sub-2pF-capacitance-chan... 

Based on what I have working already I want to do something slightly different with the analog comparator where I I have the single sense pin and do a tight loop while charging that pin through the limit resistor until it exceeds 90% of VCC then flip modes and wait in a tight loop until until it drops below 10% of VCC.  Rather than measure time for each I will see how many cycles I can complete in a given amount of time.  I think based on what you showed that I should be able  to use 

ACOMP_SetInputChannel(ACOMP_PERIPHERAL, ACOMP_POSITIVE_INPUT, ACOMP_NEGATIVE_INPUT);

to switch back and forth between the two comparisons using two separate pins with

voltage dividers at 0.9VCC and 0.1VCC as the compare points or I should be able to
switch out the comparison voltage using the DAC which would be preferrable
to save pins.

I should be able to detect the transition with:

if (ACOMP_GetOutputStatusFlags(ACOMP_PERIPHERAL))

{

break;

}


Does this make sense or is it better to reserve the analog comparator for other uses since I have the logic level version working well.

I tried to get the analog comparator example working on my board for several hours but it just never detected the transition even though I tried both external pins and the DAC compare.  Will go back and try it after I try what you showed me.

 

 

 

0 件の賞賛