Programas para Pic C Compiler (Tutorial)

Que tal, queria saber si alguien me puede dar una idea de cÓmo hacer lo siguiente:
Necesito hacer con el pic18f452 un dispositivo que va a tener 4 sensores de presencia (a,b,c y d) necesito que al ser accionados en el orden descrito me muestre en una lcd la velocidad entre a y b, entre b y c, y entre c y d, pero que me las vaya mostrando cuando presiono un boton, si alguien tiene alguna idea de como hacer esto por favor haganmelo saber, muchas gracias
 
Que tal de nuevo,
tengo el mismo problema de medir el tiempo real que pasa entre dos pulsos,
ya tengo un avance con algo de investigación que he realizado, cuando presiono un botón en la simulación en proteus (simulando el primer pulso o sensor) empieza a contar el tiempo, cuando lo presiono por segunda ocas Ión (simulando el sensor dos o pulso 2) me muestra en la lcd el tiempo pero la mera verdad no sé si es la correcta, me lo muestra en micro segundos, pero cuando dejo que pase mas tiempo entre los pulsos parece ser que mide el mismo tiempo,
*lo que necesito es mostrar el tiempo real y en segundos, como comentario puse una lÍnea donde me lo podría mostrar en segundos pero sigue siendo lo mismo,, les agradecería muchísimo su ayuda, plis hheeeelp!En la realidad los sensores son de presencia los cuales son activados por un objeto que pasa muy rápido por ellos y lo que intento es medir el tiempo real en segundos que tarda en pasar del 1° al 2° sensor la distancia entre sensores es aproximadamente de 20cm.

a continuación les dejo el código y la simulación para que se observe lo que me muestra
Código:
#include "C:\Users\G\Documents\.Docs GFT\TRABAJOS(pic)\tiempo entre pulsos\MedTEP.h"
#use delay(clock=4000000)
float const uSxTick = 1;
#define LCD_TYPE 2
#include <lcd.c>                                   
int8  numFlancoQueLlega=0;                   // Número de Flanco que llega
int1  flagToggleFlanco=0;                    // Flag para cambiar de flanco
int16 t1=0x00,t2=0x00,t3=0x00;               // Variables para guardar estados de timers y pulsos
int16 tth=0x00,ttl=0x00,tt=0x00;            
float sth=0.0,stl=0.0,st=0.0,T=0.0;          // Para hacer las restas oportunas en uS
int1  flagHayDatos=0;                        // Flag para indicar que ya hay datos                                         // dos flancos (de subida y bajada)60.
#int_ext
void handle_ext_int()
{
++numFlancoQueLlega;                         // Cuento flanco que llega
   if(flagToggleFlanco==0)
   {                                         // He recibido Flanco de Subida
      if(numFlancoQueLlega==1)
      {
      set_timer1(0);                         // Reinicio TMR1
      t1=get_timer1();                       // Guardo en t1 el valor de TMR1 al primer Flanco de Subida      
      }
      if(numFlancoQueLlega==3)
      {
      t3=get_timer1();                       // Guardo en t1 el valor de TMR1 al primer Flanco de Subida101.
         if(flagHayDatos==0)
         {               
         flagHayDatos=1;                     // Indico que ya hay nuevos datos de flancos para calcular       
         }      
      } 
      ext_int_edge(0,H_TO_L);                // Configuro para capturar siguiente flanco de Bajada    
      flagToggleFlanco=1;                    // Indico que el siguiente flanco será de Bajada
   } 
   else 
   {                                         // He recibido Flanco de Bajada
   t2=get_timer1();                          // Guardo en t2 el valor de TMR1 al Flanco de Bajada    
   ext_int_edge(0,L_TO_H);                   // Configuro para capturar siguiente flanco de subida    
   flagToggleFlanco=0;                       // Indico que el siguiente flanco será de Subida  
   }
}
void main()
{
   lcd_init();
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
//Setup_Oscillator parameter not selected from Intr Oscillotar Config tab

   // TODO: USER CODE!!

   delay_ms(333);
   disable_interrupts(global);
   disable_interrupts(int_timer1); 
   disable_interrupts(int_rda);
   disable_interrupts(int_ext);   
   disable_interrupts(int_ext1);   
   disable_interrupts(int_ext2);   
   setup_adc_ports(NO_ANALOGS); 
   setup_adc(ADC_OFF);   
   setup_spi(FALSE);  
   setup_psp(PSP_DISABLED);   
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);  
   setup_timer_0(RTCC_OFF);   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);   
   setup_timer_2(T2_DISABLED,0,1);  
   setup_timer_3(T3_DISABLED);   
   port_b_pullups(FALSE);  
   
   delay_ms(333);
   ext_int_edge(0,L_TO_H);
   flagToggleFlanco = 0;
   enable_interrupts(int_rda);
   enable_interrupts(int_ext);   
   enable_interrupts(global);
   lcd_gotoxy(1,1);
   lcd_putc("FISICA");
   do 
   {
      if(flagHayDatos==1)
      {
         if((t3>t2)&&(t2>t1))
         {
         tth = t2 - t1;
         ttl = t3 - t2;
         tt  = tth + ttl;
         sth = uSxTick * tth;
         stl = uSxTick * ttl;
         st  = uSxTick * tt;
         //T = st*.000001;
         lcd_gotoxy(1,2);
         printf(lcd_putc," T=%1.1fuSeg",st);
         }
      }
   }
   while(true);
}
 

