Autor Tema: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876  (Leído 3884 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado alanitotkd

  • PIC10
  • *
  • Mensajes: 20
hola que tal necesito ayuda para poder hacer funcionar todo eso LCD_I2C_2 displays de 7 segmentos y comunicacion serial con el 16f876
de echo ya tengo el programa hecho pero no tengo ninguna interrupcion, todo corrido.
lo cual no soy muy bueno en interrupciones necesito que me envie datos serialmente y multiplexee los displays sin problema .. a y ke el I2C de un Ds1307 se muestre en el LCD


haber si me pueden ayudar a estructurar mi programa para que funcione ..

Help ...

Les dejo mi codigo ..


#include <LCD.c>
#byte portc = 0x07


#define ds_seconds 0x00
#define ds_minutes 0x01
#define ds_hours 0x02
#define ds_day 0x03
#define ds_date 0x04
#define ds_month 0x05
#define ds_year 0x06
#define ds_control 0x07




#define MULT1 PIN_C1
#define MULT2 PIN_C3


int16 time,lm35,retardo=250;
int8 data,unidad,decena;
//Dato en registro ds, a mandar o leer
int seconds,minutes,hours,day,date,month,year,control;

void ds1307(void);
void multiplex(void);


void main()
{
   set_tris_c(0x00);
   SETUP_ADC_PORTS(AN0_AN1_AN3);
   setup_adc(ADC_CLOCK_INTERNAL);
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_2(T2_DIV_BY_4,249,1);    // Timer2 a ikhz
   setup_ccp1(CCP_PWM);
   set_adc_channel(0);
   
   seconds= 0x00;
   minutes= 0x30;
   hours = 0x17;
   day = 0x04;
   date = 0x08;
   month = 0x06;
   year = 0x11;
   control= 0x00;
   
   delay_ms(retardo);

   i2c_start();
   i2c_write(0xd0);
   i2c_write(ds_seconds);

   i2c_write(seconds);
   i2c_write(minutes);
   i2c_write(hours);
   i2c_write(day);
   i2c_write(date);
   i2c_write(month);
   i2c_write(year);
   i2c_write(control);
   i2c_stop();

 lcd_init();
 lcd_putc("\f");
 lcd_putc("Temp: \n");
 lcd_gotoxy(13,1);
 lcd_putc("oC");

   while(TRUE)
   {
   delay_ms(retardo);
   
   i2c_start();
   i2c_write(0xd0); 
   i2c_write(ds_seconds);
   i2c_stop();

   i2c_start();
   i2c_write(0xd1);
   seconds = i2c_read();
   minutes = i2c_read();
   hours = i2c_read();
   day = i2c_read();
   date = i2c_read();
   month = i2c_read();
   year = i2c_read(0);
   i2c_stop();
   
   time = read_adc();
   lm35 = time/10.23;
   time = time*0.97752;
   set_pwm1_duty(time);
   set_timer2(0);
   //delay_ms(200);
   
   data = lm35;
   unidad = data%10;
   decena = data/10;
   
printf("%Lu",lm35);
   multiplex();   
   lcd_gotoxy(7,1);
   printf(lcd_putc,"   ");
   printf(lcd_putc,"%Lu",lm35);
   lcd_gotoxy(1,2);
   printf(lcd_putc,"%2x-%2x-20%2x %2x:%2x:",date,month,year,hours,minutes); //xxx.x °C
   
   }

}
void multiplex(void)
{
portc=decena*16;
     output_high(MULT1);
     delay_ms(15);
     output_low (MULT1);
     delay_ms(15);
     
     portc=unidad*16;
     output_high(MULT2);
     delay_ms(15);
     output_low(MULT2);
     delay_ms(15);
}



espero alguien me pueda ayudar .

saludos

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #1 en: 09 de Junio de 2011, 01:27:26 »
Hola, exactamente que es lo que le quieres cambiar a tu programa, si la comunicacion serie solo la vas a usar para enviar datos y no para recibir no necesitarias interrupcion para rs232.

talvez podrias usar interrupciones de timer para multiplexar tus displays o para hacer la impresion en la lcd.

no se si entendi bien lo que quieres, ppero si no corrigeme y vere en que puedo ayudarte
"Nada es imposible, no si puedes imaginarlo"

Desconectado alanitotkd

  • PIC10
  • *
  • Mensajes: 20
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #2 en: 09 de Junio de 2011, 01:34:28 »
claro es lo que quiero ... poder multiplexar los diaplay's y mandar imprimir al LCD con interrupciones ya que si corro el programa asi como esta ... la vrd imprime los display's y espera a que retorne el ciclo para volver a hacerlo

igual con el LCD... y el I2C del reloj .. tardan mucho en ejecutarse..

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #3 en: 09 de Junio de 2011, 01:50:30 »
puedes usar el timer0 para que te genere una interrupcion y hagas el corrimiento de tus displays.

para usar la interrupcion necesitas primero configurar el timer para que te de el tiempo de desbordamiento que quieras(supongo que sabes esto, si no me dices y te digo como)

para activar la interrupcion necesitas poner

enable_interrupts(int_timer0);
enable_interrupts(global);


y declarar la funcion de interrupcion respectiva que en este caso seria


#int_timer0
void mux()
{

..... aca pones lo quieres que haga en la interrupcion
}
"Nada es imposible, no si puedes imaginarlo"

Desconectado alanitotkd

  • PIC10
  • *
  • Mensajes: 20
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #4 en: 09 de Junio de 2011, 02:12:37 »
creo que ya lo agregue como me dijiste ... solo que quisiera que me ayudaras un poco por ke que el multiplexeo esta bien pero
no me agrada mucho lo que veo creo ke estoy haciendo algo mal  ... te adjunto mi archivo y la simulacion ...



Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #5 en: 09 de Junio de 2011, 02:18:00 »
te falto agregar el .h, no me deja compilar.

el multiplexeo no creo que se vea en la simulacion como se veria realmente, creo que tendrias que probarlo fisicamente para que veas si se prenden bien los displays
"Nada es imposible, no si puedes imaginarlo"

Desconectado alanitotkd

  • PIC10
  • *
  • Mensajes: 20
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #6 en: 09 de Junio de 2011, 02:20:40 »
hola seguimos viendo que onda... mira te adjunto con el .h

creo ke tengo un error en la funcion bcd()
me aparecen 2 warnings....
y en la interrucion del timer 0
puse delay's no importa ?

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #7 en: 09 de Junio de 2011, 02:32:51 »
algunos comentarios.

el warning que te da por bcd es porque lo estas declaranto como variable, pero lo abajo lo pones como funcion, si es funcion no necesitas declararlo arriba solo pon

int bcd()
{
...
return valor
}

y pusiste la interrupcion pero la estas usando mal, la idea de la interrupcion era para que quitaras los delays, es decir, entra una vez a la interrupcion y prendes el display 1, y cuando vuelva a entrar apagas el display 1 y prendes el 2, y asi los vas alternando
"Nada es imposible, no si puedes imaginarlo"

Desconectado alanitotkd

  • PIC10
  • *
  • Mensajes: 20
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #8 en: 09 de Junio de 2011, 02:42:05 »
entonces seria algo parecido como ... 

int flag;
flag = 0;
#int_timer0
void mux()
{   
flag ++;
switch(flag)
{   
     case 1:
     portc=decena*16;
     output_high(MULT1);
     break;
     
     case 2:
     output_low (MULT1);
     break;

     case 3:
     portc=unidad*16;
     output_high(MULT2);
     break;

     case 4:
     output_low(MULT2);     
     break;
}
if (flag ==4)
flag = 0;
}




o como ... ? es ke no entiendo muy bien eso ...

     

     
   

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #9 en: 09 de Junio de 2011, 02:50:46 »
si, mas o menos asi, podria ser asi:

int1 flag

Código: [Seleccionar]
#int_timer0
void mux()
{
if(flag)//si vas a prender el display 1
{
     output_low(display2);  apagas el display 2
     //sacas el valor para el display 1
    ouput_high(display 1); prendes el display 1
    flag=false
}

else
{
    output_low(display 1);  apagas el display 1
     //sacas el valor para el display 2
    ouput_high(display 2); prendes el display 2
    flag=true
   
}
}


espero se entienda, no necesitas 4 estados, porque tienes 2 estados en los que estan apagados los 2 displays, solo necesitas alternar entre uno y otro y en hardware no se vera que parpadean
"Nada es imposible, no si puedes imaginarlo"

Desconectado alanitotkd

  • PIC10
  • *
  • Mensajes: 20
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #10 en: 09 de Junio de 2011, 03:07:38 »
ok correcto ...
lo estoy haciendo de esa manera ... al simularlo el PWM varia a lo loco ... y no esta en el valor que debe ser ... no se si te paso lo mismo en mi simulacion??
varia el ancho del pulso ... dsenfrenadamente .... ke podra ser . ???



#include "FINAL_UC1.h"
#include <LCD.c>
#byte portc = 0x07

//Registros DS1307
#define ds_seconds 0x00
#define ds_minutes 0x01
#define ds_hours 0x02
#define ds_day 0x03
#define ds_date 0x04
#define ds_month 0x05
#define ds_year 0x06
#define ds_control 0x07


#define MULT1 PIN_C1
#define MULT2 PIN_C3
//#use standard_io (C)

int16 time,lm35,retardo=250;
int8 data,unidad,decena;
//Dato en registro ds, a mandar o leer
int seconds,minutes,hours,day,date,month,year,control;
int8 bcd();
void ds1307(void);
void multiplex(void);
int1 flag;

#int_timer0
void mux()
{
if(flag)//si vas a prender el display 1
{
     output_low(MULT2);  //apagas el display 2
     portc=decena*16; //sacas el valor para el display 1
    output_high(MULT1); //prendes el display 1
    flag=false;
}
else
{
    output_low(MULT1); // apagas el display 1
    portc=unidad*16;   //sacas el valor para el display 2
    output_high(MULT2); //prendes el display 2
    flag=true;
}
}


void main()
{
   set_tris_c(0x00);
   SETUP_ADC_PORTS(AN0_AN1_AN3);
   setup_adc(ADC_CLOCK_INTERNAL);
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_2(T2_DIV_BY_4,249,1);    // Timer2 a ikhz
   setup_ccp1(CCP_PWM);
   enable_interrupts(int_timer0);
   enable_interrupts(global);

   set_adc_channel(0);
   
   seconds= 0x00;
   minutes= 0x30;
   hours = 0x17; //modo 24 hrs
   day = 0x04; //1 es domingo
   date = 0x08;
   month = 0x06;
   year = 0x11;
   control= 0x00; //OUT=0 SQWE=0 RS0-1=0 no hay onda cuadrada
   
   delay_ms(retardo); //Usuario lee
   //Establece fecha y hora
   i2c_start(); //Inicia I2C
   i2c_write(0xd0); //Direcciona DS1307 write
   i2c_write(ds_seconds); //Indica que empiece en registro ds_seconds
   //Aquí establece fecha y hora respecto a la puesta arriba
   i2c_write(seconds);
   i2c_write(minutes);
   i2c_write(hours);
   i2c_write(day);
   i2c_write(date);
   i2c_write(month);
   i2c_write(year);
   i2c_write(control);
   i2c_stop(); //Ya puso la hora y fecha
   //El RTC ya está marcando el tiempo y fecha

//Rutina LCD
 lcd_init();
 lcd_putc("\f"); //Limpia LCD
 lcd_putc("Temp: \n");
 lcd_gotoxy(13,1);
 lcd_putc("oC");

   while(TRUE)
   {
   time = read_adc();
   printf("%Ld",time);
   lm35 = time/10.23;
   data = lm35;
   data=bcd();
   set_pwm1_duty(time);
   set_timer2(0);
   delay_ms(200);
   
   
   delay_ms(retardo); //Usuario lee
   i2c_start(); //Inicia I2C
   i2c_write(0xd0); //Direcciona DS1307 write
   i2c_write(ds_seconds); //Indica que ponga registro en ds_seconds
   i2c_stop();

   i2c_start();
   i2c_write(0xd1); //Lee DS1307
   seconds = i2c_read();
   minutes = i2c_read();
   hours = i2c_read();
   day = i2c_read();
   date = i2c_read();
   month = i2c_read();
   year = i2c_read(0); 
   i2c_stop();
   

   lcd_gotoxy(7,1);
   printf(lcd_putc,"%Lu",lm35); //xxx.x °C
   lcd_gotoxy(1,2);
   printf(lcd_putc,"%2x-%2x-20%2x %2x:%2x:",date,month,year,hours,minutes); //xxx.x °C
   
   }

}


int bcd()

    unidad = data%10;
    decena = data/10;
}

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #11 en: 09 de Junio de 2011, 03:19:11 »
me parece raro que te haga eso, solo lo estas tomando de tu ADC, cada cuando necesitas hacer tu muestreo y enviar tus datos por i2c?
tal vez lo estes muestreando muy rapido, tal vez podrias usar la interrupcion por timer 1 para hacer una lectura en cada interrupcion y luego enviar tus datos por i2c.

