PID.c
#include <18F452.h>
#device *=16 ADC=10
#use delay(clock=20000000)
#use rs232(baud=38400,xmit=PIN_C6,rcv=PIN_C7)
#include "PID.h"
#INT_TIMER0
TIMER0_isr(){
drive = UpdatePID(&plantPID,(plantCommand - position), position );
}
void main(){
setup_adc_ports ( NO_ANALOGS );
setup_adc ( ADC_OFF );
setup_psp ( PSP_DISABLED );
setup_spi ( FALSE );
setup_wdt ( WDT_OFF );
setup_timer_0 ( RTCC_INTERNAL|RTCC_DIV_8|RTCC_8_bit );
enable_INTerrupts ( INT_TIMER0 );
enable_INTerrupts ( GLOBAL );
setup_oscillator ( False );
while( 1 ) {
}
}
PID.h
typedef struct {
signed int16 dState, // Last position input
iState; // Integrator state
signed int16 iMax,
iMin; // Maximum and minimum allowable integrator state
signed int16 iGain, // integral gain
pGain, // proportional gain
dGain; // derivative gain
} SPid;
SPid plantPID;
signed int16 plantCommand, position, drive;
//PID controller code
signed int16 UpdatePID(SPid *pid, signed int16 error, signed int16 position)
{
signed int16 pTerm,
dTerm,
iTerm;
// calculate the proportional term
pTerm = pid->pGain * error; // calculate the proportional term
// calculate the integral state with appropriate limiting
pid->iState += error;
if ( pid->iState > pid->iMax){
pid->iState = pid->iMax;
}
else if ( pid->iState < pid->iMin){
pid->iState = pid->iMin;
}
iTerm = pid->iGain * pid->iState; // calculate the integral term
dTerm = pid->dGain * ( pid->dState - position);
pid->dState = position;
return (pTerm + dTerm + iTerm);
}