This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

i have issues with the identification TM4C PIN

Other Parts Discussed in Thread: TM4C123GH6PM
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

  • Hello Pablo.

    Snce you mentioned you are beginner, it would fertile ground to check the Signal Description Section of the Peripherals in the Data Sheet. For dedicated functions the direction would be mentioned as I or O (input or output respectively). For pure GPIO control the API describes it all.

    Regards
    Amit
  • You asked, "How to identify whether a pin is "Input or Output."     As poster Amit directed - the MCU manual & API provide that answer in great detail.

    It proves very difficult to understand and proceed w/these class MCUs w/out making a real commitment to manual & API study.

    In direct answer of your question - most all MCU (general) pins may serve as GPIO - and then may be configured as either Inputs or Outputs.    It's even possible to "switch such GPIO pin between Input & Output!" (1 wire communication is one example of that utility)

    Your (first) drawing shows a motor - insure that you do not directly connect your MCU to the motor.    Special power capable ICs exist which must be placed between the MCU & Motor - your instructor should guide you in this area...    MCUs are famed as the "brain" of control devices - not so much as, "beasts of burden!"

  • Pablo Lopez said:
    PWMGenIntTrigEnable(PWM1_BASE, PWM_GEN_0, PWM_TR_CNT_ZERO);

    You seek to have the PWM Generator trigger the ADC - the last parameter (highlighted above) will not do that.      The parameter, "PWM_TR_CNT_LOAD" will achieve your goal.      Study of the APIs will build your knowledge of correct parameter usage.

    The code you presented is - imho - too advanced for any beginner.      Multiple peripherals are "in play" and "exchange" data.     Hard to imagine (everything) going right - and where does one (begin) to test/troubleshoot?

    KISS is a superior method - works by breaking down the complex into more elemental, basic, building blocks.      You then attack these far smaller parts - one at a time - and (only) after all have been proven - do you attempt to "exhange" data & operations.      Most always this proves far faster - and easier - limiting the scope of battle has long been part of battlefield command - works in this area too!

  • Hello Pablo

    I understand the diagram very well, but as cb1 also mentioned and so did I, the original question still remains unanswered. cb1 has taken it up a notch by posting the default, but without the right questions seldom does the right answer comes out.

    Regards
    Amit
  • Amit Ashara said:
    ...without the right questions seldom does the right answer comes out.

    SO TRUE - so true - as you - beyond all others here, Amit - so well know!

    Yet posters so often are frustrated, bewildered, pressured - know "not" how to (properly) proceed.

    That's why, "Product Guidelines for Posters" was suggested.     

    Has any attempt (ever) been made to "measure" the lost time/effort and costs of the endless (back & forth "teasing") required to extract needed poster data?

    The fact that, "no such measure" exists - does not minimize the, "misspent" time/effort/costs!