//Se genera una señal coseno y se guarda sus DRTM; //deshabilita interrupciones real time valores en salida mode InitSysCtrl(); //inicializa el sistema como #include "DSP281x_Device.h" PLL,clocks,watcgdog #include "DSP281x_Examples.h" InitPieCtrl(); //inicializa el apoyo de #include "math.h" interrupción de periféricos #include "lab1.h" IER = 0x0000; //limpia máscara de float salida[1000]; //variable de salida interrupciones long int k=0; //muestra k IFR = 0x0000; //limpia bandera de float T=0; //periodo de muestreo interrupciones const float pi=3.1415926535897932384; InitPieVectTable(); //inicializa tabla de float w=0; //velocidad angular en rad/seg interrupciones por defecto float t=0; //variable de entrada o tiempo EINT; //habilita interrupciones main(void) ERTM; IniciarSerial(); //Inicialización de los parámetros { del puerto serial A DINT; //deshabilita interrupciones do{ //hacer loop por lo menos una vez DRTM; //deshabilita interrupciones real time IteraSerial(); //Rutina de espera del puerto serial mode }while(1); //Itera infinitamente InitSysCtrl(); //inicializa el sistema como } PLL,clocks,watchdog InitPieCtrl(); //inicializa el apoyo de El programa monitor.c interrupción de periféricos IER = 0x0000; //limpia máscara de #include "stdlib.h" interrupciones #include "DSP281x_Device.h" IFR = 0x0000; //limpia bandera de #include "monitor.h" interrupciones const float mipi=3.14141515; InitPieVectTable(); //inicializa tabla de Uint16 LoopCount; interrupciones por defecto Uint16 SendChar; EINT; //habilita interrupciones Uint16 ReceivedChar; ERTM; void AddrCant(void); T=0.001; //carga el periodo de muestreo =1KHz Uint32 Direccion=0; w=2*pi*10; //carga la velocidad angular int16 *memoria=0; for (k=0;k<1000;k++) Uint32 Cantidad=0; int caso=0; { Uint32 j=0; t=k*T; void IniciarSerial(void) salida[k]=func_coseno(w*t); { }; scia_fifo_init(); // Inicializa el FIFO del SCI } scia_init(); // Inicializa el lazo de iteración float func_coseno(float angulo) SendChar = 0; { } return 100*cos(angulo); void IteraSerial(void) { //dar al DSP la posibilidad de comunicarse con while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { alguna PC mientras esta se encuentra corriendo return; un programa, el archivo que permite esta }; // espera por XRDY =1 comunicación es el monitor.c junto con su ReceivedChar = SciaRegs.SCIRXBUF.all; //se archivo cabecera monitor.h. A través del puerto lee el byte serial se pueden enviar y recibir datos SendChar=ReceivedChar; //se guarda en una variable El programa lab2.c scia_xmit(SendChar); //se retransmite como ECO para que la PC sepa #include "DSP281x_Device.h" caso=ReceivedChar; // se decodifica #include "DSP281x_Examples.h" switch (caso) { // con el CASE #include "lab2.h" case 0: #include "monitor.h" LeerDSP(); // Si el comando es un CERO Leer void main(void) DSP break; recibido a la parte alta case 1: while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { LeerDSP(); } // esperar a XRDY =1 estado listo break; ReceivedChar = SciaRegs.SCIRXBUF.all; case 2: //Leer byte del buffer LeerDSP(); scia_xmit(ReceivedChar); // Enviar ECO break; SendChar = SendChar+ ReceivedChar; // case 3: Agrega parte baja del dato EscribirDSP(); // Si el comando es un TRES memoria[Direccion]=SendChar; // Graba el Escribir DSP valor del dato en memoria break; Direccion++; // Incrementa para la próxima case 4: dirección EscribirDSP(); }; break; } case 5: void scia_init() EscribirDSP(); { break; SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No }; loopback } // No parity,8 char bits, void LeerDSP(void) // modo asíncrono, protocolo idle-line línea en { espera AddrCant(); //Averiguar la Dirección de SciaRegs.SCICCR.bit.SCICHAR = 7; memoria y cuantos datos SciaRegs.SCICTL1.all =0x0003; // Habilitar for (j=0;j<Cantidad+1;j++) TX, RX, SCICLK interno, { // Deshabilitar RX ERR, SLEEP, TXWAKE memoria=0; SciaRegs.SCICTL2.all =0x0003; SendChar=memoria[Direccion]; // Buscar el SciaRegs.SCICTL2.bit.TXINTENA = 0; dato en memoria SciaRegs.SCICTL2.bit.RXBKINTENA =1; Direccion++; SciaRegs.SCIHBAUD =0x0000; do{ SciaRegs.SCILBAUD =0x0028; //a 150mhz while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { SciaRegs.SCICCR.bit.LOOPBKENA =0; // No } // esperar a XRDY =1 estado listo habilitar loop back ReceivedChar = SciaRegs.SCIRXBUF.all; SciaRegs.SCICTL1.all =0x0023; // SCI fuera de //Leer byte del buffer Reset } while (ReceivedChar!=0x40); // Esperar a que } sea el byte 64 void scia_xmit(int a) scia_xmit(SendChar>>8); //Enviar parte alta del { dato SciaRegs.SCITXBUF=a; // Cargar buffer para do{ transmitir while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { } } // esperar a XRDY =1 estado listo ReceivedChar = SciaRegs.SCIRXBUF.all; void scia_fifo_init() } while (ReceivedChar!=0x40); // Esperar a que { sea el byte 64 SciaRegs.SCIFFTX.all=0xE040; scia_xmit(SendChar); //Enviar parte baja del SciaRegs.SCIFFRX.all=0x204f; dato SciaRegs.SCIFFCT.all=0x0; }; } } void EscribirDSP(void) void AddrCant(void) { { AddrCant(); int i=0; for (j=0;j<Cantidad+1;j++) // Preparar la Direccion=0; cantidad de veces ReceivedChar=0; { for (i=0;i<4;i++) while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { { } // esperar a XRDY =1 estado listo while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { ReceivedChar = SciaRegs.SCIRXBUF.all; } // esperar a XRDY =1 estado listo //Leer byte del buffer ReceivedChar = SciaRegs.SCIRXBUF.all; scia_xmit(ReceivedChar); // Enviar ECO //Leer byte del buffer SendChar = ReceivedChar<<8; // Sube el valor scia_xmit(ReceivedChar);// Enviar ECO Direccion=(Direccion<<8)+ReceivedChar; // Ir EALLOW; agregando Dirección GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0 }; =0; // Pines de las 6 llaves de PWM1-6 for (i=0;i<4;i++) GpioMuxRegs.GPAMUX.bit.PWM2_GPIOA1 { =0; while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { GpioMuxRegs.GPAMUX.bit.PWM3_GPIOA2 =0; } // esperar a XRDY =1 estado listo GpioMuxRegs.GPAMUX.bit.PWM4_GPIOA3 ReceivedChar = SciaRegs.SCIRXBUF.all; =0; //Leer byte del buffer GpioMuxRegs.GPAMUX.bit.PWM5_GPIOA4 scia_xmit(ReceivedChar);// Enviar ECO =0; Cantidad=(Cantidad<<8)+ReceivedChar; // Ir GpioMuxRegs.GPAMUX.bit.PWM6_GPIOA5 agregando Cantidad =0; }; } GpioMuxRegs.GPFMUX.bit.MCLKXA_GPIO F8 =0; //Entradas y Salidas GPIO GpioMuxRegs.GPFMUX.bit.MCLKRA_GPIO F9 =0; El pin si en caso fuera una salida, determinando GpioMuxRegs.GPFMUX.bit.MFSXA_GPIOF1 si esta va a estar en estado lógico uno o cero, 0 = 0; esto se logra con cuatro tipo de sentencias GpioMuxRegs.GPFMUX.bit.MFSRA_GPIOF1 1 =0; * GPADAT .- Con 0=estado lógico bajo GpioMuxRegs.GPFMUX.bit.MDXA_GPIOF12 1=estado lógico alto =0; GpioMuxRegs.GPFMUX.bit.MDRA_GPIOF13 * GPASET .- Con 0=no hace nada 1=fuerza el =0; pin al estado lógico alto GpioMuxRegs.GPFMUX.bit.XF_GPIOF14 = 1; // Función primaria, no es IO //Dirección de los pines * GPACLEAR .- Con 0=no hace nada 1=fuerza GpioMuxRegs.GPADIR.bit.GPIOA0 = 1; el pin al estado lógico bajo //Pwm1 salida GpioMuxRegs.GPADIR.bit.GPIOA1 =0; // * GPATOOGLE .- Con 0=no hace nada Pwm2 entrada 1=fuerza el pin a cambiar el estado lógico GpioMuxRegs.GPADIR.bit.GPIOA2 = 1; anterior //Pwm3 salida GpioMuxRegs.GPADIR.bit.GPIOA3 = 1; //Pwm3 salida GpioMuxRegs.GPFDIR.all = 0x000; #include "monitor.h" GpioMuxRegs.GPFDIR.bit.GPIOF8 #include "lab3.h" =0;//MCLKXA entrada long int i,k,l; EDIS; long int retardo=500; //Datos a poner en los pines long int test=0; // Variable para buscar errores GpioDataRegs.GPADAT.bit.GPIOA0 = 1; // void main(void) { Pin de salida en ON DINT; //deshabilita interrupciones GpioDataRegs.GPADAT.bit.GPIOA2 = 1; // DRTM; //deshabilita interrupciones real time Pin de salida en ON mode GpioDataRegs.GPACLEAR.bit.GPIOA3 =1 ; // InitSysCtrl(); //inicializa el sistema como 1 Seria apagar, 0 es no hacer nada PLL,clocks,watcgdog GpioDataRegs.GPATOGGLE.bit.GPIOA0 = 1; InitPieCtrl(); //inicializa el apoyo de // Pin de salida cambiar a OFF interrupción de periféricos InitXintf(); // Inicialización de la interfase de IER = 0x0000; //limpia máscara de salida Memoria Externa (velocidad) interrupciones EINT; IFR = 0x0000; //limpia bandera de ERTM; interrupciones InitPieVectTable(); //inicializa tabla de //XF bandera externa interrupciones por defecto for (i=0;i<2500;i++) //Los retardo son EINT; //habilita interrupciones proporcionales a la velocidad de la memoria ERTM; { //si el programa está instalado en la memoria //Multiplexor de los pines externa (.text) GpioDataRegs.GPATOGGLE.bit.GPIOA0 =1; IniciarSerial(); //Alternar estado del pin GPIOA0 // ADC setup for (k=0;k<retardo;k++){asm(" nop");}; // AdcRegs.ADCTRL1.bit.RESET = 1; bloque de retardo asm(" NOP "); asm(" setc xf"); // prender pin conecto al led asm(" NOP "); rojo AdcRegs.ADCTRL1.bit.ACQ_PS = 15; asm(" nop"); AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; for (k=0;k<retardo/100;k++){asm(" nop"); AdcRegs.ADCTRL3.bit.ADCBGRFDN = 3; }; DSP28x_usDelay(((((long double) 5000L * asm(" clrc xf"); 1000.0L) / (long double)CPU_RATE) - 9.0L) / asm(" nop"); 5.0L); }; AdcRegs.ADCTRL3.bit.ADCPWDN = 1; GpioDataRegs.GPADAT.bit.GPIOA0 =0; //Al DSP28x_usDelay(((((long double) 5000L * terminar dejar pin OFF 1000.0L) / (long double)CPU_RATE) - 9.0L) / botones.all=0; 5.0L); while(1){ //hacer loop por lo menos una vez AdcRegs.ADCTRL1.bit.RESET = 0; IteraSerial(); // Revisar si hay bytes en el puerto AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 serial A Cascada mode test++; // test debería cambiar en cada pasada AdcRegs.ADCCHSELSEQ1.all = 0x0128; // *(long int *)0x100100=test; // La memoria Canal B0 =0x100100 debe cambiar cada vez AdcRegs.ADCCHSELSEQ2.all = 0xABCD; botones.bit.boton0=GpioDataRegs.GPFDAT.bit AdcRegs.ADCCHSELSEQ3.all = 0x9572; .GPIOF8; //Leer pin con boton[0] AdcRegs.ADCCHSELSEQ4.all = 0x4444; botones.bit.boton1=GpioDataRegs.GPFDAT.bit AdcRegs.ADCMAXCONV.bit.MAX_CONV1 .GPIOF9; //Leer pin con boton[1] = 15; botones.bit.boton2=GpioDataRegs.GPFDAT.bit AdcRegs.ADCMAXCONV.bit.MAX_CONV2 .GPIOF10; //Leer pin con boton[2] = 7; // Menor a 7 y solo en modo dual botones.bit.boton3=GpioDataRegs.GPFDAT.bit AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // .GPIOF11; //Leer pin con boton[3] Modo no continuo AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; GpioDataRegs.GPADAT.bit.GPIOA2= //Sugerencia de Texas para arrancar botones.bit.boton0 && botones.bit.boton1; correctamente //GPIOA2=boton0 and boton1 EINT; //habilita interrupciones }; //Itera infinitamente ERTM; } do{ //hacer loop por lo menos una vez IteraSerial(); AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; //Convertidor Análogo digital //Arranque de conversión SOC por SW while(AdcRegs.ADCST.bit.SEQ1_BSY ==1) Laboratorio # 4 {}; //Esperar a que termine ResultadoADC[0]= #include "DSP281x_Device.h" AdcRegs.ADCRESULT0>>4; //Leer resultados #include "DSP281x_Examples.h" ResultadoADC[1]= #include "monitor.h" AdcRegs.ADCRESULT2>>4; long int i,k; }while(1); //Itera infinitamente unsigned int ResultadoADC[16]; } void main(void) { DINT; //deshabilita interrupciones //interrupciones DRTM; //deshabilita interrupciones real time mode #include "DSP281x_Device.h" InitSysCtrl(); //inicializa el sistema como #include "DSP281x_Examples.h" PLL,clocks,watcgdog #include "lab6.h" InitPieCtrl(); //inicializa el apoyo de #include "monitor.h" interrupción de periféricos int ResultadoADC[16]; IER = 0x0000; //limpia máscara de Uint16 fase[1000]; interrupciones int *Source; IFR = 0x0000; //limpia bandera de int *Dest; interrupciones long int i,k,l; InitPieVectTable(); //inicializa tabla de void main(void) { interrupciones por defecto DINT; //deshabilita interrupciones DRTM; //deshabilita interrupciones real time EvaRegs.GPTCONA.bit.T1PIN =2; // activo mode arriba InitSysCtrl(); //inicializa el sistema como EvaRegs.GPTCONA.bit.T1CMPOE =1; // PLL,clocks,watcgdog habilitar las comparaciones InitPieCtrl(); //inicializa el apoyo de EvaRegs.GPTCONA.bit.TCMPOE =1; // interrupción de periféricos habilitar ambos comparadores sistema antiguo IER = 0x0000; //limpia máscara de EvaRegs.EXTCONA.bit.INDCOE=1; // Nueva interrupciones forma sin PDP con CTRIPE IFR = 0x0000; //limpia bandera de EvaRegs.EVAIMRA.bit.PDPINTA = 0; // Ya interrupciones no tripea pero si puede interrumpir InitPieVectTable(); //inicializa tabla de } interrupciones por defecto interrupt void eva_timerT1PER_isr(void) EALLOW; { PieVectTable.T1PINT = k++; // K es un contador que dá el número de &eva_timerT1PER_isr; // Cambia dirección de muestra la isr de T1PER if (k>10000) // Si el T1 está en 10Khz entonces PieVectTable.T1CINT = una vez por segundo &eva_timerT1CMP_isr; // Cambia dirección de { k=0; // cada segundo volver k = 0 la isr de T1CMP if(l<1000) fase[l]=EvaRegs.T1CMPR; //Graba GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA 1000 puntos/segundos de fase T1 6=1; l++; GpioMuxRegs.GPFMUX.bit.XF_GPIOF14 = 1; }; EDIS; EvaRegs.EVAIMRA.bit.T1PINT = 1; // PieCtrlRegs.PIEIER2.all = M_INT4 | M_INT5; Terminó interrupción entonces actualizar // Habilita interrupciones 4 y 5 PIE grupo2 EvaRegs.EVAIFRA.bit.T1PINT = 1; // máscara IER = M_INT2; // Habilita interrupción 2 del y banderas CPU PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; i=0; // contadores a cero //Rehabilitar grupo de donde provino interrupt k=0; } l=0; interrupt void eva_timerT1CMP_isr(void) iniciarADC(); { ini_eva_timer1(); Source= (void *)&AdcRegs.ADCRESULT0; // EINT; Actualiza resultados y los graba ERTM; Dest = ResultadoADC; // en la variable do{ //hacer loop por lo menos una vez ResultadoADC IteraSerial(); for(i=0; i < 16; i++) // con dos punteros Source }while(1); //Itera infinitamente y Dest } *Dest++ = *Source++; void ini_eva_timer1(void) EvaRegs.EVAIMRA.bit.T1CINT = 1; // { Terminó interrupción entonces actualizar EvaRegs.T1PR = 1874; // 10Khz EvaRegs.EVAIFRA.bit.T1CINT = 1; // máscara EvaRegs.T1CMPR = 937; //50% duty cycle y banderas EvaRegs.EVAIMRA.bit.T1PINT = 1; // PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; Habilitar la int Periodo del T1 //Rehabilitar grupo de donde provino interrupt EvaRegs.EVAIFRA.bit.T1PINT = 1; // } Limpiando la bandera void iniciarADC(void) EvaRegs.EVAIMRA.bit.T1CINT = 1; // { Habilitar la int Comparador del T1 // Configuración del ADC: EvaRegs.EVAIFRA.bit.T1CINT = 1; // AdcRegs.ADCTRL1.bit.RESET = 1; Limpiando la bandera asm(" NOP "); EvaRegs.T1CNT = 0x0000; // Contador a cero asm(" NOP "); EvaRegs.T1CON.all = 0x1202; //(75MHz/4) AdcRegs.ADCTRL1.bit.ACQ_PS = 15; asm(" nop"); AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; asm(" nop"); // Arranque de las fuentes EvaRegs.T1CON.all = 0x1242; // Si fuera AdcRegs.ADCTRL3.bit.ADCBGRFDN = 3; 0x9242 el T1 no para en emulación DSP28x_usDelay(((((long double) 5000L * EvaRegs.GPTCONA.bit.T1CTRIPE =0; // No 1000.0L) / (long double)CPU_RATE) - 9.0L) / hacer caso a emergencia T1CTRIP 5.0L); EvaRegs.GPTCONA.bit.T1TOADC = 2; // AdcRegs.ADCTRL3.bit.ADCPWDN = 1; interrupt del T1PER DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L); AdcRegs.ADCTRL1.bit.RESET = 0; AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascaded mode AdcRegs.ADCCHSELSEQ1.all = 0x3210; // Canales a ser leídos AdcRegs.ADCCHSELSEQ2.all = 0x7654; AdcRegs.ADCCHSELSEQ3.all = 0xBA98; AdcRegs.ADCCHSELSEQ4.all = 0xFEDC; AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 15; // Leer 16 canales por cada SOC AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Modo no continuo AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // SOC desde EVA AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; //Sugerencia de Kick Off while(AdcRegs.ADCST.bit.SEQ1_BSY ==1) {}; // esperar a ADC termine Source= (void *)&AdcRegs.ADCRESULT0; // Actualizar primeros datos en Dest = ResultadoADC; // variable ResultadoADC for(i=0; i < 16; i++) *Dest++ = *Source++; }
//activar int ecap
// ECAP module 1 config
ECap1Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE; ECap1Regs.CAP1 = 1200; // Set period value ECap1Regs.CTRPHS = 0; // make eCAP1 reference phase = zero ECap1Regs.ECCTL2.bit.APWMPOL = EC_ACTV_HI; ECap1Regs.ECCTL2.bit.SYNCI_EN = EC_DISABLE; // No sync in for Master ECap1Regs.ECCTL2.bit.SYNCO_SEL = EC_CTR_PRD; // eCAP1 is Master ECap1Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; // Allow TSCTR to run
// ECAP module 2 config ECap2Regs.CAP1 =
1200; // Set period value ECap2Regs.CTRPHS = 800; // Phase offset = 1200-400 = 120 deg ECap2Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE; ECap2Regs.ECCTL2.bit.APWMPOL = EC_ACTV_HI; ECap2Regs.ECCTL2.bit.SYNCI_EN = EC_ENABLE; // slaved off master ECap2Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCI; // sync "flow-through" ECap2Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; // Allow TSCTR to run