Programa: Generador y medidor de señales
Introducción:
El desarrollo de nuevas tecnologías requiere
del dominio de herramientas y técnicas para procesar información, en ingeniería
eléctrica un tema de mucha importancia es la medición de energía y con el
avance de los sistemas digitales, hoy se cuenta con medidores inteligentes que
ofrecen distintos beneficios como:
Ø Mayor precisión.
Ø No presentan desgastes (No tienen partes móviles).
Ø Soportan diferentes tipos de mediciones.
Ø Actualización del software.
Objetivo General:
Este
programa tiene su principal razón en la implementación de FRDM-K64F y el
programa Kinetis Design Studio para generar señales sinusoidales y la obtención
de resultados en diferentes condiciones de operación.
Objetivo Específico:
Este programa
tiene como objetivo el generar señales con el componente DAC (Digital Analogic
Converter por sus siglas en ingles). Como la señal fundamental, también tercer
armónico, quinto armónico, variar la frecuencia, la amplitud de cada onda
(fundamental, tercer armónico, y quinto armónico). Esto con el fin de crear
diferentes escenarios y verificar el funcionamiento del medidor.
El
medidor tiene como prioridad verificar las señales generadas (Componente DAC),
con el componente ADC (Analogic Digital Converter por sus siglas en ingles). Esto
lo realiza digitalizando la señal de entrada que en este caso es analógica,
procesada para calcular los parámetros de la señal de entrada y los muestre en
pantalla los resultados como:
Ø Voltaje RMS.
Ø Corriente RMS.
Ø Frecuencia
Ø Ángulo.
Ø Magnitud.
Ø potencias.
Contenido:
Este
programa se realiza a base de funciones e interrupciones que hacen posible su
funcionamiento, a continuación se describen cada una de ellas.
FUNCIÓN “ASCII2Number”
Introducción:
Las computadoras solamente entienden números. El
código ASCII es una representación numérica de un carácter como ‘a’ o ‘@’. Como
otros códigos de formato de representación de caracteres, el ASCII es un método
para una correspondencia entre cadenas de bits y una serie de símbolos
(alfanuméricos y otros), permitiendo de esta forma la comunicación entre
dispositivos digitales así como su procesado y almacenamiento
El código ASCII
(siglas en inglés para American Standard Code for Information Interchange, es
decir Código Americano Estándar para el intercambio de Información) (se
pronuncia Aski). Fue creado en 1963 por el Comité Estadounidense de Estándares
o "ASA", este organismo cambio su nombre en 1969 por "Instituto
Estadounidense de Estándares Nacionales" o "ANSI" como se lo
conoce desde entonces.
Este código nació a partir de reordenar y expandir el conjunto de símbolos y caracteres ya utilizados en aquel momento en telegrafía por la compañía Bell. En un primer momento solo incluía letras mayúsculas y números, pero en 1967 se agregaron las letras minúsculas y algunos caracteres de control, formando así lo que se conoce como US-ASCII, es decir los caracteres del 0 al 127.
Así con este conjunto de solo 128 caracteres fue publicado en 1967 como estándar, conteniendo todos lo necesario para escribir en idioma inglés.
En 1981, la empresa IBM desarrolló una extensión de 8 bits del código ASCII, llamada "página de código 437", en esta versión se reemplazaron algunos caracteres de control obsoletos, por caracteres gráficos. Además se incorporaron 128 caracteres nuevos, con símbolos, signos, gráficos adicionales y letras latinas, necesarias para la escrituras de textos en otros idiomas, como por ejemplo el español. Así fue como se sumaron los caracteres que van del ASCII 128 al 255.
IBM incluyó soporte a esta página de código en el hardware de su modelo 5150, conocido como "IBM-PC", considerada la primera computadora personal. El sistema operativo de este modelo, el "MS-DOS" también utilizaba el código ASCII extendido
Este código nació a partir de reordenar y expandir el conjunto de símbolos y caracteres ya utilizados en aquel momento en telegrafía por la compañía Bell. En un primer momento solo incluía letras mayúsculas y números, pero en 1967 se agregaron las letras minúsculas y algunos caracteres de control, formando así lo que se conoce como US-ASCII, es decir los caracteres del 0 al 127.
Así con este conjunto de solo 128 caracteres fue publicado en 1967 como estándar, conteniendo todos lo necesario para escribir en idioma inglés.
En 1981, la empresa IBM desarrolló una extensión de 8 bits del código ASCII, llamada "página de código 437", en esta versión se reemplazaron algunos caracteres de control obsoletos, por caracteres gráficos. Además se incorporaron 128 caracteres nuevos, con símbolos, signos, gráficos adicionales y letras latinas, necesarias para la escrituras de textos en otros idiomas, como por ejemplo el español. Así fue como se sumaron los caracteres que van del ASCII 128 al 255.
IBM incluyó soporte a esta página de código en el hardware de su modelo 5150, conocido como "IBM-PC", considerada la primera computadora personal. El sistema operativo de este modelo, el "MS-DOS" también utilizaba el código ASCII extendido
Diagrama de flujo.
Código:
int32_t ASCII2Number(int rxIndex)
{
int i,a;
int suma=0;
int x=rxIndex-2;
for(i=0;i<rxIndex-1;i++)
{
a=(demoRingBuffer[i]-0x30)*pow(10,x);
x=x-1;
suma=suma+a; //suma el dato nuevo al anterior
}
numero=suma;
return(numero);
FUNCIÓN RMS “f_Rms”.
Introducción
El valor RMS es el valor del voltaje o
corriente en C.A. que produce el mismo efecto de disipación de calor que su
equivalente de voltaje o corriente directa. El valor eficaz de una señal
periódica se define por la ecuación:
Dónde:
· XRMS =
Valor eficaz
·
x(t)= Función periódica continua en el tiempo
· T
= Periodo de x (t)
De manera similar, el valor eficaz
para señales en tiempo discreto está dado por:
Dónde:
·
XRMS=
Valor eficaz
·
x[n]= Función periódica en el tiempo discreto
· T = Numero de muestras
DIAGRAMA:
CODIGO:
uint32_t f_Rms(int16_t *Measures)
{
uint8_t i;
uint32_t suma=0;
uint32_t prom=0;
uint32_t rms;
for(i=0;i<N_MUESTRAS;i++)
{
suma=suma+(Measures[i]*Measures[i]);//Acumula el cuadrado de todas las muestras de 1 ciclo
}
prom=suma/N_MUESTRAS;
rms=f_Raiz(prom); //Obtiene RMS
return (rms);
}
FUNCIÓN
“f_dft”
Introducción:
El
análisis de Fourier es una familia de técnicas matemáticas basadas en la
descomposición de señales periódicas, en ondas sinusoidales.
Una señal puede ser representada
como una función matemática que depende de una o más variables independientes.
En caso de las señales continuas, la variable independiente es continua, por lo
que estas señales se definen para una sucesión continua de valores de la variable
independiente. Por otra parte, las señales discretas sólo están definidas en
tiempos discretos, como resultado, la variable independiente de estas señales
toma solamente un conjunto discreto de valores.
Una clase muy importante de señales
discretas surge del muestreo de señales continuas. En estos casos, una señal
discreta x[n] representa muestras sucesivas de un fenómeno subyacente para el
cual la variable independiente es originalmente continua.
La DFT se define matemáticamente
como:
DFT por
correlación.
La
correlación es una operación matemática en la que se toman dos señales de
entrada para obtener una tercera como salida. Es una técnica óptima para
detectar una forma de onda conocida dentro de una señal contaminada con ruido.
Dada una señal
discreta de N muestras en el dominio del tiempo definida como x[n], es posible
obtener la DFT por correlación y obtener la parte real e imaginaria de dicha
señal en el dominio de la frecuencia. Utilizando las siguientes ecuaciones:
DIAGRAMA
CÓDIGO
void f_dft(int16_t *Measures,DFT_STRUCT *ptr_dft)
{
uint16_t i;
int32_t suma_cos=0,suma_sen=0;
int32_t Re_Aux;
uint32_t int_mag;
for(i=0;i<N_MUESTRAS;i++)
{
suma_cos=suma_cos+((Measures[i])*(cos_ref[i]))/2047; //Acumula la multiplicacion de las muestras por la onda Coseno Referencia, PARTE REAL
suma_sen=suma_sen+((Measures[i])*(sen_ref[i]))/2047; //Acumula la multiplicacion de las muestras por la onda Seno Referencia, PARTE IMAGINARIA
}
ptr_dft->DFT_Re=(2*suma_cos/N_MUESTRAS);
ptr_dft->DFT_Im=-(2*suma_sen/N_MUESTRAS);
int_mag=ptr_dft->DFT_Re*ptr_dft->DFT_Re+ptr_dft->DFT_Im*ptr_dft->DFT_Im;
ptr_dft->DFT_Mag=f_Raiz(int_mag);
//Re_Aux se utiliza para determinar el valor del coseno del ángulo
//Se necesita el valor absoluto de la variable debido a que la tabla
//solo existen valores positivos
if(ptr_dft->DFT_Re<0)
Re_Aux=-ptr_dft->DFT_Re;
else
Re_Aux=ptr_dft->DFT_Re;
//if(Re_Aux==0)
//Re_Aux=1;
//ptr_dft->DFT_Ph es el valor al que se tiene que apuntar en la tabla de coseno inverso
ptr_dft->DFT_Ph=((Re_Aux*255)/ptr_dft->DFT_Mag);
}
FUNCIÓN
“f_angulo”
DIAGRAMA
CÓDIGO
void f_angulo(DFT_STRUCT *ptr_dft)
{
//con el valor obtenido en la función DFT se obtiene el valor del ángulo
ptr_dft->DFT_Ph=(int32_t)arc_cos[ptr_dft->DFT_Ph];
if (ptr_dft->DFT_Re<0 && ptr_dft->DFT_Im >=0)
ptr_dft->DFT_Ph=18000-ptr_dft->DFT_Ph;
else if (ptr_dft->DFT_Re<=0 && ptr_dft->DFT_Im <0)
ptr_dft->DFT_Ph=18000+ptr_dft->DFT_Ph;
else if (ptr_dft->DFT_Re>0 && ptr_dft->DFT_Im <=0)
ptr_dft->DFT_Ph=36000-ptr_dft->DFT_Ph;
}
FUNCIÓN “f_Frec”
El algoritmo del cálculo de la frecuencia por
cruce por cero consiste en detector un cambio de signo de la señal de interés,
ya sea con pendiente negativa o positiva, y a partir de este instante,
cuantificar el número de muestras hasta que se detecte el próximo cambio de
signo bajo las mismas características. Normalmente, la cantidad de muestras
entre un cero y otro será un número fraccionario; por lo tanto, se requiere
contabilizar las muestras entre ceros y adicionalmente calcular la fracción de
muestra para obtener una cantidad precisa.
DIAGRAMA
CCÓDIGO
uint32_t f_Frec(FREC_STRUCT_PTR frec_ptr)
{
uint32_t frac_muestra_new, frac_muestra_act,abs_actual;
if( frec_ptr->v_act <= 0 && frec_ptr->v_ant > 0) //Detecta Cruce por cero con pendiente negativa
{
if(frec_ptr->v_act < 0)
{
abs_actual = -frec_ptr->v_act;
frac_muestra_new = (abs_actual*10000)/(frec_ptr->v_ant + abs_actual); //Fraccion de muestra antes del cruce por cero (1000=pu)
frac_muestra_act = 10000-frac_muestra_new; //Fraccion de muestra despues del cruce por cero (1000=pu)
frec_ptr->suma_muestras = frec_ptr->suma_muestras + frac_muestra_new; //Acumula numero de muestras
if(frec_ptr->suma_muestras > 70000) //(32/2) muestras evaluadas por ciclo (15 pu)
frec_ptr->frecuencia = AJUSTE_FREC / frec_ptr->suma_muestras; //Calcula Frecuencia
frec_ptr->suma_muestras = frac_muestra_act; //Actualiza sumatoria, asignandole la freccion de muestra despues del cruce por cero
}
else
{
if(frec_ptr->suma_muestras > 70000)
frec_ptr->frecuencia = AJUSTE_FREC / frec_ptr->suma_muestras;
frec_ptr->suma_muestras = 0;
}
guarda_frec();
}
else
{
frec_ptr->suma_muestras = frec_ptr->suma_muestras + 10000;
}
frec_ptr->v_ant = frec_ptr->v_act;
return 0;
FUNCIÓN “f_potencias”
En un sistema
monofásico la potencia activa o potencia promedio es dada por la expresión:
En el caso de un
sistema monofásico que es medido por medio de una microcomputadora se tiene que
la potencia activa:
DIAGRAMA
CÓDIGO
void f_potencias (int16_t *Measures0, int16_t *Measures1, POT_STRUCT *ptr_pot)
{
uint8_t i;
uint32_t suma=0;
uint32_t Aux_Pot_Re;
for(i=0;i<N_MUESTRAS;i++)
{
suma+=(Measures0[i]*Measures1[i]);
}
ptr_pot->Pot_Activa=suma/N_MUESTRAS;
ptr_pot->Pot_Aparente=Value_Rms_V*Value_Rms_I;
Aux_Pot_Re=(ptr_pot->Pot_Aparente*ptr_pot->Pot_Aparente)-(ptr_pot->Pot_Activa*ptr_pot->Pot_Activa);
ptr_pot->Pot_Reactiva=f_Raiz(Aux_Pot_Re);
}
FUNCIÓN “Mide_v”
DIAGRAMA
CODIGO
void mide_v( )
{
if(event_bits_V){
Value_Rms_V=f_Rms(ptr_toBufferV);
f_dft(ptr_toBufferV,&DFT_BUFFER0);
f_angulo(&DFT_BUFFER0);
event_bits_V=0;
}
}
FUNCIÓN “Mide_i”
}
DIAGRAMA
CÓDIGO
void mide_i( )
{
if(event_bits_I){
Value_Rms_I=f_Rms(ptr_toBufferI);
f_dft(ptr_toBufferI,&DFT_BUFFER1);
f_potencias(ptr_toBufferV, ptr_toBufferI, &POTENCIAS);
f_angulo(&DFT_BUFFER1);
event_bits_I=0;
}
}
FUNCIÓN “menu”
DIAGRAMA
CÓDIGO.
void menu()
{
enum {INICIO, AMP1,AMP3,AMP5,FREC,MEDICION,SELEC,FASE,ERROR} ;
static int Menu=INICIO;
static int SubMenu='A';
switch (Menu)
{
case INICIO:
{
UART_WriteBlocking(DEMO_UART, g_tipString, sizeof(g_tipString) / sizeof(g_tipString[0]));
Menu=SELEC;
break;
}
case SELEC:
{
if(conv_bandera) //si conv_bandera=true
{
if(numero==0||numero>6)
Menu=ERROR;
else
Menu=numero;
SubMenu='A';
}
break;
}
case AMP1:
{
switch (SubMenu)
case 'A': {
conv_bandera=false;
UART_WriteBlocking(DEMO_UART, g_tipString_amp1, sizeof(g_tipString_amp1) / sizeof(g_tipString_amp1[0]));
SubMenu='B';
}
case 'B':{
if(conv_bandera){
if (numero > 100 || numero < 0)
{
Menu=ERROR;
break;
}
else amp1=numero;
conv_bandera=false;
Menu=INICIO;
break;
}
else
break;
}
}
case AMP3:
{
switch (SubMenu)
case 'A': {
conv_bandera=false;
UART_WriteBlocking(DEMO_UART, g_tipString_amp3, sizeof(g_tipString_amp3) / sizeof(g_tipString_amp3[0]));
SubMenu='C';
}
case 'C':{
if(conv_bandera){
if (numero > 100 || numero < 0)
{
Menu=ERROR;
break;
}
else amp3=numero;
conv_bandera=false;
Menu=INICIO;
break;
}
else
break;
}
}
case AMP5:
{
switch (SubMenu)
case 'A': {
conv_bandera=false;
UART_WriteBlocking(DEMO_UART, g_tipString_amp5, sizeof(g_tipString_amp5) / sizeof(g_tipString_amp5[0]));
SubMenu='D';
}
case 'D':{
if(conv_bandera){
if (numero > 100 || numero < 0)
{
Menu=ERROR;
break;
}
else amp5=numero;
conv_bandera=false;
Menu=INICIO;
break;
}
else
break;
}
}
case FREC:
{
switch (SubMenu)
case 'A': {
conv_bandera=false;
UART_WriteBlocking(DEMO_UART, g_tipString_frec, sizeof(g_tipString_frec) / sizeof(g_tipString_frec[0]));
SubMenu='E';
}
case 'E':{
if(conv_bandera){
if (numero > 1000 || numero <= 300)
{
Menu=ERROR;
break;
}
else {
frecuencia=numero;
period_muestreo = (10000000 / (frecuencia * 32));
// Set timer period for channel 0
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0,USEC_TO_COUNT(period_muestreo, PIT_SOURCE_CLOCK));
//la contante de tiempo del pit se calcula pot la formula siguiente T/32 = 1/(f*32) = 52083.33333(microsegundos)
// Enable timer interrupts for channel 0
PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable);
// Enable at the NVIC
EnableIRQ(PIT_IRQ_ID);
PIT_StartTimer(PIT, kPIT_Chnl_0);
conv_bandera=false;
Menu=INICIO;
break;
}
}
else
break;
} //fin de caso B
} //fin de caso FREC
case MEDICION:
{
sprintf(s,"SEC_ADC = %d\r\nVRMS = %d\r\nIRMS = %d\r\n\n",sec_adc,Value_Rms_V,Value_Rms_I);
UART_WriteBlocking(DEMO_UART, s, sizeof(s) / sizeof(s[0]));
sprintf(s,"Potencia Activa = %d\r\nPotencia Reactiva = %d\r\nPotencia Aparente = %d\r\n\n",POTENCIAS.Pot_Activa,POTENCIAS.Pot_Reactiva,POTENCIAS.Pot_Aparente);
UART_WriteBlocking(DEMO_UART, s, sizeof(s) / sizeof(s[0]));
sprintf(s,"MAGNITUD VOLTAJE = %d\r\nFASE VOLTAJE = %d\r\nMAGNITUD CORRIENTE = %d\r\n\n",DFT_BUFFER0.DFT_Mag,DFT_BUFFER0.DFT_Ph,DFT_BUFFER1.DFT_Mag);
UART_WriteBlocking(DEMO_UART, s, sizeof(s) / sizeof(s[0]));
sprintf(s,"FASE CORRIENTE = %d\r\nFRECUENCIA DE LA SEÑAL = %d \r\n\n",DFT_BUFFER1.DFT_Ph,frec_ptr->frec_mediana);
UART_WriteBlocking(DEMO_UART, s, sizeof(s) / sizeof(s[0]));
conv_bandera=false;
Menu=INICIO;
SubMenu='A';
break;
}
case FASE:
{
switch (SubMenu)
case 'A': {
conv_bandera=false;
UART_WriteBlocking(DEMO_UART, g_tipString_fase, sizeof(g_tipString_fase) / sizeof(g_tipString_fase[0]));
SubMenu='F';
}
case 'F':{
if(conv_bandera){
if (numero > 8 || numero < 0)
{
Menu=ERROR;
break;
}
else retardo=numero;
conv_bandera=false;
Menu=INICIO;
break;
}
else
break;
}
}
case ERROR:
{
UART_WriteBlocking(DEMO_UART, g_tipString_error, sizeof(g_tipString_error) / sizeof(g_tipString_error[0]));
conv_bandera=false;
Menu=SELEC;
break;
}
} //SWITCH principal
}
PROGRAMA PRINCIPAL
DIAGRAMA
CÓDIGO
#include <string.h> //librerias
#include <math.h>
#include <stdio.h>
#include "fsl_debug_console.h"
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_pdb.h"
#include "fsl_adc16.h"
#include "fsl_pit.h"
#include "fsl_dac.h"
#include "fsl_uart.h"
#include "fsl_device_registers.h"
#include "fsl_port.h"
#include "PIT.h"
#include "DAC.h"
#include "pdb_adc.h"
#include "rgb.h"
#include "sw.h"
#include "mediciones.h"
#include "main.h"
#define PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
#define PIT_IRQ_ID PIT0_IRQn
#define DEMO_DAC_INSTANCE DAC0
#define B0 (1 << 0)
#define B1 (1 << 1)
#define DEMO_UART UART0
#define DEMO_UART_CLKSRC UART0_CLK_SRC
#define DEMO_UART_IRQn UART0_RX_TX_IRQn
#define DEMO_UART_IRQHandler UART0_RX_TX_IRQHandler
/*! @brief Ring buffer size (Unit: Byte). */
#define DEMO_RING_BUFFER_SIZE 16
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables Globales
******************************************************************************/
int16_t ADC0_Inst_Value;
int16_t ADC1_Inst_Value;
FREC_STRUCT frec; //Variable de la estructura de la frecuencia
FREC_STRUCT_PTR frec_ptr = &frec; //Apuntador a la estructura de la frecuencia
uint32_t datos[ORDEN]; //Arreglo para guardar los datos obtenidos de la frecuencia
uint32_t flag_frec=0;
extern uint32_t Value_Rms_V;
extern uint32_t Value_Rms_I;
volatile uint32_t g_AdcConvValue;
uint32_t event_bits_V;
uint32_t event_bits_I;
int16_t buff_V[N_SIZE];
int16_t buff_I[N_SIZE];
int16_t buff_retardo[N_SIZE];
DFT_STRUCT DFT_BUFFER0;
DFT_STRUCT DFT_BUFFER1;
POT_STRUCT POTENCIAS;
uint32_t sec_adc=0;
uint32_t Value_Rms_V;
uint32_t Value_Rms_I;
int16_t i_rms = 0;
int16_t v_rms = 0;
int32_t Pot_Activa, Pot_Aparente, Pot_Reactiva;
int16_t *ptr_toBufferV;
int16_t *ptr_toBufferI;
int8_t retardo=0;
int32_t gen_seno[32] = { 0, 399, 783, 1137, 1447, 1702, 1891, 2008, 2047, 2008,
1891, 1702, 1447, 1137, 783, 399, 0, -399, -783, -1137, -1447, -1702,
-1891, -2008, -2047, -2008, -1891, -1702, -1447, -1137, -783, -399 };
int16_t gen_seno3[32] = { 0, 1136, 1890, 2007, 1447, 399, -782, -1701, -2048,
-1701, -782, 399, 1447, 2007, 1890, 1136, 0, -1136, -1890, -2007, -1447,
-399, 782, 1701, 2048, 1701, 782, -399, -1447, -2007, -1890, -1136 };
int16_t gen_seno5[32] = { 0, 1701, 1890, 399, -1447, -2007, -782, 1136, 2048,
1136, -782, -2007, -1447, 399, 1890, 1701, 0, -1701, -1890, -399, 1447,
2007, 782, -1136, -2048, -1136, 782, 2007, 1447, -399, -1890, -1701 };
int32_t value_inst ;
uint32_t value_sen = 0;
int32_t amp1, amp3, amp5;
uint32_t frecuencia, period_muestreo;
uint8_t g_tipString[] = ("Selecciona el parametro que quieres cambiar o visualizar\r\n 1.Amplitud de la onda fundamental\r\n2.Amplitud de la onda del tercer armonico\r\n3.Amplitud de la onda del quinto armonico\r\n4.Frecuencia\r\n\n5.Mediciones\r\n\n6.Fase Voltaje Corriente\r\n\n");
uint8_t g_tipString_amp1[] = ("Dame la amplitud de la onda fundamental (0-100)\r\n amplitud=");
uint8_t g_tipString_amp3[] = ("Dame la amplitud de la onda del tercer armonico (0-100)\r\n amplitud=");
uint8_t g_tipString_amp5[] = ("Dame la amplitud de la onda del quinto armonico (0-100)\r\n amplitud=");
uint8_t g_tipString_frec[] = ("Dame la nueva frecuencia que deseas: \n\r");
uint8_t g_tipString_rms[] = ("voltaje rms= \r\n");
uint8_t g_tipString_seg[] = (" Segundos de muestreo\r\n");
uint8_t g_tipString_error[] = ("Seleccion invalida\r\n\n");
uint8_t g_tipString_fase[] = ("Ingresa Valor para Retardo de Corriente (0-8): \n\r retardo=");
uint8_t demoRingBuffer[DEMO_RING_BUFFER_SIZE];
volatile uint16_t txIndex; /* Index of the data to send out. */
/* Index of the memory to save new arrived data. */
uint8_t data;
int32_t amp;
volatile bool conv_bandera = false;
uint32_t numero=0;
char s[100];
void menu(void);
void mide_v( void);
void mide_i(void );
int32_t ASCII2Number(int rxIndex);
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief ISR for ADC16 interrupt function
*/
void DEMO_ADC_IRQ_HANDLER(void)
{
static int8_t contbuff_v=0;
static int fracsec=0;
/* Read to clear COCO flag. */
ADC0_Inst_Value=ADC16_GetChannelConversionValue(DEMO_ADC_BASE, DEMO_ADC_CHANNEL_GROUP)-2047;
buff_V[contbuff_v] =ADC0_Inst_Value;
frec_ptr->v_act = buff_V[contbuff_v];
contbuff_v++;
if(contbuff_v )
f_Frec(frec_ptr);
if(contbuff_v==N_MUESTRAS){
event_bits_V= B0;
ptr_toBufferV=buff_V;
}
if(contbuff_v==N_SIZE){
event_bits_V = B1;
ptr_toBufferV=buff_V+N_MUESTRAS;
}
contbuff_v %=64;
fracsec++; //segundero
fracsec%=1920;
if(fracsec==0){
sec_adc++;
}
}
void DEMO_ADC1_IRQ_HANDLER(void)
{
static int8_t contbuff_i=0;
int apuntador;
/* Read to clear COCO flag. */
buff_retardo[contbuff_i]=ADC16_GetChannelConversionValue(DEMO_ADC_BASE1, DEMO_ADC_CHANNEL_GROUP1)-2047;
apuntador=contbuff_i+retardo;
if (apuntador >= N_SIZE)
apuntador-=64;
if (apuntador <= N_SIZE)
apuntador+=64;
ADC1_Inst_Value=buff_retardo[apuntador];
buff_I[contbuff_i] =ADC1_Inst_Value;
contbuff_i++;
if(contbuff_i==32){
event_bits_I = B0;
ptr_toBufferI=buff_I;
}
if(contbuff_i==64){
event_bits_I= B1;
ptr_toBufferI=buff_I+N_MUESTRAS;
}
contbuff_i %=64;
}
#define PIT_LED_HANDLER PIT0_IRQHandler
void PIT_LED_HANDLER(void) {
/* Clear interrupt flag.*/
PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, PIT_TFLG_TIF_MASK);
DAC_SetBufferValue(DEMO_DAC_INSTANCE, 0U,
((gen_seno[value_sen] * amp1 + gen_seno3[value_sen] * amp3
+ gen_seno5[value_sen] * amp5) / 100 + 2047));
value_sen++;
value_sen%=32;
}
/*!
* @brief Main function
*/
int main(void)
{
uart_config_t config;
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
Ini_RGB();
Ini_SW3_IRQ();
Ini_SW2_IRQ();
Init_pit();
ini_dac();
ini_pdb_adc();
amp1=100;
amp3=0;
amp5=0;
frecuencia=600;
period_muestreo = (10000000 / (frecuencia * 32));
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0,
USEC_TO_COUNT(period_muestreo, PIT_SOURCE_CLOCK));
/*
* config.baudRate_Bps = 115200U;
* config.parityMode = kUART_ParityDisabled;
* config.stopBitCount = kUART_OneStopBit;
* config.txFifoWatermark = 0;
* config.rxFifoWatermark = 1;
* config.enableTx = false;
* config.enableRx = false;
*/
UART_GetDefaultConfig(&config);
config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;
UART_Init(DEMO_UART, &config, CLOCK_GetFreq(DEMO_UART_CLKSRC));
/* Send g_tipString out. MANDAR UN MENSAJE COMO CADENA*/
//UART_WriteBlocking(DEMO_UART, g_tipString, sizeof(g_tipString) / sizeof(g_tipString[0]));
/* Enable RX interrupt. */
UART_EnableInterrupts(DEMO_UART, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable);
EnableIRQ(DEMO_UART_IRQn);
while (1)
{
menu();
mide_v();
mide_i();
}
}
A continuación se muestra el funcionamiento del programa