Autor Tema: Pogramacion pic 16F876 Termometro de 4 canales.  (Leído 48952 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado danone

  • PIC12
  • **
  • Mensajes: 78
Pogramacion pic 16F876 Termometro de 4 canales.
« en: 29 de Mayo de 2006, 18:54:29 »
Hola buenasa todos soy nuevo en este foro me he registrado hace pocos dias, ante todo os pido que tengais un poco de paciencia conmigo ya que es el primer intento que hago con los pics haciendo el codigo yo, asi que es probable que tenga muchos errores, de eso a que me decida a contaros como es el proyecto a ver si me podeis ayudar.

El proyecto consta de un termometro que muestra 4 temperaturas en un display LCD Hitachi 2x16, como sondas voy a usar sondas TMP36, en otro foro  Teo me recomendo estas por el motivo de que entregan un voltaje positivo al adc del pic para temperaturas Negativas( necesito poder temperaturas negativas, ya que lo voy a necesitar para una peltier entre otras cosas).

El circuito original quiero decir que es de una persona llamada Ionitron podeis encontrarlo en la web www.x-robotics.com , yo con la ayuda de Teo lo he modificado para las sondas TMP36, le he añadido la parte de oscilacion del pic y los condensadores que faltaban para no meter ruido en la entradas de alimentacion a las sondas.

El circuito en cuestion ya modificado:

   

NUEVO DISEÑO DEL CIRCUITO MODIFICADO PARA LCD 4 BITS PARA PODER USARLO CON LA LIBRERIA LCD.C




Voy a usar el compilador CCS C, aun no he hecho nada el codigo lo he escrito a pelo en un papel con la poca idea que tengo de esto, ni lo he compilado aun, mas que nada quiero que me comenteis por encima lo que esta mal y demas o como se deberia hacer pa hacerlo bien y poder seguir con ello.

Código: [Seleccionar]
#include "16f876.h"
#include "lcd.c"
#fuses NOLVP,XT,NOWDT,NOPROTECT,PUT
#use delay(clock=4000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)

#byte_port_a=5
#byte_port_b=6
#byte_port_c=7

#device adc=8

void main(void){

  int temp1,temp2,temp3,temp4
  const int tmp=50
 
  set_tris_a(0xFF)   //todos como entrada sondas de temperatura y vref
  set_tris_b(0x00)  //todos como salida datos lcd
  set_tris_c(0x00)         // pines de control lcd salida todos
 
  setup_adc_ports(RA0_RA1_RA2_RA5);
  setup_adc(ADC_CLOCK_INTERVALS);

   while(true){
     set_adc_channel(0);
     temp1=read_adc;
     temp1=(temp1/10)-tmp;
     set_adc_channel(1);
     temp2=read_adc;
     temp2=(temp2/10)-tmp;
     set_adc_channel(2);
     temp3=read_adc;
     tmp3=(temp3/10)-tmp;
     set_adc_channel(3);
     temp4=read_adc;
     temp4=(temp4/10)-tmp;
     lcd_init();
     lcdgotoxy(0,1);   //me posiciono en la linea 1 en el primer caracter
     printf(lcdputc,"T1= %d1 ºC",temp1); //Escribo temperatura del sensor1
     delay(500);   
     lcdgotoxy(8,1);   //me posiciono en la linea 1 , en el octavo caracter
     printf(lcdputc,"T2= %d1 ºC",temp2); //Escribo temperatura del sensor2
     delay(500);
     lcdgotoxy(0,2); //me posiciono en la linea 2, en el primer caracter
     printf(lcdputc,"T3= %d1 ºC",temp3); //Escribo temperatura sensor3
     delay(500);
     lcdgotoxy(8,2); //me posiciono en la segunda linea , octavo caracter
     printf(lcdputc,"T4= %d1 ºC",temp4); //Escribo temperatura del sensor4
     delay(500);
   }
}


A mas de uno os parecera una barbaridad seguro el codigo por la cantidad de fallos que tendra pero por eso os pido paciencia :P

Lo que mas me estas costando es comprender la parte superior del programa, sobre todo los uses_fast_io, byte_port_ y los set_tris_ ( concretamente como declarar no todos los pines como salida/entrada sino solo algunos)

Supongo que habra que usar Lcdgotoxy y demas funciones para posicionarme en sitios concretos del lcd, pero no tengo mucha idea tampoco de como escribirlo colocado.

Un saludo y muchisimas gracias a todos.
« Última modificación: 30 de Mayo de 2006, 19:03:30 por danone »

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #1 en: 29 de Mayo de 2006, 19:32:03 »
Asi mirando por encima, los condensadores de desacoplo, desacoplan tanto que no dejan pasar la alimentación :). Estan puestos en serie y hay que ponerlos en paralelo, si no no funcionara el circuito.

