10
Examen Final Procesadores Digitales de Señales Problema 1 Problema 1 Problema 1 Problema 1 Proyectar un sistema de control de temperatura de un líquido si tenemos un sensor de temperatura que entrega un voltaje de 0 – 8 voltios que equivale de 0 – 150 °C, y se controla el actuador con una señal de PWM. La temperatura se debe medir con la entrada analógica ADC5, generar el tiempo de muestreo con el timer 4 y el PWM con el timer 1. El controlador del sistema hacer con la entrada digital B3 y con B4 activar un led de encendido. (8 puntos) Solución: Diagrama de flujo de funcionamiento del sistema:

Examen Final Procesadores Digitales de señales

Embed Size (px)

Citation preview

Examen Final Procesadores Digitales de

Señales Problema 1Problema 1Problema 1Problema 1

Proyectar un sistema de control de temperatura de un líquido si tenemos un sensor de temperatura que entrega un voltaje de 0 – 8 voltios que equivale de 0 – 150 °C, y se controla el actuador con una señal de PWM. La temperatura se debe medir con la entrada analógica ADC5, generar el tiempo de muestreo con el timer 4 y el PWM con el timer 1. El controlador del sistema hacer con la entrada digital B3 y con B4 activar

un led de encendido. (8 puntos)

Solución:

• Diagrama de flujo de funcionamiento del sistema:

• Seleccione las entradas y salidas necesarias del DSP y hacer el diagrama de conexión de los dispositivos electrónicos.

Señales de la planta:

Item Descripción Código Tipo DSP

1 Señal On/Off SON/OFF Digital/Entrada GPIOB3 2 Indicador de encendido LON/OFF Digital/Salida GPIOB4 3 Señal de la salida de la planta y Analógico/Entrada ADCIN5 4 Señal de Control u PWM/Salida T1PWM_T1CMP

Diseño Electrónico de la planta:

• Diagrama de flujo del programa con las señales de DSP.

INICIO

Iniciar Timer 1

Iniciar Timer 4

Configurar Registros

Habilitar

interrupciones

SON/OFF=1

Si

No

SON/OFF=0

Detener Timer 1

Detener Timer4

Interrupcion Timer 4

Leer Señal «y» ADCIN 5

Calcular Señal de error

Error = ref- y

Guardar error anterior

errorant=Error

Calcular derivada e integral del error

Derror=(Error-errorant)/T

Ierror=Ierror+T*(Error+errorant)/2

Calcular señal de control

U=Kp*Error+Kd*Derror+Ki*Ierror

Saturar la señal de error a un maximo

del registro de periodo del timer 1

Generar PWM con :

T1CMP=U

FIN

• Programa para el DSP en C.

#include "DSP281x_Device.h"

#include "DSP281x_Examples.h"

unsigned int Ref;

unsigned int y;

int e=0; // Error

int eant=0; // Error Anterior

float de=0; // Derivada del error

float ie=0; // Integral del error

const T=0.0005 // Tiempo de muestreo = 500 uS

const kp=10;

const ki=8;

const kd=3;

void iniciar_timer1();

void iniciar_timer4();

void iniciar_conversor_AD();

interrupt void interrupcion_timer4_muestreo();

void main()