Adjuntos

  • med tiempo.jpg
    med tiempo.jpg
    104.8 KB · Visitas: 97
Última edición por un moderador:
grasia por los aporte me sirvi mucho el del motor a pasos disculpa como soy nuevo en eto no me podrias explicar como aser un pwm para un servo con 18f452 es que no les entiendo muy bien
 
Hola estoy programando en ccs c y estoy aprendiendo a utilizar los Timer para generar un retardo de 8.33ms, pero no entiendo como "entra" la interrupción del Timer0, hice un calculo para cargar el Timer0 cada 2.78ms y también puse un contador que cuando llega a 3 pone en alto el RB0 y si el contador es mayor a 4 pone en bajo a RB0, ¿como puedo hacer que en RB0 este en alto 8.33ms y después RB0 este em bajo otros 8.33ms, por lo que entiendo es que si el contador llega a 3 el Timer entra 3 veces por lo que se tendría 3 x 2.78ms = 8.33ms, no se si esto esta bien, espero que me puedan ayudar corrigiendo mi error ya que este retardo lo necesito para un proyecto escolar, anexo el código que hice, GRACIAS.

Código:
#include <16F873A.H>         //Libreria del Pic Implementado.
#fuses HS, NOWDT, PUT, NOLVP   //Deshbilita el Doggy, Oscilador Externo.
#use delay( clock = 20M )      //Frecuencia de Reloj.
#byte port_B = 0x06            //Direccion del Puerto B.

 int Cont = 0;               //Variable que Cuenta.

#int_Timer0                  //Interrupcion del Timer0.               
void TIMER0_isr( void )
   {
      Cont++;               //Incrementa el Contador.
      set_timer0( 39 );     //Carga el Timer0.
   }
   
void main( void )
   {  
      set_tris_B( 0x00 );   //Puerto B como Salida.
      setup_timer_0( RTCC_INTERNAL | RTCC_DIV_64 );   //Preescaler de 64.
      enable_interrupts( INT_TIMER0 );      //Habilita la Interrupcion del Timer0.
      enable_interrupts( GLOBAL );         //Habilita la Interrupcion Global.
      set_timer0( 39 );               //Carga el Timer0.
      
      while( 1 )
      {
         if( Cont == 3 )            //Si Llega 3 RB0 = 1.
            {
               output_high( PIN_B0 );
            }
         else if( Cont > 4 )        //Si llega 4 RB0 = 0.
            {
               output_low( PIN_B0 );
               Cont = 0;
            }
      }
}
 
Última edición por un moderador:
Hola de Nuevo Tengo un problema con un programa que hice, quiero que con un botón mover un motor a pasos con 3 diferentes casos uno en que esta detenido, izquierda y derecha,el programa que hice solo hace la secuencia de la derecha la de izquierda y detenido no lo hace.