Un saludo.
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #2 en: 29 de Mayo de 2006, 19:36:22 »
en cuanto a las preguntas sobre los fast_io ,byte_ port, set_tris
se utilizan para configuracion de puertos.
aca la explicacion de eso y much mas

http://www.todopic.com.ar/foros/index.php?topic=4533.0
Existo, aunque pienses que no pienso

Desconectado danone

  • PIC12
  • **
  • Mensajes: 78
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #3 en: 30 de Mayo de 2006, 05:07:22 »
Asi mirando por encima, los condensadores de desacoplo, desacoplan tanto que no dejan pasar la alimentación :). Estan puestos en serie y hay que ponerlos en paralelo, si no no funcionara el circuito.

Un saludo.

Muy bien, gracias :D luego cuando pueda modifico el circuito :P

en cuanto al codigo como lo veis?

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #4 en: 30 de Mayo de 2006, 12:23:20 »
danone ya as compilado tu programa?
Te cuento cuando lo compilas te van apareciendo los errores.
En los printf te falta el %f de la variavble que estas imprimiendo
Otra cosita por el foro de c en los ejemplos de Vs zener tenes una traduccion del manual de CCS y el de la ultima vercion (en ingles)
Existo, aunque pienses que no pienso

Desconectado danone

  • PIC12
  • **
  • Mensajes: 78
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #5 en: 30 de Mayo de 2006, 12:32:25 »
buenas , que va juancho aun no he tenido tiempo de compilarlo todo lo que he hecho esta hecho en papel y eso, las variables las he declarado como enteras, a lo mejor segun estoy pensando lo msimo tengo que declararlas como numeros reales ...
He puesto %d porque como las habia declarado como enteras...
El resto del codigo como lo veis? Ahora dentro de un rato me pondre con el ccs a instalarlo y demas.

Un saludo.

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #6 en: 30 de Mayo de 2006, 12:38:19 »
a primera vista no veo mas errores una sola cosa declaras los puertos como constantes pero no se si es nesesario cuando usas el fast-io,va dejame probar en el picc y te cuento
Existo, aunque pienses que no pienso

Desconectado danone

  • PIC12
  • **
  • Mensajes: 78
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #7 en: 30 de Mayo de 2006, 13:42:40 »
ya he instalado el ccs y demas y pruebo y me falla en la libreria lcd.c, creo que el error puede ser el siguiente, no se si toy en lo cierto, el circuito estaba hecho por un tio en asm, y yo lo he modificado y lo toy programando para c, segun el tiene puesto el lcd como podeis ver en la foto, segun veo eso no esta controlado a 4 bits no? tendria que hacerlo como esta preparado la libreria no? pero yo mirando la libreria lcd.c me pone que tiene que estar de la siguiente manera:

RD0 a enable
RD1 a RS
RD2 a RW

RD4 a D4
RD5 a D5
RD6 a D6
RD7 a D7

empezando por que el pic que uso no tiene puerto D, que es lo que hago? cambio el esquema a 4 bits de datos? y 3 pines de control? usando el puerto B del pic?

saludos.

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #8 en: 30 de Mayo de 2006, 16:20:24 »
bien como vos decis la libreria que que estas usando es para manejarlo con 4bits asique tendras cambiar el circuito como vos decis.
Con respecto a lo de el puerto tenes dos opciones.

o bien lo cambias en la libreria o usas la linea

#define use_portb_lcd TRUE  antes de presesar los datos ,es decir en el preprosesado

un saludo juan
Existo, aunque pienses que no pienso

Desconectado danone

  • PIC12
  • **
  • Mensajes: 78
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #9 en: 30 de Mayo de 2006, 17:21:34 »
puedo cambiar el circuito usando el puerto B para el lcd ,
siendo :


RB0 a enable
RB1 a RS
RB2 a RW