{

DINT;

DRTM; InitSysCtrl();

InitPieCtrl();

IER = 0x0000; // Deshabilitamos interrupciones

IFR = 0x0000; // Ponemos todos los flag a 0

InitPieVectTable(); // Inicia la tabla de interrupciones

EALLOW;

PieVectTable.T4PINT = &interrupcion_timer4_muestreo; ////////////////////////////CONFIGURACION DE PUERTOS////////////////////////////

GpioMuxRegs.GPBMUX.bit.PWM10_GPIOAB3 = 0; // GPIOA0 como I/O

GpioMuxRegs.GPBMUX.bit.PWM11_GPIOAB4= 0; // GPIOA1 como I/O

GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6 = 1; // GPIOA6 como PWM

GpioMuxRegs.GPBDIR.bit.GPIOB3 = 0; // GPIOB3 como Entrada

GpioMuxRegs.GPBDIR.bit.GPIOB4 = 1; // GPIOB4 como Salida ////////////////////////////////////////////////////////////////////////////////

EDIS;

PieCtrlRegs.PIEIER5.all = M_INT1; // Habilitamos las interrupciones T5PINT IER = IER | M_INT5;

EINT;

ERTM;

while(1){ while(GpioDataRegs.GPADAT.bit.GPIOA0==0){

GpioDataRegs.GPADAT.bit.GPIOA1=0; // Led de encendido está apagado

}

iniciar_timer1();

iniciar_timer2();

iniciar_conversor_AD();

while(GpioDataRegs.GPADAT.bit.GPIOA0==1){ // mientras que el switch permanece encendido GpioDataRegs.GPADAT.bit.GpioA1=1; // Led de encendido esta prendido

}

EvaRegs.T1CON.bit.TMODE=0; // Si se apaga el switch de encendido

EvbRegs.T4CON.bit.TMODE=0; // Detenemos los timers (Modo hold)

}

/////////////CONFIGURACION DE REGISTROS PARA INICIAR LOS TIMER//////////////////

// TIMER 1: GENERAR PWM

// TIMER 4: TEMPORIZADOR PARA LA CONVERSION ANALOGA DIGITAL

// FUNCION PARA INICIAR TIMER 1:

void iniciar_timer1(){

EvaRegs.T1PR = 0xFFFF; // Se configura el registro de periodo 10Khz

EvaRegs.T1CMPR = 0xFFFF; // Iniciamos con una comparacion

EvaRegs.T1CNT = 0x0000; // Se reinicia el contador a 0 EvaRegs.T1CON.all = 0x9702; //(75MHz/4)

asm(" nop");

asm(" nop");

EvaRegs.T1CON.all = 0x9742;

EvaRegs.EXTCONA.all = 0x0001;

} // FUNCION PARA INICIAR TIMER 4:

void iniciar_timer4(){

EvbRegs.T4PR = 0xFFFF; // Registro de periodo para configurar el tiempo de muestreo

EvbRegs.EVBIMRB.bit.T4PINT = 1; // Se habilita la interrupción del Timer4 por periodo

EvbRegs.EVBIFRB.bit.T4PINT = 1; // Se resetea el flag de la interrupcion Timer4 por periodo

EvbRegs.T4CNT = 0x0000; // Se reinicia el contador a 0

EvbRegs.T4CON.all = 0x9702; //(75MHz/4)

asm(" nop"); asm(" nop");

EvbRegs.T4CON.all = 0x9742;

EvbRegs.GPTCONB.all = 0x007A;

EvbRegs.GPTCONB.bit.T4TOADC = 2; // El flag de la interrupcion por periodo T4PER inicia la conversion ADC

EvbRegs.GPTCONB.bit.T4PIN =2; // Tipo activo alto

}

//////////////CONFIGURACION DE REGISTROS PARA INICIAR CONVERSION AD/////////////

void iniciar_conversor_AD()

{

AdcRegs.ADCTRL1.bit.RESET = 1; // Se reinicia el ADC (recomendable)

asm(" nop");

asm(" nop");

AdcRegs.ADCTRL1.bit.ACQ_PS = 15; // Preescalador para el tiempo de toma de datos del ADC

AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; // Divisor del reloj del ADC AdcRegs.ADCTRL3.bit.ADCBGRFDN = 3; // Habilitamos el circuito interno de bandgap y referencia AdcRegs.ADCTRL3.bit.ADCEXTREF = 0; // Referencia Interna 0-3.3V

DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L); // Tiempo de espera mientras

se habilita

AdcRegs.ADCTRL3.bit.ADCPWDN = 1; // Encendemos toda la circuiteria interna del conversor AD

DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L); // Tiempo de espera antes de la

primera conversion

AdcRegs.ADCTRL1.bit.RESET = 1; // Se vuelve a reiniciar el conversor AD

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // Modo cascada

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5; // Primero convertir ADC5

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 1; // Maximo 2 conversiones simultaneas (Solo se convertira una vez)

AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Configura para que vuelva a realizar las conversiones una vez que termine con

todas las del secuenciador

AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // Se inicia la conversion analoga digital (En el secuenciador 1)

}

/////////////////////INTERRUPCION TIMER4 PERIODO (MUESTREO)/////////////////////////// interrupt void interrupcion_timer4_muestreo()

{

y = AdcRegs.ADCRESULT0>>4; //obteniendo la salida de la planta

eant=e; // guardando señal de error anterior

e = Ref - y; // Calculando la señal del error

de = (e – ea)/T; // Calculando derivada del error

ie = ie+T*(e+ea)/2; // Calculando integral del error u= kp*e+kd*de+ki*ie; // Calculando la señal de control

if(u>EvaRegs.T1PR) u=EvaRegs.T1PR // Saturador en caso de que la señal sea mayor al registro de periodo

EvaRegs.T1CMPR = u; // Registro de comparación igual a la señal de control

EvbRegs.EVBIMRB.bit.T4PINT = 1; // Se habilita la interrupcion EvbRegs.EVBIFRB.bit.T4PINT = 1; // Se resetea el flag de la interrupcion PieCtrlRegs.PIEACK.all = PIEACK_GROUP5;

}

