TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Chenao en 18 de Abril de 2010, 01:05:25
-
Saludos
Por mucho que he buscado y he intentado no logro incontrar una forma de solucionar el siguiente problema:
Tengo un arreglo de tipo entero llamado a[50] el cual posee 50 datos mi pregunta es la siguiente yo puedo en cualquier instante del programa cambiar el contenido de los datos que se encuentran en el arreglo, si no se puede como puedo solucionar el problema si tener que declarar otra variable, por ejemplo b[50], he intentado y siempre me sale un error y no se como solucionar el problema sin tener que llenar la memoria del micro. Acá el código haber si me hechan una manito.
desborde()
{
if (contador ==1)
{
a[50] = {100, 106, 113, 119, 125, 131, 137, 143, 148, 154, 159, 164, 168, 173, 177, 181, 184, 188, 190, 193, 195, 197, 198, 199, 200, 200,200, 199, 198, 197, 195, 193, 190, 188, 184, 181, 177, 173, 168, 164, 159, 154, 148, 143, 137, 131, 125, 119, 113, 106, 100};
puerto_b = a[desbordes];
set_rtcc(240);
}
if( contador == 2)
{
a[50] = {100, 113, 125, 137, 148, 159, 168, 177, 184, 190, 195, 198, 200, 200, 198, 195, 190, 184, 177, 168, 159, 148, 137, 125, 113, 100, 87, 75, 63, 52, 41, 32, 23, 16, 10, 5, 2, 0, 0, 5, 10, 16, 23, 32, 41, 52, 63, 75, 87, 100};
puerto_b = a[desbordes];
set_rtcc(253);
}
if(desbordes>=50)
{
desbordes = 0;
}
desbordes = desbordes + 1;
}
Saludos.
-
Hola estimado, no se puede modificar el contenido de un array dinámicamente, tienes que hacer un loop y así colocar en cada espacio de éste los valores deseados, o sea que esto:
a[50] = {100, 106, 113, 119, 125...
está mal.
Si quieres ayuda con el programa podrías decir en que consiste y entre todos hacer un algoritmo. :mrgreen:
-
Ademas de lo comentado anteriormente, tienes declarada una función y una variable con el mismo nombre: "desborde"
Un saludo
-
Saludos
Gracias por responder compañeros.
La idea de utilizar arreglos es que no encuentro otra forma de realizar una tabla en lenguaje C, la aplicación que deseo realizar es un pequeño generador de señales.
Los datos que ingreso en la tabla los calculo utilizando el MATLAB y así me arroja un total de 50 datos y los muestre cada 200ms, cada 10ms depende de la frecuencia de la señal que este generando, así que reccurrí al arreglo.
Hola estimado, no se puede modificar el contenido de un array dinámicamente, tienes que hacer un loop y así colocar en cada espacio de éste los valores deseados, o sea que esto:
No se a que te requieres con un loop será un for o un bucle.
Ademas de lo comentado anteriormente, tienes declarada una función y una variable con el mismo nombre: "desborde"
Cualquiera se confunde amigo jfh900 la función efectivamente se llama desborde pero la variable se llama desbordes falto una s :D :D :D.
No se otra manera de realizar el algoritmo así que cualquier sujerencia es bienvenida.
Saludos.
-
Saludos
Gracias por responder compañeros.
La idea de utilizar arreglos es que no encuentro otra forma de realizar una tabla en lenguaje C, la aplicación que deseo realizar es un pequeño generador de señales.
Los datos que ingreso en la tabla los calculo utilizando el MATLAB y así me arroja un total de 50 datos y los muestre cada 200ms, cada 10ms depende de la frecuencia de la señal que este generando, así que reccurrí al arreglo.
Hola estimado, no se puede modificar el contenido de un array dinámicamente, tienes que hacer un loop y así colocar en cada espacio de éste los valores deseados, o sea que esto:
No se a que te requieres con un loop será un for o un bucle.
Ademas de lo comentado anteriormente, tienes declarada una función y una variable con el mismo nombre: "desborde"
Cualquiera se confunde amigo jfh900 la función efectivamente se llama desborde pero la variable se llama desbordes falto una s :D :D :D.
No se otra manera de realizar el algoritmo así que cualquier sujerencia es bienvenida.
Saludos.
Hola estimado, primero debes especificar en que consiste tu generador de señales, porque cuando dices eso me imagino inmediatamente uno de esos típicos generadores que producen ondas senoidales, cuadradas y dientes de sierra.
Respecto a lo del loop, efectivamente, es un ciclo cerrado que puede hacerse con for(), while(), o do while().
Al ver las siguientes líneas:
puerto_b = a[desbordes];
set_rtcc(240);
puedo imaginarme que mandas los datos a través de un pin de algún puerto determinado, en este caso el puerto B y este valor dependerá del subíndice "desbordes". Ahora, ¿usas USART o ISP para mandar este dato al exterior? ¿En qué consiste la instrucción "set_rtcc(240)"?
Finalmente veo que hay un error al ver el subíndice de a[desbordes] ya que estableciste como valor máximo 50:
"if(desbordes>=50)"
siendo que cuando declaras a[50] el subíndice va de 0 hasta 49.
-
Saludos The_Chosen
Efectivamente es un generador casero que estoy haciendo, ya tengo programadas la señales diente de sierra, y las señales cuadradas, para generar la señales utilice MATLAB para generar un módelo que me permitiera conocer como los valores que debia generar en el micro.
Estoy generando señales de 8 bits que son enviadas al puerto B del microcontrolador 16f877 y a su vez son enviados a un convertidos DAC_8 para poderlas visualizar en un osciloscopio.
Respecto a lo del loop, efectivamente, es un ciclo cerrado que puede hacerse con for(), while(), o do while().
Por más que le hecho cabeza no veo la forma de llenar el arreglo debido, a que los valores varian bastante y no utilizo las funciones sin() que vienen implementadas en compilador porqué ocupan bastante a micro.
puerto_b = a[desbordes];
set_rtcc(240);
Efectivamente los datos son enviados al exterior por el puerto B dependiendo de la variable desborde y la función set_rtcc(240)
garantiza la señal de muestreo con que estoy trabajando.
Finalmente veo que hay un error al ver el subíndice de a[desbordes] ya que estableciste como valor máximo 50:
Si tienes toda la razón :mrgreen: :mrgreen:.
La única forma que se me ocurre solucionar el problema es bajar la frecuencias de muestreo a 25 muestras por ciclo.
Saludos y muchas gracias por la coloaboración prestada.
-
Saludos The_Chosen
Efectivamente es un generador casero que estoy haciendo, ya tengo programadas la señales diente de sierra, y las señales cuadradas, para generar la señales utilice MATLAB para generar un módelo que me permitiera conocer como los valores que debia generar en el micro.
Estoy generando señales de 8 bits que son enviadas al puerto B del microcontrolador 16f877 y a su vez son enviados a un convertidos DAC_8 para poderlas visualizar en un osciloscopio.
Respecto a lo del loop, efectivamente, es un ciclo cerrado que puede hacerse con for(), while(), o do while().
Por más que le hecho cabeza no veo la forma de llenar el arreglo debido, a que los valores varian bastante y no utilizo las funciones sin() que vienen implementadas en compilador porqué ocupan bastante a micro.
puerto_b = a[desbordes];
set_rtcc(240);
Efectivamente los datos son enviados al exterior por el puerto B dependiendo de la variable desborde y la función set_rtcc(240)
garantiza la señal de muestreo con que estoy trabajando.
Finalmente veo que hay un error al ver el subíndice de a[desbordes] ya que estableciste como valor máximo 50:
Si tienes toda la razón :mrgreen: :mrgreen:.
La única forma que se me ocurre solucionar el problema es bajar la frecuencias de muestreo a 25 muestras por ciclo.
Saludos y muchas gracias por la coloaboración prestada.
Podrías decir que convertidor digital análogo estás usando para ver el tipo de protocolo de comunicación usa y así adecuarlo al pic16f877.
Sin embargo, pensando rápidamente puedes hacer lo siguiente:
a) Declarar desde un principio el valor del array y un puntero para recorrerlo de esta manera:
char *enviar; //este puntero sirve para "apuntar" a cada uno del los contenidos de los espacios de memoria asignadas por el array
a[]={dato1, dato2, dato3,...}; //cuando lo declaras de esta manera no es necesario colocar subíndice
b) Después usas el ciclo for o while para recorrer el array y así enviar los datos digitales al DAC:
enviar=a; // También puedes escribirlo así *enviar=&a[0], son formas equivalentes XD
while(!("Ultimo dato u otro tipo de señal que me indique el término del array"))
{
"Puerto donde se envía el dato digital"= *enviar++;
}
-
Ademas de lo comentado anteriormente, tienes declarada una función y una variable con el mismo nombre: "desborde"
Cualquiera se confunde amigo jfh900 la función efectivamente se llama desborde pero la variable se llama desbordes falto una s :D :D :D.
No se otra manera de realizar el algoritmo así que cualquier sugerencia es bienvenida.
Saludos.
Tienes razón, eso me pasa por leer deprisa.
En cuanto a lo que quieres, yo crearía tantas tablas como ondas quieras generar y las apuntaría con un puntero. Para cambiar de tabla, apuntas el puntero (valga la redundancia) a la tabla que quieras sacar por el puerto, y la recorres posición a posición (while o for) escribiendo los valores por el puerto.
Un saludo
PD: Parece que se han adelantado en la respuesta. :)
-
Saludos de nuevo
Podrías decir que convertidor digital análogo estás usando para ver el tipo de protocolo de comunicación usa y así adecuarlo al pic16f877.
Compañero estoy utilizando un DAC0880 el cual va conectado directamente al puerto B
A ver si entendí declarar un arreglo así int a[] con el número de datos así int a[dato1, dato2, dato3, ............,daton];
y después llenar el arreglo con un puntero de la siguiente manera
i = i++;
a = 100;
Estoy en lo correcto? :shock:
Si es así veo un incoveniente y es el siguiente por ejemplo en la sinosoide de 100 Hz el segundo valor es de 113 pero en la de 50 Hz es de 106 no veo la forma de cuadrar con los punteros los valores según el caso de la señal que tenga.
Saludos y gracias por la ayuda voy a seguir ensayando haber si lo pongo a funcionar.
-
Si es así veo un incoveniente y es el siguiente por ejemplo en la sinosoide de 100 Hz el segundo valor es de 113 pero en la de 50 Hz es de 106 no veo la forma de cuadrar con los punteros los valores según el caso de la señal que tenga.
MMM,
Emmm, lo que entiendo es lo siguiente:
En un array a[]={datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4....} tienes guardado una cierta cantidad de datos que representan en su conjunto, por ejemplo, una señal cuadrada de cierta amplitud. Ya que todos los datos digitalizados son de 8 bits tú los envías en forma paralela al DAC0808 (según la hoja de datos del DAC la única manera de enviar estos 8 bits es en forma paralela). Por otro lado tienes un array b[]={datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4....} que representa una onda triangular de cierta amplitud.
Ahora, si quieres crear una señal cuadrada pues recorres el array a[] con el puntero y colocas en el puerto b datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4.... etc, hasta crear una señal cuadrada a la salida del DAC.
Y si quieres crear una señal triangular envías datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4.... del array b[] y obtienes a la salida una señal triangular.
-
Saludos
En un array a[]={datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4....} tienes guardado una cierta cantidad de datos que representan en su conjunto, por ejemplo, una señal cuadrada de cierta amplitud. Ya que todos los datos digitalizados son de 8 bits tú los envías en forma paralela al DAC0808 (según la hoja de datos del DAC la única manera de enviar estos 8 bits es en forma paralela). Por otro lado tienes un array b[]={datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4....} que representa una onda triangular de cierta amplitud.
En efecto eso es lo que estoy realizando.
Ahora, si quieres crear una señal cuadrada pues recorres el array a[] con el puntero y colocas en el puerto b datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4.... etc, hasta crear una señal cuadrada a la salida del DAC.
Y si quieres crear una señal triangular envías datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4.... del array b[] y obtienes a la salida una señal triangular.
El problema que veo es que necesito generar variar señales con distintas frecuencias, es decir, necesito generar 4 señales sinosoidales, 4 cuadradas y 4 dientes de cierra, la única forma de manejarlas es trabajar con la misma muestras por periodo para la señales para que el arreglo no me cambie, sólo cambia el tiempo de interrupción.
No encuentro otra forma de hacerlo, gracas nuevamente The_Chosen por la colaboración prestada.
Saludos.
-
Saludos
En un array a[]={datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4....} tienes guardado una cierta cantidad de datos que representan en su conjunto, por ejemplo, una señal cuadrada de cierta amplitud. Ya que todos los datos digitalizados son de 8 bits tú los envías en forma paralela al DAC0808 (según la hoja de datos del DAC la única manera de enviar estos 8 bits es en forma paralela). Por otro lado tienes un array b[]={datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4....} que representa una onda triangular de cierta amplitud.
En efecto eso es lo que estoy realizando.
Ahora, si quieres crear una señal cuadrada pues recorres el array a[] con el puntero y colocas en el puerto b datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4.... etc, hasta crear una señal cuadrada a la salida del DAC.
Y si quieres crear una señal triangular envías datoDigitalizado1, datoDigitalizado2, datoDigitalizado3, datoDigitalizado4.... del array b[] y obtienes a la salida una señal triangular.
El problema que veo es que necesito generar variar señales con distintas frecuencias, es decir, necesito generar 4 señales sinosoidales, 4 cuadradas y 4 dientes de cierra, la única forma de manejarlas es trabajar con la misma muestras por periodo para la señales para que el arreglo no me cambie, sólo cambia el tiempo de interrupción.
No encuentro otra forma de hacerlo, gracas nuevamente The_Chosen por la colaboración prestada.
Saludos.
Mmmm, ¿Cómo cambias la frecuencia de la señal de salida de la señal?, y ¿Cómo cambias el tipo de señal? (De cuadrada a sinusoidal o de sinusoidal a dientes de sierra) ¿Usas una o varias interrupciones externas y por lo tanto usas pulsadores?
Porque lo que yo haría es declarar cuatro arrays para la señal sinusoidal, cuatro para la cuadrada y cuatro para la dientes de sierra. Como cada array ya tiene la información necesaria para producir una señal de frecuencia determinada, entonces los llamo con interrupciones externas. (Sin te faltan interrupciones externas pues haces rutinas por poleo de pines)
-
Saludos The_Chosen
Mmmm, ¿Cómo cambias la frecuencia de la señal de salida de la señal?, y ¿Cómo cambias el tipo de señal? (De cuadrada a sinusoidal o de sinusoidal a dientes de sierra) ¿Usas una o varias interrupciones externas y por lo tanto usas pulsadores?
En efecto compañero con un pulsador incremento la frecuencia, con otro la disminuyo y con el ultimo cambio el tipo señal pero no utilizo interrupciones simplemente utilizo el viejo truco de antirebote :D.
Porque lo que yo haría es declarar cuatro arrays para la señal sinusoidal, cuatro para la cuadrada y cuatro para la dientes de sierra. Como cada array ya tiene la información necesaria para producir una señal de frecuencia determinada, entonces los llamo con interrupciones externas. (Sin te faltan interrupciones externas pues haces rutinas por poleo de pines)
El problema principal, que veo de generar un arreglo para cada señal y para cada frecuencia es que me voy a quedar sin memoria, por que no veo la forma de crear un modelo, es decir, por ejemplo en la señal de seno a un 1Hz el segundo valor vale 113 en decimal pero para 100 Hz el mismo valor vale 103 en decimal. La unica forma que es mantener las mustras por ciclos iguales para todas las señales.
Por otro lado cuando simuló en el proteus la señal senosoidal me sale muy fea en único punto es decir viene como en 2 en aplitud y inmediatamente se cae a 0 que será :shock: :shock:.
Voy a seguir intentando haber si lo termino saludos y nuevamente gracias por la respuesta.
-
El problema principal, que veo de generar un arreglo para cada señal y para cada frecuencia es que me voy a quedar sin memoria, por que no veo la forma de crear un modelo, es decir, por ejemplo en la señal de seno a un 1Hz el segundo valor vale 113 en decimal pero para 100 Hz el mismo valor vale 103 en decimal. La unica forma que es mantener las mustras por ciclos iguales para todas las señales.
¿Con cuál micro estás trabajando?
Si mantienes la misma tasa de muestreo, nada te garantiza que las muestras sean coincidentes en todos sus valores si se tratan de señales de frecuencias distintas. Tú lo has dicho, si a una señal seno de 1 HZ y a una de 100 Hz se utiliza la misma taza de muestreo, un cierta amplitud A no va tener la misma posición dentro de ambas señales ya que la variable tiempo es distinta para ambas señales. Por eso es que se necesita que las tasas de muestreo sean altas para señales de altas frecuencias, y así reconstruir la señal después lo más fiel posible.
Por otro lado cuando simuló en el proteus la señal senosoidal me sale muy fea en único punto es decir viene como en 2 en aplitud y inmediatamente se cae a 0 que será :shock: :shock:.
jejeje, es lo que decía anteriormente, las muestras que tomaste fueron insuficientes, así en el momento de interpolar los datos en un punto de la gráfica, éste pasa de amplitud 2 a 0. Si aumentas la tasa de muestreo la señal se reconstruiría un poco mejor, pero eso aumentaría la memoria ocupada en el microcontrolador.
-
Saludos
¿Con cuál micro estás trabajando?
Estoy trabajando con el 16f877
Si mantienes la misma tasa de muestreo, nada te garantiza que las muestras sean coincidentes en todos sus valores si se tratan de señales de frecuencias distintas. Tú lo has dicho, si a una señal seno de 1 HZ y a una de 100 Hz se utiliza la misma taza de muestreo, un cierta amplitud A no va tener la misma posición dentro de ambas señales ya que la variable tiempo es distinta para ambas señales. Por eso es que se necesita que las tasas de muestreo sean altas para señales de altas frecuencias, y así reconstruir la señal después lo más fiel posible.
Hasta ahora creo que funciona bien, de todas maneras si no te parece mal, subo algo del código y la simulación haber si me das alguna opión o definitivamente nada que hacer :mrgreen:. Hasta ahora ya logre simular la 3 señales con distintas frecuencias (1, 10, 50, 100) ahora le voy a poner una LCD para que indique tipo de señal y frecuencia para que quede más presentable.
-
Saludos
¿Con cuál micro estás trabajando?
Estoy trabajando con el 16f877
Si mantienes la misma tasa de muestreo, nada te garantiza que las muestras sean coincidentes en todos sus valores si se tratan de señales de frecuencias distintas. Tú lo has dicho, si a una señal seno de 1 HZ y a una de 100 Hz se utiliza la misma taza de muestreo, un cierta amplitud A no va tener la misma posición dentro de ambas señales ya que la variable tiempo es distinta para ambas señales. Por eso es que se necesita que las tasas de muestreo sean altas para señales de altas frecuencias, y así reconstruir la señal después lo más fiel posible.
Hasta ahora creo que funciona bien, de todas maneras si no te parece mal, subo algo del código y la simulación haber si me das alguna opión o definitivamente nada que hacer :mrgreen:. Hasta ahora ya logre simular la 3 señales con distintas frecuencias (1, 10, 50, 100) ahora le voy a poner una LCD para que indique tipo de señal y frecuencia para que quede más presentable.
Con el 16F877 tienes una memoria de programa de 8Kx14, creo que el espacio es suficiente para guardar distintos arrays, tendrías que probar creando una buena cantidad, o sea a lo bruto. :D
Y adelante, pon tu código :mrgreen: . A pesar que hace tiempo no programo PICs (algo me acuerdo), te puedo ayudar en lo relacionado con el lenguaje C y tu algoritmo. El resto de los presentes te pueden ayudar en los pequeños detalles ;-).
-
Saludos
Por acá pongo el código del generador de onda cuadrada y diente de sierra.
Parece que hay un problema cuando se agrega la onda seno porqué el simulador se vuelve loco y empieza a sacar un poco de warning y se empieza a volver lenta la simulación, al parecer el stack del micro se satura.
#if defined(__PCM__)
#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay (clock = 4000000)
#define use_portd_lcd TRUE
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
#byte puerto_b = 06
#byte conta = 0x20
#byte senal2 = 0x21
#byte i2 = 0x22
#include <lcd.c>
int contador,control_l,control_h,largo,senal;
#int_rtcc
desborde()
{
// Señal cuadrada de 1 Hz
if (contador == 1 && senal == 1) // Pulso de 1 Hz
{
control_h = 0;
control_l = control_l + 1;
if(control_l<=100)
{
puerto_b = 100; // Garantizo los primero 50 muestras en alto
}
else
{
puerto_b = 0;
}
if (control_l >200)
{
control_l = 0; // Garantizo las demás 50 muestras en bajo
}
set_rtcc(178); // Se garantiza el periodo de 1s
}
// Señal cuadrada de 10 Hz
else if (contador == 2 && senal == 1) // Pulso de 10Hz
{
control_l = 0;
control_h = control_h + 1;
if(control_h<=50)
{
puerto_b = 100; // Garantizo los primero 50 muestras en alto
}
else
{
puerto_b = 0;
}
if (control_h >100)
{
control_h = 0; // Ultimas muestras en 0 lógico
}
set_rtcc(240); // Se garantiza el periodo de 0.01s
}
// Señal cuadrada de 50 Hz
else if (contador == 3 && senal == 1) // Pulso de 50 Hz
{
control_l = 0;
control_h = control_h + 1;
if(control_h<=50)
{
puerto_b = 100; // Garantizo los primero 50 muestras en alto
}
else
{
puerto_b = 0;
}
if (control_h >100)
{
control_h = 0; // Ultimas muestras en 0 lógico
}
set_rtcc(253); //Garantizo el periodo 0.002s
}
// Señal cuadrada de 100 Hz
else if (contador == 4 && senal == 1) // Pulso de 100 Hz
{
control_l = 0;
control_h = control_h + 1;
if(control_h<=50)
{
puerto_b = 100; // Garantizo los primero 50 muestras en alto
}
else
{
puerto_b = 0;
}
if (control_h >100)
{
control_h = 0; // Ultimas muestras en 0 lógico
}
set_rtcc(254); //Garantizo el periodo 0.001s
}
// Señal diente de sierra 1Hz
if(contador == 1 && senal == 2) // señal diente sierra 1Hz
{
largo = largo + 1; // Se incrementa linealmente los valores hasta alcanzar la frecuencias deseada
if(largo >= 100)
{
largo = 0;
}
puerto_b = largo;
set_rtcc(178);
}
// Señal diente de sierra 10Hz
else if(contador == 2 && senal == 2) // señal diente sierra 10Hz
{
largo = largo + 10; // Se incrementa linealmente los valores hasta alcanzar la frecuencias deseada
if(largo >= 100)
{
largo = 0;
}
puerto_b = largo;
set_rtcc(240);
}
// Señal diente de sierra 50Hz
else if(contador == 3 && senal == 2) // señal diente sierra 50Hz
{
largo = largo + 5;
if(largo >= 100)
{
largo = 0;
}
puerto_b = largo;
set_rtcc(253);
}
// Señal diente de sierra 100Hz
else if(contador == 4 && senal == 2) // señal diente sierra 100Hz
{
puerto_b = largo;
set_rtcc(254);
largo = largo + 10;
if(largo >= 100)
{
largo = 0;
}
}
}
void main()
{
set_tris_b(0x00); // Puerto B como salidas digitales
set_tris_c(0xFF); // Puerto C como entradas digitales
set_tris_d(0x00); // Puerto d como salidas digitales
enable_interrupts(global);
enable_interrupts(int_rtcc); // Se habilita interrupciòn por desborde Timer 0 y se activa la interrupciòn global
setup_counters(rtcc_internal, rtcc_div_64); // Se configura con un predivisor de frecuencias 1:64
set_rtcc(240);
set_timer1(0);
senal = 1;
contador = 1;
control_l = 0; // Se inicializa todas la variables y la LCD
control_h = 0;
lcd_init();
do
{
//lcd_init();
// Pulsador para incremento de frecuencia
if(input(PIN_C0)==0) // se presiono el pulsador 1
{
lcd_init();
delay_ms(200); // eliminar antirebote
if(input(PIN_C0)==1)
{
contador = contador + 1; // cuando se acabe el rebote incremento el puerto
if(contador>4)
{
contador = 1; // Si elcontador es mayor a 4 pasa inmediatamente a uno, es decir a la señal de 1Hz
}
}
}
// Pulsador de decremento de frecuencia
if(input(PIN_C1)==0) // se presiono el pulsador 2
{
lcd_init();
delay_ms(200); // eliminar antirebote
if(input(PIN_C1)==1)
{
contador = contador - 1 ;
if(contador == 0)
{
contador = 4; // Si contador es uno pasa imediatamente a 4 es decir a 100hz
}
}
}
// Pulsador de cambio de señal
if(input(PIN_C2)==0) // se presiono el pulsador 3
{
lcd_init();
delay_ms(200); // eliminar antirebote
if(input(PIN_C2)==1)
{
senal = senal + 1 ; // Se incrementa senal en uno para cambiar de señal
if(senal > 2)
{
senal = 1; // Si senal es mayor a 3 vuelve a la señal seno
}
}
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 1 Hz y señal cuadrada
if (contador == 1 && senal == 1 )
{
lcd_gotoxy(5,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc("Cuadrada"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("1Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 10 Hz y señal cuadrada
if (contador == 2 && senal == 1)
{
lcd_gotoxy(5,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc("Cuadrada"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("10Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 50Hz y señal cuadrada
if (contador == 3 && senal == 1)
{
lcd_gotoxy(5,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc("Cuadrada"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("50Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 100 Hz y señal cuadrada
if (contador == 4 && senal == 1)
{
lcd_gotoxy(5,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc("Cuadrada"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("100Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 1 Hz y señal diente de sierra
if (contador == 1 && senal == 2)
{
lcd_gotoxy(0,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc(" Diente Sierra"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("1Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 10 Hz y señal diente de sierra
if (contador == 2 && senal == 2)
{
lcd_gotoxy(0,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc(" Diente Sierra"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("10Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 50Hz y señal dienete de sierra
if (contador == 3 && senal == 2)
{
lcd_gotoxy(0,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc(" Diente Sierra"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("50Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 100 Hz y señal diente de sierra
if (contador == 4 && senal == 2)
{
lcd_gotoxy(0,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc(" Diente Sierra"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("100Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
}
while(true);
}
.
Está un poco extenso, trate de coemntar lo que se hizo, por acá dejo una simulación en el proteus 7.0
Saludos.
-
Saludos
Por acá pongo el código del generador de onda cuadrada y diente de sierra.
Parece que hay un problema cuando se agrega la onda seno porqué el simulador se vuelve loco y empieza a sacar un poco de warning y se empieza a volver lenta la simulación, al parecer el stack del micro se satura.
#if defined(__PCM__)
#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay (clock = 4000000)
#define use_portd_lcd TRUE
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
#byte puerto_b = 06
#byte conta = 0x20
#byte senal2 = 0x21
#byte i2 = 0x22
#include <lcd.c>
int contador,control_l,control_h,largo,senal;
#int_rtcc
desborde()
{
// Señal cuadrada de 1 Hz
if (contador == 1 && senal == 1) // Pulso de 1 Hz
{
control_h = 0;
control_l = control_l + 1;
if(control_l<=100)
{
puerto_b = 100; // Garantizo los primero 50 muestras en alto
}
else
{
puerto_b = 0;
}
if (control_l >200)
{
control_l = 0; // Garantizo las demás 50 muestras en bajo
}
set_rtcc(178); // Se garantiza el periodo de 1s
}
// Señal cuadrada de 10 Hz
else if (contador == 2 && senal == 1) // Pulso de 10Hz
{
control_l = 0;
control_h = control_h + 1;
if(control_h<=50)
{
puerto_b = 100; // Garantizo los primero 50 muestras en alto
}
else
{
puerto_b = 0;
}
if (control_h >100)
{
control_h = 0; // Ultimas muestras en 0 lógico
}
set_rtcc(240); // Se garantiza el periodo de 0.01s
}
// Señal cuadrada de 50 Hz
else if (contador == 3 && senal == 1) // Pulso de 50 Hz
{
control_l = 0;
control_h = control_h + 1;
if(control_h<=50)
{
puerto_b = 100; // Garantizo los primero 50 muestras en alto
}
else
{
puerto_b = 0;
}
if (control_h >100)
{
control_h = 0; // Ultimas muestras en 0 lógico
}
set_rtcc(253); //Garantizo el periodo 0.002s
}
// Señal cuadrada de 100 Hz
else if (contador == 4 && senal == 1) // Pulso de 100 Hz
{
control_l = 0;
control_h = control_h + 1;
if(control_h<=50)
{
puerto_b = 100; // Garantizo los primero 50 muestras en alto
}
else
{
puerto_b = 0;
}
if (control_h >100)
{
control_h = 0; // Ultimas muestras en 0 lógico
}
set_rtcc(254); //Garantizo el periodo 0.001s
}
// Señal diente de sierra 1Hz
if(contador == 1 && senal == 2) // señal diente sierra 1Hz
{
largo = largo + 1; // Se incrementa linealmente los valores hasta alcanzar la frecuencias deseada
if(largo >= 100)
{
largo = 0;
}
puerto_b = largo;
set_rtcc(178);
}
// Señal diente de sierra 10Hz
else if(contador == 2 && senal == 2) // señal diente sierra 10Hz
{
largo = largo + 10; // Se incrementa linealmente los valores hasta alcanzar la frecuencias deseada
if(largo >= 100)
{
largo = 0;
}
puerto_b = largo;
set_rtcc(240);
}
// Señal diente de sierra 50Hz
else if(contador == 3 && senal == 2) // señal diente sierra 50Hz
{
largo = largo + 5;
if(largo >= 100)
{
largo = 0;
}
puerto_b = largo;
set_rtcc(253);
}
// Señal diente de sierra 100Hz
else if(contador == 4 && senal == 2) // señal diente sierra 100Hz
{
puerto_b = largo;
set_rtcc(254);
largo = largo + 10;
if(largo >= 100)
{
largo = 0;
}
}
}
void main()
{
set_tris_b(0x00); // Puerto B como salidas digitales
set_tris_c(0xFF); // Puerto C como entradas digitales
set_tris_d(0x00); // Puerto d como salidas digitales
enable_interrupts(global);
enable_interrupts(int_rtcc); // Se habilita interrupciòn por desborde Timer 0 y se activa la interrupciòn global
setup_counters(rtcc_internal, rtcc_div_64); // Se configura con un predivisor de frecuencias 1:64
set_rtcc(240);
set_timer1(0);
senal = 1;
contador = 1;
control_l = 0; // Se inicializa todas la variables y la LCD
control_h = 0;
lcd_init();
do
{
//lcd_init();
// Pulsador para incremento de frecuencia
if(input(PIN_C0)==0) // se presiono el pulsador 1
{
lcd_init();
delay_ms(200); // eliminar antirebote
if(input(PIN_C0)==1)
{
contador = contador + 1; // cuando se acabe el rebote incremento el puerto
if(contador>4)
{
contador = 1; // Si elcontador es mayor a 4 pasa inmediatamente a uno, es decir a la señal de 1Hz
}
}
}
// Pulsador de decremento de frecuencia
if(input(PIN_C1)==0) // se presiono el pulsador 2
{
lcd_init();
delay_ms(200); // eliminar antirebote
if(input(PIN_C1)==1)
{
contador = contador - 1 ;
if(contador == 0)
{
contador = 4; // Si contador es uno pasa imediatamente a 4 es decir a 100hz
}
}
}
// Pulsador de cambio de señal
if(input(PIN_C2)==0) // se presiono el pulsador 3
{
lcd_init();
delay_ms(200); // eliminar antirebote
if(input(PIN_C2)==1)
{
senal = senal + 1 ; // Se incrementa senal en uno para cambiar de señal
if(senal > 2)
{
senal = 1; // Si senal es mayor a 3 vuelve a la señal seno
}
}
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 1 Hz y señal cuadrada
if (contador == 1 && senal == 1 )
{
lcd_gotoxy(5,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc("Cuadrada"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("1Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 10 Hz y señal cuadrada
if (contador == 2 && senal == 1)
{
lcd_gotoxy(5,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc("Cuadrada"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("10Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 50Hz y señal cuadrada
if (contador == 3 && senal == 1)
{
lcd_gotoxy(5,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc("Cuadrada"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("50Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 100 Hz y señal cuadrada
if (contador == 4 && senal == 1)
{
lcd_gotoxy(5,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc("Cuadrada"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("100Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 1 Hz y señal diente de sierra
if (contador == 1 && senal == 2)
{
lcd_gotoxy(0,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc(" Diente Sierra"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("1Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 10 Hz y señal diente de sierra
if (contador == 2 && senal == 2)
{
lcd_gotoxy(0,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc(" Diente Sierra"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("10Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 50Hz y señal dienete de sierra
if (contador == 3 && senal == 2)
{
lcd_gotoxy(0,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc(" Diente Sierra"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("50Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
// Muestra mensaje de frecuencia y tipo de señal el la LCD para 100 Hz y señal diente de sierra
if (contador == 4 && senal == 2)
{
lcd_gotoxy(0,1); // Ubico el puntero en la posición (8,1) primer fila columna 8
lcd_putc(" Diente Sierra"); // Se escribe el tipo de señal
lcd_gotoxy(8,2); // Ubico en el puntero en la segunda fila columna 5
lcd_putc("100Hz"); // Se escribe la frecuencia de la señal
delay_ms(50);
}
}
while(true);
}
.
Está un poco extenso, trate de coemntar lo que se hizo, por acá dejo una simulación en el proteus 7.0
Saludos.
¿Alguien puede por favor revisar su simulación y ver si genera las dos señales con las cuatro frecuencias distintas? Tengo un error cuando ejecuto Proteus en Windows vista :mrgreen:.
El programa está entretenido :D. Modificas los valores de "contador" y "senal" con los botones y después consultas su valor usando una interrupción por timer generando la onda deseada. Sin embargo, no entiendo para que usas control_h y control_l. ¿Dónde están los arrays que tienen las muestras?
-
Saludos
El programa está entretenido . Modificas los valores de "contador" y "senal" con los botones y después consultas su valor usando una interrupción por timer generando la onda deseada. Sin embargo, no entiendo para que usas control_h y control_l. ¿Dónde están los arrays que tienen las muestras?
No hay necesidad compañero de crear una tabla simplemente como es un señal cuadrada garantizo la mitad del tiempo en alto y la otra mitad en bajo por eso los registros que se mencionan. Lo mismo para señal triangular sólo como tengo un señal diente de sierra está varia linelamente y por eso incremento en forma lineal cada vez que el micro se interrumpe.
Dejame contatarte que ya solucione el problema de la simulación no se que paso, simplemente se me ocurrio cambiar el oreden y funciono :shock:. Todavía me estoy preguntando porqué no simulaba en la otra configuración si no cambie nada de código simplemente cambie el orden del programa, pero quedo más o menos como yo queria salvo el hecho de la señal sinusoidal que me muestra un brinco (salto) bastante marcado como se podría mejorar :lol:.
Voy a seguir trabajando a ver como termina este monachito saludos y a seguir trabajando :-/ :-/
-
No hay necesidad compañero de crear una tabla simplemente como es un señal cuadrada garantizo la mitad del tiempo en alto y la otra mitad en bajo por eso los registros que se mencionan. Lo mismo para señal triangular sólo como tengo un señal diente de sierra está varia linelamente y por eso incremento en forma lineal cada vez que el micro se interrumpe.
Ammmm, ¿y qué pasa con la señal senoidal?
Dejame contatarte que ya solucione el problema de la simulación no se que paso, simplemente se me ocurrio cambiar el oreden y funciono :shock:. Todavía me estoy preguntando porqué no simulaba en la otra configuración si no cambie nada de código simplemente cambie el orden del programa, pero quedo más o menos como yo queria salvo el hecho de la señal sinusoidal que me muestra un brinco (salto) bastante marcado como se podría mejorar :lol:.
Voy a seguir trabajando a ver como termina este monachito saludos y a seguir trabajando :-/ :-/
Excelente, ¿tienes planeado hacerlo en la realidad? Entre una simulación y un circuito real hay mucha diferencia :P.
-
Saludos
Ammmm, ¿y qué pasa con la señal senoidal?
Ni idea compañero que pasa con la señal sinusoidal, hoy estuve trabajando un rato volviendo a revisar el programa y lo veo todo bien. Definitivamente no se que pasa :5]
Excelente, ¿tienes planeado hacerlo en la realidad? Entre una simulación y un circuito real hay mucha diferencia
Pues haber te comento, esté proyectico se lo estoy ayudando hacer a un compañero de estudio, la verdad no se si lo tendrá que implementar, sí así fuera hay si que se pone interesante el proyectico. :mrgreen:
Aprovecho para hacer una consultica en el foro, por ahy estuve leyendo acerca de que el MPLAB permite compilar el código hecho en lenguaje C y crea un archivo .COF "Si no estoy mal" si así es, que me recomiendan que consulte acerca de como programar lenguaje C en el MPLAB.
Saludos