Programas para Pic C Compiler (Tutorial)

Muy buenas tengan todos ustedes lectores de Foros de electrónica, eh bajado mucha información de este lugar y eh aprendido mucho aquí, soy estudiante de ing. electromecánica y estoy en mi segunda especialidad de Automatización y acabo de llevar microcontroladores. Todo esto pues quisiera compartirlo con ustedes. Estaré publicando varios programas en Pic C por su simplicidad, también programo en Assembler y empiezo con matlab para hacer controles sofisticados para misiles y posicionamiento de cosas muy complejas a las cuales no me meteré (porque todavía no soy un erudito en esos temas)

Bueno el día de hoy empezare con programas sencillos como prender y apagar un led por un pin del microcontrolador seré muy especifico en los comentarios y estaré trabajando con el pic 18f452 i/p , claro a lo largo del tuto sabras que en pic C y sabiendo leer los datasheets (hojas de datos) cualquier pic lo hacen jalar. OJO, me perdonaran que ponga los programas ya hechos, ya que esto es antietico porque ustedes deben de pensar para hacer las cosas, pero espero que aquí se comparta mucho conocimiento y verlo en aplicaciones reales.

Bueno sin mas por el momento empecemos: (mucho ojo con los comentarios porque ocupan muchas lineas en algunos casos para la explicación).

1.- //Programa para prender y apagar un led sin timer.

Código:
#include <18F452.h>                                     //Libreria del pic a usar aqui se pondra el pic que se usara de aqui que        dependera la configuracion de los puertos y de los bytes

#fuses HS,NOWDT,NOPROTECT,NOLVP         //tipo de cristal externo high speed, perro guardian off, sin proteccion etc..

#use delay(clock=20000000)                       //Cristal de 20 Mhz leer datasheet para conexión de capacitores se puede usar diferentes cristales ver datasheet una vez mas

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) //declaro esta libreria ya que usaremos mas adelante la comunicacion serial del pic, la explico de una vez, el pin Rc6 (patita 25 del pic) sera la de transmision y la Rc7 de recepcion (patita 26) estas van conectadas a un max 232 que aqui en el foro encontraran su conexión, a una velocidad de 9600 baudios esto se vera mas adelante para la configuracion de la PC y del monitor que viene incluido en el programa (Pic C compiler PCHW) para ver lo que transmitimos y recibimos, les pasare un bootloader para estar programando directamente del PC sin necesidad de programar con tarjetas (esto lo explico mas adelante)

#build (reset=0x200)       //Como usaremos un programa interno para programar jeje tenemos que mover el reset las 
#build (interrupt=0X208) //interrupciones y el home, porque el bootloader ocupa sus lugares establecidos y estas tres lineas
#ORG 0X0000, 0X01FF     //son para eso, para cambiar de banco al y que no se nos pierda el pic al funcionar.


void BOOTLOADER() {      //Esta subrrutina es solo para evitar el programa del bootloader cada vez que programemos 
      #ASM                            
         NOP 
      #ENDASM
}

#byte PORTA= 0XF80   //Aqui nombramos loa puertos en mi caso yo les puse PORTA PORTB etc, pero ustes les pueden 
#byte PORTB= 0XF81   //poner el nombre que quieran las direcciones de cada micro vienen el datasheet
#byte PORTC= 0XF82   // por eso muy importante leerlo para que no vallan a usar estas para todo pic que se les ocurra
#byte PORTD= 0XF83  //hay que leer antes de hacer.
#byte PORTE= 0XF84

void main(){                //En esta parte sera la declaracion de variables configuracion de puertos y configuracionde mas cosas como timers, ADC, pwm, entre otras cosas.

set_tris_B(0xff);          /*Configuracion de puertos , a mi me gusta mucho hacerlo de forma hexadecimal pero para los que no saben explicare como se sacan los valores, ya que tambien se puede poner en binario. 
Los puertos son de 8 patitas (1 byte u ocho bits) y se dividen en nibles (alto y bajo) para sacar la conversion hexadecimal yo lo hago de la siguiente manera (ya despues lo haran mentalmente):

Nible alto        Nible bajo (pensando para puerto A)
A7 A6 A5 A4    A3 A2 A1 A0    (es como se acomodan los puertos en los nibles)
 8   4   2   1      8   4   2   1     (estos son los valores decimales para los bits)
 0   0   0   0      0   0   0   0     (este sera el valor binario para los bits "0" significa output "1" sera input)
         0                     0                  (el valor hexadecimal para este sera 0x00)
 8   4   2   1      8   4   2   1     (Ahora por el puerto A yo quiero que A0, A1, A5 y A7 sean entradas y los demas salidas)
 1   0   1   0      0   0   1   1     (el codigo binario seria 0b1010011)
         A                     3            (Como sabemos en hexadecimal A=10 si sumamos 8+2=10 para la conversion de decimal a Hexadecimal tenemos A en el nible alto y 3 para el nible bajo 1+2=3, para eso sirven el 8 4 2 1) espero sea claro porque es muy tedioso explicar esto. */
set_tris_D(0x00);     //Todos  D como salida
set_tris_C(0x80);     //Pin C7 como entrada y todos los demas como salida por la transmision serial

while(1){                 //Aqui empezamos el programa While(True) es lo mismo para que simpre se cicle el programa

output_high(pin_D0);  //Aqui lo que decimos es que nos mande a 1 o prenda el pin D0 en el cual esta conectado el led con su respectiva resistencia de 330 ohms
delay_ms(100);           //Con una duracion de encendido de 100 milisegundos (ms) para nano micro segundos sera (us)
output_low(pin_D0);   //Ahora lo apagamos mandandolo a 0
delay_ms(100);           //Con una duracion en bajo de 100 ms tambien.

}    
}//Cerramos todos los corchetes que hallamos abierto
De cualquier manera el PCHW nos indicara que errores halla en caso de que los halla pero tomen en cuanta que corrige errores de sintaxis no de lógica, por otro lado verán lo fácil que son los programas ya que también hay que administrar la programación para no cargar innecesariamente el pic, recordemos que por cada instrucción ocupa un ciclo de reloj y por cada salto ocupa el doble, así que hay que hacer lo mas reducidos nuestros programas, ya verán...

En este tutorial iré poniendo cada vez mas complejos (que la verdad son muy sencillos) los programas las conexiones y la imaginación dependerá de ustedes, por ejemplo para este caso se puede conectar un relevador o transistor para accionar alga durante unos segundos y después apagarlo o depende de la imaginación de cada quien, esto se vera también después para controlar servomotores, es exactamente lo mismo para generar frecuencias de trabajo y posicionar nuestro servomotor.

Para los próximos programas ya no daré tanta explicación solo esta vez para entender lo que estamos usando, ya cuando salgan cosas nuevas la explicare en su momento.

2.- Ahora pongo el programa mas fácil que lo que hace es que si presiono un boton prende un led, lo suelto se apaga. super fácil pero funcional.

Código:
#include<18f452.h>
#fuses hs,nowdt, noprotect,no lvp
#use delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
#build(reset=0x200)
#build(interrupt=0x208)
#org 0x0000,0x01ff


void bootloader()
{
#asm
nop
#endasm
}


