viernes, 24 de enero de 2014

Control Proporcional Integral de un modelo en Simulink.(Codigo)

Código implementado para el control PI


#include"Cpu.h"
#include"Events.h"
#include"mqx_tasks.h"
#include"Functions.h"
#ifdef __cplusplus
extern"C" {
#endif

#define Kp 30U
#define Ki 2U

LDD_TDeviceData *DACptr,*ADCptr;
bool FlgDatoRecibido=FALSE;
int Value,SetPoint,Y,U_Act=0,U_Ant=0,Err_Act=0,Err_Ant=0;
short posicion;
externbyte SendChrError;
unsignedchar MatLab_Data[16],ConvertedValues[16],*ConvertedValuesptr,*AP_Data;
voidControlPI_task(uint32_t task_init_data)
{
       int i;
       short pos_actual;  
      
       ADCptr=AD1_Init(NULL);//Inicializa ADC
         MatLab_Data[15]='0'//Escribe '\n' en ultima posicion para leer primer dato
       MatLab_Data[14]='\n';
         AD1_SelectSampleGroup(ADCptr,0U);// Selecciona grupo de muestreo
       AD1_StartLoopTriggeredMeasurement(ADCptr);
       while(1) {
             if(FlgDatoRecibido==TRUE){
                    FlgDatoRecibido = FALSE;
                    Y = str2int(posicion,MatLab_Data);
                    Err_Act = (SetPoint*1000) - Y;    //Calcula el error
                      DA1_SetValue(DA1_DeviceData,2048);//Acción PI
                    U_Act = U_Ant + (Kp+Ki)*Err_Act - Kp*Err_Ant;
                      int2str(U_Act,6); 
                      ConvertedValuesptr = ConvertedValues;              
                      SendChrError = AS1_SendChar(*ConvertedValuesptr);               
                      GREEN_LED_NegVal(RED_LED_DeviceData);
                      RED_LED_SetVal(RED_LED_DeviceData);
                      U_Ant = U_Act;
                      Err_Ant = Err_Act;
               }
              RED_LED_ClrVal(RED_LED_DeviceData);
         }
}
#include"Cpu.h"
#include"Events.h"
#include"mqx_tasks.h"

#ifdef __cplusplus
extern"C" {
#endif


externbool FlgDatoRecibido;
externshort posicion;
externunsignedchar MatLab_Data[16];
externint Value,SetPoint;
externLDD_TDeviceData *ADCptr;
externunsignedchar ConvertedValues[8],*ConvertedValuesptr;
byte Error,RecvChrError,SendChrError;
AS1_TError *Err;
uint16 ValueADC;

voidAD1_OnMeasurementComplete(LDD_TUserData *UserDataPtr)
{
      
       AD1_GetMeasuredValues(ADCptr,&ValueADC);  //Toma valor del ADC
       SetPoint=(int)ValueADC*20/65535;          //Escala valor de 0 - 20
                   
}
voidAS1_OnRxChar(void)
{
       staticAS1_TComData *AP_BuffInput=MatLab_Data;
       staticint i=0;

       RecvChrError=AS1_RecvChar(AP_BuffInput);    //Recibe dato de canal de recepcion
       if (MatLab_Data[i]=='\n'&&MatLab_Data[(i-1)&0xf]=='U'){                                       FlgDatoRecibido=TRUE;                //Enciende bandera dato recibido
                    posicion=i;}                 //Guarda posicion para apuntador
             AP_BuffInput++;
             i=(i+1)&0xf; 
             if(i==0)AP_BuffInput=MatLab_Data;
}
voidAS1_OnTxChar(void)
{
       ConvertedValuesptr++;                
       if(*ConvertedValuesptr!=NULL){
             while ((SendChrError=AS1_SendChar(*ConvertedValuesptr))!=ERR_OK);
       }
}
//--------------------------------------------------------------------------------------
//Libreria de Funciones-----------------------------------------------------------------

intstr2int(int posicion, unsignedchar MatLab_Data[16])
{
short pos_actual,i;

pos_actual=(posicion-2)&0xf;    //Determina la posición a enviar al apuntador
AP_Data=&MatLab_Data[pos_actual];                
Value=*AP_Data-'0';             //Convierte ASCII a Decimal '0'= 30
i=10;            
while ( *(AP_Data=&MatLab_Data[(--pos_actual)&0xf]) != '\n'){            
if(*AP_Data == '-')Value = -Value;   //Si el dato es negativo niega el valor.
       else{Value=Value + (*AP_Data - '0')*i;//Si no sumar decenas, centenas y millares.
       i=i*10;}                         //Multiplicador de decenas, centenas y millares.     
       }
return Value;
}
voidint2str(int value,int p)
{
int Aux,i,n,r;
ConvertedValues[p+1]='\n';              //Escribe Terminador
ConvertedValues[p]='U';                 //Escribe Terminador
if (value < 0){                         //Pregunta por numero negativo
       value=abs(value);                                        //Hace el valor positivo
       ConvertedValues[0] = '-'; //Coloca signo negativo en primera posición
       for(i=2;i<=p;i++){           //infiere numero comenzando por el más significativo
    Aux=numpow(10,(p-i));       //Llama a función numpow
       ConvertedValues[i-1]=((value/Aux)%10)+48;
       }
}
else{
       for(i=1;i<=p;i++){           //infiere numero comenzando por el más significativo
    Aux=numpow(10,(p-i));       //Llama a función numpow
       ConvertedValues[i-1]=((value/Aux)%10)+48;
       }
}
}
intnumpow(int num,int n)
{
int Aux,i;
Aux=num;
if(n!=0)                  //Verifica que la potencia a elevar sea diferente a cero
       for(i=1;i<=n-1;i++)Aux=Aux*num;   //Calcula el número a la potencia 'n'
else Aux=1;                              //si n=0 entonces el resultado es 1
return Aux;                             //regresa entero

}



No hay comentarios:

Publicar un comentario