Lo que hice es detectar los flancos de bajada y subida e ir cambiándolos en la interrupción pero no lo hace, si primero detecta un flanco de bajada seguiría la secuencia derecha y con esto cambiaría la detección del flaco a uno de subida, si logra detectar un cambio en el flanco tendría que seguir haciendo la secuencia de derecha y de nuevo cambia para que detecte un flanco de bajada para que ahora siga la secuencia correspondiente pero creo que la interrupción no lo hace o tal vez las condiciones que puse no están bien. Espero que puedan corregirme y ayudar a solucionar mi problema, Anexo mi código. Gracias.

Código:
#include <16F648A.H>   //Libreria del PIC Implementado.
#fuses HS, NOWDT, NOLVP, PUT, MCLR   //Oscilador Externo, Deshabilita el Doggy.
#use delay( clock = 20M )   //Crystal de 20MHz.
#byte port_A = 0x05         //Direccion del Puerto A.
#byte port_B = 0x06         //direccion del Puerto B.

int Pasa = 0, Cont = 0;

#INT_EXT
void ext_isr( void )
   {
      int PC;
                   
      if( Cont == 0 & Pasa == 0 | Cont == 0 & Pasa == 1 )
         {
           if( Pasa == 0 )
              {
                 ext_int_edge( 0, L_TO_H );
                 Pasa = 1;
                 Cont = 0;
              }
           else if( Pasa == 1 )
              {
                 ext_int_edge( 0, H_TO_L );
                 Cont = 1;
                 Pasa = 0;
              }
           do{
               PC = 0xC0;
               port_B = PC;
               delay_ms( 500 );
           
               PC = PC - 0X60;
               port_B = PC;
               delay_ms( 500 );
            
               PC = PC - 0X30;
               port_B = PC;
               delay_ms( 500 );
            
               PC = PC + 0X60;
               port_B = PC;
               delay_ms( 500 );
            
               PC = PC - 0X90;
               port_B = PC;
               delay_ms( 10 );
           }while( 1 );     
           
           if( Pasa == 0 )
              {
                 ext_int_edge( 0, L_TO_H );
                 Pasa = 1;
                 Cont = 0;
              }
           else if( Pasa == 1 )
              {
                 ext_int_edge( 0, H_TO_L );
                 Cont = 1;
                 Pasa = 0;
              }
         }
         
      if( Cont == 1 & Pasa == 0 | Cont == 1 & Pasa == 1 )
         {
            if( Pasa == 0 )
               {
                  ext_int_edge( 0, L_TO_H );
                  Cont = 1;
                  Pasa = 1;
               }
            else if( Pasa == 1 )
               {
                  ext_int_edge( 0, H_TO_L );
                  Cont = 2;
                  Pasa = 0;
               }
            do{
               PC = 0x90;
               port_B = PC;
               delay_ms( 500 );
            
               PC = PC - 0x60;
               port_B = PC;
               delay_ms( 500 );
            
               PC = PC + 0x30;
               port_B = PC;
               delay_ms( 500 );
            
               PC = PC + 0x60;
               port_B = PC;
               delay_ms( 500 );
            
               PC = PC - 0xC0;
               port_B = PC;
               delay_ms( 10 );
            }while( 1 );
         }
            
      if( Cont == 2 & Pasa == 0 | Cont == 2 & Pasa == 1 )
         {
            if( Pasa == 0 )
               {
                  ext_int_edge( 0, L_TO_H );
                  Cont = 2;
                  Pasa = 1;
               }
            else if( Pasa == 1 )
               {
                  ext_int_edge( 0, H_TO_L );
                  Cont = 0;
                  Pasa = 0;
               }
            do{
               port_B = 0x00;
               delay_ms( 10 );
            }while( 1 );
         }
   }

void main( void )
   { 
      set_tris_B( 0x01);
      port_B = 0x00;
      
      Pasa = 0;
      Cont = 0;
      
      ext_int_edge( 0, H_TO_L );
      enable_interrupts( INT_EXT );
      enable_interrupts( GLOBAL );
      
      while( 1 )
      {  
      }
   }
 
