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.