#byte portA=0xF80
#byte portB=0xF81
#byte portC=0xF82
#byte portD=0xF83
#byte portE=0xF84     //Hasta aqui lo de siempre


void main()
{
set_tris_B(0xFF);
set_tris_D(0x00);
set_tris_C(0x80);

portD=0;
portB=1;

while(1)
{
portD=portB; /*Si presiono un boton en el puerto D; recuerden que los botones van con una resistencia pull-up o  pull-down depende del valor que quieran asegurar (1 o 0 sea el caso), me madara el valor al puerto B prendiendo el led que este ahi, ojo si pongo el boton en D0 el led tendra que ir en B0 */
}
}
Esto es para todo el puerto pero se puede hacer mas fácil solo por bits con la función if:

Código:
While(True)
{
  if (input(pin_D0)
     output_high(b0);
  else
     output_low(b0);
}
Depende de su uso.

3.- El siguiente programa es para hacer corrimientos en los puertos, yo los uso mucho para controlar motores a pasos, este programa va a controlar el nible bajo el alto es lo mismo.
Me voy a evitar todo lo anterior ya saben que es lo que va.

Código:
void main()
{

   int m1=16;           /*Declaramos variable tipo entero (int) recuerden que solo llega hasta 255 porque es un pic de 8 bits y la igualamos a 16*/

   set_tris_D(0x00);  //Configuracion de puertos 

   PortD=0;               //Limpiamos el pueto para que no halla basura

   while(1)
   {

      PortD=m1;        /*El puerto D es = a 16 o sea que estan todos los led apagados en 15 todos estarian prendidos la explicacion es precido a la de la configuracion de los puertos*/
      delay_ms (500);     //REtardo de medio segundo entre led y led
      m1=m1>>1 | m1 <<3;   /*Logica del programa esto >> significa que corra hacia la derecha y << hacia la izquierda lo que le digo yo es que recorra 1 y que el sume tres pa el otro lado: con manzanas:

0 0 0 0  0 0 0 0 (asi empiezo) int =16 me dice que le ponga 1 y que le quite 3 recordemos que son corrimientos
1 0 0 0  0 0 0 0 (le puse hacia la derecha)
1 0 0 0  1 0 0 0 (ahora mas 3 hacia la izq) se pone ahi el 1 porque recuerden que estamos en 16 no en 15. y volvera a hacer lo mismo*/


      m1=m1 & 0x0F;   /*Todo el nible bajo lo multiplico por 1 1 1 1 para que me gurde el dato para el siguiente, si no les convece hagan las operaciones y veran que si da.*/
   } //Cerramos todo
Con este programita se puede hacer girar un motor a pasos conectado al puerto D con sus respectivos transistores yo uso los TIP 125 por aguantar mucha corriente, son tipo darlington y estan protegidos internamente. recuerden que es el nible bajo D0, D1, D2, D3. estos van a las bases de los transistores. WUA eso no lo tengo que explicar.

Experimenten con este programa y pueden controlar 2 motores a pasos simultáneamente cambien la dirección de >> o << para que cambie el giro y si quieren visualizar los dos nibles cambien esto m1=m1 & 0x0F; por esto m1=m1 & 0xFF; y analicenlo para que vean porque. También si cambian esto m1=m1>>1 | m1 <<3; por valores en ves de 3 por 5 o 7 verán lo que hace. Espero que les sirva.

Para los próximos programas veremos como contar el numero de veces que prende y apaga los led en los corrimientos esto para hacer que los motores a pasos lleguen hasta cierto punto y se paren. quiere decir que si le pongo 50, solo va a hacer 50 pasos el motor. Esto para la próxima. (y tendrán que ver la resolución de sus motores (Usamos motores Unipolares)

O si dejo el programa bootloader para que lo carguen en su pic (este solo funciona para el 18f452, después publico el que esta en assembler para que modifiquen el bootloader y lo usen para cualquier pic de la serie 18F, sorry no tengo para otros, pero si buscan en la red encontraran para varios pics, incluso en el PCHW, en uno de los ejemplos viene uno, no lo eh calado pero chance y funcione, Chequenlo) yo lo mando en hexadecimal para que lo carguen de volada.
 
Última edición por un moderador:
Aqui el archivo hexadecimal Bootloader para el pic y para asi programar por el puerto serial sin complicaciones. a por cierto se tienen que descar el programa para cargar el pic se llama Colt pic bootlader. Se lo descargan de esta pagina http://mdubuc.freeshell.org/Colt/

Código:
:08000800FFD082BEF4D0040019
:0600100082AEFED71200D3
:08001800FFD0A66AA968AA68DE
:10002000A680A84A05D0A84CEBD0066E310ECD6E46
:10003000949C900EAB6E260EAC6EAB98030ED56EF4
:10004000D76AD66AD8D8D58ED6D8D59ED6CF03F063
:10005000D7320332D8A0030603C0AFFFAB88AE503F
:10006000AE50B6D80F0AE9E100EE08F0006A016A66
:10007000AFD80F0AF6E00450040A0AE00450050A5B
:1000800001E1A6D804500026EE6E014ED6D7F0D777
:100090000052D3E1CD900A50F66EA96E0B50F76E68
:1000A000AA6E0CC0F8FF00EE0DF00950016ED8B436
:1000B000FF0008500808C1E3FA6AFB6A0844F92601
:1000C00008D01ED025D034D03ED048D019D052D040
:1000D000FF00EE50AF02F446F446FC0EF416F34671
:1000E000F346030EF314F424A86E040EA66E78D81B
:1000F000A6B2FED70C0E0A6E000E0B6E040E45D093
:100100000900F5CFEEFF012EFBD70950050F3DD0BA
:10011000F80EF616080EEECFF5FF0D00E82EFBD711
:100120000A00840EA66E5CD80900012EF1D72CD0EF
:10013000940EA66E55D8400EF626E86AF722F822ED
:10014000012EF6D721D0A66AA680A8CFEEFFA94A35
:10015000AA2A012EF8D70950050F17D0EECFA8FF15
:10016000040EA66E3DD8A6B2FED7A94AAA2A012E31
:10017000F5D70AD0C40EA66EEECFF5FF0C0030D82E
:100180000900012EF7D700D0010E016E0F0E1BD80B
:100190001AD8006A00EE08F0EE50002608D8012EAA
:1001A000FBD7006C005003D8040E0DD846D7056E5F
:1001B0000F0A06E00550040A03E00550050A02E1B3
:1001C000050E01D8055004009EA8FED7AD6E1200A2
:1001D0000400ABB2FF009EAAFED7AE50046E120020
:1001E0000400550EA76EAA0EA76EA682000012008C
:0A01F6009EA008D79E90062E05D7A4
:020000040030CA
:0E000000FFFAFCFEFFFFFBFFFFFFFFFFFFFF0D
:00000001FF

Ya saben copian y pegan y guardan como .HEX de todos modos ahi mando el archivo.
 

Adjuntos

  • bootload_156.rar
    789 bytes · Visitas: 773
Bueno aqui dejo por el momento la imagen de como va la conexion para la comunicacion serial con el max232.

Los pasos para programar por comunicacion serial son los siguientes:

1.-Programar pic18f452-I/P con Bootloader, con cargador normal (el que ustedes prefieran)
2.-Hacer las conexiónes necesarias para la comunicacion serial (imagen abajo)
3.-Conectar cable a puerto Serial, y chekar que este habilitado el puerto o que no este ocupado en caso de que lo este, deshabilitarlo, reiniciar la maquina y habilitarlo nuevamente.
3.-Ya instalado el programa Colt Pic Bootloader dejarlo de la siguiente manera:

4.- Seleccionar archivo .hex que nos da una vez al compilar nuestro programa en Pic C en el PCHW y presionar el boton PROGRAM (F4).
5.-Presionar el reset del pic para que empiece a cargar el programa esto toma aproximadamente como 3 seg. varia depende del programa y la PC. (los leds del max232 parpadearan indicando que si esta programando bien)
6.-Verificar que todo funcione como lo pensamos y programamos

No creo muy necesario el poner las imagenes de cada circuito, ya que ustedes seran los que decidan que hacer y como conectar dependiendo de su programacion los puertos y salidas y entradas, pero en caso de ser muy muy necesario lo hare, de hecho mas adelante pondre un programa que sera un contador de 0 a 99 con displays multiplexandolos y pondre su conexión como debe de ser. Y con esto ya estaremos listos para hacer un elevador con un motor a pasos, un display y no mas; bueno claro la etapa de potencia del motor a pasos que son los transistores tip125. Pero eso en un rato que tenga mas tiempo,

Aqui la imagen.

Recomiendo mucho pasar este circuito a plaquita. ya que si lo hacen bien, podran comuniocarse con muchas pic (recordando que para cada serie de pic's el programa bootloader sera diferente, y tambien las conexiones hay que ver cada datasheet para encontrar tx y rx)

Nota : El cristal depende de ustedes, recuerden leer la hoja de datos para ver hasta cual se puede usar. y si van a hacer programas ya muy avanzados hay que hacer calculso eso ya lo pondre despues para ver cuanto tardara nuestro pic en reaccionar.

Y nuestro siguiente programa
4.- Programa para hacer corrimientos controlados.

Código:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Este programa prendera y apagara leds en un solo nible (solo controlaremos un motor a pasos)         //
//50 veces esto queire decir que si se tiene un motor con una resolucion con 2.5° por paso tendremos // 
//50 x 2.5 = 125° con este programa (variará dependiendo de cada motor a pasos.  Todo esto pasará //
//Cuando presionemos un boton pulsador (PB) en A0, que sera nuestra entrada. al terminar se parará//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#build (reset=0x200)
#build (interrupt=0X208)
#ORG 0X0000, 0X01FF

void BOOTLOADER() {
      #ASM
         NOP
      #ENDASM
}

#byte PORTA= 0XF80
#byte PORTB= 0XF81
#byte PORTC= 0XF82
#byte PORTD= 0XF83
#byte PORTE= 0XF84

void main()
{

   int P=0;                                //definicion de variable para iniciar conteo
   int m1=8;                            //en que nible se va a hacer la funcion (1000)

   set_tris_A(0xFF);                ////////////////////////////////////
   set_tris_D(0x00);               //Configuracion de puertos//
   set_tris_B(0x00);               ////////////////////////////////////

   portd=0;     

   while(TRUE){                      //ciclo infinito


         if(!input(PIN_A0))        //negado para que nos de simpre cero con conexion pull up
                                             //espera pulso para iniciar ciclo.
            {

               for (P=0;P<=49;P++)    /*Pregunta si 0 es <= a 49, como es si la respuesta,
                                                        incremente P en 1, y P ahora es igual a 1, hace la pregunta
                                                        de si 1 es <= a 49, como es cierto incrementa P (2) y hace lo que este dentro
                                                        del for una vez mas, y asi sucesivamente hasta llegar a 50,
                                                        como 50 no es <= a 49 se sale del ciclo for y espera el pulso otra vez*/
                  {
                  PortD=m1;
                  delay_ms(100);                //retardo (para el motor a pasos sera mucho mas rapido
                  m1=m1<<1 | m1>>3;      //sentido de giro (ya explicado anteriormente
                  m1=m1 & 0x0F;               //multiplicacion por 1 1 1 1b para nible bajo (ya explicado tambien)
                  }
             }
         }
}

Conexion (Nota la conexion mostrano no incluye la comunicacion serial max232, esto queire decir que si lo piensas simular en Proteus como lo hago yo tendran que borrar del programa todo lo que tenga que ver con el bootloader, como el void bootloader y su subrrutina, los build y el ORG)



Bueno en la proxima ya empiezo con los displays, su conexion y programacion. Por el momento es todo en una opurtunidad mas sigo poniendo proyectos,

Siempre hay que darle una explicacion a las cosas y tambien verle una aplicacion. Si no se sabe investigar y despues preguntar.

tips.-(Recuerden que los motores a pasos unipolares tienen 5 o 6 cables, si es de 5 uno de ellos es comun, si tiene 6 dos de ellos son comunes, y los demas es donde se le manda el pulso, hay que buscar la secuencia de los motores a pasos una manera es probandolos con un fuente. la otra con un multimetro.)

tips.- Hay que tener muy en cuenta que si se va a conectar el motor a pasos con transistores las tierras deben de ser comunes pero las alimentaciones diferentes, una para el control y otra para la potencia, si no hacen esto se les va a calentar el pic, y posiblemente se les queme lo digo por experiencia :evil:

Que tengan un buen dia
 
Muy bien, ya mas o menos sabesmos com controlar un motor a pasos, haciedno que llegue hasta cierto numero de vuletas pasos o grados, pues para no seguir con mas ejmeplos de esto ahora pasaremos a los displays y despues de esto haremos un elvevador con un motor a pasos y un display para que indique en que piso estamos.

Programas para contar de 0 a 9 en un display (2)

a)


Código:
//////////////////////////////////////////////////////////////////////////////////////////
//Aqui tenemnos un programa que muestra por medio de un display  //
//conmectado al puerto B el conteo de 0 a 9 ascendentemente y        //
//conestado al pin A2 tenemos un boton con resistencia pull up para //
//al presionarlo empiece a contar descendentemente.//
/////////////////////////////////////////////////////////////////////////////////////////

#include <18F452.h>                                                     //Lo de siempre.
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000, RESTART_WDT)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#build (reset=0x200)        //Esto se queita si no van a usar el bootloader, de lo contrario se deja ya esta explicado.
#build (interrupt=0X208)
#ORG 0X0000, 0X01FF


void BOOTLOADER()
   {
      #ASM
         NOP
      #ENDASM
   }

#byte PORTA= 0XF80
#byte PORTB= 0XF81
#byte PORTC= 0XF82
#byte PORTD= 0XF83
#byte PORTE= 0XF84

void main()
{
   unsigned char const disp[10]  = {0x3f, 0x06, 0x5b, 0x4f,
                       0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};  //Declaracion de vector para display de [b]catodo comun.[/b], una breve explicaicion para sacar cada vector de los displays es muy parecida a como declarar los puertos si como salidas o como entradas, en caso de que se quieran usar displays matriciales es algo diferente, no me metere pro ahora, creo que cuando llegue al teclado matricial se entendera mejor.

   signed char i = 0;  //inicializar la variable del vector en 0, es otra manera de nombrar variables de tipo entero

   set_tris_B(0x00);   //Puerto B como salida
   portB = 0;              //limpiamos el puerto b.


   while(1)
   {

   if(input(PIN_A2))  //Si no se presiona A2 suma 1 al vector o recorre uno al vector. (Tenemos un boton en A2 como pull up)
      i++;
   else                     //Si se presiona lo resta.
      i--;

   if (i < 0)               //Creo que es muy logico, es para que solo llegue hasta 0 y regrese a 9. 
      i = 9;
   if (i > 9)               // aqui es solo para que llegue a 9 y se regrese a o
      i = 0;

   portb = disp[i];   //Sacar la variable i por el puerto B quiere decir que i toma el valor de cada uno de los vectores declarados. 

   delay_ms(500);     //Retardo entre cambios. medio segundo.

A continuacion haremos uno que cuente de 0 a 99, obvio con 2 diplays todo pro el puertoB.
En el ejemplo anterior que usamos el puerto b, solo conectamos al microcontrolador, de las patitas B0 a B6, que son las 7 de los 7 segmentos, ahora conectaremos todo el puerto B para hacer que los dos displays se "multiplexen" usando 2 transistores uno tipo pnp y otro tipo npn, estos haran el multiplexeo., pondre el diagrama para que se entienda mejor.



y el programa es:

Código:
#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#build (reset=0x200)
#build (interrupt=0X208)
#ORG 0X0000, 0X01FF

void BOOTLOADER() {
      #ASM
         NOP
      #ENDASM
}

#byte PORTA= 0XF80
#byte PORTB= 0XF81
#byte PORTC= 0XF82
#byte PORTD= 0XF83
#byte PORTE= 0XF84


void main()
{
   int i,j,x;                                                       //Declaracion de variables
   int const disp[10]  = {0xC0, 0xF9, 0xA4, 0xB0,                 //Se declaran como constantes
                          0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};   //Codigo Hexa para cada nuemro Inverso


   set_tris_B(0x00);

   portB = 0;


   while(TRUE)
   {

           for(i=0;i<=9;++i)            //Ciclo que indica cuando terminaron de contar las decenas.
      {
            for(j=0;j<=9;++j)           //Ciclo que indica cuando termianron de contar las unidades.

               for(x=0;x<=10;++x)       //Este ciclo sirve para no ver los parpadeos de los diplay en el multiplexado.
         {
                {
                portb=disp [i]+0x80;    //Aqui sucede el multiplexado, al sumarle al resultado 1000 0000, para hacer que
                                        //prenda D7 instantaneamente por el delay indicado.
                delay_ms(10);
                portb=disp[j];          //Aqui esta sacando las unidades multiplexadas ya anteriormente por i.
                delay_ms(10);
                }

         }
      }
   }
}
Bueno en caso de alguna duda me lo dicen, y como hoy ya se me acabo el tiempo despues le seguimos para hacer un elevador con todo esto que ya mas o menos sabemos.

Que tengan muy buen dia.
 
Hola. Estoy utilizando el 18F2455, despues de un dia completo de uso, se tilda. Me gustaria implementarle un reset, pero no he podido, ni con el wdt, ni e probado con el MCLR.

Me podrias ayudar?

Saludos y desde ya muchas gracias
 
piojoadrian dijo:
Hola. Estoy utilizando el 18F2455, despues de un dia completo de uso, se tilda. Me gustaria implementarle un reset, pero no he podido, ni con el wdt, ni e probado con el MCLR.

Me podrias ayudar?

Saludos y desde ya muchas gracias

Claro que si te podria ayudar pero creo que me seria muy util si me dijeras que es lo que esta haciedno tu pic (o t sistema) para ver porque te "tildea" (me gustaria saber a que te refieres con esa palabra, ¿qe te epieza a variar si setido?), lo que se me viene a la cabeza por el momento es que te esta consumiedo mas corriente de lo que el pic puede soportor por horas de trabajo y por eso te empieza a fallar, pero hay que ser mas especifico, asi que espero algo mas detallado.
 
agustinzzz dijo:
frivoldeux, ¿podrías postear un link a la página oficial del PIC C compiler?

Gracias.

Hola camarada, pues no creo que sirva de mucho la pagina oficial de CSS ya que solo bajaras el trial de 30 dias y pues no sirve de mucho de todos modos para alguna información y o algo de ayuda la pagina es http://www.ccsinformación.com/, seria mas facil que algun foro lo localizaras yo lo baje de otro foro pero ya no lo encuentro para darte la direccion, seguire buscando para que lo puedan bajar. Si lo encuentras este debe de venir con dos archivos setup (pchwupd.exe y ideutilsupd.exe) y tres arcivos mas con extensión .crg los cuales deberas de cambiar por los que se instalan originalmente y listo ya tendras tu programa funcionando a la perfeccion.
 
Pues bueno lo pormetido es deuda asi que aqui les va el programa del elevador con sus conexiónes que son muy sencillas mas se tarda uno en andar armando el elevador para que quede bonito y todo eso, ustedes pueden hacerlo todavia mas bonito yo ya no tenia para mas pero lo importante es hacer el programa asi que hay va.

Nota: El numero de pulsos entre piso y piso va a variar mucho dependiendo el tipo de motor a pasos que ustedes usen, los pueden sacar a prueba y error o con alguna formula matematica que relaciones los grados que se mueve su motor a pasos por paso. Deberan cambiar tanto el numero que se encuentra en la subrutina "ShowPiso" como los pasos que habra entre piso y piso, vean muy bien el programa no esta muy complicado.

Despues pondre uno que guarda en su memoria el piso al que debe de llegar ya que este programa solo les indica en el piso que se encuentra, pero si presionan otro boton por ejemplo el 1 4 3 2 solo va a irse del 1 al 4 y los demas no los hara, despues posteo el que si presionan un monton de pisos este se ira a todos los que le hallan dicho, como un verdadero elevador. Este solo es para entender un poco las sentencias y logica que hemos manejado hasta ahora.

Bueno sin mas preambulos:::::

Código:
/////////////////////////////////////////////////////////////////////////////////////////////
//Para el armado de este circuito el cual sera un elevador de 4 pisos      //
//se usara un pic18f452-i/p el cual llevara conectado en el puerto A        //
//los botones pulsadores en A0, A1, A2 y A3 siendo A0 para el piso 1     //
//A1 para el piso 2, A2 para el piso 3 y A3 para el piso 4, solo se            //
//usara un solo display asi que usaremos el puerto B para el display      //
//haciendo la caneccion mensionada anteriormente para el conteo de 0 //
//a 9, y en el puerto D se hara la conexión del motor a pasos (D0,        //
//D1 D2 y D3 para motor a pasos bipolar de 5 o 6 cables.                       //
////////////////////////////////////////////////////////////////////////////////////////////

#include <18f452.h>
#fuses hs,nowdt,noprotect,nolvp
#use delay(clock=20000000)


#byte porta=0xf80
#byte portb=0xf81
#byte portc=0xf82
#byte portd=0xf83
#byte porte=0xf84

void ShowPiso (long p)   //Muestra en que piso se encuentra por medio del display
{
 if (p==1)        //Pulsos en que el display cambia a 1
    portb=0x06;   //Muestra 1 en display de 7 segmentos

 if (p==328)      //Pulsos en que el display cambia a 2
    portb=0x5b;   //Muestra 2 en display de 7 segmentos

 if (p==626)      //Pulsos en que el display cambia a 3
     portb=0x4f;  //Muestra 3 en display de 7 segmentos

 if (p==880)      //Pulsos en que el display cambia a 4
     portb=0x66;  //Muestra 4 en display de 7 segmentos
}

void main()
{
long p=1;       //Declaracion de variables
long m1=8;
set_tris_d(0);  //Configuracion de puertos
set_tris_b(0);
portd=0;       //limpianmos puertos
portb=0;

      while(1)
      {
         ShowPiso (p);
         if (p==1)  //si estoy en el piso 1 para ir al piso 2
         {
            if (!input(pin_a1))    
            {
               for(p=1;p<=327;++p) //Cantidad e pulsos necesarios para llegar al piso 2
               {
               portd=m1;
               delay_ms(20);     //Velocidad entre pulso y pulso.
               m1=m1>>1|m1<<3;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==328)   //si estoy en el piso 2 para ir al piso 1
         {
            if (!input(pin_a0))
            {
               for (p=328;p>=2;--p) //Cantidad e pulsos necesarios para ir de 2 a 1
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>3|m1<<1;
               m1=m1&0x0f;
               ShowPiso (p);
               }

            }
         }


         if (p==1)       //si estoy en el piso 1 para ir al piso 3
         {
            if (!input(pin_a2))
            {
               for (p=1;p<=625;++p) //Cantidad e puylsos nmecesaris para ir de 1 a 3
               {
               portd=m1;
               delay_ms(20); 
               m1=m1>>1|m1<<3;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==626)    //si estoy en el piso 3 para ir al piso 2
         {
            if (!input(pin_a1))
            {
               for (p=626;p>=329;--p)
               {
               portd=m1;
               delay_ms(10);
               m1=m1>>3|m1<<1;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==626)   //si estoy en el piso 3 para ir al piso 1
         {
            if (!input(pin_a0))
            {
               for (p=626;p>=2;--p)
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>3|m1<<1;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==1)  //si estoy en el piso 1 para ir al piso 4
         {
            if (!input(pin_a3))
            {
               for (p=1;p<=879;++p)
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>1|m1<<3;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==328)  //si estoy en el piso 2 para ir al piso 3
         {
            if (!input(pin_a2))
            {
               for (p=328;p<=625;++p)
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>1|m1<<3;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }



         if (p==328)   //si estoy en el piso 2 para ir al piso 4
         {
            if (!input(pin_a3))
            {
               for (p=328;p<=879;++p)
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>1|m1<<3;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==626)  //si estoy en el piso 3 para ir al piso 4
         {
            if (!input(pin_a3))
            {
               for (p=626;p<=879;++p)
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>1|m1<<3;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==880)    //si estoy en el piso 4 para ir al piso 3
         {
            if (!input(pin_a2))
            {
               for (p=880;p>=627;--p)
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>3|m1<<1;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==880)  // si estoy en el piso 4 para ir al piso 2
         {
            if (!input(pin_a1))
            {
               for (p=880;p>=329;--p)
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>3|m1<<1;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }


         if (p==880)    //si estoy en el piso 4 para ir al piso 1
         {
            if (!input(pin_a0))
            {
               for (p=880;p>=2;--p)
               {
               portd=m1;
               delay_ms(20);
               m1=m1>>3|m1<<1;
               m1=m1&0x0f;
               ShowPiso (p);
               }
            }
         }
      }
}
 
A por cierto para esto deberan de hacer la conexión para el motor a pasos como ya lo habia mensionado antes, con sus respectivos Transistores TIP120, donde D0, D1 D2 y D3 iran a la base del transistor. o puede ser TIP125, el que ustedes quieran uno es NPN y otro PNP, yo uso el 120 para esto. Recuerden que van alimentados por separado 5V para el pic y el motor a pasos en otro etapa (potencia) con sus transistores, ya sea a 5 o a 9 o a 12 depende de sus motores a pasos. Oh si! con las tierras puenteadas para que no haya ruidos e interferencias. No se que mas se me olvida, pero espero les funcione muy bien. De todos modos aqui ando para lo que necesiten y claro, yo sepa, jejeje. Posteo fotos de rato de mi elevador.

Buena vibra
 
piojoadrian escribió: Hola. Estoy utilizando el 18F2455, despues de un dia completo de uso, se tilda. Me gustaria implementarle un reset, pero no he podido, ni con el wdt, ni e probado con el MCLR.

Me podrias ayudar?

Saludos y desde ya muchas gracias



Claro que si te podria ayudar pero creo que me seria muy util si me dijeras que es lo que esta haciedno tu pic (o t sistema) para ver porque te "tildea" (me gustaria saber a que te refieres con esa palabra, ¿qe te epieza a variar si setido?), lo que se me viene a la cabeza por el momento es que te esta consumiedo mas corriente de lo que el pic puede soportor por horas de trabajo y por eso te empieza a fallar, pero hay que ser mas especifico, asi que espero algo mas detallado.

Gracias frivoldeux por responder...

Adjunto el codigo.

Intente programar el WDT pero no me resetea el PIC al parecer.
Luego de un dia de encuestar el pic, es probable que en la planta industrial el generador o algo se prenda y haga que todo claudique.
Con un reseteo periodico andariamos barbaro!

Saludos cordiales y desde ya muchas gracias


Código:
#include <18F2455.h>
#fuses HSPLL,WDT,WDT512,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000, restart_wdt)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#int_RDA
void  RDA_isr(void) 
{
   char caracter;
   int8 canal0,canal1,canal2,canal3,canal4,canal8,canal9,canal10,canal11,canal12;
   
   caracter=getchar();

   if (caracter=='c')
   {
        restart_wdt()             //Canal 0
        set_adc_channel(0);
        delay_us(10);
        restart_wdt()
        canal0 = read_adc(); //read_adc(ADC_START_ONLY);
        delay_ms( 10 );
        restart_wdt()
        canal0 = read_adc(); //read_adc(ADC_READ_ONLY);
 
        restart_wdt()
        printf("00=%3u",canal0);
        restart_wdt()
        



        restart_wdt()             //Canal 1
        set_adc_channel(1);
        delay_us(10);
        restart_wdt()
        canal1 = read_adc(); 
        delay_ms( 10 );
        restart_wdt()
        canal1 = read_adc(); 
        
        restart_wdt()
        printf("01=%3u",canal1);
        restart_wdt()
        
        
        
        
        restart_wdt()              //Canal 2
        set_adc_channel(2);
        delay_us(10);
        restart_wdt()
        canal2 = read_adc(); 
        delay_ms( 10 );
        restart_wdt()
        canal2 = read_adc(); 
        
        restart_wdt()
        printf("02=%3u",canal2);
        restart_wdt()
        
        
        
        restart_wdt()               //Canal 3
        set_adc_channel(3);
        delay_us(10);
        restart_wdt()
        canal3 = read_adc(); 
        delay_ms( 10 );
        restart_wdt()
        canal3 = read_adc(); 
        
        restart_wdt()
        printf("03=%3u",canal3);
        restart_wdt()
        
        
        
        restart_wdt()               //Canal 4
        set_adc_channel(4);
        delay_us(10);
        restart_wdt()
        canal4 = read_adc(); 
        delay_ms( 10 );
        restart_wdt()
        canal4 = read_adc(); 
        
        restart_wdt()
        printf("04=%3u",canal4);
        restart_wdt()
      
      
      
        restart_wdt()               //Canal 8
        set_adc_channel(8);
        delay_us(10);
        restart_wdt()
        canal8 = read_adc(); 
        delay_ms( 10 );
        restart_wdt()
        canal8 = read_adc(); 
 
        restart_wdt()
        printf("08=%3u",canal8);
        restart_wdt()
        
        
        
        restart_wdt()               //Canal 9
        set_adc_channel(9);
        delay_us(10);
        restart_wdt()
        canal9 = read_adc(); 
        delay_ms( 10 );
        restart_wdt()
        canal9 = read_adc(); 
        
        restart_wdt()
        printf("09=%3u",canal9);
        restart_wdt()
      
      
      
        restart_wdt()                 //Canal 10
        set_adc_channel(10);
        delay_us(10);
        restart_wdt()
        canal10 = read_adc(); 
        delay_ms( 10 );.
        restart_wdt()
        canal10 = read_adc(); 
 
        restart_wdt()
        printf("10=%3u",canal10);
        restart_wdt()
        
        
        
        
        restart_wdt()                  //Canal 11
        set_adc_channel(11);
        delay_us(10);
        restart_wdt()
        canal11 = read_adc(); 
        delay_ms( 10 );
        restart_wdt()
        canal11 = read_adc(); 
 
        
        restart_wdt()
        printf("11=%3u",canal11);   
        restart_wdt()
        
        
        
        
        restart_wdt()                     //Canal 12
        set_adc_channel(12);
        delay_us(10);
        restart_wdt()
        canal12 = read_adc(); 
        delay_ms( 10 );
        restart_wdt()
        canal12 = read_adc(); 
        
        restart_wdt()
        printf("12=%3u\r",canal12);      //El ultimo canal termina con un retorno de carro;
        restart_wdt()
       
        
   }

   
}


void main(void) {
   
   setup_adc_ports(ALL_ANALOG|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_2);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   

  
   while (TRUE) {}
  
}
 
De acuerdo con lo que vi en tu programa para hechar a jalar el perro guardian o WDT esta bien, no hay problema con tu configuracion, aunque es muy larga y se puede hacer mas corta, pero asi esta bien, lo unico que esta mal es que te faltan muchos puntos y comas en cada "restart_wdt(); " , en fin al parecer como lo predecia, tu pones que cada vez que arranca un generador o algo que jala mucha corriente falla o tildea el pic, eso es porque al haber una caida de tension o un jalon de mucha corriente el pic se desstabiliza, ahi es dodne biene la parte de CONTROL, esto significa que tienes que diseñar en este caso un control tipo PID para hacer que tu PIC nop tildie, esto lo puedes hacer con Op. Amp. (amplificador operacionales) o incluso con otro pic que resguarde al controlador principal.

A mi me llego a pasar algo similar pero con motores de corriente directa que despues de estrar un funcionamiento por largo timpo era cuestion de que algo mas se encendiera para que el pic se apagara y reseteara.

Recuerda que al usar el WDT que tu propones te jala 6% en ROM, puedes usar sentencias para hacerlo mas efectivo sin necesidad de que se resetee, aunque vuelvo a lo mismo tu WDT esta bien, no es problema de la programacion es problema del Circuito exterior. necesitas hacer algunos calculos para ver en que anda fallando no estoy muy seguro pero creo que el pic que usas te puede entregar hasta 50 mA por patita (no estoy seguro ver el datasheet) si en tus calculos te sale que jala mas corriente cuando entra un generador hay puede estar el problema, o la caida de tensión es mucha que el pic no recive lo que debe de ser y tambien por eso falla. Para eso aplica el Control en la industria.

Espero que sea por ahi porque tu configuracion de WDT esta bien reitero.

En los proximos programas entraremos a lo que es manejo de señales Analogas y Digitales con salida a display y a LCD. para sensores de cualquier tipo, (temperatura, humedad, presion, flujo, etc...) y una breve explicacion de los de Efecto Hall.

Hasta la proxima.
 
piojoadrian dijo:
piojoadrian escribió: Hola. Estoy utilizando el 18F2455, despues de un dia completo de uso, se tilda. Me gustaria implementarle un reset, pero no he podido, ni con el wdt, ni e probado con el MCLR.

Me podrias ayudar?

Saludos y desde ya muchas gracias



Claro que si te podria ayudar pero creo que me seria muy util si me dijeras que es lo que esta haciedno tu pic (o t sistema) para ver porque te "tildea" (me gustaria saber a que te refieres con esa palabra, ¿qe te epieza a variar si setido?), lo que se me viene a la cabeza por el momento es que te esta consumiedo mas corriente de lo que el pic puede soportor por horas de trabajo y por eso te empieza a fallar, pero hay que ser mas especifico, asi que espero algo mas detallado.

Gracias frivoldeux por responder...

Adjunto el codigo.

Intente programar el WDT pero no me resetea el PIC al parecer.
Luego de un dia de encuestar el pic, es probable que en la planta industrial el generador o algo se prenda y haga que todo claudique.
Con un reseteo periodico andariamos barbaro!

Saludos cordiales y desde ya muchas gracias

Jajajaja que onda de nuevo piojoadrian, me pusiste a pensar un rato y analice mas detenidamente tu configuracionde programa y algunas aplicaiones que le vi, me voy por partes para que las cheques y talves tambien una de estas puede ser.

1.- hay que checar bien la configuracion de #fuses.
2.- Creo que estas usado un cristal que desestabiliza a tu pic, 40 MHz es hasta donde trabaja bien.
3.- lo que haces con tu configuracion es que cuando precionas la tecla 'c' haces un reseteadero de canales de lectura Analogica y los vuelves a prender y los pones a leer, cada uno de ellos por separado cosa que te quita tiempo de procesamiento y usas demasiado el restar_wdt().

Un ejemplo que vi en el mismo programa CSS esta algo asi

Código:
#include <16F877.h>
#fuses HS,WDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9200, xmit=PIN_C6, rcv=PIN_C7)


void main()   {

   switch ( restart_cause() )
   {
      case WDT_TIMEOUT:
      {
         printf("\r\nRestarted processor because of watchdog timeout!\r\n");
         break;
      }


      case NORMAL_POWER_UP:
      {
         printf("\r\nNormal power up!\r\n");
         break;
      }
   }
   setup_wdt(WDT_2304MS);

   while(TRUE)
   {
      restart_wdt();
      printf("Hit any key to avoid a watchdog timeout.\r\n");
      getc();
   }
}

Bueno antes que nada no se para que usas el HSPLL y el PLL5, despues nunca configuras el wdt (setup_wdt(mode))
Dentro de mode pueden ir estas opciones WDT_ON, WDT_OFF, WDT_TIMES_32, WDT_TIMES_64, WDT_TIMES_128, WDT_TIMES_256, WDT_TIMES_512, WDT_TIMES_1024, WDT_TIMES_2048, WDT_TIMES_4096, WDT_TIMES_8192, WDT_TIMES_16384, WDT_TIMES_32768, WDT_TIMES_65536. Si vas a trabajar solo con uno en tu caso que pusiste 512 lo deberias usar con la configuracion anterior.

y para ahorrarte todo lo que pusiste podrias poner muy bien en vez de esto

Código:
        restart_wdt();             //Canal 0
        set_adc_channel(0);
        delay_us(10);
        restart_wdt();
        canal0 = read_adc(); //read_adc(ADC_START_ONLY);
        delay_ms( 10 );
        restart_wdt();
        canal0 = read_adc(); //read_adc(ADC_READ_ONLY);
 
        restart_wdt();
        printf("00=%3u",canal0);
        restart_wdt() ;

Esto:

Código:
restar_wdt();
set_adc_channel(ALL);
delay_us(10);
canal0=read_adc();
printf("00=%3u",canal0);
delay_ms(lo que quieras);
canal1=read_adc();
prinf("00=%3u",canal0);
delay_ms(loquequiera);
etc......

y dentro del programa usar algo asi para que vuelva a iniciar automaticamente:

Código:
  while(true){

     restart_wdt();

     perform_activity();

   }
espero sea de ayuda y dale una revisada al datasheet para ver lo del oscilador y a la ayuda del CSS para que veas la configuracion del WDT, yo la eh usado muy poco pero si me funciona con esta configuracion.

Suerte:
[/i]
 
Vamos por parte.

Antes que nada estoy muy agradecido por la dedicación a este problema que me está sacando el sueño.

Es mi proyecto de grado, me recibo de Ing. Electrónico. Como bien se sabe, la carrera generalmente, poco tiene que ver con la realidad que se afronta día a día, es por ello que hay que investigar e indagar todos los caminos para solucionarlo.

Nuevamente muchas gracias por responder.

El tema es el siguiente.
Es un sistema de monitoreo de temperatura wireless a distancia. Utilizo los modulos Xbee PRO.
Encuesto los PIC´s y estos me devuelven los valores de los conversores. Hasta ahí todo mas que bien. Todas las placas estan alimentadas con la misma señal de 220v. Luego de varias horas (ultimamente 1 dia ) una de las placas que contiene al pic, no responde a la encuesta. Es decir, como que se colgara, reseteando la termica y volviendo a conectar, todo vuelve a la normalidad.

Posibles fallas que no logro descifrar:

--cerca de la placa pasa un manojo de cables de alta tension (estimo trifasica) que es posible que me induzca algun campo que me haga tildar todo.

--Ya que todas las placas estan con la misma alimentacion, y solo se cuelga esta (la c) puede ser que sea la placa.



Implementando un reset periodico, es probable que solucione el problema, aunque no logre determinar el origen de tal.

Estoy en etapa de calibracion, las demas estan funcionando correctamente.

Espero pueda sacarlo andando pronto.



Vamos por parte,

Gracias frivoldeux por ayudar

piojoadrian escribió: Hola. Estoy utilizando el 18F2455, despues de un dia completo de uso, se tilda. Me gustaria implementarle un reset, pero no he podido, ni con el wdt, ni e probado con el MCLR.

Me podrias ayudar?

Saludos y desde ya muchas gracias



Claro que si te podria ayudar pero creo que me seria muy util si me dijeras que es lo que esta haciedno tu pic (o t sistema) para ver porque te "tildea" (me gustaria saber a que te refieres con esa palabra, ¿qe te epieza a variar si setido?), lo que se me viene a la cabeza por el momento es que te esta consumiedo mas corriente de lo que el pic puede soportor por horas de trabajo y por eso te empieza a fallar, pero hay que ser mas especifico, asi que espero algo mas detallado.



Gracias frivoldeux por responder...

Adjunto el codigo.

Intente programar el WDT pero no me resetea el PIC al parecer.
Luego de un dia de encuestar el pic, es probable que en la planta industrial el generador o algo se prenda y haga que todo claudique.
Con un reseteo periodico andariamos barbaro!

Saludos cordiales y desde ya muchas gracias



Jajajaja que onda de nuevo piojoadrian, me pusiste a pensar un rato y analice mas detenidamente tu configuracionde programa y algunas aplicaiones que le vi, me voy por partes para que las cheques y talves tambien una de estas puede ser.

1.- hay que checar bien la configuracion de #fuses.
2.- Creo que estas usado un cristal que desestabiliza a tu pic, 40 MHz es hasta donde trabaja bien.
3.- lo que haces con tu configuracion es que cuando precionas la tecla 'c' haces un reseteadero de canales de lectura Analogica y los vuelves a prender y los pones a leer, cada uno de ellos por separado cosa que te quita tiempo de procesamiento y usas demasiado el restar_wdt().

Un ejemplo que vi en el mismo programa CSS esta algo asi

1- La configuracion de fuses la chequee, estimo que esta bien ya que funciona
2- El cristal que utilizo es de 20Mhz, pero debes colocar ese valor en el programa (desconozco porque, pero funciona)
3- No entendi, estoy haciendolo bien? Al parecer, lo puse en funcionamiento y anda, hoy te confirmo si se mantiene a lo largo de los dias.


WDT_ON, WDT_OFF, WDT_TIMES_32, WDT_TIMES_64, WDT_TIMES_128, WDT_TIMES_256, WDT_TIMES_512, WDT_TIMES_1024, WDT_TIMES_2048, WDT_TIMES_4096, WDT_TIMES_8192, WDT_TIMES_16384, WDT_TIMES_32768, WDT_TIMES_65536. Si vas a trabajar solo con uno en tu caso que pusiste 512 lo deberias usar con la configuracion anterior.

Para que son los WDT_TIMES_1024? No lo se.

Es buena tu aclaracion de donde colocar el restart_wdt(), pero el problema, es que dentro del programa no tengo nada como ya habras visto. El PIC solo permanece a la espera de ser encuestado. Si coloco un restart_wdt() dentro del while del programa, nunca actuaria.



Muchas gracias frivoldeux, eres de lo mas en este foro! (te he leido por varios temas de debate)
 
Muy bien piojoadrian espero a que lo heches a jalar este dia, a ver que pasa, si le doy mas por la circuiteria que ni el programa por lo que dices, pero otra cosa rapida. si debes de indicar los 20 MHZ, si le pones un cristal diferente si jalan pero no en el tiempo de reloj que deberian, eso lo pienso poner mas adelante, las formulas y todo eso, se pone 48MHZ por lo general cuando manejas conexion por USB, pero en ese caso para el uso que le estas dando te recomiendo usar un DSPIC, ya que manejas por lo visto todos los puertos de A/D y manejo de señales. Si no ponle un cristal de 40MHz y configura de nuevo el #DELAY para que trabaje en sus ciclos de reloj como debe.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Ok, este progrmaa es para leer una señal analogica y mandar atravez del pic a una salida Digital, si alguna vez usaron una ADC con su potenciometro a lo que les conectaban leds. y mandaba un nemero binario a su salido esto es parecido pero dentro del programa cambiamos la salida a nuestro placer. en nuestro caso para leerlo o visulizarlo en dos display de 7 segmentos, y poara que sirve esto, pues para tener una lectura mas precisa de lo que pasa en el mundo Analogico.

Código:
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#build (reset=0x200)
#build (interrupt=0X208)
#ORG 0X0000, 0X01FF

void BOOTLOADER() {
      #ASM
         NOP
      #ENDASM
}

#byte PORTA= 0XF80
#byte PORTB= 0XF81
#byte PORTC= 0XF82
#byte PORTD= 0XF83
#byte PORTE= 0XF84

void main(){

  int const disp [10] = {0x3f, 0x06, 0x5b, 0x4f,0x66,     //declaramos los vectores para el display
                         0x6d, 0x7d, 0x07, 0x7f, 0x6f};

  int dato, uni, dec, multi, i;   //declaracion de variables tipo entero
  float temp;                     //Declaracion de variables tipo flotatentes

  set_tris_A(0x01);               //Puerto de lectura del ADC
  set_tris_B(0x00);               //Configuracion de los puertos
  set_tris_D(0x00);
  
  setup_port_A(2);               //Iniciamos puertos ADC en el puerto A
  setup_adc(adc_clock_div_32);   //Configuramos la lectura del ADC (reloj)
  set_adc_channel(0);            //Declaramos el canal ADC que se va a usar o leer

  portB=0;
  portC=0;

   while(TRUE)
   {
     dato = read_adc();           //Leemos el ADC del canal 0 (A0) y lo almacenamos en "dato"
     temp = 0.019607843 * dato;   //lo multiplicamos por el resultante de la resolucion esto es (5V/255=0.019607843~) y lo almacenamos en temp
     multi = temp*10;             //esto lo multiplicamos por 10 y lo almacenamos en "multi"
     dec =  multi/10;            //las decenas mostradas en el display sera multi entre 10 para entregar un valor entero
     uni = multi % 10;            //y las unidades sera el el 10 porciento del valor de multi, entregando 10 numero antes de cambiar una decena

      for(i=0;i<=40;i++)
         {
         portb=disp[uni];
         delay_ms(10);
         portb=disp[dec] + 0x80;
         delay_ms(15);
         }
        }
}

En lo que seria en el canal 0 (A0 ira conectado un potenciometro, y lo que nos dara en la lectura de los 2 displays es un valor entre 0 y 5 V que es lo que estamos leyendo con el potenciomentro (voltaje en este caso) entonces el lado izquierdo sera las unidades y el lado derecho seran las decimales.

La conexión es la misma de los displays como lo era para el conteo de 0 a 99 antes ya posteado, solo se agregara el potenciometro, en caso de querer hacer el sensor de temperatura con esto ya se puede hacer, quitanm el potenciometro y ponenm su Lm35 o el que les plazca ma, configuran su programa para que haga los respectivos cambios recordando que por cada Grado Celsius equivalea a 10mV en el LM35, eso ya depende de su imaginacion para hacer la formula en su programa para hacer el sensor de temperatura, o un sistema sensorial de lo que ustes quieran. Yo eh hecho ya sistemas de flujo con esto, sistemas de monitoreo de presion, temperatura y de Efecto Hall por proximidad y magnetismo, asi que si funciona y muy bien....

el del LCD pues es super facil.

Es lo mismo pero sin la configuracon del puerto para visulaizar los displays, Solo se agrega una libreria mas para la concexion del LCD, el cual yo lo conecto al puerto B para esto si hacen su programa en PCHW PIC C compiler CSS tendremos que cambiar una cosita de la libreria.

Esta libreria esta configurada por default para que al display sea conectado al puerto D, pero siendo mas facil la canexion el el puerto B el cambio que haremos es la siguiente (Esto depende a gusto del que hace esto, lo pueden dejar asi o cambiarlo pero pues un dato curioso para que lo sepan.)

No s vamos a la carpeta donde instalamos el programa PICC que en mi caso es este C:\Archivos de programa\PICC despues nos metemos a la carpeta que dice drivers y buscamos la libreria LCD.h una vez adentro (lo pueden abrir con block de notos o con el mismo programa PICC) modifican esta linea // #define use_portb_lcd TRUE quitando las diagonales para que se quite de ser comentario y ahora ya estara listo para hacer la conexion al puerto b, si no hacen esto nunca lo hara. Pasara lo mismo para el teclado matricial que veremos despues. Guardan los cambios y cierran y listo.

Código:
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#include <LCD_flex.c>       //Libreria del LCD modificada para que mande todo al puerto B

#byte PORTB= 6            //Cambio de nombre a los puertos.
#byte PORTD= 8

void main()
{
   int dato;           //Variables declaradas
   float temp;
   
   set_tris_b(0);
   lcd_init();                      //inicializacion del LCD
   setup_adc_ports(2);
   setup_adc(adc_clock_div_32);    //Configuracion de los ADC
   set_adc_channel(0);
   
   while (TRUE)
   {
      dato=read_adc();
      temp=0.0196078 * dato;
      printf(LCD_PUTC,"Voltaje= %1.3f",temp);     //Asi debe de ir jajaja Lo que hace es mandar UN ENTERO (1) y TRES DECIMALES (3) (1.3) y la f pues es porque es flotante la variable.
      lcd_gotoxy(0,1);  le decimos que inicie en el renglon 0, en la columna 1 porque recordemos que es un LCD de 16x2.
   }
}

Bueno asi como leimos que se puede modificar las librerias de los programas para hacerlos mas efectivos o eficientes, tengo un amigo que modifico la libreria del LCD para leer un lcd mucho mas grande que este por cierto es para lcd de 16 x 2, bueno a todo esto el logra hacer monitos y pajaritos y figuras bien locas que se movian atravez del LCD, esto ya es mas de meterse a la programacion del LCD pero todo es posible. Claro tambien pueden bajar librerias que ya hacen esto, pero es mejro saber como se hace ¿no creen?...

NOTA:
Los LCD tienen una memoria integrada, si no borran lo ultimo que dejaron en el lcd al prenderlo leeran otra vez lo mismo, asi que no olviden en caso de quitarlo apargarlo desconectarlo o lo que se limpiar el LCD. mandando imprimir nada.

Seguimos despues con mas programas y mas explicaion para ustedes.
 
Hola por favor podrias postear como se usa el PICC?
yo estoy tratando de iniciarme en el lenguaje C ya tengo el picc pero no se como usarlo, por ejemplo quihsiera peegar uno de los programas que pones pero despues no entiendo que tocar para que me genere el exe.

Gracias
 
Gracias por contestar

Perdon fue un error de tipeo quise decir hex.

quisiera saber si lo que hago esta bien
1º abro pic wizar elijo el pic a usar y seteo las distintas configuraciones y cuando lo cierro me genera un archivo . H por ejemplo main.H
2º en la cabecera del picc pone automaticamente include el archivo que genero con el pic wizar
a continuacion escribo el programa y lo guardo con un nombre distinto al que genero el pic wizar por ejemplo modulo
3º luego le doy compile y el archivo hex. que genera se llama main.hex
y por supuesto cuando lo grabo en el pic nada hace no funciona

por favor me podrias decir que hago mal

Gracias
Saludos
 
Atrás
Arriba