Última edición por un moderador:
Después de pensar un poco lo corregí, creo que sobraba mucho código, se que esta muy básico pero es que apenas estoy empezando lo único que falta es que cada secuencia dure hasta el próximo flanco eso no se como hacerlo dejo de nuevo el código para que lo puedan corregir si esta mal, ojala puedan ayudarme con lo del tiempo de cada secuencia, pienso que puede ser con un timer, pero mejor ayúdenme. Gracias.

Código:
#include <16F886.H>   //Libreria del PIC Implementado.
#fuses HS, NOWDT, NOLVP, PUT, MCLR   //Oscilador Externo, Deshabilita el Doggy.
#use delay( clock = 20M )   //Crystal de 20MHz.
#include <LCD_PORTC.C>      //Libreria del LCD.
#byte port_A = 0x05         //Direccion del Puerto A.
#byte port_B = 0x06         //direccion del Puerto B.

int PC, Cont = 0;         //Variable que Cuenta y Paso Completo.

void Derecha( void )
   {
      printf( lcd_putc, "\fMotor Derecha");   //Muestra Motor Derecha.
      
      PC = 0xC0;
      port_B = PC;
      delay_ms( 500 );
           
      PC = PC - 0X60;
      port_B = PC;
      delay_ms( 500 );
            
      PC = PC - 0X30;
      port_B = PC;
      delay_ms( 500 );
            
      PC = PC + 0X60;
      port_B = PC;
      delay_ms( 500 );
            
      PC = PC - 0X90;
      port_B = PC;
      delay_ms( 5 );            
      
      printf( lcd_putc, "\fMotor Detenido");   //Muestra Motor Detenido.
   }

void Izquierda( void )
   {
      printf( lcd_putc, "\fMotor Izquierda" );   //Muestra Motor Izquierda.
      
      PC = 0x90;         //Secuencia Motor Izquierda.
      port_B = PC;
      delay_ms( 500 );
            
      PC = PC - 0x60;
      port_B = PC;
      delay_ms( 500 );
            
      PC = PC + 0x30;
      port_B = PC;
      delay_ms( 500 );
            
      PC = PC + 0x60;
      port_B = PC;
      delay_ms( 500 );
            
      PC = PC - 0xC0;
      port_B = PC;
      delay_ms( 5 );
      
      printf( lcd_putc, "\fMotor Detenido");   //Muestra Motor Detenido.
   }
   
void Detenido( void )
   {
      printf( lcd_putc, "\fMotor Detenido");   //Muestra Motor Detenido.
      
      port_B = 0x00;   //Secuencia Motor Detenido.
      delay_ms( 500 );
      
      printf( lcd_putc, "\fMotor Detenido");   //Muestra Motor Detenido.
   }
   
#INT_EXT
void ext_isr( void )
   {               
      if( Cont == 0 )      //Compara el Contador.
         {
           Detenido();   //Llama a Detenido.
           
           ext_int_edge( 0, L_TO_H );   //Cambia a Flanco de Subida.
           Cont = 1;      //Incrementa al Contador.
         }
         
      else if( Cont == 1 )    //Compara el Contador.
         {
            Derecha();    //Llama a Derecha.

            ext_int_edge( 0, H_TO_L );   //Cambia a Flanco de Bajada.
            Cont = 2;   //Incrementa al Contador.
         }
         
      else if( Cont == 2 )   //Compara el Contador.
         {
            Izquierda();    //Llama a Izquierda.
            
            ext_int_edge( 0, H_TO_L );   //Cambia a Flanco de Bajada.
            Cont = 0;   //Reinicia el Contador.
         }
   }

void main( void )
   { 
      set_tris_B( 0x01);   //RB7 - RB2 como Salidas, RB0 como Entrada. 
      port_B = 0x01;      //Iniciliza el Puerto B.
      
      lcd_init();   //Iniciliza el LCD.
      Cont = 0;         //Iniciliza el Contador.
      printf( lcd_putc, "\fMotor A Pasos");   //Muestra Motor A Pasos.
      
      ext_int_edge( 0, H_TO_L );      //Inicia con un Flanco de Bajada.
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa.
      enable_interrupts( GLOBAL );   //Habilita la Interrupcion Global.
      
      while( 1 )
      {  
      }
   }
 
