Hallo,
hier mal code aus einem P-Spannungsregler für pc-lüfter. Funktioniert hier einwandfrei. Ausregelzeit ist natürlich bescheiden, aber es ist ein step up der avalanche rated ist. D.h. Wegfall der Last im laufenden Betrieb ist i.O.

Der code ist nur für mich geschrieben und nie für die Veröffentlichung vorgesehen. Deswegen auch kaum comments.

Code:
// set voltage in mV
void setVoltage(uint16_t voltageDesired){
	setPoint = voltageDesired / VOLTAGE_FACTOR;
}

void setUseSetPoint(bool flag){
	useSetPoint = flag;
}

ISR(ADC_vect)
{
	static uint8_t counter;
	counter++;
	// calculate new pwm value
	if (counter % 4 == 0) {
		static uint16_t adc;

		setADC(3); // 3 = poti

		adc -= (adc >> LOWPASS);
		adc += getADC();
		int16_t error = setPoint - adc;
		if (error > 0 && (adc < (VOLTAGE_MAX/VOLTAGE_FACTOR)) ) {
			setTimer1(error * KP);
		} else {
			setTimer1(0);
		}
	}

	// measure setPoint
        // only every second pass is possible
	else if (counter % 4 == 2){
		static uint16_t adc;

		setADC(1); // 1 = voltage divider
		adc -= (adc >> LOWPASS);
		adc += getADC();

		// only use this value if bool flag is set.
		// used for startup
		if(useSetPoint){
			setPoint  = adc;
		}
	}
}
Code:
#define VOLTAGE_START 13000			// startup voltage in mV
#define VOLTAGE_MAX 14000

/* PID Control
 */

#define LOWPASS 2
#define KP 2

/*
 * lower resistor = 1k
 * upper resistor = 12k
 * U = 1k/13k = 0.0769
 * 10bit resolution, 0 = 0mV_ref, 1023 = 1100mV_ref
 * 1 unit = 1100mV_ref / 1023 = 1.0753mV_ref
 * 1 unit = ( 1100mV_ref / 1023 ) * ( 13k / 1k ) = 13,9785mV
 * 1023 units = 14300mV
 */
#define VOLTAGE_FACTOR  (14>>LOWPASS) 	// error = 0,15%