Other Parts Discussed in Thread: TM4C123GH6PM
Tool/software: Code Composer Studio
Hello,
I've never wrote something in here but, since I did not find problems related to mine, it is good give it a try
My code has two problems:
-I could not set a harware interruption for ADC
-I could not set a timer 1B interruption by overflow with ADC TRIGGER PROCESSOR
-I could not generate two different PWM signs on my tiva even with diffrent bases and generators
What I intended to do is only modify this code for PWM 1 kHz and ADC 100kHz
But when I get ADC and PWM working, both are in same frequency.
MY CODE IS BELOW:
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/tm4c123gh6pm.h" // definiçõoes para interrupções e atribuições deregistradores. //
#include "driverlib/sysctl.h"
#include "inc/hw_types.h" // definem tipos comuns e macros //
#include "driverlib/interrupt.h"
#include "driverlib/timer.h"
#include "driverlib/gpio.h"
#include "driverlib/debug.h"
#include "driverlib/pwm.h"
#include "driverlib/rom.h"
//#include "inc/hw_ints.h"
#include "driverlib/pin_map.h"
#include "inc/hw_gpio.h"
#include "driverlib/adc.h"
#include "driverlib/fpu.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "inc/hw_timer.h"
#include "math.h"
#include <stdlib.h>
#include "driverlib/comp.h"
#ifdef DEBUG
void __error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
#define PWM_FREQUENCY 1000
#define ADC_FREQUENCY 96000 //equivalente a tempo de amostra de 100 kHz
#define vetor_serie 180
#define n_R 20
#define r0_R 0.855
#define i0_R 0.35
#define v0_R 1.8
#define kv_R -724.64 // =1/kvR kvR=-0.00138
#define f0_R 0.425
#define c0_R 1.0602
#define c1_R -0.00174
#define d0_R 0.0577
#define d1_R 2.623
#define t0 25
#define n_B 8
#define r0_B 0.352
#define i0_B 0.35
#define f0_B 0.69
#define v0_B 2.75
#define kv_B -667.11 // =1/kvB kvB=-0.001499
//#define f0_B 0.635
//#define f0_B 0.6055
#define c0_B 1.028
#define c1_B -0.0009
#define d0_B 0.2375
#define d1_B 2.0732
#define kiz_R 0.01872 //proj 4
#define kiz_B 0.1546 //proj 4
//diminuindo o Ki, aumenta a margem de fase e deixa a resposta mais lenta
//dados Pedro Almeida
/*#define v0_R 1.792
#define kv_R -0.001347
#define f0_R 0.425
#define c0_R 1.068
#define c1_R -0.001834
#define d0_R 0.062
#define d1_R 2.623*/
/*#define v0_B 2.715
#define kv_B 693.96 // 1/-0.001441
#define c0_B 1.03
#define c1_B -0.000899
#define d0_B 0.249
#define d1_B 2.072*/
int flagteste=0;
uint32_t ab=0;
float duty = 500;
float duty1 = 500;
int flag_R=0;
int flag_B=0;
int flag_canal=0;
int flag_fluxo=0;
int flag_red=2;
char a;
int flag_menu=0;
int status=0;
float e_R=0; //erro
float e_B=0;
float e_ant_R=0; //valor de erro anterior
float e_ant_B=0;
int flag_c0=0;
int flag_etapa=0;
int cont=0;
float flux_Bserie[vetor_serie];
float flux_Rserie[vetor_serie];
int pace=0;
uint32_t n=0;
int cont_pwm=0;
uint32_t ADC[4]; // vetor criado para armazenar os dados lidos do ADC
uint32_t ADC1[4];
uint32_t ui32Load=0;
uint32_t ui32Load1=0;
uint32_t ui32Load2=0;
uint32_t ui32Load3=0;
uint32_t ADC_iR; // variável utilizada para armazenar a média dos valores lidos
uint32_t ADC_vR;
uint32_t ADC_vB;
uint32_t ADC_iB;
uint32_t timer_cont=0;
uint32_t timer_load=0;
uint32_t flagcontagem=0;
uint32_t ui32Period=0;
uint32_t ui32Period1=0;
int flag_duty1=0;
int flag_duty=0;
char flux_vetor[256];
int i=0;
int flux=0;
int freq = 8000; //freq do timer
float flux_R=0;
float flux_B=0;
float flux_max_R=n_R*f0_R*(d0_R+d1_R)*0.01;
float flux_max_B=n_B*f0_B*(d0_B+d1_B)*0.01; //multiplicado para colocarreferência de 0 a 100%
float i_R=0;
float v_R=0;
float i_B=0;
float i_B_controle=0;
float i_R_controle=0;
float v_B=0;
float tj_est_R=0;
float tj_est_B=0;
float tj_est_B_c=0;
float flux_est_R=0;
float flux_est_B=0;
float flux_est_B_cont=0;
float flux_est_R_cont=0;
float il_ref_R=0;
float il_ref_B=0;
float il_ref_R_ant=0;
float il_ref_B_ant=0;
//otimzação de calculo do estimador
float o_R1 = kv_R/n_R;
float o_R2 = r0_R*kv_R;
float o_R3 = (v0_R*kv_R)+t0;
float o_R4 = n_R*f0_R*d0_R;
float o_R5 = n_R*f0_R*d1_R;
float o_B1 = kv_B/n_B;
float o_B2 = r0_B*kv_B;
float o_B3 = (v0_B*kv_B)+t0;
float o_B4 = n_B*f0_B*d0_B;
float o_B5 = n_B*f0_B*d1_B;
/*
--------------------------------------------------------------------------------
------------------------------------ */
/* ----- MAIN FUNCTION - void main -----
*/
/*
--------------------------------------------------------------------------------
------------------------------------ */
int main(void)
{
/*
--------------------------------------------------------------------------------
-------------------------------- */
// MCU settings
/*
--------------------------------------------------------------------------------
-------------------------------- */
//Enable System clock at 80 Mhz with a PLL, with crystal 16Mhz (PLL = 200MHz, Clock = PLL/div)
SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
ab= SysCtlClockGet();
// Enable FPU
FPUEnable();
// Configure FPU
FPULazyStackingEnable();
FPUStackingEnable();
FPUHalfPrecisionModeSet(FPU_HALF_IEEE);
//Configuração de periféricos
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
//SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
//Habilitação de Interrupção
IntMasterEnable();
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//Inicialização PINOS
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;
//GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
//Habilitação do Clock TIMER --------------------------------------
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); //Configura o timer 0 em 32 bits no modo periódico //
ui32Period = (SysCtlClockGet() / freq); //Para Timer de 1 Hz
TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period - 1); // é necessário subtrair 1 para interrupção dispare em zero counts //
TimerEnable(TIMER0_BASE, TIMER_A); // Habilita o timer. Este comando inicia o timer e as interrupções irão ocorrer nos timeouts. // //
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
//SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC); //Configura o timer 0 em 32 bits no modo periódico //
ui32Period1 = (SysCtlClockGet() / ADC_FREQUENCY); //Para Timer de 1 Hz
TimerLoadSet(TIMER1_BASE, TIMER_B, ui32Period1 - 1); // é necessário subtrair 1 para interrupção dispare em zero counts //
IntEnable(INT_TIMER1B);
TimerEnable(TIMER1_BASE, TIMER_B); // Habilita o timer. Este comando inicia o timer e as interrupções irão ocorrer nos timeouts. // //
TimerIntClear(TIMER1_BASE, TIMER_TIMB_TIMEOUT);
//PWM
SysCtlPWMClockSet(SYSCTL_PWMDIV_16); //clock do processador 80 Mhz
GPIOPinConfigure(GPIO_PD0_M0PWM6); //config o base PWM0 gen 3
GPIOPinConfigure(GPIO_PD1_M1PWM1); //config o base PWM1 gen 1
GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1); //habilita saida do pwm como D0 e D1
ui32Load2 = (SysCtlClockGet() / (16*PWM_FREQUENCY ))-1;
PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN); // Definição do tipo de PWM usado
PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, ui32Load2);
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, duty);
PWMGenEnable(PWM0_BASE, PWM_GEN_3);
PWMOutputState(PWM0_BASE, PWM_OUT_6_BIT, true);
PWMIntEnable(PWM0_BASE, PWM_INT_GEN_3);
IntEnable(INT_PWM0_3);
PWMGenIntTrigEnable(PWM0_BASE,PWM_GEN_3,PWM_INT_CNT_LOAD);
ui32Load1 = (SysCtlClockGet() / (16*ADC_FREQUENCY))-1;
PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN); // Definição do tipo de PWM usado
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, ui32Load3);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_1, duty1);
PWMGenEnable(PWM1_BASE, PWM_GEN_0);
PWMOutputState(PWM1_BASE, PWM_OUT_1_BIT, true);
PWMGenEnable(PWM1_BASE, PWM_GEN_0);
PWMIntEnable(PWM1_BASE, PWM_INT_GEN_0);
IntEnable(INT_PWM1_0);
PWMGenIntTrigEnable(PWM1_BASE,PWM_GEN_0,PWM_INT_CNT_LOAD);
//Interrupção externa
GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_FALLING_EDGE);
GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_0);
IntEnable(INT_GPIOF);
//Configuração do ADC ----------------------------------------------
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);
ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_TIMER, 0); //#define ADC_TRIGGER_PWM0 0x00000006 // PWM0 event
ADCSequenceConfigure(ADC1_BASE, 2, ADC_TRIGGER_TIMER, 0);
//ADCHardwareOversampleConfigure(ADC0_BASE,64);
//ADCHardwareOversampleConfigure(ADC1_BASE,64);
//GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3); //IR
ADCSequenceStepConfigure(ADC0_BASE, 2, 0, 0);
//GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2); //VR
ADCSequenceStepConfigure(ADC0_BASE, 2, 1, 1 | ADC_CTL_IE | ADC_CTL_END);
//GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1); //VB
ADCSequenceStepConfigure(ADC1_BASE, 2, 0, 2);
//GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0); //IB
ADCSequenceStepConfigure(ADC1_BASE, 2, 1, 3 | ADC_CTL_IE | ADC_CTL_END);
ADCSequenceEnable(ADC0_BASE, 2); // enable sequencer 1 of ADC0
ADCSequenceEnable(ADC1_BASE, 2); // enable sequencer 1 of ADC1
//Habilita configração receptor e transmissor UART
/*GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//Baud Rate e string
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
UARTFIFOEnable(UART0_BASE); //first in first out
IntEnable(INT_UART0);
UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
//para acionamento do LED de interrupção de UART
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);*/
/*UARTStdioInit(0);
UARTCharPut(UART0_BASE, 'P');
UARTCharPut(UART0_BASE, 'r');
UARTCharPut(UART0_BASE, 'e');
UARTCharPut(UART0_BASE, 's');
UARTCharPut(UART0_BASE, 's');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'S');
UARTCharPut(UART0_BASE, 't');
UARTCharPut(UART0_BASE, 'a');
UARTCharPut(UART0_BASE, 'r');
UARTCharPut(UART0_BASE, 't');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, '(');
UARTCharPut(UART0_BASE, 'S');
UARTCharPut(UART0_BASE, 'W');
UARTCharPut(UART0_BASE, '2');
UARTCharPut(UART0_BASE, ')');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 't');
UARTCharPut(UART0_BASE, 'o');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'c');
UARTCharPut(UART0_BASE, 'h');
UARTCharPut(UART0_BASE, 'a');
UARTCharPut(UART0_BASE, 'n');
UARTCharPut(UART0_BASE, 'g');
UARTCharPut(UART0_BASE, 'e');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'F');
UARTCharPut(UART0_BASE, 'l');
UARTCharPut(UART0_BASE, 'u');
UARTCharPut(UART0_BASE, 'x');
UARTCharPut(UART0_BASE, '\n');
UARTprintf("Programa inicializado\n\r");
UARTprintf("Rotina FluxR = 200\n\r");*/
//inicializacao do start
while(1)
{
timer_cont= TimerValueGet(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
timer_load= TimerLoadGet(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
switch (cont)
{
case 1:
{
flux_B=0*flux_max_B;
flux_R=0*flux_max_R;
flag_c0=1;
cont=0; //TIRAR PARA COLOCAR ROTINA NO TEMPO
break;
}
default:
{pace=0;}
}
//PD1=duty1
if(cont_pwm==1)
{
//duty = ((pui32ADC0ValueM1*ui32Load)/4095);
//tratameno de dados ADC
i_R = (ADC_iR-3614.375)*0.0001753;
v_R = ((ADC_vR+2407.759)*0.00884);
v_B = ((ADC_vB+28231.99)*0.0007828);
i_B = ((ADC_iB-3143.428)*0.002754);
//limitadores
if(v_R<0)
{
v_R=0;
}
if(i_R>4)
{
i_R=0;
}
if(v_B<0)
{
v_B=0;
}
if(i_B>4)
{
i_B=0;
}
if(flag_c0==1)
{
//calculo Tj
//tj_est_R = (((v_R/n_R)-(i_R*r0_R)-v0_R)*kv_R)+t0;
tj_est_R = (v_R*o_R1)-(i_R*o_R2)-o_R3; //equação otimizada
//tj_est_B = (((v_B/n_B)-(i_B*r0_B)-v0_B)*kv_B)+t0;
tj_est_B = (v_B*o_B1)-(i_R*o_B2)-o_B3; //equação otimizada
//calculo de Fluxo
//flux_est_R = n_R*f0_R*(d0_R+(d1_R*i_R))*(c0_R+(c1_R*tj_est_R));
flux_est_R =(o_R4+(o_R5*i_R))*(c0_R+(c1_R*tj_est_R));
//flux_est_B = n_B*f0_B*(d0_B+(d1_B*i_B))*(c0_B+(c1_B*tj_est_B));
flux_est_B =(o_B4+(o_B5*i_B))*(c0_B+(c1_B*tj_est_B));
//Integradores
e_R = flux_R-flux_est_R;
il_ref_R = (kiz_R*(e_ant_R + e_R) + il_ref_R_ant); //integrador
e_ant_R = e_R;
il_ref_R_ant = il_ref_R;
e_B = flux_B-flux_est_B;
il_ref_B = (kiz_B*(e_ant_B + e_B) + il_ref_B_ant); //integrador
e_ant_B = e_B;
il_ref_B_ant = il_ref_B;
//Ajuste de PWM
duty1=il_ref_R;
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_1, duty1);
duty=il_ref_B;
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, duty);
//limites
if(duty1>400)
{duty1 = 400;
}
if(duty1<0)
{duty1 = 0;
}
if(duty>400)
{duty = 400;
}
if(duty<0)
{duty = 0;
}
}
cont_pwm=0;
}
//PD0=duty
}
}
extern void PWMInttHandler(void)
{
//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,0xFF);
flag_duty1=1;
PWMGenIntClear(PWM1_BASE,PWM_GEN_0,PWM_INT_CNT_LOAD);
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, duty);
cont_pwm=1;
//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,0x00);
}
extern void PWMIntHandler(void)
{
//PWMPulseWidthSet(PWM1_BASE, PWM_OUT_1, duty1);
PWMGenIntClear(PWM0_BASE,PWM_GEN_3,PWM_INT_CNT_LOAD);
}
void Timer0IntHandler(void) //ESSE TIMER FAZ A CONTAGEM PRA ROTINA DE MUDANÇA DE REFERÊNCIA
{
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
//cont++;
cont=1;
}
void Timer1IntHandler(void) //ESSE TIMER FAZ A CONTAGEM PRA ROTINA DE MUDANÇA DE REFERÊNCIA
{
TimerIntClear(TIMER1_BASE, TIMER_TIMB_TIMEOUT);
//cont++;
//cont=1;
flagteste=2;
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,0xFF);
ADCIntClear(ADC0_BASE, 2);
ADCProcessorTrigger(ADC0_BASE, 2);
ADCSequenceDataGet(ADC0_BASE, 2, ADC);
ADC_iR=(ADC[0]); //E3
ADC_vR=(ADC[1]); //E2
ADCIntClear(ADC1_BASE, 2);
ADCProcessorTrigger(ADC1_BASE, 2);
ADCSequenceDataGet(ADC1_BASE, 2, ADC1);
ADC_vB=(ADC1[0]); //E1
ADC_iB=(ADC1[1]); //E0
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2,0x00);
}
/*void UARTIntHandler(void)
{
uint32_t ui32Status;
ui32Status = UARTIntStatus(UART0_BASE, true); //get interrupt status
UARTIntClear(UART0_BASE, ui32Status); //clear the asserted interrupts
if(flag_menu==2)
{
while(UARTCharsAvail(UART0_BASE)) //loop while there are chars
{
flux_vetor[i]=UARTCharGetNonBlocking(UART0_BASE);
i++;
}
i=0;
flux=atoi(flux_vetor);
if(flux!=0)
{
flag_menu=3;
}
}
else
{
status=UARTCharGet(UART0_BASE);
}
}*/
void InteExtAInttHandler(void)
{
GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_0);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
flag_menu=1;
/*UARTCharPut(UART0_BASE, 'S');
UARTCharPut(UART0_BASE, 'e');
UARTCharPut(UART0_BASE, 'l');
UARTCharPut(UART0_BASE, 'e');
UARTCharPut(UART0_BASE, 'c');
UARTCharPut(UART0_BASE, 't');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'C');
UARTCharPut(UART0_BASE, 'h');
UARTCharPut(UART0_BASE, 'a');
UARTCharPut(UART0_BASE, 'n');
UARTCharPut(UART0_BASE, 'n');
UARTCharPut(UART0_BASE, 'e');
UARTCharPut(UART0_BASE, 'l');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'R');
UARTCharPut(UART0_BASE, 'E');
UARTCharPut(UART0_BASE, 'D');
UARTCharPut(UART0_BASE, '(');
UARTCharPut(UART0_BASE, '1');
UARTCharPut(UART0_BASE, ')');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'o');
UARTCharPut(UART0_BASE, 'r');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'B');
UARTCharPut(UART0_BASE, 'L');
UARTCharPut(UART0_BASE, 'U');
UARTCharPut(UART0_BASE, 'E');
UARTCharPut(UART0_BASE, '(');
UARTCharPut(UART0_BASE, '0');
UARTCharPut(UART0_BASE, ')');
UARTCharPut(UART0_BASE, ':');*/
//SysCtlDelay(SysCtlClockGet() / (1000*3)); //delay ~1 msec
IntEnable(INT_TIMER0A);
}
It is a generic code with other fuction i will return later. Tried so many stuff and probabilly the code is to messy because of it, sorry