Última edición por un moderador:
Hola quiero hacer un sistema de censado de potencia, ya tengo los sensores de corriente por efecto Hall, que son no invasivos y para censar el voltaje no tengo mayor problema, estoy usando PIC18f2550 y ya tengo la parte de conversión analógica a digital y la exhibición en una LCD 16x2 sin embargo no se como hacer para almacenar los datos en algún dispositivo como una memoria por ejemplo, ni como programar la interfaz con un puerto USB, para poder obtener a través de una memoria o una PC los datos resguardados para su posterior análisis, alguien tendra algún tutorial avanzado para poder hacer lo que les comento... De antemano le agradezco su atención...
 
Hola que tal, ojala me puedan ayudar con este programa, estoy intentando generar un pulso de 100useg a partir de un pwm sincronizado con la linea, lo que hago es detectar flacos de subida y bajada de un cruce por cero para lograr la sincronía, puse una interrupción externa y entra un flanco de bajada empieza a leer el adc ( resolución de 10 ) y a generar el pwm, el pwm si modula pero solo a la mitad del pulso del cruce por cero y la verdad no se por que hace esto. Pienso que que los 1024 valores del adc no son suficientes para abarcar el estado alto de la onda cuadrada del cruce por cero, lo que pienso es asignar a un valor del tiempo a cada valor del adc con una regla de tres:

8.33mseg------->1023
ADCT----------->ADC = valor que lee el adc

pero esto no se si este bien, y si hago esto no tendria forma de generar el pulso por que es un numero float, dejo mi codigo para que ME PUEDAN AYUDAR la verdad no se me ocurre una solucion. GRACIAS.
Código:
#include <16F886.H>   //Libreria del PIC Implementado.
#device ADC = 10   //Resolucion del ADC.
#fuses HS, NOWDT, NOLVP, PUT, MCLR   //Oscilador Externo, Deshabilita el Doggy.
#use delay( clock = 20M )   //Crystal de 20MHz.

int16 ADC, PWML;   //Varoable del ADC.
int Cambiar;

#INT_EXT
void ext_isr( void )
   {
      if( Cambiar == 0 )
         {
            ADC = read_adc();   //Lee el ADC.
            delay_us( 10 );
            PWML = 1023 - ADC;   //PWM en Bajo.
            
            for( ADC; ADC > 0; ADC-- )   //Crea el PWM en Alto.
               {
                  output_high( PIN_B2 );
               }
            for( PWML; PWML > 0; PWML-- )   //Crea el PWM en Bajo.
               {
                  output_low( PIN_B2 );
               }
            
            ext_int_edge( 0, L_TO_H );
            Cambiar = 1;
         }
         
      else if( Cambiar == 1 )
         {           
            output_low( PIN_B2 );
            
            ext_int_edge( 0, H_TO_L );
            Cambiar = 0;
         }
   }
   
void main( void )
   {
      setup_adc_ports( SAN0 );   //AN0 como Cana Analogico.
      setup_adc( ADC_CLOCK_INTERNAL );   //Oscilador Interno.
      set_adc_channel( 0 );   //Habilita el Canal 0.
      
      Cambiar = 0;   //Inicializa el Cambio.
      
      ext_int_edge( 0, H_TO_L );   //Inicia con Flanco de Subida.
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa.
      enable_interrupts( GLOBAL );   //Habilita la Interrupcion Global.
      
      while( 1 )
         {
         }
   }
 
Última edición por un moderador:
Hola, tal vez ustedes me pueden colaborar, resulta que estoy metido en mi proyecto de tesis de grado y estoy haciendo una tarjeta de adquicion de datos con pic para realizar control predictivo, empece a programar en asm pero se me dificultaba realizar la gran cantidad de operaciones matematicas por lo que decidi aprender a programas con c, lo primero que encontré el la web fue pic c ccs, y me parece muy amable al momento de programar, pero ahorita que estoy tratando de realizar simulacines en proteus no me muestra lo q deberia, he tratado de simular progrmas que ya he probado en hardware y se que funcionan pero no me corren en proteus, alguien q sepa a se debe??? He llegado a pensar que sea problema del software xq tomo ejemplos bajados de la internet y los corro y funcionan hasta que lo modifico y lo compilo en mi pc el codigo fuente, necesito ayuda!!! Gracias...
 