RB4 a D4
RB5 a D5
RB6 a D6
RB7 a D7


he añadido ya la linea al programa que me has dicho el #define use_portb_lcd TRUE

la libreria que tengo es la siguiente:

Código: [Seleccionar]
///////////////////////////////////////////////////////////////////////////
////                             LCDD.C                                ////
////                 Driver for common LCD modules                     ////
////                                                                   ////
////  lcd_init()   Must be called before any other function.           ////
////                                                                   ////
////  lcd_putc(c)  Will display c on the next position of the LCD.     ////
////                     The following have special meaning:           ////
////                      \f  Clear display                            ////
////                      \n  Go to start of second line               ////
////                      \b  Move back one position                   ////
////                                                                   ////
////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)    ////
////                                                                   ////
////  lcd_getc(x,y)   Returns character at position x,y on LCD         ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//     D0  enable
//     D1  rs
//     D2  rw
//     D4  D4
//     D5  D5
//     D6  D6
//     D7  D7
//
//   LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B
#define use_portb_lcd TRUE


struct lcd_pin_map {                 // This structure is overlayed
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rs;               // access to the LCD pins.
           BOOLEAN rw;               // The bits are allocated from
           BOOLEAN unused;           // low order up.  ENABLE will
           int     data : 4;         // be pin B0.
        } lcd;


#if defined(__PCH__)
#if defined use_portb_lcd
   #byte lcd = 0xF81                   // This puts the entire structure
#else
   #byte lcd = 0xF83                   // This puts the entire structure
#endif
#else
#if defined use_portb_lcd
   #byte lcd = 6                  // on to port B (at address 6)
#else
   #byte lcd = 8                 // on to port D (at address 8)
#endif
#endif

#if defined use_portb_lcd
   #define set_tris_lcd(x) set_tris_b(x)
#else
   #define set_tris_lcd(x) set_tris_d(x)
#endif


#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40    // LCD RAM address for the second line


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING[i]);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE address;

   if(y!=1)
     address=lcd_line_two;
   else
     address=0;
   address+=x-1;
   lcd_send_byte(0,0x80|address);
}

void lcd_putc( char c) {
   switch (c) {
     case '\f'   : lcd_send_byte(0,1);
                   delay_ms(2);
                                           break;
     case '\n'   : lcd_gotoxy(1,2);        break;
     case '\b'   : lcd_send_byte(0,0x10);  break;
     default     : lcd_send_byte(1,c);     break;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}

me da error en la linea delay_us(1) la he marcado en negrita en el codigo, no hay manera de hacerlo compilar :(

BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}

la duda que tengo es con RB0 que creo que es un pin de interrupcion, puedo hacerlo asi con ese pin o pasa algo pq sea un pin de interrupcion?

muchisimas gracias por la ayuda juanacho me estas ayudando mucho
« Última modificación: 30 de Mayo de 2006, 17:35:10 por danone »

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #10 en: 30 de Mayo de 2006, 18:01:15 »
podrias colgar el archivo del picc (tu programa en el picc) para ejecutarlo yo en mi picc
Porcierto lo estas simulando en proteus ?
si es asi pues tambien el archivo de tu simulacon en proteus.
Existo, aunque pienses que no pienso

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #11 en: 30 de Mayo de 2006, 18:22:07 »
proba poniendolo asi y se te solucionara ese problema

#include "16f876.h"
#define use_portb_lcd TRUE 
#use delay(clock=4000000)
#include "lcd.c"
#fuses NOLVP,XT,NOWDT,NOPROTECT,PUT
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)

El problema es que en la libreria estabas usando una rutina de tiempo (delay_us()) y esta nesecita siempre tener definido antes el clock
Por cierto no declares los puertos como constantes o sea no pongas #byte_port_a=5 ni a los otros dos

Bueno a ver que dices
un saludo
« Última modificación: 30 de Mayo de 2006, 18:33:54 por juanacho_ar »
Existo, aunque pienses que no pienso

