Hola
Quisiera saber si existe alguna forma de ir incrementando la frecuencia en valores de 50 Hz hasta llegar a 1000 Hz, yo lo estoy haciendo con delays pero como la base es en ms pues obviamente la de frecuencia no es la misma. La verdad no le hallo como hacerle, estaba pensando en usar timers pero las diferencias en ms no son constantes y pues no hallo como. Si alguien me puede ayudar le agradecería bastante. El programa que tengo es este:
Codigo:
#include <16f874A.h>
#fuses HS, NOPROTECT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#BIT RBIF=0xB.0
#byte PORTB=0x06
#include <lcd.c>
int i;
float periodo=100;
int tecla=0;
float freq;
void retardo()
{
for(i=1;i<=periodo;i++)
{
delay_ms(10);
}
}
void flash()
{
output_a(5);
retardo();
output_a(6);
retardo();
output_a(10);
retardo();
output_a(9);
retardo();
}
void opcion()
{
if(tecla==1)
{
tecla=0;
if(periodo==1)
periodo=100;
else
periodo=periodo-1;
}
if(tecla==2)
{
tecla=0;
if(periodo==100)
periodo=1;
else
periodo=periodo+1;
}
}
void despliegue_lcd()
{
lcd_putc("f");
lcd_gotoxy(13,1);
printf(lcd_putc,"Hz"
;
freq=1000/periodo;
lcd_gotoxy(1,1);
printf (lcd_putc, "Freq=%3.3f", freq);
}
#int_RB
void interrupcion()
{
int current;
static int last=0xF0;
delay_ms(50);
current=PORTB;
if (!(bit_test(current,4))&&(bit_test(last,4))) {tecla=1;} if (!(bit_test(current,5))&&(bit_test(last,5))) {tecla=2;} if (!(bit_test(current,6))&&(bit_test(last,6))) {tecla=3;}
if (!(bit_test(current,7))&&(bit_test(last,7))) {tecla=4;}
last=current;
opcion();
despliegue_lcd();
}
void main()
{
set_tris_a(0x00);
port_b_pullups(TRUE);
RBIF=0;
enable_interrupts(int_RB);
enable_interrupts(global);
lcd_init();
despliegue_lcd();
while(TRUE)
{
flash();
}
}
Hola..
Yo lo haria por PWM, el problema es que empezaria aproximadamente desde 300Hz y hay para arriba no tendras problema, mas o menos sería algo de este estilo
Codigo:
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_ccp1(CCP_PWM); // asigno el PWM al modulo ccp1
setup_timer_2(T2_DIV_BY_1, 48, 1); // configuración frecuencia
set_pwm1_duty(25); // Ancho de pulso
while(TRUE){}
}
Este es para 425Hz.. con un cristal de 4Mhz, el calculo es de esta forma..
Frecuencia = 1 / ((frec_cristal^-1)*4*t2div*(periodo+1))
setup_timer_2(t2div,periodo,postscale)
Pues de hay conoces todo menos el periodo.. lo despejas y ya lo reemplazas en la función setup.. cuadras el duty.. y asignas el PWM al ccp1 o ccp2
Hola
Gracias por los consejos pero yo lo que ando buscando es no usar el PWM, por eso quiero ver si existe alguna forma de manejarlo con delays. Yo lo he estado intentando pero tengo dudas en cierta parte de mi programa, siendo específico en la función ajuste. Me podrían echar la mano, lo que quiero es partir un flotante en parte entera y parte fraccionaria. Este es el código:
Codigo:
#include <16f874A.h>
#include <math.h>
#fuses HS, NOPROTECT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#BIT RBIF=0xB.0
#byte PORTB=0x06
#include <lcd.c>
int i;
float msec=20;
int usec=0;
float dato=1;
int tecla=0;
float freq;
void retardo()
{
for(i=1;i<=msec;i++)
{
delay_ms(1);
}
if(usec>0)
{
for(i=1;i<=usec;i++)
{
delay_us(10);
}
}
}
void flash()
{
output_a(5);
retardo();
output_a(6);
retardo();
output_a(10);
retardo();
output_a(9);
retardo();
}
void opcion()
{
if(tecla==1)
{
tecla=0;
if(dato==20)
dato=1;
else
dato=dato+1;
}
if(tecla==2)
{
tecla=0;
if(dato==1)
dato=20;
else
dato=dato-1;
}
}
void ajuste()
{
msec=fmod(20,dato);
usec=((20/dato)-msec)*100;
}
void despliegue_lcd()
{
lcd_putc("f");
lcd_gotoxy(12,1);
printf(lcd_putc,"Hz"
;
freq=dato*50;
lcd_gotoxy(1,1);
printf (lcd_putc, "Freq=%4.1f", freq);
}
#int_RB
void interrupcion()
{
int current;
static int last=0xF0;
delay_ms(50);
current=PORTB; //Valor actual del puerto B
if (!(bit_test(current,4))&&(bit_test(last,4))) {tecla=1;}
if (!(bit_test(current,5))&&(bit_test(last,5))) {tecla=2;}
if (!(bit_test(current,6))&&(bit_test(last,6))) {tecla=3;}
if (!(bit_test(current,7))&&(bit_test(last,7))) {tecla=4;}
last=current;
opcion();
ajuste();
despliegue_lcd();
}
void main()
{
set_tris_a(0x00);
port_b_pullups(TRUE);
RBIF=0;
enable_interrupts(int_RB);
enable_interrupts(global);
lcd_init();
despliegue_lcd();
while(TRUE)
{
flash();
}
}
Gracias por la ayuda
Hola..
Yo lo hice por medio de la interrupcion del TMR0..
Claro que ya no me acuerdo como fue que le hice para calcular el tiempo, salen tres señales..
pongo el programa.. depronto te sirve
Codigo:
#define INTS_PER_SECOND 1
#define aux 4
byte seconds, sec2;
int int_count, sec;
short flag, flag1, flagb;
#int_RTCC
void clock_isr(){
if(--int_count==0) {
++seconds;
int_count=INTS_PER_SECOND;
if(flag==0){
flag=1;
output_high(PIN_B1);
}else{
flag=0;
output_low(PIN_B1);
}
}
if(--sec==0) {
++sec2;
sec=aux;
if(flag1==0){
flag1=1;
output_high(PIN_B2);
}else{
flag1=0;
output_low(PIN_B2);
}
}
set_rtcc(235);
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while(TRUE){
if(flagb==0){
flagb=1;
output_high(PIN_B3);
//delay_cycles(1);
}else{
flagb=0;
output_low(PIN_B3);
//delay_cycles(1);
}
}
}
La maxima freduencia que logro es aproximadamente 12Khz
Gracias a todos por su ayuda, ya quedó como yo quería. Fue cuestion de entender el manejo de los enteros con los flotantes.
Codigo:
#include <16f874A.h>
#include <math.h>
#fuses HS, NOPROTECT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#BIT RBIF=0xB.0
#byte PORTB=0x06
#include <lcd.c>
int i;
int msec=100;
int usec=0;
float dato=1;
int tecla=0;
float freq;
void retardo()
{
for(i=1;i<=msec;i++)
{
delay_ms(1);
}
if(usec>0)
{
for(i=1;i<=usec;i++)
{
delay_us(10);
}
}
}
void flash()
{
output_a(5);
retardo();
output_a(6);
retardo();
output_a(10);
retardo();
output_a(9);
retardo();
}
void opcion()
{
if(tecla==1)
{
tecla=0;
if(dato==100)
dato=1;
else
dato=dato+1;
}
if(tecla==2)
{
tecla=0;
if(dato==1)
dato=100;
else
dato=dato-1;
}
}
void ajuste()
{
msec=100/dato;
usec=((100/dato)-msec)*100;
}
void despliegue_lcd()
{
lcd_putc("f");
lcd_gotoxy(12,1);
printf(lcd_putc,"Hz"
;
freq=dato*10;
lcd_gotoxy(1,1);
printf(lcd_putc, "Freq=%4.1f", freq);
lcd_gotoxy(1,2);
printf(lcd_putc, "msec=%3d",msec);
lcd_gotoxy(9,2);
printf(lcd_putc, "usec=%2d",usec);
}
#int_RB
void interrupcion()
{
int current;
static int last=0xF0;
delay_ms(50);
current=PORTB; //Valor actual del puerto B
if (!(bit_test(current,4))&&(bit_test(last,4))) {tecla=1;}
if (!(bit_test(current,5))&&(bit_test(last,5))) {tecla=2;}
if (!(bit_test(current,6))&&(bit_test(last,6))) {tecla=3;}
if (!(bit_test(current,7))&&(bit_test(last,7))) {tecla=4;}
last=current;
opcion();
ajuste();
despliegue_lcd();
}
void main()
{
set_tris_a(0x00);
port_b_pullups(TRUE);
RBIF=0;
enable_interrupts(int_RB);
enable_interrupts(global);
lcd_init();
despliegue_lcd();
while(TRUE)
{
flash();
}
}