Me da gusto saber que hay personas que postean programas funcionales y que ademas los explican. lo que si no tolero son aquellos que postean programas preguntando por el error. Yo les recomendaria que si tienen programas funcionales y su respectivo circuito en proteus los postearan para asi poder analizarlos y aprender de ellos o en caso de necesitarlos usarlos de base para la realizacion de aplicaciones similares.
 
Buenas noches, en pregunta de algunos sobre sensores, posteare un control de temperatura muy sencillo, esta basado en la lectura de un sensor de temperatura el famoso LM35 y la salida la entrega en dos displays de 7 segmentos.

Explico:

Código:
#include <18f452.h>  //Mc a utilizar
#include <STDIO.h>  //librería para hacer operaciones matemáticas
#fuses hs,nowdt,noprotect,nolvp    //High speed, sin perro guardian, no pretegido, no bajo voltaje.
#use delay(clock=4000000,RESTART_WDT)     //reloj a 4 MHz

#byte porta=0xf80
#byte portb=0xf81
#byte portc=0xf82     // Cambiando nombres a los puertos
#byte portd=0xf83
#byte porte=0xf84

void main()   // Deja de leer todo lo primero y vamonos a:
{ 
   
   int const disp [10] = /*{0x3f, 0x06, 0x5b, 0x4f,0x66,     //declaramos los vectores para el display (Catodo Común)
                          0x6d, 0x7d, 0x07, 0x7f, 0x6f};*/  
                         {0x40, 0x79, 0x24,0x30, 0x19,       //declaramos los vectores para el display (Anodo Común)
                          0x12, 0x02, 0x78, 0x00, 0x18};
   int uni,dec,multi,k;      //Variables para los displays y k como retardo
   int b=1;                    // Bandera lógica
   int a=1;                    //Bandera lógica
   float temp,temperatura;    //Variables para las operaciones y así obtener la temperatura dentro del PIC
   float dato;                      

   SETUP_TIMER_2(t2_div_by_16,200,10);     //definimos el Timer 2 
   enable_interrupts(GLOBAL);                     //Activamos las interrupciones globales
   setup_adc_ports(2);                              //número de puertos ADC, puse 2 porque aveces conecto otro sensor y sacar promedios.
   setup_adc(adc_clock_div_32);                 //Configuración de los ADC
   set_adc_channel(0);                              //Activamos el ADC 0
   delay_us(10);                                       //Esperamos 10 microsegundos

   set_tris_B(0x00);
   set_tris_C(0x80);                             //Configuración de puertos.
   set_tris_D(0x00);
   portb=0;                        //Limpiamos el puerto b, que es donde estan conectados los displays de 7 segmentos.
                        

      while (TRUE)                      //Programa
      {
         dato  = read_adc();                      //Leemos el ADC y metemos el valor a la variable dato
         read_adc(ADC_START_ONLY);         //decirle al pic que solo y únicamente lea el ADC para una buena lectura
         dato = read_adc(ADC_READ_ONLY); //meter de nuevo el valor a dato para corroborar
         temp  = (0.0196078*dato);            //¿porqué 0.0196078? 5 volts entre 255 (recordemos que estamos trabajando con 8 bytes del ADC) nos da ese numero, o sea conversion de Analógico a digital. 
         multi = temp*100;                               //multiplicamos por 100 para tener la temperatura real entre 10.
         dec   = multi/10;                                 //Con esta operación solo tengo el dato de las decenas
         uni   = multi%10;                                //Con esta solo tengo el dato de las unidades en una variable
         temperatura  = temp * 100;                 //Temperatura con el valor verdadero.
         
// Control para encender o apgar un ventilador o una bomba  

         if(temperatura > 29 && a==0)      //Se activa D2 (Ventilador)
          {
            b=1;
            output_high(PIN_D2);
            output_low(PIN_D1);
          }
         if(temperatura <= 29 && temperatura >= 27)                               //Todo esta inactivo
          {
            b=1;
            output_low(PIN_D2);
            output_low(PIN_D1);
          }  
         if(temperatura < 27 && b==0)      //Se activa D1 (Calentador)
          {
            a=1;
            output_low(PIN_D2);
            output_high(PIN_D1);
          }
         if(temperatura < 25)
          {
           b=0;
          }
         if(temperatura > 31)
          {
           a=0;
          }

Para mostrar la temperatura en dos Displays de 7 segmentos, recordemos que los displays son multiplexados, primero prende uno y después el otro tan rapido que no alcanzamos a percibirlo, esto se logra con un transistor, si hay duda en esto, me daría a la tarea de subir el diagrama, pero el multiplexeo se hace con la patita B7, las demás son las que van conectadas con su respectiva resistencia a los displays de 7 segmentos.

Explico:

Código:
for (k=0;k<=50;k++)   //Variable k me permite crear ciclos con la orden "for" para el multiplexeo y aparte tiempo al PIC para que piense.
         {
          portb=disp[uni];   Le digo al pic que me arroje el dato de "uni" al vector "disp" para mostrar las unidades en los displays. 
          delay_ms(10);         //Retardo de 10 ms y se apaga.
          portb=disp[dec] + 0x80;   // le digo al pic que me arroje el dato de "dec" al vector "disp" y que mande un 1 (5 volts) a la patita B7 para que se encienda todo el display de las decenas.
          delay_ms(5);          //Dura 5 ms prendido y se apaga
         }                          //Volvemos a empezar el ciclo for infinitamente, ya que la variable al alcanzar las 51 cuentas, vuelve a leer el pic y se vuelve a hacer 0.
      }
   }

