INSTITUTO TECNOLÓGICO DE MORELIA MAESTRIA EN CIENCIAS EN INGENIERÍA ELECTRÓNICA ELECTRÓNICA DIGITAL AVANZADA REPORTE 9 “PICCOLO C2000, LECTURA DEL ADC PARA DIFERENTES FRECUENCIAS Y DESPLIEGUE EN MATLAB” NOMBRE: ING. ANTONY MORALES CERVANTES N. C. M06120218 PROFESOR: DR. ARTURO MENDEZ PATIÑO JUNIO DEL 2012 Contenido 1 Descripción ......................................................................................................................................................3 2 Código del programa. ......................................................................................................................................3 2.1 Programa principal. .................................................................................................................................3 3 Programa Matlab .............................................................................................................................................9 4 Conclusiones ..................................................................................................................................................11 2 1 Descripción Se realizó un código para leer datos del ADC de diferentes señales tomadas con un generador de frecuencias, por medio de matlab escoger la frecuencia de muestreo a la que se va a configurar el timer del piccolo y el numero de muestras que se deseen. El código se muestra a continuación: 2 Código del programa. 2.1 Programa principal. En la ¡Error! No se encuentra el origen de la referencia. se muestran las librerías usadas, las funciones y las variables. Asi como también el programa principal, donde se incializa el ADC, el Timer y el Uart, y en el for infinito donde con la función freq_mues() se reciben los datos desde matlab para configurar la frecuencia de muestreo y el numero de muestras, para posteriormente mandar los datos a matlab para graficar los valores leidos del ADC. 3 //Comentarios del programa #include "dsp2802x_device.h" //Funciones e Interrupciones void init_UART0(void); //rutina de inicializacion del puerto UART void Tx_UART(unsigned char Datoo); //rutina para transmision unsigned char Rx_UART (void); //rutina para recepcion void init_ADC(void); //rutina para inicializacion del ADC10 void init_TIMER0(void); //rutina para inicializar el TIMER 0 void grafica(long int a, int cm); void freq_muest(void); //rutina para almacenar el valor de frecuencia y numero de muestras void print_UART(int datto); //rutina para desplegar varibales tipo enteras //variables globales long int resul,freq=60000000; int i,x[200],Recepcion,aux,datRX,nm=100,fm=200; //***********************programa principal************************** int main(void) { init_TIMER0(); init_UART0(); init_ADC(); for (;;) { freq_muest(); fm=aux; // se almacena lo que contiene en la variable auxiliar en fm para la frecuencia de muestreo freq_muest(); nm=aux; // se almacena lo que contiene en la variable auxiliar en nm para la numero de muestreas grafica(fm,nm); //frecuencia y muestras } } //*********************** FIN DEL PROGRAMA PRINCIPAL ******************* Seccion de Código 1. Librerias, variables, funciones y programa principal. 4 En la sección de código 2 se muestra las rutina para la inicializar el Uart, así como para transmitir y para recibir datos. //*******************rutina para inicializar UART************************** void init_UART0(void) { EALLOW; SysCtrlRegs.WDCR=0xE8; SysCtrlRegs.PCLKCR0.bit.SCIAENCLK=1; //habilita el reloj GpioCtrlRegs.GPAMUX2.bit.GPIO28=1; GpioCtrlRegs.GPAMUX2.bit.GPIO29=1; EDIS; SciaRegs.SCICTL1.all=0x03; SciaRegs.SCICCR.all=0x07; SciaRegs.SCIHBAUD=0; SciaRegs.SCILBAUD=194; SciaRegs.SCICTL1.bit.SWRESET=1; } //**************************fin rutina******************************** //****************rutina para transmicion de datos********************* void Tx_UART(unsigned char Datoo) { while(SciaRegs.SCICTL2.bit.TXRDY==0); SciaRegs.SCITXBUF=Datoo; } //**************************fin rutina******************************** //****************rutina para recibir de datos********************* unsigned char Rx_UART (void) { while(SciaRegs.SCIRXST.bit.RXRDY==0);//espera que se reciba un dato return SciaRegs.SCIRXBUF.all; } //**************************fin rutina******************************** Seccion de Código 2. Inicialización de UART, transmición y recepción. 5 En la sección de código 3 se muestran las configuraciones para el Timer0 y el ADC. //rutina para inicializar TIMER0 void init_TIMER0(void) { CpuTimer0Regs.TCR.bit.TSS=1;//SE DETIENE EL TIMER 0 CpuTimer0Regs.TCR.bit.FREE=1;//EN MODO CARRERA LIBRE CpuTimer0Regs.PRD.all = 0x000249F0;// Initialize timer period 200Hz: CpuTimer0Regs.TPR.all = 0; // Initialize pre-scale counter to divide by 1 (SYSCLKOUT): CpuTimer0Regs.TPRH.all = 0; CpuTimer0Regs.TCR.bit.TSS=0;//SE ARRANCA EL TIMER 0 } //******************fin********************************* //*******************inicializacion del ADC*************************** void init_ADC(void) { EALLOW; // habilitar los registro para i/o SysCtrlRegs.PCLKCR0.bit.ADCENCLK=1; //Habilita el reloj del ADC AdcRegs.ADCCTL1.bit.ADCREFSEL=0; //Vref interno del 3.3 AdcRegs.ADCCTL1.bit.ADCPWDN=1; //Desenergizar ADC activo en bajo AdcRegs.ADCCTL1.bit.ADCBGPWD=1; //activo en bajo, deshabilita Vref AdcRegs.ADCCTL1.bit.ADCREFPWD=1; //activo en bajo, buffer parte analogica AdcRegs.ADCCTL1.bit.ADCENABLE=1; //Habilita ADC AdcRegs.ADCSOC0CTL.bit.ACQPS=6; //determina el tiempo que tarda AdcRegs.ADCSOC0CTL.bit.CHSEL=0; //selecciona canal 5 tamperatura sensor AdcRegs.ADCSOC0CTL.bit.TRIGSEL=0; //selecciona la fuente de disparo EDIS; // deshabilitar los registro para i/o } //*****************************fin************************************ Seccion de Código 3. Rutinas del Timer0 y ADC. 6 En la sección de Código 4 se muestra la rutina para mandar los datos leidos del ADC, primero se configura el timer para la frecuencia de muestreo que se le asigne y manda los datos del ADC n veces que se eligio también a través de matlab. Y la rutina con la que se leen los datos desde matlab para escoger los datos de la frecuencia de muestreo y el numero de muestras. //****************rutina mandar y graficar datos********************* void grafica(long int f, int n) { resul=(freq/f); CpuTimer0Regs.TCR.bit.TSS=1; //se detiene el timer CpuTimer0Regs.PRD.all=resul; //se le escribe el numero de cuentas para dar la frecuencia de muestreo pedida CpuTimer0Regs.TCR.bit.TSS=0; //se arranca el timer for(i=0;i<n;i++) { while(CpuTimer0Regs.TCR.bit.TIF==0);//espera que el timer llegue a 0 CpuTimer0Regs.TCR.bit.TIF=1;//limpia la bandera de timer AdcRegs.ADCSOCFRC1.bit.SOC0=1;//arranca la conversión while(AdcRegs.ADCSOCFLG1.bit.SOC0==0){}//espera la conversión AdcRegs.ADCSOCFLG1.bit.SOC0=1;//borra la bandera de fin de conversión x[i]=AdcResult.ADCRESULT0;//carga el resultado } for(i=0;i<n;i++) { print_UART(x[i]); } } //*****************************fin************************************ //****************rutina frecuencia de datos********************* void freq_muest(void) { aux=0; datRX=0; while(datRX!=0x0A) { datRX=Rx_UART(); if ((datRX>=0x30) & (datRX<=0x39)) { aux=(aux*10)+(datRX-0x30); } } } //**************************fin rutina******************************** Seccion de Código 4. Rutina para mandar los datos a graficar y la rutina para leer los datos para la frecuencia de muestreo y el numero de muestras. 7 En la Seccion de Código 5 se muestra la rutina para poder mandar los datos leídos del ADC y los convierte a carácter para enviarlos dato a dato. Convirtiendo primero el dato de los millares, luego las decenas, centenas y unidades. //****************rutina para desplegar varibales tipo enteras**************** void print_UART(int datto) { unsigned char zero, uni, dec, cen, mil; zero = 0; mil = ((datto / 1000) % 10) + 0x30; if(mil != 0x30 || zero == 0) { Tx_UART(mil); zero = 0; } cen = ((datto / 100) % 10) + 0x30; if(cen != 0x30 || zero == 0) { Tx_UART(cen); zero = 0; } dec = ((datto/ 10) % 10) + 0x30; if(dec != 0x30 || zero == 0) { Tx_UART(dec); zero = 0; } uni = (datto % 10) + 0x30; Tx_UART(uni); Tx_UART(0x0A); } //*****************************fin*********************** Seccion de Código 5. Rutina para enviar numeros como datos. 8 3 Programa Matlab reply='Y'; for k=1:10 if reply=='Y' || reply =='y' clear all; clc; close all; disp('eliga la frecuencia de muestreo') x=input('introduzca un numero:','s'); FRECUENCIA=str2num(x); xx=num2str(x); disp('eliga el numero de muestras') y=input('introduzca un numero:','s'); MUESTRAS=str2num(y); yy=num2str(y); disp(['Frecuencia de muestreo = ',x ]); disp(['Número de muestras = ',y ]); s = serial('COM8'); %configuracion del puerto serial set(s,'StopBits',1); set(s,'FlowControl','none'); set(s,'Parity','none'); set(s,'terminator','LF'); set(s,'InputBufferSize',1024); set(s,'TimeOut',40); b=0; fopen(s); fprintf(s,x); fprintf(s,y); a=0; for i=1:MUESTRAS b(i)=fscanf(s,'%e',5); a(i)=(i/FRECUENCIA); end fclose(s); b=(b*3.3)/4095; plot(a,b); disp('¿Desea nueva frecuencia?') reply=input('Continuar (Y), salir (N):','s'); else break; end end disp('**************************') disp(date) disp('***********FIN************') disp('**************************') 9 Sección de Código 6. Programa de matlab para recibir enviar configuración de número de muestras y frecuencia de muestreo. y recepción de datos leídos del ADC para graficar. En la Sección de Código 6 se muestra el programa de matlab, donde es un programa que se repite diez veces mientras el usuario diga que quiere continuar con mediante la letra “y”, cualquier otra letra termina el programa. Se cierra todo lo que tenga abierto el programa y borra todo lo que tenia escrito, después se pide escribir la frecuencia de muestreo al usuario, una vez escrita se pide escribir el número de muestras, los valores escritos se convierten a número y a cadena para usarlos en matlab y para enviarlos al micro sucesivamente. Después se configura el puerto serial, se abre, y se mandan los datos de frecuencia de muestreo y número de muestras. Después se hace un ciclo que va desde 1 hasta el número de muestras tecleado, donde se leen los valores que ha tomado el ADC y se almacenan en una matriz llamada “b” y a su vez se va llenando otra matriz “a” para el tiempo dividiendo el número de muestras entre la frecuencia de muestreo. Una vez terminado el ciclo se cierra el puerto y la matriz “b” se multiplica por 3.3 que es valor de entrada máximo del ADC y se divide entre 4095 que es el total de número de cuentas que llega el ADC para después graficar “a” y “b” con la función “plot”. Después pregunta al usuario que si quiere definir una nueva frecuencia con el ciclo que esta descrito al principio de esta página. 10 4 Conclusiones Mientras se escoja una frecuencia igual o en múltiplos de 10 de la frecuencia leída por el ADC la forma de onda mantiene su figura, pero si se escoge otra frecuencia se empiezan a desplegar ondas diferentes, esto es porque las muestras que va tomando el ADC no se toman en los puntos necesarios para representar esa onda. Así también el número de muestras influye para que se vea más clara la señal. 11