Desconectado danone

  • PIC12
  • **
  • Mensajes: 78
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #12 en: 30 de Mayo de 2006, 18:49:17 »
que digo? que estas hecho un maquina tio, muchisimas gracias ya no me da ningun error la libreria lcd.c ya puse eso antes como comentabas, ahora el error me lo da en las lineas q te marco en negrita a ver si ya conseguimos hacerlo rular :P en proteus no puedo simularlo aunke lo tuviese bien compilado porque el programa no trae las sondas q utilizo :( un saludo.

#include "16f876.h"

#fuses NOLVP,XT,NOWDT,NOPROTECT,PUT
#use delay(clock=4000000)
#include "lcd.c"
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
//#define use_portb_lcd TRUE  no uso esta linea pq ya la tengo en la libreria.

//#byte_port_a=5
//#byte_port_b=6
//#byte_port_c=7

//#device adc=8

void main(void){

  int temp1,temp2,temp3,temp4;
  const int tmp=50;

  set_tris_a(0xFF);   //todos como entrada sondas de temperatura y vref
  set_tris_b(0x00);  //todos como salida datos lcd
  set_tris_c(0x00);         // pines de control lcd salida todos

  setup_adc_ports(all_analog);
  setup_adc(ADC_CLOCK_INTERNAL);

   while(true){
     set_adc_channel(0);
     temp1=read_adc();
     temp1=(temp1/10)-tmp;
     set_adc_channel(1);
     temp2=read_adc();
     temp2=(temp2/10)-tmp;
     set_adc_channel(2);
     temp3=read_adc();
     temp3=(temp3/10)-tmp;
     set_adc_channel(3);
     temp4=read_adc();
     temp4=(temp4/10)-tmp;
     lcd_init();
     lcd_gotoxy(0,1);   //me posiciono en la linea 1 en el primer caracter
     printf(lcd_putc,"T1= %d1 ºC",temp1); //Escribo temperatura del sensor1
     delay_ms(500);
     lcd_gotoxy(8,1);   //me posiciono en la linea 1 , en el octavo caracter
     printf(lcd_putc,"T2= %d1 ºC",temp2); //Escribo temperatura del sensor2
     delay_ms(500);
     lcd_gotoxy(0,2); //me posiciono en la linea 2, en el primer caracter
     printf(lcd_putc,"T3= %d1 ºC",temp3); //Escribo temperatura sensor3
     delay_ms(500);
     lcd_gotoxy(8,2); //me posiciono en la segunda linea , octavo caracter
     printf(lcd_putc,"T4= %d1 ºC",temp4); //Escribo temperatura del sensor4
     delay_ms(500);
   }
}
« Última modificación: 30 de Mayo de 2006, 19:14:49 por danone »

Desconectado Arbolito

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 893
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #13 en: 30 de Mayo de 2006, 18:54:09 »
lo setup del adc los corregis asi

 setup_adc_ports(all_analog);
  setup_adc(ADC_CLOCK_INTERNAL);
si tardo en contestar es por mi servidor que es una babosa
Existo, aunque pienses que no pienso

Desconectado JavisusII

  • PIC12
  • **
  • Mensajes: 79
Re: Pogramacion pic 16F876 Termometro de 4 canales.
« Respuesta #14 en: 30 de Mayo de 2006, 19:03:21 »
Buenas Danone,

Me gustaría felicitarte por tu proyecto y ganas de superación.

Yo sólo quiero comentarte un par de observaciones sobre el circuito;

- en primer lugar veo que te has preocupado por desacoplar las sondas de temperatura, lo cual me parece correcto, pero
  tienes un problema de acoplo inductivo. Las sondas comparten la misma línea de retorno.
- en segundo lugar no veo las líneas de alimentación del uC. Éste también es sensible al ruido e interferencias. Debes    
  también poner le un condensador de desacoplo. Y si le pones un zener de protección mejor que mejor. Los pines que no
  utilizes no pueden estar al aire.
- Si programas en serie deberás poner una resistencia en el MCLR.
- No es usual ver una conexión de LCD al aire, debes poner pull-ups, Las líneas digitales siempre las verás forzadas.
- supongo que filtrarás digitalmente las señales de temperatura. :shock:
- Es muy usual filtrar la alimentación con algún condensador pesado, pon como mínimo uno de 10uf. :?

en fin ya iremos revisándolo poco a poco.

A nivel de soft no he utilizado este micro, programo usualmente el 18f8722,  30f6014a, y algunos modelos de Hitachi.
pero te veo fuerte y con ganas y la verdad es que aquí no faltan expertos en soft.

 



 
l
  
Xavi (Barcelona)