Bueno espero que haya quedado claro como leer un sensor y mostrarlo en displays de 7 segmentos en este caso solo 2, si se necesitan 4 displays, se ocupa un poco mas de electrónica para lograrlo sin desperdiciar patitas del PIC, muy sencillo.

Estamos para ayudar y enseñar...
 
Última edición por un moderador:
Oye, gracias por el aporte, por favor puedes subir el diagrama.

Ya lo compile y esta bien sin errores, ahora me puedes decir como arranco el segundo display con el transistor? ¿Va en que pin?

Gracias.
 
Oye, gracias por el aporte, por favor puedes subir el diagrama.

Ya lo compile y esta bien sin errores, ahora me puedes decir como arranco el segundo display con el transistor? ¿Va en que pin?

Gracias.

Muy bien, el transistor va en el PIN B7, que hace las veces de interruptor multiplexor. el diagrama deja lo hago pero por el momento espero que te sirva esta información.

En la explicación del programa especifica mejor cómo hace esto. Será un transistor conectado a la para B7 y este ira conectado al común de las decenas haciendo este las veces de interruptor a tierra. con eso consigues lo que necesitas. Haré el diagrama y lo subo en estos días espero ayudarte.
 
hice un programa para prender y apagar led de hyperterminal y funciono , ahora quiero hacer el proyecto de leer temperaturas con el lm35 en hyperterminal ahora he finalizado un programa que haga las lecturas de temperatura en hyperterminal, también simule el programa con proteus y me cree unos puertos com virtuales para así simular con proteus y hyperterminal juntos y todo anda bien en la simulacion ahora cuando lo llevo al circuito real y hago la conexión modulo y hyperteminal lo único que me muestra es xxxxxx xxxxx xxxxx como que el modulo esta transmitiendo los datos pero no los correctos mostrándome puras xxxxx en el hyperterminal
estoy usando el pic 18f2550 y uso el ccs para la compilación.

este es el programa

Código:
#include <18f2550.h>
#device adc=10
#fuses XT,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#use rs232(uart1,baud=9600)

float TEMPERATURA;

void config(void){

set_tris_c(0xB0);
set_tris_a(0x01);
setup_adc(ADC_CLOCK_INTERNAL|VSS_VDD);
setup_adc_ports(AN0);

}