si quieres ver paso por paso que esta pasando con tu programa, o porque varia asi el pwm puedes vero en proteus, al tu pic cargale el archivo .cof en lugar del .hex, y cuando pongas pausa te abrira la linea de codigo de tu programa y podras ver las variables y saber linea a linea que hace tu programa
"Nada es imposible, no si puedes imaginarlo"

Desconectado alanitotkd

  • PIC10
  • *
  • Mensajes: 20
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #12 en: 09 de Junio de 2011, 03:25:43 »
No es que tiene que mostrar el reloj en tiempo real del ds1307 y a la ves tomar la lectura del ADC de un lm35 acondicionado. el valor del adc de 10 bits se va a enviar al pwm y multiplexar el% de modulacion por los displays. mandar el adc tambien por serial y la hora con fecha y temperatura mostrarlas en un LCD

esta medio raro ...

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #13 en: 09 de Junio de 2011, 03:29:10 »
si quieres mostrar en tiempo real, porque no haces un muestreo cada segundo, puede configurar el timer 1 para que te de la interrupcion cada segundo y en ese momento tendrias un segundo antes del siguiente muestreo para actualizar tus datos y enviar por i2c
"Nada es imposible, no si puedes imaginarlo"

Desconectado alanitotkd

  • PIC10
  • *
  • Mensajes: 20
Re: USO DE ADC_PWM_LCD_I2C_RS232_DISPLAY'S 7 SEGMENTOS CON 16F876
« Respuesta #14 en: 09 de Junio de 2011, 03:35:28 »
me parece muy bueno eso ... nad mas ke no se usar esa interrupcion... si me puedes ayudar con eso ...
eso es lo que keria hacer ...


 

anything