excuse me, i want to test this code. But i am beginner in this area. Somebody can help me please. How identificate the diferent pins for out and in signal?.
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/debug.h"
#include "driverlib/pwm.h"
#include "driverlib/pin_map.h"
#include "inc/hw_gpio.h"
#include "driverlib/rom.h"
#include "inc/tm4c123gh6pm.h"
#include "driverlib/adc.h"
#include "driverlib/interrupt.h"
#define PWM_FREQUENCY 500
//#define SET_POINT
uint32_t muestrasPot[4]={0,0,0,0}; //Muestras del potenciometro
bool rflag= false;
int main(void)
{
volatile int32_t SET_POINT;
volatile int32_t integral=0;
volatile int32_t diff=0;
volatile int32_t prop=0;
volatile int32_t sample[2]={0,0};
volatile int32_t PID;
volatile uint32_t ui32Load;
volatile uint32_t ui32PWMClock;
volatile uint32_t output;
SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); //Reloj a 80Mhz
SysCtlPWMClockSet(SYSCTL_PWMDIV_64); //Reloj de PWM con Preescaler de 64
//Habilitamos el reloj a los periféricos a utilizar
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//Configuramos PWM y Salidas Digitales
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3 |GPIO_PIN_1);
GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);
GPIOPinConfigure(GPIO_PD0_M1PWM0);
//Desbloqueamos el PIN D0
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2|GPIO_PIN_5); //PE5, PE2 como pin Analógico
ADCReferenceSet(ADC0_BASE, ADC_REF_INT);
//Se configura que el trigger de ADC lo dispare el PWM-1 generador 0
ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PWM0|ADC_TRIGGER_PWM_MOD1, 0);
ADC0_TSSEL_R=0x10; //Corrije un bug que se encuentra en la librería TIVAWARE 2.01
ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH8);
ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_END); // Aca es donde pueden hacer variar el SET-POINT solamente cambiando de canal y levantando acá la interrupción
ADCSequenceEnable(ADC0_BASE, 1);
//Acá configuramos la frecuencia a utilizar por el módulo de PWM
ui32PWMClock = SysCtlClockGet() / 64;
ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1;
output = ui32Load/2;
//Configuramos el PWM
PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN);
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, ui32Load);
//Hacemos que el PWM1 funcione con el generador 0, además hacemos que dispare un trigger al final de cada periodo.
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, output);
PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT, true);
PWMGenEnable(PWM1_BASE, PWM_GEN_0);
PWMGenIntTrigEnable(PWM1_BASE, PWM_GEN_0, PWM_TR_CNT_ZERO);
//Activamos las interrupciones
ADCIntEnable(ADC0_BASE, 1);
IntEnable(INT_ADC0SS1);
ADCIntClear(ADC0_BASE, 1);
IntMasterEnable();
//Esperamos para evitar un golpe en el sistema
SysCtlDelay(40000);
while(1)
{
if(rflag){
SET_POINT = muestrasPot[1];
sample[1]=SET_POINT-muestrasPot[0];
if(integral < sample[1]){
integral=integral+sample[1]; //Evitamos un desbordamiento del error acumulado
}
diff=sample[1]-sample[0]; //Calculamos el error diferencial
prop=sample[1]; //Calculamos el error proporcional
PID=prop/30+diff/2000-integral/50000;
/*Escribimos nuestra ecuación con PID, recordemos que las variables que acompañan pueden variar
dependiendo del sistema físico. Además pueden ser tanto positivas como negativas, mayores o menores que 1.
Para orientarnos como escogerlas podemos ver las gráficas de PID.
*/
sample[0]=sample[1]; //Llevamos registro del error a una muestra acumulada
if (PID < (-1)){ //Solamente ajustamos la salida acorde a la información obtenida en la variable PID.
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_3,0x08);
output=-PID;
}
else if (PID >= -5 && PID <= 5 )
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_3,0x00);
output=0;
}
else if (PID > (1)){
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_3,0x02);
output=PID;
}
//Evitamos un desbordamiento en la salida
if(output>ui32Load-1)
{
output=ui32Load-1;
}
//Salida
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, output);
//Tenemos que tener en cuenta que acá evitamos que el error se tome más rápido que nuestro muestreo
rflag=~rflag;
}
}
}
void ADCSeq1IntHandler(void)
{
//Toma de la entrada.
ADCIntClear(ADC0_BASE, 1);
ADCSequenceDataGet(ADC0_BASE, 1, muestrasPot);
rflag=true;
}
SOME PICTURES