void main(void){
config();
puts("temperatura actual");
do{

delay_us(50);
TEMPERATURA=read_adc();//leo el ADC y lo guardo en variable temperatura
TEMPERATURA=(TEMPERATURA*300)/614;//combierto la lectura adc en dato real

printf("temperatura: %.1f\r\n",TEMPERATURA);//muestro temperatura en hyperterminal
delay_ms(500);



}while(true);

}
 
Última edición por un moderador:
lo intente pero no hace la multiplexion podrias apoyarme en esto
saludos

Trato de ser muy explicito incluso en la conexión:

1.- Esta conexión es para 2 displays de 7 segmentos, los cuales serán multiplexados por medio de transistores uno tipo npn y otro tipo npn
2.- Las conexiones se hacen de la siguiente manera:
2.1.- Del puerto B0 al puerto B6 se conectan con sus respectivas resistencias de 330 a
cada una de las patititas del primer display. B0 = a, B1 = b, B2 = c, etc...
2.2.- Del primer display al segundo se hacen las mismas conexiones a-a, b-b, c-c etc...
2.3.- La patita B7 es la patita que hace la multiplexión y esta va coenctada a la base del
transistor NPN en mi caso un 3904 y de ahí mismo a la base del transistor PNP en mi
caso 3906.
2.4.- El colector del NPN va conectado al comun del display 1 (las decenas), la orta patita
del transistor a tierra.
2.5.- El emisor del PNP va al comun del display 2 (unidades). La otra patita del transistor a
tierra.
3.- Copias el código de uno de los programas que puse y deberá de funcionar.

Lo que hace la siguiente parte del programa es prender el display 2 y apagar el 1 y despues lo contrario, esto tan rápido que no se nota, eso es un tipo de multiplexeo. Esta parte del programa portb=disp[dec] + 0x80; es lo que hace, manda un dato al la patita B7 (0x80) y es lo que hace...
Código:
for (k=0;k<=50;k++) //Variable k me permite crear ciclos con la orden "for" para el multiplexeo 
                               y aparte tiempo al PIC para que piense.
{
portb=disp[uni];// Le digo al pic que me arroje el dato de "uni" al vector "disp" para mostrar las  
                         unidades en los displays. 
delay_ms(10);   //Retardo de 10 ms y se apaga.
portb=disp[dec] + 0x80; // le digo al pic que me arroje el dato de "dec" al vector "disp" y que 
                                     mande un 1 (5 volts) a la patita B7 para que se encienda todo el 
                                     display de las decenas.
delay_ms(5); //Dura 5 ms prendido y se apaga
}                 //Volvemos a empezar el ciclo for infinitamente, ya que la variable al alcanzar las 
                     51 cuentas, vuelve a leer el pic y se vuelve a hacer 0.
}
}

Espero haber ayudado. :D

hola a todos en la cuestión de los retardos si deseas un retardo mayor de 1000 ms como se hace ??

Para mi lo mas fácil seria crear un contador cada 1000 ms y ya con los números de tu contador ya haces lo que quieras.

Pero mas interesante seria saber para que quieres hacer el retardo, ya que si quieres meterte con tiempos grandes, es mejor usar los Timers...
 
hola pues mira mi proyecto es de lo siguiente:
1.-monitoreo de la corriente que consume una lampara durante la noche atraves de sensor de corriente TC , la lampara es de esas de encendido automatico
2.- a travez de una fotorresistencia monitorear si es de dia o de noche.
estas dos variables a travez de un circuito obtengo de cada una de ellas una salida logica que el pic 16f84a compara de la siguiente manera:
fotorresistencia < TC = despues de 5 minutos (enciende un led);
fotorresistencia > TC =despues de 5 minutos (enciende un led);
fotorresistencia == TC =despues de 5 minutos ( apaga el led):
el puerto que estoy utilizando es el B;
es solo que el retardo que se requiero es para eliminar durante un tiempo las comparaciones que pueden estar surgiendo durante se enciende la lampara y durante que la fotorresistencia no logra resivir luz del sol. entonces solo requiero esa seccion en la cual aun no e logrado tener un retardo largo para evitar esos disparos falsos
 
Atrás
Arriba