Problema Problema Problema Problema 2222

Hacer un programa que genere PWMs dobles con los PWM 7, 8, 9, 10, 11, 12 con una zona muerta de 12.

(4 puntos)

Solución:

#include "DSP281x_Device.h"

#include "DSP281x_Examples.h"

void iniciar_timer3();

void main()

{

DINT;

DRTM;

InitSysCtrl();

InitPieCtrl();

IER = 0x0000; // Deshabilitamos interrupciones IFR = 0x0000; // Ponemos todos los flag a 0

InitPieVectTable(); // Inicia la tabla de interrupciones

EALLOW; ////////////////////////////CONFIGURACION DE PUERTOS////////////////////////////

GpioMuxRegs.GPBMUX.bit.PWM7_GPIOB0=1; // Pines de las 6 llaves de PWM7-12

GpioMuxRegs.GPBMUX.bit.PWM8_GPIOB1 =1;

GpioMuxRegs.GPBMUX.bit.PWM9_GPIOB2 =1;

GpioMuxRegs.GPBMUX.bit.PWM10_GPIOB3 =1;

GpioMuxRegs.GPBMUX.bit.PWM11_GPIOB4 =1;

GpioMuxRegs.GPBMUX.bit.PWM12_GPIOB5 =1;

//////////////////////////////////////////////////////////////////////////////// EDIS;

iniciar_timer3(); // Iniciamos timer 1 para generar PWM

EINT;

ERTM;

}

/////////////CONFIGURACION DE REGISTROS PARA INICIAR LOS TIMER////////////////// // TIMER 3: GENERAR PWM Dobles

// FUNCION PARA INICIAR TIMER 3:

void iniciar_timer3(){

EvbRegs.T3PR = 0xFFFF; // Se configura el registro de periodo 10Khz

EvbRegs.CMPR4=0x8080;

EvbRegs.CMPR5=0x0880;

EvbRegs.CMPR6=0x0080; EvbRegs.T3CNT = 0x0000; // Se reinicia el contador a 0 EvbRegs.T3CON.all = 0x9702; //(75MHz/4)

asm(" nop");

asm(" nop");

EvbRegs.T3CON.all = 0x9742;

EvbRegs.EXTCONB.all = 0x0000;

EvbRegs.COMCONB.bit.CENABLE=1; //Habilita la comparacion

EvbRegs.COMCONB.bit.SVENABLE=2; //Habilita el modo vector de PWM EvbRegs.COMCONB.bit.ACTRLD=2;

EvbRegs.COMCONB.bit.FCOMPOE=1; //Habilitar el modo Full compare

EvbRegs.COMCONB.bit.FCMP4OE=1; //Habilitar los full compare

EvbRegs.COMCONB.bit.FCMP5OE=1;

EvbRegs.COMCONB.bit.FCMP6OE=1;

EvbRegs.ACTRB.bit.CMP7ACT=1; //Activo Bajo EvbRegs.ACTRB.bit.CMP8ACT=2; //Activo Alto

EvbRegs.ACTRB.bit.CMP9ACT=2;

EvbRegs.ACTRB.bit.CMP10ACT=1;

EvbRegs.ACTRB.bit.CMP11ACT=1;

EvbRegs.ACTRB.bit.CMP12ACT=2;

EvbRegs.DBTCONB.bit.DBT=12; // Periodo de los timers de banda muerta de 4 bits

EvbRegs.DBTCONB.bit.EDBT1=1; // Habilitar timer de banda muerta 1 (PWM 7 y 8 de la unidad de comparación 1) EvbRegs.DBTCONB.bit.EDBT2=1; // Habilitar timer de banda muerta 2 (PWM 9 y 10 de la unidad de comparación 2) EvbRegs.DBTCONB.bit.EDBT3=1; // Habilitar timer de banda muerta 3 (PWM 11 y 12 de la unidad de comparación 3)

EvbRegs.DBTCONB.bit.DBTPS=5; // Preescalador 1/32 de los timer de banda muerta

}

Problema Problema Problema Problema 3333

Hacer el programa para configurar el ADC para que convierta en modo continuo las entradas ADC2, ADC5,

ADC8, ADC12, ADC3 en el orden indicado. (4 puntos)

Solución:

#include "DSP281x_Device.h"

#include "DSP281x_Examples.h"

void iniciar_ADC() ;

void main()

{

DINT;

DRTM;

InitSysCtrl();

InitPieCtrl(); IER = 0x0000; // Deshabilitamos interrupciones

IFR = 0x0000; // Ponemos todos los flag a 0 InitPieVectTable();

EALLOW;

EDIS;

iniciar_ADC(); // Iniciamos el módulo ADC

EINT; ERTM;

}

void iniciar_ADC()

{

AdcRegs.ADCTRL1.bit.RESET = 1; // Se reinicia el ADC (recomendable)

asm(" nop");

asm(" nop");

AdcRegs.ADCTRL1.bit.ACQ_PS = 15; // Preescalador para el tiempo de toma de datos del ADC AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; // Divisor del reloj del ADC

AdcRegs.ADCTRL3.bit.ADCBGRFDN = 3; // Habilitamos el circuito interno de bandgap y referencia

AdcRegs.ADCTRL3.bit.ADCEXTREF = 0; // Referencia Interna 0-3.3V

DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L); // Tiempo de espera mientras

se habilita

AdcRegs.ADCTRL3.bit.ADCPWDN = 1; // Encendemos toda la circuiteria interna del conversor AD

DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L); // Tiempo de espera antes de la

primera conversion

AdcRegs.ADCTRL1.bit.RESET = 1; // Se vuelve a reiniciar el conversor AD AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // Modo cascada

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // Primero convertir ADC2

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5; // luego convertir ADC5

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x8; // luego convertir ADC8

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0xC; // luego convertir ADC12

// Solo 4 conversiones por registro por eso a la siguiente se cambia al registro ADCCHELSEQ2

AdcRegs.ADCCHSELSEQ2.bit.CONV00 = 0x3; // finalmente convertir ADC3

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 4; // Maximo 5 conversiones simultaneas (Solo se convertira una vez)

AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Configura para que vuelva a realizar las conversiones una vez que termine con

todas las del secuenciador

AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // Se inicia la conversion analoga digital (En el secuenciador 1)

}

Problema Problema Problema Problema 4444

Hacer un programa para atender una interrupción de la función de comparación simple del timer 3, definir

la función de atención de interrupción. (4 puntos)

Solución:

#include "DSP281x_Device.h"

#include "DSP281x_Examples.h"

void iniciar_timer3();

interrupt void interrupcion_timer3_comparacion();

void main()

{ DINT;

DRTM;

InitSysCtrl();

InitPieCtrl();

IER = 0x0000; // Deshabilitamos interrupciones IFR = 0x0000; // Ponemos todos los flag a 0

InitPieVectTable(); // Inicia la tabla de interrupciones EALLOW;

PieVectTable.T3CINT = &interrupcion_timer3_comparacion;

////////////////////////////CONFIGURACION DE PUERTOS////////////////////////////

////////////////////////////////////////////////////////////////////////////////

EDIS;

PieCtrlRegs.PIEIER4.all = M_INT5; // Habilitamos las interrupciones T3CINT

IER = IER | M_INT4; iniciar_timer3(); // Iniciamos timer 3

EINT;

ERTM;

}

void iniciar_timer3(){

EvbRegs.T3PR = 0xFFFF; // Se configura el registro de periodo 10Khz

EvbRegs.T3CMPR= 0x7FFF; // Se inicia el registro de comparación

EvbRegs.EVBIMRA.bit.T3CINT= 1; EvbRegs.EVBIFRA.bit.T3CINT=1;

EvbRegs.T3CNT = 0x0000; // Se reinicia el contador a 0

EvbRegs.T3CON.all = 0x9702; //(75MHz/4)

asm(" nop");

asm(" nop");

EvbRegs.T3CON.all = 0x9742;

EvbRegs.GPTCONB.all = 0x007A;

EvbRegs.GPTCONB.bit.T3PIN =2; // Tipo activo alto }

// FUNCION PARA INICIAR TIMER 3:

interrupt void interrupcion_timer3_comparacion()

{

// AQUÍ SE ATIENDE LA INTERRUPCION

EvbRegs.EVBIMRA.bit.T3CINT = 1; // Se habilita la interrupcion

EvbRegs.EVBIFRA.bit.T3CINT = 1; // Se resetea el flag de la interrupcion

PieCtrlRegs.PIEACK.all = PIEACK_GROUP4; }