position_feedback_loop/ER3_Boujon_Chaupitre/ER3.cydsn/main.c

196 lines
6.2 KiB
C

/*******************************************************************************
* File Name: main.c
*
* Version: 2.20
*
* Description:
* This project demonstrates the UART transmission mechanism.
* Data is sent through serial port that is visible in the Hyperterminal and on
* the LCD. ASCII characters from 0x20 to 0x7F(Space to ~ ) that can be
* displayed through Hyperterminal/LCD at the same time Interrupt is triggered
* and incremented while sending.
*
********************************************************************************
* Copyright 2012-2017, Cypress Semiconductor Corporation. All rights reserved.
* This software is owned by Cypress Semiconductor Corporation and is protected
* by and subject to worldwide patent and copyright laws and treaties.
* Therefore, you may use this software only as provided in the license agreement
* accompanying the software package from which you obtained this software.
* CYPRESS AND ITS SUPPLIERS MAKE NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* WITH REGARD TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT,
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*******************************************************************************/
#include <project.h>
#include <stdlib.h>
#include <stdio.h>
#define PERIODE 256
void modulation_pwm(float alpha);
float getAngle(void);
void DAC_conv(float erreur);
char ADC_conv(void);
int signalCarre(int consigne,int flagTemp);
int signalTriangle(int consigne,int flagTemp);
int acquerir_position(void);
volatile unsigned char flag=0;
CY_ISR_PROTO(int_3);
CY_ISR(int_3)
{
flag=1;
Timer_1_ReadStatusRegister();
}
int main()
{
CyGlobalIntEnable;
VDAC8_1_Start();
ADC_SAR_1_Start();
ADC_SAR_1_StartConvert();
PWM_1_Start();
UART_1_Start();
Timer_1_Start();
isr_3_StartEx(int_3);
int angleConsigne=0,i=0,flagTemp=0,consigne=50; //consigne = 50 pour carre et 0 pour triangle
char anglaUART[10+1];
// Kp = 0.1/27.7 -> mais adapte pour etre plus opti +0.001
float Kp=0.00461,Ki=0.000075;
float pwm_val,erAngle,angleCool,erreur_integral=0;
//////////////////////////////////////////////
//////////////passage par 0///////////////////
//////////////////////////////////////////////
do
{
modulation_pwm(0.55);
}while(acquerir_position() == 0);
modulation_pwm(0.5);
QuadDec_1_Start();
//////////////////////////////////////////////
for(;;)
{
//////////////////////////////////////////////////
//liaison UART -> enlever angleConsigne=consigne//
//////////////////////////////////////////////////
if(UART_1_GetRxBufferSize()>0)
{
do{
while(UART_1_GetRxBufferSize()==0);
anglaUART[i]=UART_1_GetChar();
i++;
}while((anglaUART[i-1] != '\r') || (i==11));
anglaUART[i]='\0';
i=0;
//UART_1_PutString(anglaUART); //pour voir si l'UART fonctionne
//angleConsigne=atoi(anglaUART);
};
//////////////////////////////////////////////////
//////////////////////////////////////////////////
//////////////// Asservissement //////////////////
//////////////////////////////////////////////////
if(flag == 1)
{
flagTemp++;
angleCool=getAngle(); //On récupère l'angle
angleConsigne=consigne; //!// permet d'utiliser les signaux mais empeche putty de fonctionner //!//
erAngle=angleConsigne-angleCool; //calcul de l'erreur
erreur_integral=erAngle+erreur_integral;
DAC_conv(erAngle); //conversion analogique de cette erreur
pwm_val=(erAngle*Kp)+(erreur_integral*Ki)+0.5; //calcul du PWM pour asservissement
modulation_pwm(pwm_val); //PWM sorti sur les pins
consigne = signalCarre(consigne,flagTemp); //mettre consigne = 50
//consigne = signalTriangle(consigne,flagTemp); //mettre consigne = 0
flag = 0;
}
///////////////////////////////////////////////////
///////////////////////////////////////////////////
/////////// calcul jusqu'à 1 seconde //////////////
///////////////////////////////////////////////////
if(flagTemp > 100)
{
flagTemp=0;
}
///////////////////////////////////////////////////
}
}
void modulation_pwm(float alpha)
{
uint16 value = alpha*PERIODE;
PWM_1_WriteCompare1(value);
PWM_1_WriteCompare2(value);
}
float getAngle(void)
{
uint16 counter=QuadDec_1_GetCounter();
float angle = counter*0.144; //0.144 = 360/2500
return angle;
}
void DAC_conv(float erreur)
{
int ampli=1; //permet d'amplifier si lerreur nest pas observable
//erreur=abs(erreur);
if(erreur > 180)
{
erreur=180.0;
}
if(erreur < -180)
{
erreur = -180.0;
}
int erreur_set=(int)(erreur*ampli*0.71111111); //0.71111 = 255/360 +180 deg -> à 0 deg = +2V
VDAC8_1_SetValue(erreur_set+127);
}
int signalCarre(int consigne,int flagTemp) //signal carre allant de 50 à -50
{
if(flagTemp == 100)
{
consigne = -consigne;
};
return consigne;
}
int signalTriangle(int consigne,int flagTemp) //signal triangle allant de 0 à 100
{
if(flagTemp > 0 && flagTemp <= 50)
{
consigne=consigne+4;
}
if(flagTemp > 50 && flagTemp <= 100)
{
consigne=consigne-4;
}
return consigne;
}
int acquerir_position(void)
{
int position=0;
position=ADC_SAR_1_GetResult16(); //On récupère l'angle à 0
if(position == 1854)
{
return 1;
}
else
{
return 0;
}
}
/* [] END OF FILE */