5.1 Using the Internal Resistor Ladder
The internal resistor ladder has several connection points accessible with a wiper. A specific connection point can be selected by writing to the MUXWIP bit field in the OPnRESMUX register. The voltage level at the wiper position will be a function of VDD, R1 and R2:
MUXWIP Setting | Fraction of VDD | Approximate Output Voltage |
---|---|---|
0x2 | 3/4 | 3.75V |
0x3 | 1/2 | 2.50V |
0x4 | 3/8 | 1.88V |
To enable the internal resistor ladders, and make the OPAMP into a power supply, the following steps are needed:
- Connect the negative input of the OPAMP to its output.
- Connect the positive input of the OPAMP to the wiper of the resistor ladder.
- Connect the top of the resistor ladder to VDD.
- Connect the bottom of the resistor ladder to GND.
- Set the wiper position to the desired position.
The function below takes a wiper position as input defined by the data sheet and sets up the OPAMP to act as a power supply.
void op_amp_setup_int_resistors(OPAMP_OP0RESMUX_MUXWIP_t MUXWIP_gc)
{
OPAMP.OP0INMUX = OPAMP_OP0INMUX_MUXNEG_OUT_gc | OPAMP_OP0INMUX_MUXPOS_WIP_gc;
OPAMP.OP0RESMUX = OPAMP_OP0RESMUX_MUXTOP_VDD_gc|OPAMP_OP0RESMUX_MUXBOT_GND_gc|MUXWIP_gc;
}
When using this method to supply power to the MVIO, and considering the electrical limitations of this power supply implementation, only the three wiper positions listed in table Resistor ladder outputs with VDD=5V provide useful outputs for this application.
The code below will enable the functionality mentioned above:
#define F_CPU 4000000ul #define CLK_PER 4000000ul #define OPAMP_MAX_SETTLE_TIME 0x7F #include <avr/io.h> #include <math.h> void op_amp_init(); void op_amp_setup_int_resistors(uint8_t MUXWIP_gc); int main(void) { op_amp_init(); op_amp_setup_int_resistors(OPAMP_OP0RESMUX_MUXWIP_WIP4_gc); while (1) { /*Your application goes here*/ } } void op_amp_init() { /*Disable input on op amp output pin*/ PORTD.PIN2CTRL = PORT_ISC_INPUT_DISABLE_gc; /*Set up op amp*/ OPAMP.CTRLA = OPAMP_ENABLE_bm; OPAMP.TIMEBASE = (uint8_t) ceil(CLK_PER*0.000001)-1; /*Number of peripheral clock cycles that amounts to 1us*/ OPAMP.OP0CTRLA = OPAMP_RUNSTBY_bm | OPAMP_ALWAYSON_bm | OPAMP_OP0CTRLA_OUTMODE_NORMAL_gc; OPAMP.OP0SETTLE = OPAMP_MAX_SETTLE_TIME; //As the settle time is unknown, the maximums should be set } void op_amp_setup_int_resistors(OPAMP_OP0RESMUX_MUXWIP_t MUXWIP_gc) { OPAMP.OP0INMUX = OPAMP_OP0INMUX_MUXNEG_OUT_gc | OPAMP_OP0INMUX_MUXPOS_WIP_gc; /* MUXWIP is the bit field that decides the output voltage of the op amp With VDD at 5V you will get: OPAMP_OP0RESMUX_MUXWIP_WIP4_gc -> ~1.88V OPAMP_OP0RESMUX_MUXWIP_WIP3_gc -> ~2.5V OPAMP_OP0RESMUX_MUXWIP_WIP2_gc -> ~3.75V */ OPAMP.OP0RESMUX = OPAMP_OP0RESMUX_MUXTOP_VDD_gc|OPAMP_OP0RESMUX_MUXBOT_GND_gc|MUXWIP_gc; }
The code for this example is available in the
using-internal-resistor-ladder folder in these github
repositories: