Sie sind auf Seite 1von 10

Examen Final Procesadores Digitales de Seales

Problema 1
Proyectar un sistema de control de temperatura de un lquido 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 seal de PWM. La temperatura se debe medir con la entrada analgica 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) Solucin:

Diagrama de flujo de funcionamiento del sistema:

Seleccione las entradas y salidas necesarias del DSP y hacer el diagrama de conexin de los dispositivos electrnicos.

Seales de la planta: Item 1 2 3 4 Descripcin Seal On/Off Indicador de encendido Seal de la salida de la planta Seal de Control Cdigo SON/OFF LON/OFF y u Tipo Digital/Entrada Digital/Salida Analgico/Entrada PWM/Salida DSP GPIOB3 GPIOB4 ADCIN5 T1PWM_T1CMP

Diseo Electrnico de la planta:

Diagrama de flujo del programa con las seales de DSP.

INICIO

Interrupcion Timer 4

Configurar Registros Habilitar interrupciones No

Leer Seal y ADCIN 5

Guardar error anterior errorant=Error

SON/OFF=1 Calcular Seal de error Error = ref- y Si Iniciar Timer 1 Iniciar Timer 4 Calcular derivada e integral del error Derror=(Error-errorant)/T Ierror=Ierror+T*(Error+errorant)/2

SON/OFF=0

Calcular seal de control U=Kp*Error+Kd*Derror+Ki*Ierror

Detener Timer 1 Detener Timer4

Saturar la seal 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 // Se reinicia el contador a 0 EvaRegs.T1CNT = 0x0000; 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 interrupcin del Timer4 por periodo EvbRegs.EVBIFRB.bit.T4PINT = 1; // Se resetea el flag de la interrupcion Timer4 por periodo // Se reinicia el contador a 0 EvbRegs.T4CNT = 0x0000; 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() { //obteniendo la salida de la planta y = AdcRegs.ADCRESULT0>>4; eant=e; // guardando seal de error anterior e = Ref - y; // Calculando la seal 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 seal de control if(u>EvaRegs.T1PR) u=EvaRegs.T1PR // Saturador en caso de que la seal sea mayor al registro de periodo EvaRegs.T1CMPR = u; // Registro de comparacin igual a la seal 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 2
Hacer un programa que genere PWMs dobles con los PWM 7, 8, 9, 10, 11, 12 con una zona muerta de 12. (4 puntos) Solucin:
#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 comparacin 1) EvbRegs.DBTCONB.bit.EDBT2=1; // Habilitar timer de banda muerta 2 (PWM 9 y 10 de la unidad de comparacin 2) EvbRegs.DBTCONB.bit.EDBT3=1; // Habilitar timer de banda muerta 3 (PWM 11 y 12 de la unidad de comparacin 3) EvbRegs.DBTCONB.bit.DBTPS=5; // Preescalador 1/32 de los timer de banda muerta }

Problema 3
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) Solucin:
#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 mdulo 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 // Se inicia la conversion analoga digital (En el secuenciador 1) AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; }

Problema 4
Hacer un programa para atender una interrupcin de la funcin de comparacin simple del timer 3, definir la funcin de atencin de interrupcin. (4 puntos) Solucin:
#include "DSP281x_Device.h" #include "DSP281x_Examples.h" void iniciar_timer3(); interrupt void interrupcion_timer3_comparacion(); void main() { DINT; DRTM; InitSysCtrl(); InitPieCtrl(); // Deshabilitamos interrupciones IER = 0x0000; 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 comparacin 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; }

Das könnte Ihnen auch gefallen