TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: velaki en 27 de Abril de 2007, 07:43:44

Título: Cursillo en C18 para PICS DESDE CERO
Publicado por: velaki en 27 de Abril de 2007, 07:43:44
Bueno, seguramente no sea yo el mas indicado para comenzar este cursillo, pero visto lo visto, aqui expongo todo lo que tengo con respecto al c18, espero que aquellos que esteis empezando con este compilador expongais aqui vuestros ejemplos y dudas porque la verdad esque ahi pokitos ejemplos por ahi de C18, y yo practicamente estoy empezando,  bueno aqui dejo alguna iformación que tengo...  :shock:

TUTORIAL INICIACION PARA C18
http://informatica.uv.es/iiguia/SBM/manual.pdf
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 30 de Abril de 2007, 13:25:37
Yo tambien estoy empezando en C18, ya que he dejado el CCS, y la verdad es que hay pocos ejemplos de los que ir aprendiendo.¿Hay alguien que pueda ir poniendo ejemplitos en C18?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: manuelroin24 en 30 de Abril de 2007, 14:51:02
Mi amigo unas casillas mas abajo ya hay unos ejemplitos de C18 ahi puedes plantear tus dudas
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Mayo de 2007, 01:47:09
bueno amigos, lo primero que se tiene que hacer es leer todos los pdfs que vienen en la carpeta DOC del programa C18 una vez instalado, me refiero al getting started , el user guide y el library, tambien el archivo de ayuda hlppic18configset, no se vayan a aburrir!!!  :-/ jejej despues de esto estamos listos para programar, ah! y me olvidaba  :mrgreen: tambien leer el datasheet del pic18 que vamos a usar,  en mi caso se trata del 18F2525 y escogi este por 3  razones: tiene 28 patas para 3 puertos, esta en el proteus6.9, y mi amigo Juan (kedutpic) se compro el 18F2550 cuya diferencia con el 2525 es que el 18f2525 no tiene modulo USB.
cuando domine bien el C18 me paso al toque al 18f2550, asi que en el camino de aprender el C18 es que una motivacion más para mí es la de compartir la plancha (los archivos y demas cosas del C18) asi que sin mas preambulos vayamos al asunto...

materiales:
- compilador C18 de microchip.
- MPLAB, el ultimo si pueden creo q van en la 7.50.
- proteus 6.9
- paciencia y mucha curiosidad. :-/

revisar este hilo antes:
http://www.todopic.com.ar/foros/index.php?topic=11553.0


Indice

A continuación el indice de ejemplos de este humilde tutorial del C18

PRENDER UN LED (http://www.todopic.com.ar/foros/index.php?topic=17017.msg114252#msg114252)

PARPADEAR UN LED (http://www.todopic.com.ar/foros/index.php?topic=17017.msg114253#msg114253)

LEDS SECUENCIALES (http://www.todopic.com.ar/foros/index.php?topic=17017.msg114256#msg114256)

DISPLAY AUTOMATICO (http://www.todopic.com.ar/foros/index.php?topic=17017.msg114257#msg114257)

TEORIA ESTRUCTURAS DE CONTROL EN C18 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg115138#msg115138)

TEORIA DE VARIABLES EN C18 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg116457#msg116457)

TEORIA DE FUNCIONES EN C18 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg116474#msg116474)

INTERRUPCIONES EN C18 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg117440#msg117440)

INTERRUPCION CON EL TIMER0 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg117461#msg117461)

INTERRUPCION POR FLANCO EN RB0 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg117666#msg117666)

INTERRUPCION POR CAMBIO DE ESTADO EN RB0 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg117670#msg117670)

INTERRUPCION POR FLANCO EN RB1 Y RB2 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg118012#msg118012)

LCD16X2 A 4 BITS (http://www.todopic.com.ar/foros/index.php?topic=17017.msg119694#msg119694)

TEORIA DEL MODULO EUSART EN C18 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg119773#msg119773)

TEORIA DEL MODULO I2C EN C18 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg120877#msg120877)

EEPROM 24LC32 CON VISUALIZACION EN LCD (http://www.todopic.com.ar/foros/index.php?topic=17017.msg121087#msg121087)

LA LIBRERIA DEL DS1307 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg121438#msg121438)

PROYECTO TEMPORADA 1 RELOJ CON PANEL DE LEDS



Otras librerías:

Escribir/leer EEPROM Interna (http://www.todopic.com.ar/foros/index.php?topic=17017.msg190008#msg190008) por raraavis

Flex_LCD_C18 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg251661#msg251661) y uso de Printf por Suky

RTC DS1307 (http://www.todopic.com.ar/foros/index.php?topic=17017.msg267470#msg267470) por RedPIC&Suky


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Mayo de 2007, 02:17:59
PRENDER UN LED
Este programa enciende un led por cada puerto, en el pin RA0, RB0 y RC0.

Aca el codigo:
Código: C#
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. void main(void){
  16.         TRISA = 0X00;
  17.         TRISB = 0X00;
  18.         TRISC = 0X00;
  19. //*******************************************************
  20. //*******************************************************
  21.         LATA = 0X01;
  22.         LATB = 0X01;   
  23.         LATC = 0X01;
  24.         while (1);
  25. //*******************************************************
  26. //*******************************************************
  27. }
Todos los archivos: h**p://www.box.net/shared/ljus5d8v95

algun detalle que no se entienda gustoso estare en explicarlo  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Mayo de 2007, 02:40:45
PARPADEAR UN LED
Este programa hara parpadear un led por cada puerto, en el pin RA0, RB0 y RC0.
OSC XT: 4MHz

Aca el código:
Código: C#
  1. #include <p18f2525.h>
  2. #include <delays.h>
  3. #include <stdio.h>
  4. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  5. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  6. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  7. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  8. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  9. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  10. #pragma config CPB = ON,CPD = ON//CONFIG5H
  11. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  12. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  13. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  14. #pragma config EBTRB = ON//CONFIG7H
  15.  
  16. void main(void){
  17.         TRISA = 0X00;
  18.         TRISB = 0X00;
  19.         TRISC = 0X00;
  20. //*******************************************************
  21. //*******************************************************
  22.         while(1){
  23.                 LATA = 0X01;
  24.                 LATB = 0X01;   
  25.                 LATC = 0X01;
  26.                 Delay10KTCYx(20);//200 mseg
  27.                 LATA = 0X00;
  28.                 LATB = 0X00;
  29.                 LATC = 0X00;
  30.                 Delay10KTCYx(20);//200 mseg
  31.         }
  32.  
  33. //*******************************************************
  34. //*******************************************************
  35. }

Todos los archivos: h**p://www.box.net/shared/51111xhblr

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Mayo de 2007, 03:24:27
LEDS SECUENCIALES
Este programa hara un juego secuencial con leds en el puerto B.
OSC XT: 4MHz
Código: C#
  1. #include <p18f2525.h>
  2. #include <delays.h>
  3. #include <stdio.h>
  4. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  5. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  6. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  7. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  8. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  9. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  10. #pragma config CPB = ON,CPD = ON//CONFIG5H
  11. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  12. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  13. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  14. #pragma config EBTRB = ON//CONFIG7H
  15.  
  16. void main(void){
  17.         TRISA = 0X00;
  18.         TRISB = 0X00;
  19.         TRISC = 0X00;
  20.         LATA = 0X00;
  21.         LATC = 0X00;
  22. //*******************************************************
  23. //*******************************************************
  24.         LATB = 0X01;
  25.         for(;;){
  26.                 while(PORTB != 0X80){
  27.                         LATB <<= 1;
  28.                         Delay10KTCYx(50);//500 mseg
  29.                 }
  30.                 while(PORTB != 0X01){
  31.                         LATB >>= 1;
  32.                         Delay10KTCYx(50);//500 mseg
  33.                 }
  34.         }
  35. //*******************************************************
  36. //*******************************************************
  37. }

Todos los archivos: h**p://www.box.net/shared/j6t7hfx819
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Mayo de 2007, 04:20:52
DISPLAY AUTOMATICO
Este programa decrementa e incrementa automaticamente un display de 7 segmentos.
OSC XT: 4MHz
Código: C#
  1. #include <p18f2525.h>
  2. #include <delays.h>
  3. #include <stdio.h>
  4. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  5. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  6. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  7. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  8. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  9. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  10. #pragma config CPB = ON,CPD = ON//CONFIG5H
  11. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  12. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  13. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  14. #pragma config EBTRB = ON//CONFIG7H
  15.  
  16. int digito,
  17. display[10] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X67};
  18. void main(void){
  19.         TRISA = 0X00;
  20.         TRISB = 0X00;
  21.         TRISC = 0X00;
  22.         LATA = 0X00;
  23.         LATB = 0X00;
  24.         LATC = 0X00;
  25. //*******************************************************
  26. //*******************************************************
  27.         while(1){
  28.                 for(digito=1;digito<=9;digito++){
  29.                         LATB = display[digito];
  30.                         Delay10KTCYx(50);
  31.                 }
  32.                 for(digito=8;digito>=0;digito--){
  33.                         LATB = display[digito];
  34.                         Delay10KTCYx(50);
  35.                 }
  36.         }
  37. //*******************************************************
  38. //*******************************************************
  39. }

Todos los archivos: h**p://www.box.net/shared/lkneue4csl
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: manuelroin24 en 03 de Mayo de 2007, 04:33:39
Ese Henry siempre me gana, jajajaja felicitaciones mi amigo vas por muy buen camino
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Mayo de 2007, 04:47:52
no olviden leer los documentos del C18 y el datasheet de sus pic18
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: velaki en 06 de Mayo de 2007, 10:28:34
ESTUPENDO, AQUI AHI PARA RATO
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: velaki en 08 de Mayo de 2007, 13:09:19
No se porque pero no me acaba de funcionar el codigo en proteus, alugno de vosotros tiene un esquema de un 18f452  para  proteus? yo creo que los que empecemos con este compilador seria bueno hacerlo practicando con el mismo ejemplo en proteus... y de ahi ir abanzando, no creeis?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 08 de Mayo de 2007, 16:59:43
sube tus archivos pa chekearlos y sobrepasar el probelmilla antes de seguir avanzando con los ejemplos  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 10 de Mayo de 2007, 17:27:22
continuando con la linea de este post, ahora se va a colocar mas archivos, en esta ocasion vamos a reventar (es decir vamos a estudiar con muchas ganas) las estructuras de control del C aplicado en el C18 me refiero a lo siguiente:

Selectivas:
- if
- if else
- switch case

Repetitivas:
- while
- do while
- for

Bifurcaciónes:
- break
- continue

recomiendo que vayan buscando cualquier libro de C para saber un poco mas sobre el funcionamiento de la sintaxis, yo pondre lo poco que encontre, sin embargo uno no debe conformarse con una unica fuente.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 10 de Mayo de 2007, 19:49:27
Estructura de Control IF
Es una declaración condicional cuyo código asociado es ejecutado dependiendo de la condición. Si la expresion o condicion es TRUE entonces se ejecuta la sentencia, si es FALSE se terminara la condicion, ahora, TRUE es un valor cualquiera diferente de cero 0, FALSE es un valor igual a cero 0.
 
if (expresion o condicion)
  sentencia;
ejem:
      if(PORTA == 0X01) //portA es igual a 1?
         LATB = 0X01;//si, ejecutar sentencia
             //no, fin de declaracion

if (expresion o condicion)
   {
  sentencia1;
  sentencia2;
  sentencia3;
  sentencia4;
  sentencia5;
    }
ejem:
      //***************
      if(PORTA == 0X02) //puertoA es igual a 2?
      {
         LATB = 0X02; //si, ejecutar sentencias dentro de las llaves
         LATC = 0X02;
      }
      //***************
               //no, fin de condicional


Estructura de Control IF-ELSE
Tenemos 2 bloques de codigo separados por la condicion, de esta manera, si la condicon es TRUE ejecutar bloque 1, si es FALSE entonces ejecutar bloque2.

if (expresion o condicion)
{
  sentencia1; //bloque 1
  sentencia2;
}
else
{
  sentencia3; // bloque 2
  sentencia4;
}
ejem:
      //***************
      if(PORTA >= 0X09); porta es mayor o igual que 9?
      {
         a=255; //bloque 1     TRUE
         b=0;
      }
      else  //sino, entonces...
      {
         b=255;//bloque 2       FALSE
         a=0;
      }
      //***************
           //fin de condicion

Estructura de Control IF - ELSE/ELSE IF
Es una variante del IF - ELSE, por la cual el lenguaje C nos permite realizar una estructura de condicion con mas de 2 decisiones.

if (expresion1 o condicion1)
{
  sentencia1; //bloque 1
  sentencia2;
}
else if (expresion2 o condicion2)
{
  sentencia3; // bloque 2
  sentencia4;
}
else
{
  sentencia5; // bloque 3
  sentencia6;
}
ejem:
      //***************
      if(PORTA == 0X0F) //condicion 1
      {
         LATB = 0X0F;
         LATC = 0X0F;
      }
      else if (PORTA == 0X0E) // condicion 2
      {
         LATB = 0X0E;
         LATC = 0X0E;
      }
      else //sino , entonces
      {
         a++;
         b--;
      }

Finalmente, anotamos los operadores con lo que se obtienen las condiciones o expresiones del condicional IF:
Citar
x == y   :    x (igual a) y
x != y    :    x (es diferente a) y
x > y     :    x (es mayor que) y
x < y     :    x (es menor que) y
x <= y   :    x (es menor o igual que) y
x >= y   :    x (es mayor o igual que) y
x && y    :   AND logico
x || y     :   OR logico



APLICACION DEL IF, ELSE, ELSE IF

Código: C#
  1. //micro_cadaver
  2. //hlaredo@gmail.com
  3. #include <p18f2525.h>
  4. #include <stdio.h>
  5. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  6. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  7. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  8. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  9. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  10. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  11. #pragma config CPB = ON,CPD = ON//CONFIG5H
  12. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  13. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  14. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  15. #pragma config EBTRB = ON//CONFIG7H
  16.  
  17. unsigned int a,b;
  18.  
  19. void main(void){
  20.         //inicializar puertoA
  21.         //todos los pines
  22.         //seran digitales
  23.         PORTA = 0X00;
  24.         LATA = 0X00;
  25.         ADCON0 = 0X00;
  26.         ADCON1 = 0X0F;
  27.         CMCON = 0X07;
  28.         //*******************
  29.         TRISA = 0XFF;
  30.         TRISB = 0X00;
  31.         TRISC = 0X00;
  32.         LATB = 0X00;
  33.         LATC = 0X00;
  34. //*******************************************************
  35. //*******************************************************
  36.         while(1)
  37.         {
  38.                 //***************
  39.                 if(PORTA == 0X01)
  40.                         LATB = 0X01;
  41.                 //***************
  42.                 if(PORTA == 0X02)
  43.                 {
  44.                         LATB = 0X02;
  45.                         LATC = 0X02;
  46.                 }
  47.                 //***************
  48.                 if(PORTA <= 0X05)
  49.                         a=10;
  50.                 else
  51.                         a=100;
  52.                 //***************
  53.                 if(PORTA >= 0X09)
  54.                 {
  55.                         a=255;
  56.                         b=0;
  57.                 }
  58.                 else
  59.                 {
  60.                         b=255;
  61.                         a=0;
  62.                 }
  63.                 //***************
  64.                 if(PORTA == 0X0F)
  65.                 {
  66.                         LATB = 0X0F;
  67.                         LATC = 0X0F;
  68.                 }
  69.                 else if (PORTA == 0X0E)
  70.                 {
  71.                         LATB = 0X0E;
  72.                         LATC = 0X0E;
  73.                 }
  74.                 else
  75.                 {
  76.                         a++;
  77.                         b--;
  78.                 }
  79.         }
  80. //*******************************************************
  81. //*******************************************************
  82. }

todos los archivos:h**p://www.box.net/shared/ez6axq7sq1
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 11 de Mayo de 2007, 02:32:02
Estructura de Control SWITCH CASE
Recuerdan que con el IF ELSE IF se puede seleccionar hasta mas de dos decisiones o alternativas?, que tal si tuvieramos multiples alternativas, el codigo se haria engorroso y el compilador la pasaria mal también, para estos casos existe la estructura SWITCH la cual permite de manera ordenada y práctica la elaboración de múltiples alternativas frente a una variable.

La variable es contrastada con cada constante de los CASEs, cuando se ubica una coincidencia, el bloque de sentencias definido dentro de dicho case es ejecutado hasta que se encuentra al break y termina la busqueda de coincidencias y también la estructura misma. Si no se encontrara ninguna opcion que satisfaga la variable se seleccionará por defecto la opcion DEFAULT, cuya presencia en un SWITCH CASE es opcional.

switch (variable)
{
        case constante1:
               sentencia1;
               break;
        case constante2:
               sentencia2;
               break;
        case constante3:
               sentencia3;
               break;
        case constante4:
               sentencia4;
               break;
           .
           .
           .

        default:
               sentenciaX;
}

pueden ir dentro de cada CASE mas de una sentencia; segun el ANSI standard dice que el C soporta hasta 257 CASEs, eso es bastante  :mrgreen:

APLICACION DEL SWITCH CASE
OSC XT: 4MHz
Código: C#
  1. //micro_cadaver
  2. //hlaredo@gmail.com
  3. #include <p18f2525.h>
  4. #include <stdio.h>
  5. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  6. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  7. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  8. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  9. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  10. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  11. #pragma config CPB = ON,CPD = ON//CONFIG5H
  12. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  13. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  14. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  15. #pragma config EBTRB = ON//CONFIG7H
  16.  
  17. unsigned int a,b;
  18.  
  19. void main(void){
  20.         //inicializar puertoA
  21.         //todos los pines
  22.         //seran digitales
  23.         PORTA = 0X00;
  24.         LATA = 0X00;
  25.         ADCON0 = 0X00;
  26.         ADCON1 = 0X0F;
  27.         CMCON = 0X07;
  28.         //*******************
  29.         TRISA = 0XFF;
  30.         TRISB = 0X00;
  31.         TRISC = 0X00;
  32.         LATB = 0X00;
  33.         LATC = 0X00;
  34. //*******************************************************
  35. //*******************************************************
  36.         while(1)
  37.         {
  38.                 switch (PORTA)
  39.                 {
  40.                         case 0:
  41.                         LATB=0X00;
  42.                         break;
  43.                         case 2:
  44.                         LATB=0X02;
  45.                         break;
  46.                         case 4:
  47.                         LATB=0X04;
  48.                         break;
  49.                         case 6:
  50.                         LATB=0X06;
  51.                         break;
  52.                         case 8:
  53.                         LATB=0X08;
  54.                         break;
  55.                         case 10:
  56.                         LATB=0X0A;
  57.                         break;
  58.                         case 12:
  59.                         LATB=0X0C;
  60.                         break;
  61.                         default:
  62.                         LATB=0XFF;
  63.                 }
  64.         }
  65. //*******************************************************
  66. //*******************************************************
  67. }
todos los archivos:h**p://www.box.net/shared/f8cr8n7n03
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 13 de Mayo de 2007, 22:37:40
ESTRUCTURA DE CONTROL FOR

Es un bucle que el lenguaje C nos proporciona para obtener repeticiones de bloques de codigo de manera clara y precisa. su sintaxis es la siguiente:

for ( inicializacion;condicional;incremento)
{
    sentencia1;
    sentencia2;
    sentencia3;
    .
    .
    .
}

La inicializacion es usada para dar un valor inicial al contador (que es una variable ya declarada) del bucle for; el condicional es evaluado antes de ejecutar el codigo dentro del bucle y su valor al ser evaluado puede ser TRUE o FALSE, si es TRUE entonces el codigo dentro del bucle for es ejecutado, sin embargo si es FALSE se termina con el bucle for; el incremento es el que se encarga de incrementar la variable contador dentro del bucle for.

Ejem:
   for(a=0;a<=30;a++)
   {
      LATB++;
      LATC--;
      Nop();
   }


ESTRUCTURA DE CONTROL WHILE
Otro bucle del C. Mientras la expresión sea TRUE se repetira una porción de codigo que esté dentro del bucle while, cuando la espresión evaluada sea FALSE se terminara el bubcle while. Siempre sera evaluada la expresió nantes de seguir ejecutando la porción de código.

while  (expresion)
{
         sentencia1;
         sentencia2;
         sentencia3;
         .
         .
         .
}

Ejm:
   while(PORTA==0X00)
   {
      a++;
      b--;
   }


ESTRUCTURA DE CONTROL DO WHILE
En este caso se combinan el DO con el WHILE, realizando un bucle en el cual se ejecuta primero las sentencias o codigo y luego se evalua la expresión o condicional, de la misma forma que el while y el for, si la expresión evaluada resulta TRUE se continúa con el bucle, de lo contrario, si resulta FALSE se termina con el bucle.

do
{
         sentencia1;
         sentencia2;
         sentencia3;
         .
         .
         .
}
while  (expresion);

Ejm:
   do
   {
      LATC=0XAA;
      LATB=0X55;   
   }
   while(PORTA==0X00);

CODIGO DE APLICACION
Código: C#
  1. //micro_cadaver
  2. //hlaredo@gmail.com
  3. #include <p18f2525.h>
  4. #include <stdio.h>
  5. #include <delays.h>
  6. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  7. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  8. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  9. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  10. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  11. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  12. #pragma config CPB = ON,CPD = ON//CONFIG5H
  13. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  14. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  15. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  16. #pragma config EBTRB = ON//CONFIG7H
  17.  
  18. unsigned int a,b;
  19.  
  20. void main(void){
  21.         //inicializar puertoA
  22.         //todos los pines
  23.         //seran digitales
  24.         PORTA = 0X00;
  25.         LATA = 0X00;
  26.         ADCON0 = 0X00;
  27.         ADCON1 = 0X0F;
  28.         CMCON = 0X07;
  29.         //*******************
  30.         TRISA = 0XFF;
  31.         TRISB = 0X00;
  32.         TRISC = 0X00;
  33.         LATB = 0X00;
  34.         LATC = 0X00;
  35. //*******************************************************
  36. //*******************************************************
  37.         for(a=0;a<=30;a++)
  38.         {
  39.                 LATB++;
  40.                 LATC--;
  41.                 Delay1KTCYx(100);
  42.         }
  43.         //*****************
  44.         for(b=60;b>=40;b--)
  45.         {
  46.                 LATB=~LATB;
  47.                 Nop();
  48.                 Delay1KTCYx(200);
  49.         }
  50.         //*****************
  51.         while(PORTA!=0X05);
  52.         //*****************
  53.         while(PORTA!=0X00)
  54.         {
  55.                 a++;
  56.                 b--;
  57.         }
  58.         //*****************
  59.         do
  60.         {
  61.                 LATC=0XAA;
  62.                 LATB=0X55;     
  63.         }
  64.         while(PORTA==0X00);
  65.         //*****************
  66.         LATB=0;
  67.         LATC=0;
  68.         while(1);
  69. //*******************************************************
  70. //*******************************************************
  71. }
todos los archivos:h**p://www.box.net/shared/70r3lbe0fy

Código: C#
  1. bonus:  :-/
  2. bucle infinito con while:
  3. while(1);
  4.  
  5. bucle infinito con for:
  6. for(;;);

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 14 de Mayo de 2007, 00:20:56
BIFURCACIONES DE CONTROL BREAK
Esta instrucción nos permite salir de cualquier bucle ya sea WHILE , DO WHILE, FOR. Cuando el programa encuentra a esat instrucción simplemente salta a la siguiente instruccion fuera del bucle donde se hallaba contenido.

Ejm:
   for(a=0;a<=200;a++)
   {
      Delay1KTCYx(200);
      if (PORTA==0X05)
         break;
      LATB=~LATB;
   }

En esta situación, tenemos un bucle FOR que contara hasta 200 con la variable " a " para satisfacer la expresión del bucle, sin embargo existe un break el cual depende de la estructura condicional IF que inidica si PORTA is igual a 5 entonces ejecuta break, de lo contrario finaliza el IF y continua con el bucle. Cuando PORTA sea igual a 5 el programa se topara con el BREAK y como consecuencia terminara con el bucle FOR y continuará con la siguiente instrucción fuera del bucle.


BIFURCACIONES DE CONTROL CONTINUE
Digamos que dentro de nuestro bucle existe una instrucción al final del bloque de codigo que queremos saltarla o no ejecutarla dependiendo de alguna condición extra, la instruccion CONTINUE permite saltar todas las instrucciones posteriores a su aparición dentro del bloque de codigo escrito en el bucle.

Ejm:
   for(b=0;b<=200;b++)
   {
      Delay1KTCYx(200);
      if (PORTA==0X0A)
         continue;
      LATC=~LATC;
   }

En este caso, el bucle FOR contara hasta 200 con la variable " b " y ejecutará la ultima instruccion LATC=~LATC dependiendo del estado del PORTA, siempre y cuando sea igual a 0X0A, de esta manera se utiliza el CONTINUE.

EJEMPLO PARA EL PIC18
Código: C#
  1. //micro_cadaver
  2. //hlaredo@gmail.com
  3. #include <p18f2525.h>
  4. #include <stdio.h>
  5. #include <delays.h>
  6. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  7. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  8. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  9. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  10. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  11. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  12. #pragma config CPB = ON,CPD = ON//CONFIG5H
  13. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  14. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  15. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  16. #pragma config EBTRB = ON//CONFIG7H
  17.  
  18. unsigned int a,b;
  19.  
  20. void main(void){
  21.         //inicializar puertoA
  22.         //todos los pines
  23.         //seran digitales
  24.         PORTA = 0X00;
  25.         LATA = 0X00;
  26.         ADCON0 = 0X00;
  27.         ADCON1 = 0X0F;
  28.         CMCON = 0X07;
  29.         //*******************
  30.         TRISA = 0XFF;
  31.         TRISB = 0X00;
  32.         TRISC = 0X00;
  33.         LATB = 0X00;
  34.         LATC = 0X00;
  35. //*******************************************************
  36. //*******************************************************
  37.         for(a=0;a<=200;a++)
  38.         {
  39.                 Delay1KTCYx(200);
  40.                 if (PORTA==0X05)
  41.                         break;
  42.                 LATB=~LATB;
  43.         }
  44. //*******************************************************
  45. //*******************************************************
  46.         for(b=0;b<=200;b++)
  47.         {
  48.                 Delay1KTCYx(200);
  49.                 if (PORTA==0X0A)
  50.                         continue;
  51.                 LATC=~LATC;
  52.         }
  53. //*******************************************************
  54. //*******************************************************
  55.         for(;;);
  56. }
todos los archivos:h**p://www.box.net/shared/6pxn2zqir8
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 15 de Mayo de 2007, 02:46:09
bueno bueno bueno, a ver m.... que se cocina por aca....  :-) antes de pasar a las interrupciones en C18 vamos a darle una repasada a los FUNCTIONS y a los tipos de VARIABLES pues las interrupciones en el C18 tienen una sintaxis similar a la de los functions y se declaran como volatiles que es un tipo de variable.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 17 de Mayo de 2007, 02:00:32
 :mrgreen: hola henry , te felicito por tu trabajo esta muy bueno, por mi parte ya pude probar algunos de tus programas con el pic18F2550,me funcionaron sin ningun error,  claro que la palabra de configuracion es diferente, por lo que solo le hice una leve modificacion al encabezado de todos tus programas, sigue asi amigo del planeta VULCANO , desde aqui el planeta TIERRA , cambio y fuera ,  :D  :D  :D .
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 17 de Mayo de 2007, 14:18:43
Hola a todos.

Excelente trabajo del amigo micro_cadaver para los que estamos empezando en este mundo del C18.Yo tengo algunos problemas y no soy capaz de compilar bien ningun ejemplo.Creo que es porque no añado las librerias oportunas o algo asi.

Antes de seguir con tus explicaciones, ¿podrias dar unas nociones para que se compile bien un ejemplo de los que has expuesto aqui?Te lo agradeceria mucho porque no consigo avanzar.Los errores que me ponen son:

Error [1027] unable to locate 'p18cxxx.h'
Error [1099] "osc not defined"

Gracias
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 17 de Mayo de 2007, 14:27:25
 :mrgreen: ups !
bueno no hay problema pero... me parece que ya alguien habia hablado del tema de configurar el C18 dentro del MPLAB ademas en los pdfs que te vienen con el c18 (en la capreta docs) revisa el gettind started . pdf ahi especifican bastante sobre el asunto, si encuentro el hilo lo coloco para simplificar ese problemilla  :mrgreen: y gracias me gustaria hacerlo mejor pero el tiempo me tiene cogido de los huev....s  :D

mira: http://www.todopic.com.ar/foros/index.php?topic=11553.0
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 20 de Mayo de 2007, 19:50:23
Antes de continuar con las Funciones para el C18 hagamos un repaso a las variables en el compilador C18.

VARIABLES:
Es la forma en que se almacenan datos en el compilador C18.

TIPOS DE DATOS:
La siguiente tabla nos muestra los tipos de datos existentes en el compilador C18.

       Tipo                Tamaño      Mínimo                   Máximo           
char                          8bits          -80                        +7F               
unsigned char            8bits           00                          FF                 
int                            16bits       -8000                     +7FFF               
unsigned int              16bits        0000                       FFFF                       
short long                 24bits      -800000                 +7FFFFF             
unsigned short long   24bits       000000                   FFFFFF               
long                         32bits    -80000000              +7FFFFFFF             
unsigned long           32bits     00000000                FFFFFFFF             
float                         32bits     2^(-126)      2^(+128) * (2 - 2^(-15))

Para mayor información consultar el documento: MPLAB C18 compiler user's guide , capitulo 2.  :mrgreen:

DECLARACIONES:
El formato de declaración de una variable es la siguiente:
tipo_de_variable    nombre_de_la_variable;
Ejm:
int    micro_cadaver;

Las variables que son declaradas dentro de una función se llaman Variables Locales; y las que son declaradas fuera de todas las funciones se llaman Variables Globales.

Las Variables Locales solo pueden ser utilizadas dentro de la función donde fueron declaradas. Se permite que en diferentes funciones existan variables que tengan el mismo nombre.

Ejm:
Código: C#
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. void funcion1(void){
  16.         char todopic;//variable local
  17.         unsigned char megapic;//variable local
  18.         todopic ++;
  19.         megapic --;
  20. }
  21. //*******************
  22. void funcion2(void){
  23.         int todopic;//variable local
  24.         unsigned int megapic;//variable local
  25.         todopic --;
  26.         megapic --;
  27. }
  28. //*******************
  29. void funcion3(void){
  30.         float a,b,c;//variable local
  31.         a=-0.17;
  32.         b=5.355;
  33.         c=0.93;
  34. }
  35. //*******************
  36. void funcion4(void){
  37.         short long kedutpic;//variable local
  38.         unsigned short long manuelroin;//variable local
  39.         kedutpic = 0x0F;
  40.         manuelroin = 0x08;
  41. }
  42. //********************************************
  43. //********************************************
  44. //
  45. //      funcion principal
  46. //
  47. //********************************************
  48. //********************************************
  49. void main(void){
  50.         unsigned long macro_cadaver;//variable local
  51.         long micro_cadaver;//variable local
  52.         TRISA = 0X00;
  53.         TRISB = 0X00;
  54.         TRISC = 0X00;
  55.  
  56.         macro_cadaver = 0XFFFFFFFF;
  57.  
  58.         micro_cadaver = +26556;
  59.         micro_cadaver = -26556;
  60.  
  61.         funcion1();
  62.         funcion2();
  63.         funcion3();
  64.         funcion4();
  65.         while (1);
  66. //*******************************************************
  67. //*******************************************************
  68. }

Por otro lado, las variables globales pueden ser usadas en distintas funciones.
Código: C#
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. char todopic='A';//variable global
  16. unsigned char megapic='h';//variable global
  17. float a,b,c;//variable global
  18. short long kedutpic;//variable global
  19. unsigned short long manuelroin=0;//variable global
  20. unsigned long macro_cadaver=15;//variable global
  21. long micro_cadaver;//variable global
  22.  
  23. void funcion1(void){
  24.         todopic ++;
  25.         c=0.93;
  26.         megapic --;
  27. }
  28. //*******************
  29. void funcion2(void){
  30.         todopic --;
  31.         c=0.93;
  32.         megapic --;
  33. }
  34. //*******************
  35. void funcion3(void){
  36.         a=-0.17;
  37.         c=0.93;
  38.         kedutpic = 0x0F;
  39. }
  40. //*******************
  41. void funcion4(void){
  42.         a=-0.17;
  43.         b=5.355;
  44.         kedutpic = 0x0F;
  45.         manuelroin = 0x08;
  46. }
  47. //********************************************
  48. //********************************************
  49. //
  50. //      funcion principal
  51. //
  52. //********************************************
  53. //********************************************
  54. void main(void){
  55.         TRISA = 0X00;
  56.         TRISB = 0X00;
  57.         TRISC = 0X00;
  58.  
  59.         macro_cadaver = 0XFFFFFFFF;
  60.  
  61.         micro_cadaver = +26556;
  62.  
  63.         kedutpic = 0x0F;
  64.         a=-0.17;
  65.  
  66.         funcion1();
  67.         funcion2();
  68.         funcion3();
  69.         funcion4();
  70.         while (1);
  71. //*******************************************************
  72. //*******************************************************
  73. }
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 20 de Mayo de 2007, 22:42:11
FUNCIONES
Son un conjunto de sentencias que realizan una determinada tarea, pueden tomar valores de entrada y proporcionar un valor de retorno. Una función que siempre estará presente en un programa es la función " main ". Se puede hacer una analogía con las rutinas en el assembler.

COMO DECLARAR UNA FUNCIÓN?
Una función debe ser declarada y definida antes de ser invocada, así como sucede con las variables.

Una manera de declarar las funciones es presentándola antes de la función principal main:
Código: C#
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. unsigned int a,b,c;//variables globales
  16.  
  17. void funcion1(void){
  18.         a=234;
  19.         b--;
  20.         c>>=2;
  21. }
  22. //*******************
  23. void funcion2(void){
  24.         a=68;
  25.         b++;
  26.         c<<=5;
  27. }
  28.  
  29. //********************************************
  30. //********************************************
  31. //
  32. //      funcion principal
  33. //
  34. //********************************************
  35. //********************************************
  36. void main(void){
  37.         TRISA = 0X00;
  38.         TRISB = 0X00;
  39.         TRISC = 0X00;
  40.                
  41.         a=15;
  42.         b++;
  43.         c=~c;
  44.  
  45.         funcion1();//se invoca a la funcion
  46.         funcion2();//se invoca a la funcion
  47.  
  48.         while (1);
  49. //*******************************************************
  50. //*******************************************************
  51. }

La otra forma es utilizando los prototipos:
Código: C#
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. unsigned int a,b,c;//variables globales
  16.  
  17. void funcion1(void);//prototipo
  18. void funcion2(void);//prototipo
  19.  
  20. //********************************************
  21. //********************************************
  22. //
  23. //      funcion principal
  24. //
  25. //********************************************
  26. //********************************************
  27. void main(void){
  28.         TRISA = 0X00;
  29.         TRISB = 0X00;
  30.         TRISC = 0X00;
  31.                
  32.         a=15;
  33.         b++;
  34.         c=~c;
  35.  
  36.         funcion1();//se invoca a la funcion
  37.         funcion2();//se invoca a la funcion
  38.  
  39.         while (1);
  40. //*******************************************************
  41. //*******************************************************
  42. }
  43. void funcion1(void){
  44.         a=234;
  45.         b--;
  46.         c>>=2;
  47. }
  48. //*******************
  49. void funcion2(void){
  50.         a=68;
  51.         b++;
  52.         c<<=5;
  53. }
su importancia no es aparente en programas pequeños, sin embargo su utilidad se hace necesaria en la depuración de errores en programas grandes con mas de 1000 sentencias.

CÓMO Y PARA QUÉ DEFINIMOS UNA FUNCIÓN?
La definición de una función sirve para informarle al compilador sobre las instrucciones con las que va a trabajar la función declarada. Además la defnición es la que contiene el cuerpo o bloque de sentencias de la función. El formato general para la definición de funciones es la siguiente:

Tipo_de_retorno  Nombre_de_función (tipo_entrada1,tipo_entrada2,tipo_entrada3,...);

Donde: " Tipo_de_retorno " es el tipo de valor que la función puede devolver.
            " Nombre_de_función " es el nombre de la función declarada.
            " tipo_entradaX " es el tipo de valor que ingresa a la función y se declara como una variable.

En el ejemplo siguiente se va a mostrar los tipos de funciones más comunes que podemos elaborar dentro del C18:
Código: C#
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. int a,c,z;//variables globales
  16. long b,temp;//variables globales
  17.  
  18. //Esta funcion va a retornar un valor tipo " int "
  19. //y tiene como valores de entrada 2 variables tipo "int".
  20. int funcion1(int x,int y)
  21. {
  22.         PORTA = 0x05;
  23.         PORTB = 0x08;
  24.         return x+y;//retorna valor tipo "int"
  25. }
  26. //Esta funcion va a retornar un valor tipo " long "
  27. //y tiene como valor de entrada una variables tipo "int".
  28. long funcion2(int x)
  29. {
  30.         temp=x;
  31.         temp<<=3;
  32.         temp*=10;
  33.         return temp;//retorna valor tipo "long"
  34. }
  35.  
  36. //Esta funcion va a retornar un valor tipo "int"
  37. //y no tiene valor de entrada.
  38. int funcion3(void)
  39. {
  40.         if(PORTC == 0X88)
  41.                 return 1;
  42.         z++;
  43.         return z;
  44. }
  45.  
  46. //Esta funcion no tiene valor a retornar
  47. //ni tiene valor de entrada.
  48. void funcion4(void)
  49. {
  50.         z--;
  51.         temp = 0x12167;
  52. }
  53.  
  54. //********************************************
  55. //********************************************
  56. //
  57. //      funcion principal
  58. //
  59. //********************************************
  60. //********************************************
  61. void main(void){
  62.         TRISA = 0X00;
  63.         TRISB = 0X00;
  64.         TRISC = 0XFF;
  65.        
  66.         //funcion1 se carga con valores tipo "int"
  67.         //y espera retorno de variable tipo "int"
  68.         a = funcion1(10,20);
  69.  
  70.         //funcion2 se carga con un valor tipo "int"
  71.         //y espera retorno de variable tipo "long"
  72.         b = funcion2(30);
  73.  
  74.         //funcion3 no tiene valor de carga
  75.         //y espera retorno de variable tipo "int"
  76.         c = funcion3();
  77.  
  78.         //funcion4 no tiene valor de carga
  79.         //ni espera retorno
  80.         funcion4();
  81.  
  82.         while (1);
  83. //*******************************************************
  84. //*******************************************************
  85. }


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 21 de Mayo de 2007, 02:20:32
 8) hola henry tengo 1 dudas con respecto a tus programas :

Que pasaria si yo tuviera un dato < de 16 bits y lo defino como un short long  que es de  24bits segun lo que has escrito ,  tendra algun efecto en la memoria del PIC  , al momento de compilarlo y grabarlo ??.

   
void funcion4(void){
a=-0.17;
b=5.355;
kedutpic = 0x0F;
manuelroin = 0x08;

 :? Otra cosa , me gustan el nombre de tus variables son originales jajajjaja  :D
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 21 de Mayo de 2007, 02:46:01
habla tio  :-/ , no pasaria nada, el compilador simplemente llenaria con ceros el resto de bits, es mas si el dato fuera > de 24 bits y lo defines como un short long, el compilador solo ingresa los 24bits que corresponden a la definicion de la variable y perderías el resto de bits, tampoco te aparece ningun error en el compilado.

PD: ya se vienen las interrupciones!!!  :mrgreen: :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 21 de Mayo de 2007, 07:25:34
Muchas gracias por tu ayuda micro_cadaver.Lo he mirado y tenia mal configuradas las opciones del compilado.Ahora creo que ya me va bien y empezare a probar todos tus programas y a seguir aprendiendo.Espero con entusiasmo la nueva entraga de interrupciones  :D :D
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 21 de Mayo de 2007, 10:08:30
ah que bien tio!!! jjejej  :mrgreen: yo tambien sufri al inicio para hacerlo arrancar me lei como 10 veces el datasheet del C18 el user's guide son varios detalles no? cada vez que creo un proyecto tengo que poner el linker, adjuntar el codigo fuente, luego tengo que ir a projects y rutear unas carpetas H y LIB que se me borran no se porque cada vez que hago un proyecto nuevo  :shock: jeje pero ya me acostumbre  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 21 de Mayo de 2007, 12:39:28
ah que bien tio!!! jjejej  :mrgreen: yo tambien sufri al inicio para hacerlo arrancar me lei como 10 veces el datasheet del C18 el user's guide son varios detalles no? cada vez que creo un proyecto tengo que poner el linker, adjuntar el codigo fuente, luego tengo que ir a projects y rutear unas carpetas H y LIB que se me borran no se porque cada vez que hago un proyecto nuevo  :shock: jeje pero ya me acostumbre  :mrgreen:


Jeje, yo hacía eso hasta que me acostumbré a usar templates. 

Templates hechos por mi, por supuesto, no hay tal cosa en C18. 

Es decir un proyecto con código base , con todo lo necesario, linker file, archivos .h, archivos .c, paths.  Lo copio y lo pego en mi nueva ubicación y voilá!!


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 22 de Mayo de 2007, 21:33:09
hola maunix, seria algo asi:
#include <c:\archivosdeprograma\microchip\c18\h>
 :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 23 de Mayo de 2007, 08:57:19
hola maunix, seria algo asi:
#include <c:\archivosdeprograma\microchip\c18\h>
 :-/

No.  Es tener un proyecto con su archivo .mcp y .mcw en una carpeta.  En dicha carpeta también tienes tu main, tus librerías que siempre usas, el linker file, y los header (.h) que siempre usas.

Todo eso lo guardas en algun lado y lo copias y pegas cada vez que inicias un nuevo proyecto y cambias lo que debas cambiar.

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: vszener en 23 de Mayo de 2007, 11:25:54
Algo como guardar tu workspace ;)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 23 de Mayo de 2007, 14:41:10
Algo como guardar tu workspace ;)

Claro, pero casualmente el 'workspace' en un proyecto de microchip es un archivo separado.  Hay que guardar eso y todo el resto que uno crea conveniente.  Por eso hablé de 'templates'  8) 8)

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 24 de Mayo de 2007, 12:20:37
Hola amigos!!

Estoy intentando estudiar y aprender con los ejemplos de micro_cadaver pero para que yo los pueda utilizar con mi pic que es el 18F4620 tengo que saber para que sirve esta parte del programa.

#pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
#pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
#pragma config CPB = ON,CPD = ON//CONFIG5H
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
#pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
#pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
#pragma config EBTRB = ON//CONFIG7H

Yo vengo del CCS y supongo que son como los fuses alli.He estado buscando en la ayuda que significa cada cosa pero no consigo encontrarlo.Seguire buscandolo, pero si alguien me puede ayudar se lo agradeceria.

Otra pregunta, o mas bien aclaracion, es que los puertos no hay que decirles en que parte del mapa de memoria esta porque lo toma del linker, no?

Gracias :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 24 de Mayo de 2007, 12:51:19
claro jeje puedes buscar en el datasheet correspondiente a tu pic18FXX  y te diriges a CONFIGURATION BITS, ahi aparece las palabras de configuracion de todo tu micro, en el 18f2525 son 7 registros de configuracion  :? y crei conveniente ponerlo todo porque mi filosofia es que el pic maniaco debe saber exactamente que es lo que esta programando en su chip, no dejar cabos sueltos y entender todo al menos el 99% jijijiji yo voy recien por el 70% creo  :D,ya pues esa es una manera de saber que significan cada registro y cada bit de configuracion, otra manera es dirigirte a la subcarpeta DOC ques esta en la carpeta del programa MPLAB C18, dentro de la subcarpeta DOC encontraras varios archivos, como ya losmencionen antes, le das al archivo de ayuda hlpPIC18ConfigSEt , luego buscas tu pic en una lista que esta a la izquierda y te lees todooooo lo que salga  :mrgreen:

cualquier duda mas no dudes en postearlo  :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 25 de Mayo de 2007, 07:04:17
Buenas!!! :-/ :-/

He visto en un ejemplo algo de lo que no estoy familiarizado y lo expongo aqui a ver si alguien sabe que significa y para que sirve.Se trata de lo siguiente:

#if !defined(DEBUG_MODE)
   #define BIND_SWITCH             PORTBbits.RB7         // Bind = RB7 in normal operation
   #define TRIS_BIND_SWITCH        TRISBbits.TRISB7
#else
   #define BIND_SWITCH             PORTBbits.RB5         // Bind = RB5 in debug
   #define TRIS_BIND_SWITCH        TRISBbits.TRISB5
#endif

No entiendo porque pone # delante de la sentencia if.¿Sabe alguien porque se hace esto?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jfh900 en 25 de Mayo de 2007, 09:41:52
Hola barg son instrucciones de preprocesado, se ejecuatn antes de la compilación y permiten cambiar el programa en funcion de variables externas. Para el caso que pones, si definimos la variable DEBUG_MODE la variable BIND_SWITCH se asigana al bit 7 del puerto B y si no está definida se asigna al bit 5 del puerto B. Permite por lo tanto tener distintas versiones del programa con un mismo código fuente (con DEBUG y SIN DEBUG), dependiendo como esten definidas las variables del preprocesador.

Un saludo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 28 de Mayo de 2007, 05:56:04
Micro_cadaver he intentado bajarme los archivos de los programas que has puesto aqui pero no he podido bajarmelos.Los puedes volver a poner o mandarmelos a rg_benitez@hotmail.com .Muchas gracias

Gracias por tu explicacion jfh900
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 28 de Mayo de 2007, 13:51:04
Hola de nuevo,  :) :)

Estoy intentando probar el programita de micro_cadaver de hacer parpadear un led, como veis mis pasos son lentos aunque espero que firmes :P.Y cuando le doy a "build all" me da error y pone lo siguiente:

Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "D:\PROGRAMAS\MCC18\bin\mcc18.exe" -p=18F4620 "parpadeo.c" -fo="parpadeo.o" -Oa -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:1:Error [1027] unable to locate 'p18f4620.h'
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:2:Error [1027] unable to locate 'delays.h'
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:3:Error [1027] unable to locate 'stdio.h'

Creo que el problema es que no reconoce la localizacion de los archivos, pero lo he provado de muchas formas distintas y siempre es el mismo resultado.¿Alguien sabe el porque de mi error?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 28 de Mayo de 2007, 15:39:12
m....
si recuerdo ese error, m..... creo que sucede cuando no esta direccionado la carpeta de librerias en tu C18, has visto con detalles los links donde configuran el c18? y el otro programa de prender un led te compilo bien? he estado buscando ese error y no recuerdo como generarlo, sigo en la busqueda...





pd1: que ya no funciona el link? a ver.... h**p://www.box.net/shared/51111xhblr si funciona, naturalmente amigo teneis que cambiar los  * *  por  t t de tal manera que diga http   :mrgreen: es un truquito para que no lo bajen bots de descargas  :-)
pd2: te agregue al msn para seguir conversando!!!  :mrgreen:
pd3: jijiji toy con el cerebro atorado viendo unos problemillas con el i2c en c18, termino con eso y seguimos con las interrupciones amigos  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 28 de Mayo de 2007, 23:06:02
INTERRUPCIONES CON EL C18

Como se puede apreciar en la gama 18FXXX existen 10 registros que interactúan para gestionar las interrupciones del PIC, estos son los siguientes:

Para cada interrupción existen 3 bits de control:

Cada interrupción tiene un bit de control de prioridad (priority bit) el cual determina si es de alta o baja prioridad dicha interrupción. Además, ésta característica de prioridad que tiene cada interrupción también puede ser deshabilitada y tratar a todas las interrupciones bajo una misma jerarquía (como en la gama 16FXXX), se trata del bit 7 del rgistro RCON:
(http://img503.imageshack.us/img503/4550/16948116qv8.jpg)

(http://img514.imageshack.us/img514/8223/32882569gu1.jpg)

DECLARACIÓN DE UNA INTERRUPCIÓN
En el C18 una interrupción tiene un formato de declaración definido por el propio compilador. Sin embargo tenemos que indicar al compilador donde esta ubicado el vector de interrupción correspondiente, y digo correspondiente porque tenemos dos prioridades de interrupción, una alta y otra baja:

(http://img509.imageshack.us/img509/4665/83360546qg4.jpg)

Donde la interrupción de baja prioridad corresponde al vector de memoria 0X0018, y la de alta prioridad corresponde al vector de memoria 0X0008. Para efectuar el direccionamiento de los vectores utilizamos la directiva #pragma.

#pragma
La directiva #pragma abarca aplicaciones tanto en la memoria de programa como en la memoria de datos, para efectos de entender bien lo de las interrupciones nos limitaremos (por ahora  :mrgreen:) a su aplicación a nivel de secciones con instrucciones en la memoria de programa.

Con esta directiva #pragma lo que conseguimos es que el compilador ubique un bloque de código en una posición absoluta definida por nosotros. La sintaxis sería asi:

#pragma code [nombre_de_seccion]=[dirección absoluta de la seccion]
   //aca va el bloque de código
   .
   .
   .
#pragma code //se devuelve la posición de meoria por defecto al compilador


Entonces aplicándolo a los PIC, apuntamos al vector de alta prioridad de interrupción:
Código: C
  1. void interrupcion_por_timer0(void); funcion declarada prototipo
  2.  
  3. #pragma code prioridad_alta = 0X0008         //se apunta al vector de interrupcion de alta prioridad
  4. void interrupcion_alta (void)                       //bloque de codigo, en el caso de interrupciones ubicamos una funcion
  5. {
  6.         _asm
  7.         goto interrupcion_por_timer0                  //indicamos al compilador donde esta la interrupcion
  8.         _endasm
  9. }
  10. #pragma code                                               //fin de la interrupcion, como un retfie en el assembler

Ahora, apuntamos al vector de baja prioridad de interrupción:
Código: C
  1. void interrupcion_por_portb(void); funcion declarada prototipo
  2.  
  3. #pragma code prioridad_baja = 0X0018         //se apunta al vector de interrupcion de alta prioridad
  4. void interrupcion_baja (void)                       //bloque de codigo, en el caso de interrupciones ubicamos una funcion
  5. {
  6.         _asm
  7.         goto interrupcion_por_portb                  //indicamos al compilador donde esta la interrupcion
  8.         _endasm
  9. }
  10. #pragma code                                               //fin de la interrupcion, como un retfie en el assembler

Observemos que en ambos casos existe una función interrupcion_alta e interrupción_baja, las cuales deben de ser declaradas como prototipos y no deben tener parámetro de entrada ni de salida por ser asincronas (interrupciones), por ello va el void.

Lo que nos falta es la otra directiva que transfiere el flujo del programa a la ISR (a la interrupcion  :-)) para efectuar el codigo correspondiente. Me estoy refiriendo a la función que ha sido declarada en prototipo. Su sintaxis es la siguiente:

#pragma interrupt [nombre_de_función]
void [nombre_de_función](void)
{
   //codigo de la interrupcion
}

Ejemplo:
Código: C
  1. void interrupcion_por_timer0(void); funcion declarada prototipo
  2. //************************************************************************************
  3. //************************************************************************************
  4. #pragma code prioridad_alta = 0X0008         //se apunta al vector de interrupcion de alta prioridad
  5. void interrupcion_alta (void)                       //bloque de codigo, en el caso de interrupciones ubicamos una funcion
  6. {
  7.         _asm
  8.         goto interrupcion_por_timer0                  //indicamos al compilador donde esta la interrupcion
  9.         _endasm
  10. }
  11. #pragma code                                               //fin de la interrupcion, como un retfie en el assembler
  12. //************************************************************************************
  13. //************************************************************************************
  14. #pragma interrupt interrupcion_por_timer0
  15. void interrupcion_por_timer0(void)
  16. {
  17.         if(INTCONbits.TMR0IF)
  18.         {
  19.                 PORTB=~PORTB;
  20.                 tiempo++;
  21.                 INTCONbits.TMR0IF = 0;
  22.         }
  23. }
  24. //************************************************************************************
  25. //************************************************************************************

Código: C
  1. void interrupcion_por_portb(void); funcion declarada prototipo
  2. //************************************************************************************
  3. //************************************************************************************
  4. #pragma code prioridad_alta = 0X0008         //se apunta al vector de interrupcion de alta prioridad
  5. void interrupcion_alta (void)                       //bloque de codigo, en el caso de interrupciones ubicamos una funcion
  6. {
  7.         _asm
  8.         goto interrupcion_por_portb                  //indicamos al compilador donde esta la interrupcion
  9.         _endasm
  10. }
  11. #pragma code                                               //fin de la interrupcion, como un retfie en el assembler
  12. //************************************************************************************
  13. //************************************************************************************
  14. #pragma interrupt interrupcion_por_portb
  15. void interrupcion_por_portb(void)
  16. {
  17.         if(INTCONbits.RBIF)
  18.         {
  19.                 PORTB=~PORTB;
  20.                 tiempo++;
  21.                 INTCONbits.RBIF = 0;
  22.         }
  23. }
  24. //************************************************************************************
  25. //************************************************************************************

Ahora estudiaremos cada interrupción del PIC; tendré desahabilitada la opción de las prioridades en las interrupciones para los siguientes programas, luego activaremos las prioridades cuando dominemos cada interrupción.  :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 29 de Mayo de 2007, 03:05:45
INTERRUPCIÓN CON EL TIMER0
El timer0 tiene las siguientes características:

Para mayores detalles indagar en el propio datasheet y revisar la definición de los bits de los siguientes registros  :mrgreen::
(http://img517.imageshack.us/img517/5679/85170036gx5.jpg)

Programa de aplicación:
En este programa usaremos el modo temporizador a 16 bits, prescaler a 64, reloj generador interno y con interrupción por desborde; de tal manera que la interrupción del timer0 produzca una oscilación en los pines del puerto B. Esta osiclación tendrá la temporización:

periodo del desborde =  4  x  Prescaler  x  (65535 - valor cargado en timer0)
                                       cristal oscilador

periodo del desborde =  4  x  16  x  (65535 - 00000)
                                       4 x 10^6

periodo del desborde = 1.04856

Código: C#
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. volatile int tiempo;
  16.  
  17. void temporizador(void);
  18. //
  19. //******************************************************//
  20. //      Vector de Interrupcion
  21. //******************************************************//
  22. //
  23. #pragma code prioridad_nomal = 0X0008
  24. void interrupcion_normal (void)
  25. {
  26.         _asm goto temporizador _endasm
  27. }
  28. #pragma code
  29. //
  30. //******************************************************//
  31. //      Rutina de Interrupcion
  32. //******************************************************//
  33. //
  34. #pragma interrupt temporizador
  35. void temporizador(void)
  36. {
  37.         if(INTCONbits.TMR0IF)
  38.         {
  39.                 PORTB=~PORTB;
  40.                 tiempo++;
  41.                 INTCONbits.TMR0IF = 0;
  42.         }
  43. }
  44. //
  45. //******************************************************
  46. //******************************************************
  47. //
  48. //
  49. //
  50. //******************************************************//
  51. //******************************************************//
  52. //
  53. //
  54. //              Programa Principal
  55. //
  56. //
  57. //******************************************************//
  58. //******************************************************//
  59. //
  60. void main(void)
  61. {
  62.         ADCON0 = 0X00,ADCON1 = 0X0F,CMCON = 0X07;
  63.         //puerto A con todos los pines digitales
  64.         TRISA = 0XFF,TRISB = 0X00,TRISC = 0X00;
  65.         PORTA = 0X00,PORTB = 0X00,PORTC = 0X00;
  66.         T0CON = 0X83;//configuramos el timer0
  67.         TMR0H = 0X00,TMR0L = 0X00;//inicializamos registros del timer0
  68.         RCON = 0X00;//IPEN = 0
  69.         INTCON = 0XA0;//configuramos la interrupcion del timer0
  70. //*******************************************************
  71. //*******************************************************
  72.         while (1);
  73. //*******************************************************
  74. //*******************************************************
  75. }



Programa de aplicación:
En este programa usaremos el modo contador a 8 bits, prescaler deshabilitado, reloj generador externo por el pin RA4 para flanco de bajada y con interrupción por desborde; de tal manera que la interrupción del timer0 produzca una oscilación en los pines del puerto B, incrementándose el valor del timer0 cada vez que se aplica un pulso con flanco de bajada.
Código: C#
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. volatile int tiempo;
  16.  
  17. void temporizador(void);
  18. //
  19. //******************************************************//
  20. //      Vector de Interrupcion
  21. //******************************************************//
  22. //
  23. #pragma code prioridad_nomal = 0X0008
  24. void interrupcion_normal (void)
  25. {
  26.         _asm goto temporizador _endasm
  27. }
  28. #pragma code
  29. //
  30. //******************************************************//
  31. //      Rutina de Interrupcion
  32. //******************************************************//
  33. //
  34. #pragma interrupt temporizador
  35. void temporizador(void)
  36. {
  37.         if(INTCONbits.TMR0IF)
  38.         {
  39.                 PORTB=~PORTB;
  40.                 tiempo++;
  41.                 TMR0H = 0X00,TMR0L = 240;//inicializamos registros del timer0
  42.                 INTCONbits.TMR0IF = 0;
  43.         }
  44. }
  45. //
  46. //******************************************************
  47. //******************************************************
  48. //
  49. //
  50. //
  51. //******************************************************//
  52. //******************************************************//
  53. //
  54. //
  55. //              Programa Principal
  56. //
  57. //
  58. //******************************************************//
  59. //******************************************************//
  60. //
  61. void main(void)
  62. {
  63.         ADCON0 = 0X00,ADCON1 = 0X0F,CMCON = 0X07;
  64.         //puerto A con todos los pines digitales
  65.         TRISA = 0XFF,TRISB = 0X00,TRISC = 0X00;
  66.         PORTA = 0X00,PORTB = 0X00,PORTC = 0X00;
  67.         T0CON = 0XF0;//configuramos el timer0
  68.         TMR0H = 0X00,TMR0L = 240;//inicializamos registros del timer0
  69.         RCON = 0X00;//IPEN = 0
  70.         INTCON = 0XA0;//configuramos la interrupcion del timer0
  71. //*******************************************************
  72. //*******************************************************
  73.         while (1);
  74. //*******************************************************
  75. //*******************************************************
  76. }




todos los archivos:h**p://www.box.net/shared/9b367ilocb
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 29 de Mayo de 2007, 16:17:53
Hola de nuevo,  :) :)

Estoy intentando probar el programita de micro_cadaver de hacer parpadear un led, como veis mis pasos son lentos aunque espero que firmes :P.Y cuando le doy a "build all" me da error y pone lo siguiente:

Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "D:\PROGRAMAS\MCC18\bin\mcc18.exe" -p=18F4620 "parpadeo.c" -fo="parpadeo.o" -Oa -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:1:Error [1027] unable to locate 'p18f4620.h'
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:2:Error [1027] unable to locate 'delays.h'
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:3:Error [1027] unable to locate 'stdio.h'

Creo que el problema es que no reconoce la localizacion de los archivos, pero lo he provado de muchas formas distintas y siempre es el mismo resultado.¿Alguien sabe el porque de mi error?

Si, es porque debes indicar en tu proyecto donde están las librerías (carpeta LIB).  Tu defines archivos .h pero en realidad los archivos estandar están compilados como librerías (eso permite que se compilen tan rápido porque ya están preprocesados) y por eso debes indicarle el path a tus librerías.

Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 29 de Mayo de 2007, 16:41:42
perdón por mi offtopic.

aquí va mi voto positivo por el amigo micro_cadaver que le está dando duro al C18

¡¡sigue adelante!!

 :-/ :-/ :-/ :-/ :-/ :-/ :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 29 de Mayo de 2007, 18:34:26
 :mrgreen: jijiji
hoy pongo la siguiente interrupcion  :-/ :-/ :-/ :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 30 de Mayo de 2007, 11:48:48
INTERRUPCIÓN POR FLANCO EXTERNO EN RB0
El pin RB0 del puerto B posee una de las interrupciónes externas por flanco, para efectuar esta característica debemos tener habilitado su correspondiente bit de interrupción, configurado su flanco y puesto como entrada el pin RB0, veamos a que bits de control nos referimos:

(http://img231.imageshack.us/img231/9270/27764868ip7.jpg)

(http://img49.imageshack.us/img49/5559/17299955mn1.jpg)

Programa de aplicación:
En este programa vamos a utilizar la interrupción externa en el pin RB0 configurado para un flanco de subida, en el cual cada vez que se produzca dicha interrupción cambiará el estado de los pines del PORTA.
Código: C
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. volatile int micro_cadaver;//variable de la interrupcion
  16. void interrupciones(void);//prototipo de la interrupción
  17.  
  18. //
  19. //******************************************************//
  20. //      Vector de Interrupcion
  21. //******************************************************//
  22. //
  23. #pragma code prioridad_nomal = 0X0008
  24. void interrupcion_normal (void)
  25. {
  26.         _asm goto interrupciones _endasm
  27. }
  28. #pragma code    //fin de la interrupcion (retfie en el ASM)
  29. //
  30. //******************************************************//
  31. //      Rutina de Interrupcion
  32. //******************************************************//
  33. //
  34. #pragma interrupt interrupciones
  35. void interrupciones(void)
  36. {
  37.         if(INTCONbits.INT0IF)       //pregunta por bandera de interrupcion
  38.         {
  39.                 PORTA=~PORTA;
  40.                 micro_cadaver++;
  41.                 INTCONbits.INT0IF = 0;  //limpia bandera y salimos
  42.         }
  43. }
  44. //
  45. //******************************************************
  46. //******************************************************
  47. //
  48. //
  49. //
  50. //******************************************************//
  51. //******************************************************//
  52. //
  53. //
  54. //              Programa Principal
  55. //
  56. //
  57. //******************************************************//
  58. //******************************************************//
  59. //
  60. void main(void)
  61. {
  62.         ADCON0 = 0X00,ADCON1 = 0X0F,CMCON = 0X07;
  63.         //puerto A con todos los pines digitales
  64.         TRISA = 0X00,TRISB = 0XFF,TRISC = 0X00;
  65.         PORTA = 0X00,PORTB = 0X00,PORTC = 0X00;
  66.         RCON = 0X00;//IPEN = 0
  67.         INTCON = 0X90;//configuramos la interrupcion externa del RB0
  68.         INTCON2 = 0X40;//configuramos el flanco de subida para la interrupcion
  69. //*******************************************************
  70. //*******************************************************
  71.         while (1);
  72. //*******************************************************
  73. //*******************************************************
  74. }


todos los archivos:h**p://www.box.net/shared/jsctdrqfdf
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 30 de Mayo de 2007, 12:58:22
INTERRUPCIÓN POR CAMBIO DE ESTADO EN EL PUERTO B
El puerto B posee una interrupción por cambio de estado en los pines RB4, RB5, RB6 y RB7, los cuales deben ser configurados como entradas para su aplicación, además de los siguientes bits de control:

(http://img231.imageshack.us/img231/9270/27764868ip7.jpg)

(http://img49.imageshack.us/img49/5559/17299955mn1.jpg)

Las resistencias de pull-up son unas resistencias internas que permiten tener un pin del puerto B como entrada y sin conexión, de esta manera cuando medimos esta entrada observaremos que tiene 5V lo que no sucede con otros pines que siendo entrada y estando al aire nos marca un valor aleatorio, las pull-up participan en la implementación de teclados, botoneras, etc; para este programa no será necesario su uso.

Programa de aplicación:
En este programa cambiaremos el estado de los pines de salida del puerto A conforme se produzca un cambio en las entradas RB4-RB7 del puerto B. Se implemento un truquito porque el proteus se me rayaba con esta interrupción, si quieren intenten quitándo esto del programa:

      //*******************************
      //truquito para el proteus jijiji   
      _asm    MOVF   PORTB,0,ACCESS   _endasm
      //no implemententar en la realidad
      //********************************

Código: C
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. volatile unsigned int micro_cadaver;//variable de la interrupcion
  16. void interrupciones(void);//prototipo de la interrupción
  17.  
  18. //
  19. //******************************************************//
  20. //      Vector de Interrupcion
  21. //******************************************************//
  22. //
  23. #pragma code prioridad_nomal = 0X0008
  24. void interrupcion_normal (void)
  25. {
  26.         _asm goto interrupciones _endasm
  27. }
  28. #pragma code    //fin de la interrupcion (retfie en el ASM)
  29. //
  30. //******************************************************//
  31. //      Rutina de Interrupcion
  32. //******************************************************//
  33. //
  34. #pragma interrupt interrupciones
  35. void interrupciones(void)
  36. {
  37.         if(INTCONbits.RBIF)       //pregunta por bandera de interrupción
  38.         {
  39.                 PORTA=~PORTA;
  40.                 micro_cadaver=1;
  41.                 while(micro_cadaver!=0)
  42.                         micro_cadaver++;
  43.                 //*******************************
  44.                 //truquito para el proteus jijiji      
  45.                 _asm    MOVF    PORTB,0,ACCESS  _endasm
  46.                 //no implemententar en la realidad
  47.                 //********************************
  48.                 INTCONbits.RBIF = 0;  //limpia bandera y salimos
  49.                 //*******************************
  50.                 //truquito para el proteus jijiji      
  51.                 _asm    MOVF    PORTB,0,ACCESS  _endasm
  52.                 //no implemententar en la realidad
  53.                 //********************************
  54.         }
  55. }
  56. //
  57. //******************************************************
  58. //******************************************************
  59. //
  60. //
  61. //
  62. //******************************************************//
  63. //******************************************************//
  64. //
  65. //
  66. //              Programa Principal
  67. //
  68. //
  69. //******************************************************//
  70. //******************************************************//
  71. //
  72. void main(void)
  73. {
  74.         ADCON0 = 0X00,ADCON1 = 0X0F,CMCON = 0X07;
  75.         //puerto A con todos los pines digitales
  76.         TRISA = 0X00,TRISB = 0XFF,TRISC = 0X00;
  77.         PORTA = 0X00,PORTB = 0X00,PORTC = 0X00;
  78.         RCON = 0X00;//IPEN = 0
  79.         INTCON = 0X88;//configuramos la interrupcion por cambio de estado RB4-RB7
  80.         INTCON2 = 0X80;//deshabilitamos las pull-up
  81. //*******************************************************
  82. //*******************************************************
  83.         while (1);
  84. //*******************************************************
  85. //*******************************************************
  86. }



todos los archivos:h**p://www.box.net/shared/mhq51j2giq
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 01 de Junio de 2007, 07:16:06
Magnifico trabajo micro_cadaver!!!!Aun estoy haciendo ejemplitos faciles pero con la ayuda que me estas prestando en este hilo ya mismo me pongo con las interrupciones, jeje.

Queria hacer una pregunta.Estaba acostumbrado que en CCS podias definir los bits de los puertos como variables y trabajar con ellos con una mayor facilidad al ponerles nombres relacionados con lo que hacen.Esto se puede hacer en C18?Por ejemplo, como puedo decirle al bit 0 del puerto B que se ponga a 1 sin tener que definir el puerto entero?Para que me entendais mejor os pongo un ejemplo de lo que hacia en CCS.

#byte PORTA = 0xF80
#byte PORTB = 0xF81

#bit SEN1 = 0XF80.0
#bit SENTIDO1 = 0xF81.6
#bit SENTIDO2 = 0xF81.7
.
.
.
if (SEN1==1){
     SENTIDO1 = 0;
     SENTIDO2 = 1;
} else {
     SENTIDO1 = 1;
     SENTIDO2 = 0;
}

Espero que se entienda bien lo que quiero decir y que me podais indicar como se hace esto en C18. :-/ :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 01 de Junio de 2007, 10:46:32
claro que si amigo barq ( :mrgreen: gracias por tus comentarios, no siento merecerlos pero... muchas gracias :-)) mira, si revisas
el archivo h de tu respectivo pic ahi encontraras la definición para cada bit, también lo puedes hacer en el programa asi:

#define         led_puerto_B          LATBbits.LATB0  //donde el pin RA0 es led_puerto_B estando como salida

aca pongo una imagen del programa modificado para tu pregunta:
(http://img522.imageshack.us/img522/2262/91399287aq1.jpg)

en el C18 puedes encontrar la ruta de la carpeta H  sin mas problemas  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electronando en 01 de Junio de 2007, 11:49:27
Solo palabras de felicitacion a mi compatriota Henry (Microcadaver)  :mrgreen:te esta quedando de lujo este tutorial espero continues ,
a una pregunta tonta con que cristal estas trabajando pues tengo un pic18f448 para practicar y no quedarme
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 01 de Junio de 2007, 12:59:08
 :mrgreen: gratcie

con 4mhz fernando
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 01 de Junio de 2007, 21:07:08
INTERRUPCIÓN POR FLANCO EXTERNO EN RB1 Y EN RB2
Los pines RB1 y RB2 del puerto B poseen interrupciónes externas por flanco INT1 e INT2 respectivamente, para efectuar esta característica debemos tener habilitado su correspondiente bit de interrupción, configurado su flanco y puesto como entrada los pines RB1 y RB2, veamos a que bits de control nos referimos:

(http://img231.imageshack.us/img231/9270/27764868ip7.jpg)

(http://img49.imageshack.us/img49/5559/17299955mn1.jpg)

(http://img101.imageshack.us/img101/4521/33612887tc9.jpg)


Programa de aplicación:
En este programa vamos a utilizar las interrupciónes externas en el pin RB1 y en el pin RB2 configurando un flanco de subida para el INT1 y un flanco de bajada para el INT2, en el cual cada vez que se produzca la interrupción del INT1 cambiará el estado de los pines del PORTA y cada vez que se produzca la interrupción del INT2 cambiará el estado de los pines del PORTC.

Código: C
  1. #include <p18f2525.h>
  2. #include <stdio.h>
  3. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  4. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  5. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  6. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  7. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  8. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  9. #pragma config CPB = ON,CPD = ON//CONFIG5H
  10. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  11. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  12. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  13. #pragma config EBTRB = ON//CONFIG7H
  14.  
  15. volatile int micro_cadaver;//variable de la interrupcion
  16. volatile int mono_cadaver;//variable de la interrupcion
  17.  
  18. void interrupciones(void);//prototipo de la interrupción
  19.  
  20. //
  21. //******************************************************//
  22. //      Vector de Interrupcion
  23. //******************************************************//
  24. //
  25. #pragma code prioridad_nomal = 0X0008//posicion para modo compatibilidad de interrupciones 16FXXXX
  26. void interrupcion_normal (void)
  27. {
  28.         _asm goto interrupciones _endasm
  29. }
  30. #pragma code    //fin de la interrupcion (retfie en el ASM)
  31. //
  32. //******************************************************//
  33. //      Rutina de Interrupcion
  34. //******************************************************//
  35. //
  36. #pragma interrupt interrupciones
  37. void interrupciones(void)
  38. {
  39.         if(INTCON3bits.INT1IF)       //pregunta por bandera de interrupción
  40.         {
  41.                 PORTA=~PORTA;
  42.                 micro_cadaver++;
  43.                 INTCON3bits.INT1IF = 0;  //limpia bandera y salimos
  44.         }
  45.         if(INTCON3bits.INT2IF)       //pregunta por bandera de interrupción
  46.         {
  47.                 PORTC=~PORTC;
  48.                 mono_cadaver--;
  49.                 INTCON3bits.INT2IF = 0;  //limpia bandera y salimos
  50.         }
  51. }
  52. //
  53. //******************************************************
  54. //******************************************************
  55. //
  56. //
  57. //
  58. //******************************************************//
  59. //******************************************************//
  60. //
  61. //
  62. //              Programa Principal
  63. //
  64. //
  65. //******************************************************//
  66. //******************************************************//
  67. //
  68. void main(void)
  69. {
  70.         ADCON0 = 0X00,ADCON1 = 0X0F,CMCON = 0X07;
  71.         //puerto A con todos los pines digitales
  72.         TRISA = 0X00,TRISB = 0XFF,TRISC = 0X00;
  73.         PORTA = 0X00,PORTB = 0X00,PORTC = 0X00;
  74.         RCON = 0X00;//IPEN = 0
  75.         INTCON = 0X80;//configuramos la interrupcion general GIE
  76.         INTCON2 = 0X20; //flanco de subida para la interrupcion en RB1
  77.                                         //flanco de bajada para la interrupcion en RB2
  78.         INTCON3 = 0X18;//configuramos la interrupcion externa del RB1 y RB2
  79. //*******************************************************
  80. //*******************************************************
  81.         while (1);
  82. //*******************************************************
  83. //*******************************************************
  84. }


todos los archivos:h**p://www.box.net/shared/sgfve0uocs
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 01 de Junio de 2007, 21:31:59
bueno ... le pido publicamente a kedutpic (JUAN VEGA COD:666XXX666)  :D  que vaya implementando un circuito para probar la EUSART del pic18f2550, la siguiente entrega sera esa, pero pa el 18f2525  :-) que es casi lo mismo, los mismo pines etc etc, jiji asi que vayan repasando, de paso yo tambien  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electronando en 02 de Junio de 2007, 00:34:55
AL PONER ESTE CODIGO
#include <p18f2525.h>
#include <delays.h>
#include <stdio.h>
#pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
#pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
#pragma config CPB = ON,CPD = ON//CONFIG5H
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
#pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
#pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
#pragma config EBTRB = ON//CONFIG7H
void main(void){   
      TRISA = 0X00;   
      TRISB = 0X00;   
      TRISC = 0X00;
//*******************************************************
//*******************************************************
      while(1){      
            LATA = 0X01;   
            LATB = 0X01;      
            LATC = 0X01;
            Delay10KTCYx(20);//200 mseg   
            LATA = 0X00;   
            LATB = 0X00;
            LATC = 0X00;
            Delay10KTCYx(20);//200 mseg   
      }
//*******************************************************
//*******************************************************
   }
ME SALE LO SIGUIENTE

Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\C18\bin\mcc18.exe" -p=18F2525 "PININO1.C" -fo="PININO1.o" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
D:\FERNANDO\PC18\PININO1\PININO1.C:5:Error [1225] configuration value '0' not recognized for configuration setting 'BORV'
D:\FERNANDO\PC18\PININO1\PININO1.C:7:Error [1224] configuration setting 'LPT1OSC' not recognized
D:\FERNANDO\PC18\PININO1\PININO1.C:8:Error [1224] configuration setting 'XINST' not recognized
Halting build on first failure as requested.
BUILD FAILED: Fri Jun 01 22:32:14 2007

como se puede solucionar hay que direccionar algo pero como o donde que presionar la verdad no encuentro algun cambio para poder hacerlo:shock:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 02 de Junio de 2007, 00:41:17
has seleccionado el pic 18f2525 en la pestaña CONFIGURE luego en SLECT DEVICE? debe esatr apuntado al 18f2525  :mrgreen:

pd: para cuando he modificado este mensaje , electronanado (Fernando) ya tiene su C18 compilando y simulando!!!!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electronando en 02 de Junio de 2007, 13:13:26
Y de nuevo mil gracias publicas a mis compatriotas Henry y Curio pues despues de una caotica lucha tratando de configurar
y demas trabas logre compilar los ejemploq e Henry(uCADAVER) esta posteando , a decirles a los foreros Henry que si simulan en proteus ponerle el voltaje de 5 voltios en el pic 18f2525 en el MCLR si no no arranca chaufa y mil gracias de nuevo :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 02 de Junio de 2007, 23:46:50
bueno ... le pido publicamente a kedutpic (JUAN VEGA COD:666XXX666)  :D  que vaya implementando un circuito para probar la EUSART del pic18f2550, la siguiente entrega sera esa, pero pa el 18f2525  :-) que es casi lo mismo, los mismo pines etc etc, jiji asi que vayan repasando, de paso yo tambien  :-/

Ya normal  :P me leistes la mente, justo estaba preparando todo el hadware necesario para el USART  :mrgreen:

Y de nuevo mil gracias publicas a mis compatriotas Henry y Curio pues despues de una caotica lucha tratando de configurar
y demas trabas logre compilar los ejemploq e Henry(uCADAVER) esta posteando , a decirles a los foreros Henry que si simulan en proteus ponerle el voltaje de 5 voltios en el pic 18f2525 en el MCLR si no no arranca chaufa y mil gracias de nuevo :-/

 :) me alegra mucho que te hayas podido lograrlo  :mrgreen: para eso estamos para ayudarnos es el espiritu picmaniatico  :D  :D
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 04 de Junio de 2007, 08:45:19
Hola amigos!!!

Desde luego, este post cada vez tiene mas nivel.Y me da verguenza hacer mis preguntas que son bastante basicas.Pero bueno, espero que con trabajo, vuestra ayuda y este post pueda acabar sabiendo programar un pic con C18.

He estado buscando informacion sobre los tipos de variables que se pueden implementar y no he visto por ningun lado el tipo boolean.¿Es que no se puede utilizar en C18?Y si son validos,¿se puede hacer arrays de booleanos?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 04 de Junio de 2007, 10:08:36
m........... buena preguntio tio, creo que si se puede, dejame revisar una plancha que llego a mis manos y lo publico  :-/
jjeej no tengo nada sobre arrays de booleanos, aunque tal vez en realidad no tenga implementado una libreria dedicada a arrays de booleanos, pues si permite trabajar con bits como se vio en el post #48 de este hilo, voy a seguir buscando...

mira este hilo
http://www.todopic.com.ar/foros/index.php?topic=15860.0
hay que sacar conclusiones :)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 06 de Junio de 2007, 20:56:04
aprovechar este dia de paz y sosiego para apuntar algo sobre el modulo EUSART que tiene la gamma 18FXXX. Lo malo es que de entre lo que he leido en el datasheet del 18F2525, me habla de que ahora el EUSART tambien puede generar caracteres de sincronismos del bus LIN, ?¿?¿?¿  :? si alguien sabe que vaya posteando algo de info, yo mientras tambien ire en busqueda de saber que es y para que sirve, fuera de eso tb lei que puede despertar del SLEEP por recepción del eusart, tambien es más preciso en el baudiaje (asi se escribe  :mrgreen:  ? ), fuera de esos puntos no ha cambiado más, y su uso como lo tenemos acostumbrado es igual incluso la sequencia de codigo es similar a la de la gama 16FXXX.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 06 de Junio de 2007, 23:39:18
bueno, ya averigue un poco, el protocolo LIN es una comonucación monoalambrica, 1 solo hilo, en donde existen 1 Master y hasta 16 Esclavos por nodo, y su aplicación comun es en la red de control de los perifericos de un automovil, parabrisas, aire acondicionado, lunas, puertas, etc etc, es primo hermano del bus CAN, y como comente los ejemplos se remiten a los automoviles, m... no se si en el proteus se podra simular esto.... por ahora me enfocare al protocolo RS232 nomas, este tema quedara pendiente, ademas no tengo carro donde experimentar  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 07 de Junio de 2007, 15:59:52
suena llamativo ese protocolo micro_cadaver, con el caudal de prestaciones que traen estos 18f ya uno no se da abasto, es como sacar ropa de un cajón y siempre encontraras mas ropa.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 12 de Junio de 2007, 12:21:26
¿Sabe alguien como seria el protoco SPI en C18?Yo la verdad es que no tengo mucha idea de este protocolo y menos en C18 :oops: :oops:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 12 de Junio de 2007, 12:37:52
¿Sabe alguien como seria el protoco SPI en C18?Yo la verdad es que no tengo mucha idea de este protocolo y menos en C18 :oops: :oops:

En el C18 Libraries estan los comandos para el SPI y para los demás módulos.
El documento es el  ds51297

Ahora , si no entiendes como funciona el SPI, tampoco entenderás los comandos.  El lenguaje C te allana algunas cosas pero no te va a hacer que tus cosas funcionen si no sabes qué estas haciendo.  Te recomiendo leas sobre el tema antes de conectar algo porque sino tienes grandes chances de no hacerlo andar
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 12 de Junio de 2007, 15:58:16
claro que si, primero lee algo sobre el protocolo SPI (difiere un poco del I2C), luego estudia la parte del modulo SSP en el datasheet de tu pic, y nos posteas tus dudas de una forma más concreta.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 12 de Junio de 2007, 17:43:54
Muchas gracias por vuestra ayuda, pero al final voy a optar por otro camino en este proyecto.Aunque creo que en un futuro no muy lejano, cuando tenga mas tiempo  :?, volvere a estudiar este tema  :)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 13 de Junio de 2007, 00:24:37
bueno señores ya encontre una aplicacion para el modulo EUSART (GRACIAS JUAN  :-/), haremos una simple comunicacion con la PC (protocolo RS232) y el pic tendra un LCD 2X16 para observar el estado del proceso. asi que vayan repasando el LCD porque comenzaremos con ejemplos de aplicación en el C18 y luego lo complementaremos con el EUSART y finalmente el proyecto.

sobre el programa que va en la PC aun no tengo detalles pero ya les tendre más noticias, lo que ahora toca es el LCD.  :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 14 de Junio de 2007, 02:43:07
RUTINA PARA UN LCD 16X2 CON BUS DE DATOS A 4BITS

El siguiente codigo lo vengo modificando de el siguiente hilo  http://www.todopic.com.ar/foros/index.php?topic=17005.0
donde la amiga  :g) Mulderson amablemente compartio. La modificación que hice solo es para que se acomode al hardware que uso y le agregue una rutina para escribir strings (cadenas de caracteres) en el LCD, ubicados en la memoria de programa y en la memoria de datos.

Programa:
Escribe en el LCD.
Código: C
  1. #include <p18f2525.h>
  2. #include <delays.h>                             // Rutinas de retardo
  3. #include "C:\PIC\18F\EUART\LCD4b2x16.h"//ruta del archivo en mi PC
  4.  
  5. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  6. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  7. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  8. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  9. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  10. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  11. #pragma config CPB = ON,CPD = ON//CONFIG5H
  12. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  13. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  14. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  15. #pragma config EBTRB = ON//CONFIG7H
  16. //******************************************************//
  17. //******************************************************//
  18. //
  19. //
  20. //              Programa Principal
  21. //
  22. //
  23. //******************************************************//
  24. //******************************************************//
  25. char mensaje[]="Henry";
  26.  
  27. void main(void)
  28. {
  29.         TRISA = 0X00;
  30.         TRISB = 0XF0;
  31.         TRISC = 0X00;
  32.         PORTA = 0X00;
  33.         PORTB = 0X00;
  34.         PORTC = 0X00;
  35.         Inicializa_LCD();
  36.         Comando_LCD(CURSOR_OFF & BLINK_ON);
  37.         Dato_LCD('#');//un dato
  38.         Datos_LCD(" PERU ");//una cadena desde la memoria de programa
  39.         Dato_String_LCD(mensaje);//una cadena desde la memoria de datos
  40.  
  41.         //con este comando pasamos a la linea 2 del LCD
  42.         Comando_LCD(DDRAM_LINEA_2);
  43.         Datos_LCD("micro_cadaver");
  44.         while(1);
  45. }

aca el archivo #include "C:\PIC\18F\EUART\LCD4b2x16.h"
Código: C
  1. /******************************************************/
  2. /*
  3. /* Manejo de un Display de Cristal Liquido LCD 16X4   */
  4. /* de 16 caracteres por 4 lineas, con una interface   */
  5. /* de 4 lineas:                                       */
  6. /*
  7. /*      LCD                         PIC
  8. /* ------------------------------------
  9. /*      D4  (11)                -->     RB0
  10. /*      D5  (12)                -->     RB1
  11. /*      D6  (13)                -->     RB2
  12. /*      D7  (14)                -->     RB3
  13. /*
  14. /*      RS  (4)                 -->     RC0
  15. /*      RW  (5)                 -->     RC1
  16. /*      E   (6)                 -->     RC2
  17. /*
  18. /******************************************************/
  19. /* Conexiones del LCD al Microcontrolador */
  20. #define PIN_RS  LATCbits.LATC0  // Define la Columna 1
  21. #define PIN_RW  LATCbits.LATC1  // Define la Columna 2
  22. #define PIN_E   LATCbits.LATC2  // Define la Columna 3
  23.  
  24. /* Configuracion del Display y cursor */
  25. #define DON                             0b00001111  /* Display encendido   */
  26. #define DOFF                    0b00001011  /* Display apagado     */
  27. #define CURSOR_HOME             0b00000010  /* Cursor encendido    */
  28. #define CURSOR_ON               0b00001111  /* Cursor encendido    */
  29. #define CURSOR_OFF              0b00001101  /* Cursor apagado      */
  30. #define BLINK_ON                0b00001111  /* Cursor con parpadeo */
  31. #define BLINK_OFF               0b00001110  /* Cursor sin parpadeo */
  32. #define CLEAR                   0b00000001  /* Display encendido   */
  33.  
  34. /* Modo de entrada */
  35. #define INCREMENT               0b00000110  /* Incrementa la posicion del cursor */
  36. #define DECREMENT               0b00000100  /* Decrementa la posicion del cursor */
  37.  
  38.  
  39. /* Configuracion de los desplazamientos del cursor y del Display*/
  40. #define SHIFT_CUR_LEFT          0b00010011  /* Corrimiento del cursor a la izquierda  */
  41. #define SHIFT_CUR_RIGHT         0b00010111  /* Corrimiento del cursor a la derecha    */
  42. #define SHIFT_DISP_LEFT         0b00011011  /* Corrimiento del display a la izquierda */
  43. #define SHIFT_DISP_RIGHT        0b00011111  /* Corrimiento del display a la derecha   */
  44.  
  45.  
  46. /* Funciones de inicializacion */
  47. #define NIBLE                           0b00000010  /* interface a 4 bits */
  48. #define FOUR_BIT                        0b00101111  /* Interface a 4-bit  */
  49. #define EIGHT_BIT                       0b00111111  /* Interface a 8-bit  */
  50. #define LINE_5X7                        0b00110011  /* Una linea, caracter 5x7 */
  51. #define LINE_5X10                       0b00110111  /* Una linea, caracter 5x10 */
  52. #define LINES_5X7                       0b00111011  /* Dos lineas. character 5x7 */
  53.  
  54.  
  55. /* Lineas de trabajo */
  56. #define DDRAM_LINEA_1           0b10000000      /* Linea 1 */
  57. #define DDRAM_LINEA_2           0b11000000      /* Linea 2 */
  58. #define DDRAM_LINEA_3           0b10010000      /* Linea 3 */
  59. #define DDRAM_LINEA_4           0b11010000      /* Linea 4 */
  60.  
  61.  
  62. /* Configuracion del puerto */
  63. #define Config_Puerto           0b00000000      /* RC<0:6> como salidas */
  64. #define Mascara                         0b00001111      /* Parte baja del Byte  */
  65.  
  66.  
  67. /* Prototipos de funciones */
  68. void Inicializa_LCD(void);              /* Inicializa LCD */
  69. void Comando_LCD(char);                 /* Indica al LCD un comando */
  70. void Dato_LCD(char);                    /* Indica al LCD un caracter */
  71. void Datos_LCD(const rom char *buffer); /* escribe una cadena desde la memoria de programa al LCD */
  72. void Dato_String_LCD(char *buffer);             /* escribe una cadena desde la memoria de datos al LCD */
  73.  
  74. //**********************************************************
  75. /* Inicializacion del LCD segun fabricante */
  76. //**********************************************************
  77. void Inicializa_LCD(void)
  78. {
  79.         int i;
  80.         Delay10TCYx(110);                       /* Retardo mayor a 100 useg. */
  81.         LATB = NIBLE;                           /* Interface de 4 bits RC<0:3> */
  82.         PIN_RS = 0;
  83.         PIN_RW = 0;
  84.         PIN_E = 1;
  85.  
  86.         Delay1KTCYx(5);                         /* Retardo de 5 mseg. */       
  87.         PIN_E = 0;
  88.         Delay1KTCYx(15);                        /* Retardo de 15 mseg. */
  89.  
  90.         /* Funcion set,  DL = 0, N = 1, F = 0 */
  91.         /* Dos lineas, caracter de 5X7 e interface a 4 bits */ 
  92.         Comando_LCD(LINES_5X7 & FOUR_BIT);
  93.  
  94.         /* Display ON, D = 1, C = 1, B = 1 */
  95.         /* Display encendido, cursor encendido con parpadeo */
  96.         Comando_LCD(DON & CURSOR_ON & BLINK_ON);
  97.  
  98.         /* limpia el display */
  99.         Comando_LCD(CLEAR);
  100.  
  101.         /* Entry Mode Set */
  102.         /* Incremento del cursor */
  103.         Comando_LCD(INCREMENT);
  104. }
  105.  
  106. //**********************************************************
  107. /* Indica al LCD comandos */
  108. //**********************************************************
  109. void Comando_LCD(char dato)
  110. {
  111.         char temp;                                              /* variable auxiliar */
  112.  
  113.         Delay1KTCYx(10);                                /* Retardo de 10 mseg. */
  114.         temp = dato;                                    /* Respaldo del dato original */
  115.         dato = dato >> 4;                               /* Corrimiento del nible alto */
  116.         LATB = dato;
  117.         PIN_RS = 0;
  118.         PIN_RW = 0;
  119.         PIN_E = 1;
  120.         Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  121.         PIN_E = 0;
  122.         LATB = temp;
  123.         PIN_RS = 0;
  124.         PIN_RW = 0;
  125.         PIN_E = 1;
  126.         Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  127.         PIN_E = 0;
  128. }
  129.  
  130. //**********************************************************
  131. /* Manda datos al LCD */
  132. //**********************************************************
  133. void Dato_LCD(char dato)
  134. {
  135.         char temp;                                              /* variable auxiliar */
  136.  
  137.         Delay1KTCYx(10);                                /* Retardo de 10 mseg. */
  138.         temp = dato;                                    /* Respaldo del dato original */
  139.         dato = dato >> 4;                               /* Corrimiento del nible alto */
  140.         LATB = dato;
  141.         PIN_RS = 1;
  142.         PIN_RW = 0;
  143.         PIN_E = 1;
  144.         Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  145.         PIN_E = 0;
  146.         LATB = temp;
  147.         PIN_RS = 1;
  148.         PIN_RW = 0;
  149.         PIN_E = 1;
  150.         Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  151.         PIN_E = 0;
  152. }
  153. //**********************************************************
  154. //      Escribe una cadena desde memoria de programa al LCD
  155. //**********************************************************
  156. void Datos_LCD(const rom char *buffer)
  157. {
  158.         while(*buffer)                  // Write data to LCD up to null
  159.     {
  160.                 Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  161.         Dato_LCD(*buffer); // Write character to LCD
  162.         buffer++;               // Increment buffer
  163.         }
  164.     return;
  165. }
  166. //**********************************************************
  167. //      Escribe una cadena desde memoria de datos al LCD
  168. //**********************************************************
  169. void Dato_String_LCD(char *buffer)
  170. {
  171.         while(*buffer)                  // Write data to LCD up to null
  172.     {
  173.                 Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  174.         Dato_LCD(*buffer); // Write character to LCD
  175.         buffer++;               // Increment buffer
  176.         }
  177.     return;
  178. }

todos los archivos: h**p://www.box.net/shared/ffojdvkcdh

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 14 de Junio de 2007, 13:06:40
Antes de continuar hay que leer el datasheet del pic18f2525 (o del que esten usando) todo lo concerniente al módulo EUSART.

La EUSART en el C18
(Enhanced Universal Synchronous Receiver Transmitter)

Si revisamos el documento MPLAB-C18-Libraries.pdf y vamos al capitulo 2.10 USART Functions (pagina 66), observaremos que el C18 ya tiene una librería dedicada a esta característica, además permite implementar por software más puertos UARTs (pues como no pertenecen al hardware del pic se llaman asi), sin embargo nos cuesta más memoria de programa... pero como en los 18FXXX hay bastante... ; entonces iniciaremos con el estudio (jijij entre comillas) de las rutinas que existen para el módulo EUSART.

Rutinas del Módulo EUSART
En la siguiente imagen se muestra todas las rutinas del EUSART en el C18, detallaremos en cada una, tengo que mencionar que muchas de ellas son rebundantes, es decir que hacen lo mismo pero con diferente nombre :?, ya lo veremos con más cuidado.
(http://img390.imageshack.us/img390/2852/29344746on7.jpg)

BusyUSART: detecta si el módulo EUSART está transmitiendo o está ocupado. Retorna un valor 0 si  el buffer de transmisión está libre o disponible, y retorna un valor 1 si está ocupado el buffer de transmisión.

      //esperar a que el buffer de transmisión
      //este vacio o disponible
      while(BusyUSART());


CloseUSART: deshabilita el módulo EUSART.

      closeUSART();



DataRdyUSART: detecta si hay información lista para efectuar una lectura del buffer de recepción. Retorna el valor del bit RCIF del registro PIR, es 1 cuando el buffer está con la información disponible, y 0 cuando no hay información para leer.

      //esperamos caracter del virtual terminal
      while(!DataRdyUSART());


getsUSART: lee una cadena de caracteres y las guarda en una cadena previamente definida en la memoria de datos. Posee 2 argumentos o valores de entrada, BUFFER cadena previamente definida en la memoria de datos donde se guardará la información y LEN es la cantidad de caracteres a leer.

char recepcion_eco1[16];

   getsUSART(recepcion_eco1,9);


OpenUSART:configura y habilita el módulo EUSART. Tiene los siguientes argumentos o valores de entrada.
CONFIG: configuracion del módulo EUSART.
(http://img61.imageshack.us/img61/6945/77367596kp6.jpg)
SPBRG: valor que determina el Baud Rate del módulo EUSART.
(http://img409.imageshack.us/img409/537/22241978dr8.jpg)

   // configuramos el EUSART para 9.6K baudios
   OpenUSART(   USART_TX_INT_OFF &
            USART_RX_INT_OFF &
            USART_ASYNCH_MODE &
            USART_EIGHT_BIT &
            USART_CONT_RX &
            USART_BRGH_HIGH,
            25);

putsUSART: escribe una cadena de caracteres previamente definida en la memoria de datos. Su valor de entrada es la cadena de caracteres.

char mensaje_eco1[]="micro_cadaver"

   putsUSART(mensaje_eco1);



putrsUSART:escribe una cadena de caracteres definido en la memoria de programa. Su valor de entrada es el mensaje entre " " comillas.

   putrsUSART("kedutpic");


ReadUSART: lee un caracter del buffer de recepcion del módulo EUSART
getcUSART: lee un caracter del buffer de recepcion del módulo EUSART

      recepcion = getcUSART();


WriteUSART: escribe un caracter al buffer de transmisión del módulo EUSART.
putcUSART : escribe un caracter al buffer de transmisión del módulo EUSART.

      putcUSART(recepcion);


baudUSART: configura el Baud Rate del módulo EUSART. Esta es una de las razones el porque ahora se llama Enhanced USART, el BaudRate tiene sus propios bits de configuración con el cual puede operar en diversos modos. Tiene como argumentos las siguientes opciones.
(http://img145.imageshack.us/img145/931/56191504pi4.jpg)


Programa de aplicación:
Este programa va a recibir un caracter proveniente del Virutal Terminal de Proteus y luego mandara el mismo caracter al Virtual Terminal del Proteus, luego todo estara monitoreado en el LCD. EL nombre del programa es: eco LCD
Código: C
  1. #include <p18f2525.h>
  2. #include <delays.h>// Rutinas de retardo
  3. #include <usart.h>// Rutinas de retardo
  4. #include "C:\PIC\18F\EUART\LCD4b2x16.h"
  5.  
  6. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  7. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  8. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  9. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  10. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  11. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  12. #pragma config CPB = ON,CPD = ON//CONFIG5H
  13. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  14. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  15. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  16. #pragma config EBTRB = ON//CONFIG7H
  17. //******************************************************//
  18. //******************************************************//
  19. //
  20. //
  21. //              Programa Principal
  22. //
  23. //
  24. //******************************************************//
  25. //******************************************************//
  26. unsigned char recepcion;
  27. void main(void)
  28. {
  29.         TRISA = 0X00;
  30.         TRISB = 0XF0;
  31.         TRISC = 0X80;
  32.         PORTA = 0X00;
  33.         PORTB = 0X00;
  34.         PORTC = 0X00;
  35.  
  36.         // configuramos el LCD
  37.         Inicializa_LCD();
  38.         Comando_LCD(CURSOR_OFF & BLINK_OFF);
  39.         Comando_LCD(0X81);//posicion en el LCD
  40.         Datos_LCD("** eco LCD **");
  41.         Comando_LCD(0XC0);//posicion en el LCD
  42.         Datos_LCD("tx=");
  43.         Comando_LCD(0XCD);//posicion en el LCD
  44.         Datos_LCD("=rx");
  45.  
  46.         // configuramos el EUSART para 9.6K baudios
  47.         OpenUSART(      USART_TX_INT_OFF &
  48.                                 USART_RX_INT_OFF &
  49.                                 USART_ASYNCH_MODE &
  50.                                 USART_EIGHT_BIT &
  51.                                 USART_CONT_RX &
  52.                                 USART_BRGH_HIGH,
  53.                                 25);
  54.         for(;;)
  55.         {
  56.                 //esperar a que el buffer de transmisi&#243;n
  57.                 //este vacio o disponible
  58.                 while(BusyUSART());
  59.        
  60.                 //esperamos caracter del virtual terminal
  61.                 while(!DataRdyUSART());
  62.                 Comando_LCD(0XCC);
  63.                 recepcion = getcUSART();
  64.                 Dato_LCD(recepcion);
  65.        
  66.                 //envia caracter
  67.                 putcUSART(recepcion);
  68.                 Comando_LCD(0XC3);//posicion en el LCD
  69.                 Dato_LCD(recepcion);
  70.         }
  71. }

Programa de aplicación:
Este programa va a recibir un array proveniente de un pic y luego mandara otra cadena al otro pic, todo estara monitoreado en el LCD. EL nombre del programa es: eco cadena (proteus) , eco pic1 y eco pic2.

ECO PIC1
Código: C
  1. #include <p18f2525.h>
  2. #include <delays.h>// Rutinas de retardo
  3. #include <usart.h>// Rutinas de retardo
  4. #include "C:\PIC\18F\EUART\LCD4b2x16.h"
  5.  
  6. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  7. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  8. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  9. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  10. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  11. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  12. #pragma config CPB = ON,CPD = ON//CONFIG5H
  13. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  14. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  15. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  16. #pragma config EBTRB = ON//CONFIG7H
  17. //******************************************************//
  18. //******************************************************//
  19. //
  20. //
  21. //              Programa Principal ECO PIC 1
  22. //
  23. //
  24. //******************************************************//
  25. //******************************************************//
  26. char mensaje_eco1[]="micro_cadaver",recepcion_eco1[16],recepcion;
  27. int i;
  28. void main(void)
  29. {
  30.         TRISA = 0X00;
  31.         TRISB = 0XF0;
  32.         TRISC = 0X80;
  33.         PORTA = 0X00;
  34.         PORTB = 0X00;
  35.         PORTC = 0X00;
  36.  
  37.         // configuramos el LCD
  38.         Inicializa_LCD();
  39.         Comando_LCD(CURSOR_OFF & BLINK_OFF);
  40.         Datos_LCD("tx=");
  41.         Comando_LCD(0XC0);//posicion en el LCD
  42.         Datos_LCD("rx=");
  43.  
  44.         // configuramos el EUSART para 9.6K baudios
  45.         OpenUSART(      USART_TX_INT_OFF &
  46.                                 USART_RX_INT_OFF &
  47.                                 USART_ASYNCH_MODE &
  48.                                 USART_EIGHT_BIT &
  49.                                 USART_CONT_RX &
  50.                                 USART_BRGH_HIGH,
  51.                                 25);
  52.  
  53.         //esperar a que el buffer de transmisi&#243;n
  54.         //este vacio o disponible
  55.         while(BusyUSART());
  56.         //envia caracter
  57.         putsUSART(mensaje_eco1);
  58.         Comando_LCD(0X83);//posicion en el LCD
  59.         for(i=0;i<=12;i++)
  60.         {
  61.                 Dato_LCD(mensaje_eco1[i]);
  62.         }
  63.  
  64.         //esperar a que el buffer de transmisi&#243;n
  65.         //este vacio o disponible
  66.         while(BusyUSART());
  67.         //esperamos caracter del virtual terminal
  68.         while(!DataRdyUSART());
  69.         getsUSART(recepcion_eco1,9);
  70.         Comando_LCD(0XC3);
  71.         for(i=0;i<=8;i++)
  72.         {
  73.                 Dato_LCD(recepcion_eco1[i]);
  74.         }
  75.  
  76.         while(1);
  77. }

ECO PIC2
Código: C
  1. #include <p18f2525.h>
  2. #include <delays.h>// Rutinas de retardo
  3. #include <usart.h>// Rutinas de retardo
  4. #include "C:\PIC\18F\EUART\LCD4b2x16.h"
  5.  
  6. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  7. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  8. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  9. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  10. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  11. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  12. #pragma config CPB = ON,CPD = ON//CONFIG5H
  13. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  14. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  15. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  16. #pragma config EBTRB = ON//CONFIG7H
  17. //******************************************************//
  18. //******************************************************//
  19. //
  20. //
  21. //              Programa Principal ECO PIC 2
  22. //
  23. //
  24. //******************************************************//
  25. //******************************************************//
  26. char mensaje_eco2[]="VIVA PERU",recepcion_eco2[16],recepcion;
  27. int i;
  28. void main(void)
  29. {
  30.         TRISA = 0X00;
  31.         TRISB = 0XF0;
  32.         TRISC = 0X80;
  33.         PORTA = 0X00;
  34.         PORTB = 0X00;
  35.         PORTC = 0X00;
  36.  
  37.         // configuramos el LCD
  38.         Inicializa_LCD();
  39.         Comando_LCD(CURSOR_OFF & BLINK_OFF);
  40.         Datos_LCD("tx=");
  41.         Comando_LCD(0XC0);//posicion en el LCD
  42.         Datos_LCD("rx=");
  43.  
  44.         // configuramos el EUSART para 9.6K baudios
  45.         OpenUSART(      USART_TX_INT_OFF &
  46.                                 USART_RX_INT_OFF &
  47.                                 USART_ASYNCH_MODE &
  48.                                 USART_EIGHT_BIT &
  49.                                 USART_CONT_RX &
  50.                                 USART_BRGH_HIGH,
  51.                                 25);
  52.  
  53.         //esperar a que el buffer de transmisi&#243;n
  54.         //este vacio o disponible
  55.         while(BusyUSART());
  56.         //esperamos caracter del virtual terminal
  57.         while(!DataRdyUSART());
  58.         getsUSART(recepcion_eco2,13);
  59.         Comando_LCD(0XC3);
  60.         for(i=0;i<=12;i++)
  61.         {
  62.                 Dato_LCD(recepcion_eco2[i]);
  63.         }
  64.  
  65.  
  66.         //esperar a que el buffer de transmisi&#243;n
  67.         //este vacio o disponible
  68.         while(BusyUSART());
  69.         //envia caracter
  70.         putsUSART(mensaje_eco2);
  71.         Comando_LCD(0X83);//posicion en el LCD
  72.         for(i=0;i<=8;i++)
  73.         {
  74.                 Dato_LCD(mensaje_eco2[i]);
  75.         }
  76.  
  77.         while(1);
  78. }

todos los archivos: h**p://www.box.net/shared/ffojdvkcdh
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 14 de Junio de 2007, 14:34:39
 :mrgreen:
RUTINA PARA UN LCD 16X2 CON BUS DE DATOS A 4BITS

El siguiente codigo lo vengo modificando de el siguiente hilo  http://www.todopic.com.ar/foros/index.php?topic=17005.0
donde la amiga  :g) Mulderson amablemente compartio. La modificación que hice solo es para que se acomode al hardware que uso y le agregue una rutina para escribir strings (cadenas de caracteres) en el LCD, ubicados en la memoria de programa y en la memoria de datos.



 :mrgreen: hola henry tu programa funciona a la perfeccion , aunque al inicio :shock:  :shock:  me lleve un agran sorpresa al ver que no se inicializaba  el LCD , pues empeze a revisar el programa ...  como el pic que estoy usando era el 18F2550 le cambie el encabezado por este :

Código: [Seleccionar]
#include <p18f2550.h>
#include <delays.h> // Rutinas de retardo
#include "F:\PIC\C18\LCD4b2x16.h"

#pragma config  PLLDIV =1,CPUDIV = OSC1_PLL2,USBDIV =1 //CONFIG1L
#pragma config  FOSC = XT_XT, FCMEN = OFF,IESO = OFF//CONFIG1H
#pragma config PWRT = ON,BOR = OFF,BORV =0,VREGEN = OFF //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = ON,CP1 = ON,CP2 = ON,CP3 = ON//CONFIG5L ; PROTECCION DE LECTURA DESDE 0000-7FFFh
#pragma config CPB = OFF,CPD = OFF//CONFIG5H ; CPB: ON HABILITADO CODIGO DE PROTECCION ,CPD :ON HABILITADO PROTECCION CONTRA LECCTURA EEPROM
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON,WRT3 = ON//CONFIG6L       ; PROTECCION DE ESCRITURA DESDE 0000-7FFFh
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF//CONFIG6H                  ; WRBT = ON HABILITADO CODIGO DE PROTECCION DE ESCRITURA ,WRCT=ON PROTECCION A LOS REGISTROS (3000000-30000FFH),WRTD= ON PROTECCION DE ESCRITURA DE LOS DATOS EN LA EEPROM
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF//CONFIG7L ; PROTECCION DESDE TABLAS LEIDAS EJECUTADAS EN OTROS BLOQUES
#pragma config EBTRB = OFF//CONFIG7H
//******************************************************//
//******************************************************//

y en el programa le agrege la configuracion del ADCON1 como salida o entrada digitales (ADCON1=0X0F) ,debido a que parte del puerto B, se esta usando para mandar los datos al LCD :

Código: [Seleccionar]
//******************************************************//
//******************************************************//
//
//
// Programa Principal
//
//
//******************************************************//
//******************************************************//
char mensaje[]="Henry";

void main(void)
{
ADCON1 = 0X0F;  PUERTO B DIGITAL
UCON = 0X00;     
TRISA = 0X00;
TRISB = 0XF0;
TRISC = 0X00;
PORTA = 0X00;
PORTB = 0X00;
PORTC = 0X00;
Inicializa_LCD();
Comando_LCD(CURSOR_OFF & BLINK_ON);
Dato_LCD('#');//un dato
Datos_LCD(" VIVA EL PERU ");//una cadena desde la memoria de programa
Dato_String_LCD(mensaje);//una cadena desde la memoria de datos

//con este comando pasamos a la linea 2 del LCD
Comando_LCD(DDRAM_LINEA_2);
Datos_LCD("micro_cadaver");
while(1);
}

 8) claro me tome la molestia de cambiar algunas cositas de tu programa espero que no te molestes  :mrgreen:

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 14 de Junio de 2007, 15:07:59
 :mrgreen: harigato kedutpic san!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 15 de Junio de 2007, 08:06:30
Hola amigos!!!

No se muy bien si mostrar mi problema aqui o abrir otro tema, pero bueno,vosotros ya me decis.

La cuestion es que estoy trabajando con unos modulos de comunicacion inalambrica con el protocolo zigbee.Este protocolo lo puedes obtener en la misma web donde compre los modulos gratuitamente, lo que es una ventaja  :lol:.Este firmware esta hecho en C y para el C18.Pues bien cuando voy a compilarlo me da un error tal que asi "osc no definido" y ese es mi problema.No se como viene definido en el programa.Tambien he intentado definirlo como en los ejemplos que habeis colgado aqui y no funciona, sigue dando el mismo error.

Como no se como hacer para colgar el archivo aqui os dejo la direccion de donde se puede bajar el firmware, es gratuito :D :D

http://www.albedo.biz/products/010/002/005/

Os agradezco cualquier ayuda

Gracias
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 15 de Junio de 2007, 11:20:32
sugiero que hagas un hilo aparte porque la gente que derepente sabe algo nunca se va enterar a menos que haya estado viendo este hilo, lo cual reduce tus posibilidades (además que yo nunca he usado esos módulos  :( ....) de que alguien te responda, podrias poner problemas con zigbee y C18, o algo asip. saludos  :mrgreen: :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: barg en 16 de Junio de 2007, 07:43:19
Gracias micro_cadaver.Ya he puesto un tema nuevo en la pregunta, a ver si alguien sabe cual es el problema que tengo.Cuando consiga algo lo pongo aqui  :-/ :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 20 de Junio de 2007, 18:27:30
por ahi he visto que la gente le entra con dudas al I2C, pues le vamos a eso tambien en el C18  :mrgreen: voy a prepara material y lo lanzamos!!!  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 23 de Junio de 2007, 03:30:49
El Protocolo I2C

Una de las herramientas de comunicación muy usada en el mundo de los microcontroladores es el protocolo serial I2C, el compilador C18 tiene implementado un conjunto de librerias y rutinas para este propósito, sin embargo jijijiji  :mrgreen: no tienen una libreria de aplicación específica por ejemplo para el DS1307 (entre otros...), tiene una libreria para el manejo de memorias eeprom externas pero solo para la 24XX01, pues solo permite ingresar 1 byte de dirección de memoria.
En vista de tales inconvenientes (y para no quedar atrás del CCS) nos aventuraremos en la odisea de implementar nuestras propias rutinas jijiji  :-/, empezaremos con las memorias eeprom, y luego nos daremos un paseito por el DS1307, si alguien propone algún otro chip para hacer su libreria pues bienvenido sea  :-) .

Ah! pero antes estudiemos brevemente el modulo I2C que lleva incorporado el PIC18F2525 (en los demas PICs de esta gama la principal diferencia está en la ubicación de los pines SDA y SCL).


Módulo MSSP en Modo I2C

En el pic 18F2525 el protocolo I2C utiliza los siguientes pines para comunicarse, los cuales deben estar configurados como entradas al inicializar el modo I2C:
(http://img507.imageshack.us/img507/4484/36126727ve2.jpg)
Estos pines del pic cuando se configuran como puerto serial del módulo I2C demandan una resistencia de PULL UP en ambos pines, esto se debe al protocolo I2C. Esta resistencia puede ser de 10K -- 2K tirada a 5V, pero en el simulador usaremos un tipo de componente llamado PULL-UP, no olviden que la posicion de estos pines varia segun el modelo del pic18F, tener cuidado al momento de implementarlo si no tienen el 18F2525, no olviden setearlos como entradas.

A continuación tenemos los registros que administran el control del módulo:
(http://img220.imageshack.us/img220/8048/95440944md3.jpg)
Estos registros poseen las diversas configuraciones que puede optar el módulo I2C, para nuestros objetivos vamos a dejarlo habilitado como dispositivo I2C Maestro, bus de 100KHz para cristal de 4MHz, sin interrupciones, y unos detalles más que los podremos ver en sus registros de control:

(http://img401.imageshack.us/img401/6681/42542541ew8.jpg)
En este registro se puede configurar lo siguiente:

(http://img296.imageshack.us/img296/7062/24242412lg3.jpg)
En este registro se puede configurar lo siguiente:

(http://img144.imageshack.us/img144/4575/60419041fm3.jpg)
En este registro se puede configurar lo siguiente:

El registro SSPSR es el buffer de desplazamiento usado para enviar o recibir información de forma serial.
El registro SSPBUF es el registro donde se escribe o se guarda el valos a enviar o recibir.

El registro SSPADD es el que guarda el valor de recarga del Generador de Baudios con el cual obtenemos la velocidad del bus I2C, para nuestra experiencia requerimos 100KHz con 4MHz entonces segun la fórmula:
(http://img528.imageshack.us/img528/5968/91345688tm8.jpg)
SSPADD = 9
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 25 de Junio de 2007, 01:07:11
Rutinas del Módulo I2C
La imagen nos muestra las rutinas que tiene implementado el C18 para realizar la comunicación I2C entres dispositivos que soporten este protocolo. Esta información esta en el MPLAB C18 Libraries.pdf que viene en la carpeta DOC del C18.
(http://img440.imageshack.us/img440/3985/72575583rs0.jpg)
La función de cada rutina tiene que ver con el protocolo I2C, es decir que se implementa el bit de Start, de Stop, el ACK, la lectura get o read, la escritura write o put, los retardos, etc... y en base a estas rutinas se ha escrito una libreria que permite el uso de memorias externas eeprom con dos bytes de direccion de datos. Pues como ya comente el C18 tiene una libreria pero para la memoria 24XX01 cuyo adress (direccion de datos) es de 1 byte de tamaño.

Librería  memoria_externa.h
Esta libreria contiene las rutinas que van a desempeñar la comunicación entre el pic y la memoria serial eeprom externa con protocolo I2C con 2 bytes como tamaño de direccion de datos, por ejemplo la 24XX512,....24XX32....., a continuación la libreria:
Código: C
  1. //********************************************************
  2. //********************************************************
  3. signed char putrsI2C( const rom char *wrptr )
  4. {
  5.   while ( *wrptr )                // transmit data until null character
  6.   {
  7.         if ( WriteI2C ( *wrptr ) )   // write 1 byte
  8.     {
  9.         return ( -3 );            // return with write collision error
  10.         }
  11.     IdleI2C();                  // test for idle condition
  12.     if ( SSPCON2bits.ACKSTAT )  // test received ack bit state
  13.     {
  14.         return ( -2 );            // bus device responded with  NOT ACK
  15.         }                           // terminate putsI2C() function
  16.         wrptr ++;                       // increment pointer
  17.   }
  18.   return ( 0 );
  19. }
  20. //********************************************************
  21. //********************************************************
  22. //
  23. //      Escribir en Memoria EEPROM 24LC512
  24. //
  25. //********************************************************
  26. //********************************************************
  27. unsigned char EscribeDato_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2, unsigned char data )
  28. {
  29.   IdleI2C();                      // ensure module is idle
  30.   StartI2C();                     // initiate START condition
  31.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  32.   if ( PIR2bits.BCLIF )           // test for bus collision
  33.   {
  34.     return ( -1 );                // return with Bus Collision error
  35.   }
  36.   else                            // start condition successful
  37.   {
  38.     if ( WriteI2C( control ) )    // write byte - R/W bit should be 0
  39.     {
  40.       return ( -3 );              // set error for write collision
  41.     }
  42.  
  43.     IdleI2C();                    // ensure module is idle
  44.     if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
  45.     {
  46.                 if ( WriteI2C( address1 ) )  // write word address for EEPROM
  47.         {
  48.                 return ( -3 );            // set error for write collision
  49.         }
  50.             IdleI2C();                    // ensure module is idle
  51.             if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
  52.             {
  53.                 if ( WriteI2C( address2 ) )  // write word address for EEPROM
  54.                 {
  55.                         return ( -3 );            // set error for write collision
  56.                 }
  57.                         IdleI2C();                  // ensure module is idle
  58.                     if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  59.                     {
  60.                         if ( WriteI2C( data ) )   // data byte for EEPROM
  61.                                 {
  62.                           return ( -3 );          // set error for write collision
  63.                         }
  64.                     }
  65.                     else
  66.                     {
  67.                         return ( -2 );            // return with Not Ack error condition  
  68.                         }
  69.                 }
  70.     }
  71.     else
  72.     {
  73.         return ( -2 );              // return with Not Ack error condition  
  74.     }
  75.   }
  76.  
  77.   IdleI2C();                      // ensure module is idle  
  78.   StopI2C();                      // send STOP condition
  79.   while ( SSPCON2bits.PEN );      // wait until stop condition is over
  80.   if ( PIR2bits.BCLIF )           // test for bus collision
  81.   {
  82.     return ( -1 );                // return with Bus Collision error
  83.   }
  84.   return ( 0 );                   // return with no error
  85. }
  86. //********************************************************
  87. //********************************************************
  88. //
  89. //      Escribir Pagina en Memoria EEPROM 24LC512 desde un Cadena en la ROM
  90. //
  91. //********************************************************
  92. //********************************************************
  93. unsigned char EscribeDatos_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2, const rom char *wrptr )
  94. {
  95.   IdleI2C();                      // ensure module is idle
  96.   StartI2C();                     // initiate START condition
  97.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  98.   if ( PIR2bits.BCLIF )           // test for bus collision
  99.   {
  100.     return ( -1 );                // return with Bus Collision error
  101.   }
  102.   else                            // start condition successful
  103.   {
  104.     if ( WriteI2C( control ) )    // write byte - R/W bit should be 0
  105.     {
  106.       return ( -3 );              // set error for write collision
  107.     }
  108.  
  109.     IdleI2C();                    // ensure module is idle
  110.     if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
  111.     {
  112.                 if ( WriteI2C( address1 ) )  // write word address for EEPROM
  113.         {
  114.                 return ( -3 );            // set error for write collision
  115.         }
  116.             IdleI2C();                    // ensure module is idle
  117.             if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
  118.             {
  119.                 if ( WriteI2C( address2 ) )  // write word address for EEPROM
  120.                 {
  121.                         return ( -3 );            // set error for write collision
  122.                 }
  123. //*******************************************************************************
  124. //*******************************************************************************
  125.                         IdleI2C();                  // ensure module is idle
  126.                     if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  127.                     {
  128.                         if ( putrsI2C( wrptr ) )   // data byte for EEPROM
  129.                                 {
  130.                           return ( -4 );          // set error for write collision
  131.                         }
  132.                     }
  133. //*******************************************************************************
  134. //*******************************************************************************
  135.                     else
  136.                     {
  137.                         return ( -2 );            // return with Not Ack error condition  
  138.                         }
  139.                 }
  140.     }
  141.     else
  142.     {
  143.         return ( -2 );              // return with Not Ack error condition  
  144.     }
  145.   }
  146.  
  147.   IdleI2C();                      // ensure module is idle  
  148.   StopI2C();                      // send STOP condition
  149.   while ( SSPCON2bits.PEN );      // wait until stop condition is over
  150.   if ( PIR2bits.BCLIF )           // test for bus collision
  151.   {
  152.     return ( -1 );                // return with Bus Collision error
  153.   }
  154.   return ( 0 );                   // return with no error
  155. }
  156. //********************************************************
  157. //********************************************************
  158. //
  159. //      Escribir Pagina en Memoria EEPROM 24LC512 desde una Cadena
  160. //
  161. //********************************************************
  162. //********************************************************
  163. unsigned char EscribeCadena_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2, unsigned char *wrptr )
  164. {
  165.   IdleI2C();                      // ensure module is idle
  166.   StartI2C();                     // initiate START condition
  167.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  168.   if ( PIR2bits.BCLIF )           // test for bus collision
  169.   {
  170.     return ( -1 );                // return with Bus Collision error
  171.   }
  172.   else                            // start condition successful
  173.   {
  174.     if ( WriteI2C( control ) )    // write byte - R/W bit should be 0
  175.     {
  176.       return ( -3 );              // set error for write collision
  177.     }
  178.  
  179.     IdleI2C();                    // ensure module is idle
  180.     if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
  181.     {
  182.                 if ( WriteI2C( address1 ) )  // write word address for EEPROM
  183.         {
  184.                 return ( -3 );            // set error for write collision
  185.         }
  186.             IdleI2C();                    // ensure module is idle
  187.             if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
  188.             {
  189.                 if ( WriteI2C( address2 ) )  // write word address for EEPROM
  190.                 {
  191.                         return ( -3 );            // set error for write collision
  192.                 }
  193. //*******************************************************************************
  194. //*******************************************************************************
  195.                         IdleI2C();                  // ensure module is idle
  196.                     if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  197.                     {
  198.                         if ( putsI2C( wrptr ) )   // data byte for EEPROM
  199.                                 {
  200.                           return ( -4 );          // set error for write collision
  201.                         }
  202.                     }
  203. //*******************************************************************************
  204. //*******************************************************************************
  205.                     else
  206.                     {
  207.                         return ( -2 );            // return with Not Ack error condition  
  208.                         }
  209.                 }
  210.     }
  211.     else
  212.     {
  213.         return ( -2 );              // return with Not Ack error condition  
  214.     }
  215.   }
  216.  
  217.   IdleI2C();                      // ensure module is idle  
  218.   StopI2C();                      // send STOP condition
  219.   while ( SSPCON2bits.PEN );      // wait until stop condition is over
  220.   if ( PIR2bits.BCLIF )           // test for bus collision
  221.   {
  222.     return ( -1 );                // return with Bus Collision error
  223.   }
  224.   return ( 0 );                   // return with no error
  225. }
  226. //********************************************************
  227. //********************************************************
  228. //
  229. //      Lectura en Memoria EEPROM 24LC512
  230. //
  231. //********************************************************
  232. //********************************************************
  233. unsigned int LeeDato_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2 )
  234. {
  235.   IdleI2C();                      // ensure module is idle
  236.   StartI2C();                     // initiate START condition
  237.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  238.   if ( PIR2bits.BCLIF )           // test for bus collision
  239.   {
  240.     return ( -1 );                // return with Bus Collision error
  241.   }
  242.   else
  243.   {
  244.     if ( WriteI2C( control ) )    // write 1 byte
  245.     {
  246.       return ( -3 );              // return with write collision error
  247.     }
  248.  
  249.     IdleI2C();                    // ensure module is idle
  250.     if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition, if received
  251.     {
  252.       if ( WriteI2C( address1 ) )  // WRITE word address for EEPROM
  253.       {
  254.         return ( -3 );            // return with write collision error
  255.       }
  256.           IdleI2C();                    // ensure module is idle
  257.       if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition, if received
  258.       {
  259.         if ( WriteI2C( address2 ) )  // WRITE word address for EEPROM
  260.         {
  261.                 return ( -3 );            // return with write collision error
  262.         }
  263.                 IdleI2C();                  // ensure module is idle
  264.         if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition, if received
  265.         {
  266.                 RestartI2C();             // generate I2C bus restart condition
  267.                 while ( SSPCON2bits.RSEN );// wait until re-start condition is over
  268.                 if ( PIR2bits.BCLIF )     // test for bus collision
  269.                 {
  270.                         return ( -1 );          // return with Bus Collision error
  271.                 }
  272.             if ( WriteI2C( control+1 ) )// write 1 byte - R/W bit should be 1
  273.                 {
  274.                         return ( -3 );          // return with write collision error
  275.                 }
  276.                 IdleI2C();                // ensure module is idle
  277.                 if ( !SSPCON2bits.ACKSTAT )// test for ACK condition, if received
  278.                 {
  279.                   SSPCON2bits.RCEN = 1;       // enable master for 1 byte reception
  280.                   while ( SSPCON2bits.RCEN ); // check that receive sequence is over
  281.                   NotAckI2C();              // send ACK condition
  282.                   while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
  283.                   StopI2C();              // send STOP condition
  284.                   while ( SSPCON2bits.PEN ); // wait until stop condition is over
  285.                   if ( PIR2bits.BCLIF )   // test for bus collision
  286.                   {
  287.                         return ( -1 );         // return with Bus Collision error
  288.                   }
  289.                 }
  290.                 }
  291.         else
  292.         {
  293.           return ( -2 );          // return with Not Ack error
  294.         }
  295.       }
  296.       else
  297.       {
  298.         return ( -2 );            // return with Not Ack error
  299.       }
  300.     }
  301.     else
  302.     {
  303.       return ( -2 );              // return with Not Ack error
  304.     }
  305.   }
  306.   return ( (unsigned int) SSPBUF );     // return with data
  307. }
  308. //********************************************************
  309. //********************************************************
  310. //
  311. //              Lee una Cadena en Memoria EEPROM 24LCXX
  312. //
  313. //********************************************************
  314. //********************************************************
  315. unsigned char LeeDatos_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2,unsigned char *rdptr, unsigned char length )
  316. {
  317.   IdleI2C();                      // ensure module is idle
  318.   StartI2C();                     // initiate START condition
  319.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  320.   if ( PIR2bits.BCLIF )           // test for bus collision
  321.   {
  322.     return ( -1 );                // return with Bus Collision error
  323.   }
  324.   else
  325.   {
  326.     if ( WriteI2C( control ) )    // write 1 byte
  327.     {
  328.       return ( -3 );              // set error for write collision
  329.     }
  330.     IdleI2C();                    // ensure module is idle
  331.     if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition, if received
  332.     {
  333.       if ( WriteI2C( address1 ) )  // WRITE word address for EEPROM
  334.       {
  335.         return ( -3 );            // return with write collision error
  336.       }
  337.           IdleI2C();                    // ensure module is idle
  338.       if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition, if received
  339.       {
  340.         if ( WriteI2C( address2 ) )  // WRITE word address for EEPROM
  341.         {
  342.                 return ( -3 );            // return with write collision error
  343.         }
  344.                 IdleI2C();                  // ensure module is idle
  345.         if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  346.         {
  347.                 RestartI2C();             // generate I2C bus restart condition
  348.                 while ( SSPCON2bits.RSEN );  // wait until re-start condition is over
  349.                 if ( WriteI2C( control +1 ) )// WRITE 1 byte - R/W bit should be 1 for read
  350.                 {
  351.                         return ( -3 );          // set error for write collision
  352.                 }
  353.                 IdleI2C();                // ensure module is idle
  354.                 if ( !SSPCON2bits.ACKSTAT )// test for ACK condition received
  355.                 {
  356.                                 if ( getsI2C( rdptr, length ) )// read in multiple bytes
  357.                         {
  358.                                 return ( -1 );        // return with Bus Collision error
  359.                         }
  360.                                 NotAckI2C();            // send not ACK condition
  361.                         while ( SSPCON2bits.ACKEN );// wait until ACK sequence is over
  362.                         StopI2C();              // send STOP condition
  363.                         while ( SSPCON2bits.PEN );// wait until stop condition is over
  364.                         if ( PIR2bits.BCLIF )   // test for bus collision
  365.                         {
  366.                                 return ( -1 );        // return with Bus Collision error
  367.                         }
  368.                 }
  369.                 else
  370.                 {
  371.                                 return ( -2 );          // return with Not Ack error
  372.                 }
  373.                 }
  374.         else
  375.         {
  376.                 return ( -2 );            // return with Not Ack error
  377.         }
  378.     }
  379.     else
  380.     {
  381.         return ( -2 );              // return with Not Ack error
  382.     }
  383.   }
  384.   return ( 0 );                   // return with no error
  385.   }
  386. }
  387. //********************************************************
  388. //********************************************************
  389. //
  390. //      Esperar Ack en Memoria EEPROM 24LC512
  391. //
  392. //********************************************************
  393. //********************************************************
  394. unsigned char Ack_i2c_eeprom( unsigned char control )
  395. {
  396.   IdleI2C();                      // ensure module is idle
  397.   StartI2C();                     // initiate START condition
  398.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  399.   if ( PIR2bits.BCLIF )           // test for bus collision
  400.   {
  401.     return ( -1 );                // return with Bus Collision error
  402.   }
  403.  
  404.   else
  405.   {
  406.     if ( WriteI2C( control ) )    // write byte - R/W bit should be 0
  407.     {
  408.       return ( -3 );              // set error for write collision
  409.     }
  410.  
  411.     IdleI2C();                    // ensure module is idle  
  412.     if ( PIR2bits.BCLIF )         // test for bus collision
  413.     {
  414.       return ( -1 );              // return with Bus Collision error
  415.     }
  416.  
  417.     while ( SSPCON2bits.ACKSTAT ) // test for ACK condition received
  418.     {
  419.       RestartI2C();               // initiate Restart condition
  420.       while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
  421.       if ( PIR2bits.BCLIF )       // test for bus collision
  422.       {
  423.         return ( -1 );            // return with Bus Collision error
  424.       }
  425.  
  426.       if ( WriteI2C( control ) )  // write byte - R/W bit should be 0
  427.       {
  428.         return ( -3 );            // set error for write collision
  429.       }
  430.       IdleI2C();                  // ensure module is idle
  431.     }
  432.   }
  433.        
  434.   StopI2C();                      // send STOP condition
  435.   while ( SSPCON2bits.PEN );      // wait until stop condition is over        
  436.   if ( PIR2bits.BCLIF )           // test for bus collision
  437.   {
  438.     return ( -1 );                // return with Bus Collision error
  439.   }
  440.   return ( 0 );                   // return with no error    
  441. }
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 25 de Junio de 2007, 01:59:37
Veamos en detalle las rutinas de la librería memoria_externa.h

putrsI2C
Esta rutina permite enviar al modulo I2C una cadena ubicada en la memoria de program (ROM), su aplicación se encuentra en la rutina EscribeDatos_i2c_eeprom.

EscribeDato_i2c_eeprom
Tiene 4 argumentos de entrada y retorna un valor 0 si no existen errores, de lo contrario devolvera un valor negativo.
Código: C
  1. unsigned char EscribeDato_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2, unsigned char data )
Ejm:
   EscribeDato_i2c_eeprom(0XA0,0X00,0X00,'@');

En este ejemplo queremos escribir el caracter ascii @ en la posicion 0x0000 de la memoria de datos de la eeprom externa cuyo
registro de control es 0XA0.
(http://img146.imageshack.us/img146/9873/31010563pc4.jpg)

EscribeDatos_i2c_eeprom
Tiene 4 argumentos de entrada donde uno de ellos es una cadena ubicada en la memoria de programa del pic (ROM), y como salida retorna un valor 0 si no existen errores, de lo contrario devolvera un valor negativo.
Código: C
  1. unsigned char EscribeDatos_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2, const rom char *wrptr )
Ejm:
   EscribeDatos_i2c_eeprom(0XA0,0X00,0X10,"|||PERU|||");

Escribimos la cadena |||PERU||| a partir de la posicion 0x0010 de la memoria de datos de la eeprom externa cuyo registro de control es 0XA0.
(http://img183.imageshack.us/img183/5726/86728316fe3.jpg)

EscribeCadena_i2c_eeprom
Tiene 4 argumentos de entrada donde uno de ellos es una cadena ubicada en la memoria de datos del pic (RAM), y como salida retorna un valor 0 si no existen errores, de lo contrario devolvera un valor negativo.
Código: C
  1. unsigned char EscribeCadena_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2, unsigned char *wrptr )
Ejm:
unsigned char    henry[]="*micro_cadaver*",

   EscribeCadena_i2c_eeprom(0XA0,0X00,0X00,henry);

Escribimos la cadena henry a partir de la posicion 0x0000 de la memoria de datos de la eeprom externa cuyo registro de control es 0XA0.
(http://img140.imageshack.us/img140/3833/76356197ou9.jpg)

LeeDato_i2c_eeprom
Tiene 3 argumentos de entrada y como argumento de salida nos retorna el contenido del buffer de recepcion SSPBUF, de lo contrario nos dara un valor negativo.
Código: C
  1. unsigned int LeeDato_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2 )
Ejm:
   caracter=LeeDato_i2c_eeprom(0XA0,0X00,0X00);

Con esta rutina podemos leer un byte de la memoria eeprom externa, en el ejemplo estamos leyendo un byte ubicado en 0x0000 de la memoria con registro de control 0xA0.

LeeDatos_i2c_eeprom
Tiene 5 argumentos de entrada y como argumento de salida retorna un 0 y la cadena cargada con la cantidad de bytes solicitados, de lo contrario nos dara un valor negativo.
Código: C
  1. unsigned char LeeDatos_i2c_eeprom( unsigned char control, unsigned char address1, unsigned char address2,unsigned char *rdptr, unsigned char length )
Ejm:
unsigned char    recepcion[16];

   LeeDatos_i2c_eeprom(0XA0,0X00,0X10,recepcion,10);

Con esta rutina podemos leer varios bytes de la memoria eeprom externa, en el ejemplo estamos leyendo 10 bytes ubicados desde 0x0010 de la memoria externa con registro de control 0xA0 y los estamos guardando en la cadena recepcion. Tener en cuenta que la cadena donde se van a cargar los valores debe ser mayor que la cantidad solicitada de bytes, en este ejemplo se ve claramente que recepcion es una cadena con 16 elementos y en la rutina de lectura especificamos que queremos descargar solo 10 bytes.


Ack_i2c_eeprom
Genera un ACK para liberar el bus I2C, hacer esto después de cualquier escritura.
Código: C
  1. unsigned char Ack_i2c_eeprom( unsigned char control )
Ejm:
   EscribeDato_i2c_eeprom(0XA0,0X00,0X00,'@');
   Ack_i2c_eeprom(0XA0);   
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 25 de Junio de 2007, 02:45:42
Programa de Aplicacion
Este programa escribe datos a una memoria 24LC32 y luego los vuelve a leer y los muestra por pantalla LCD.
Código: C
  1. #include <p18f2525.h>
  2. #include <delays.h>
  3. #include <i2c.h>
  4. #include "C:\PIC\18F\MEMO\memoria_externa.h"
  5. #include "C:\PIC\18F\MEMO\LCD4b2x16.h"
  6.  
  7. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  8. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  9. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  10. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  11. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  12. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  13. #pragma config CPB = ON,CPD = ON//CONFIG5H
  14. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  15. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  16. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  17. #pragma config EBTRB = ON//CONFIG7H
  18.  
  19. int caracter;
  20. unsigned char   henry[]="*micro_cadaver*",
  21.                                 cadena[16];
  22. void main(void)
  23. {
  24.         TRISA = 0X00;
  25.         TRISB = 0X00;
  26.         TRISC = 0X18;
  27.         LATA = 0X00;
  28.         LATB = 0X00;   
  29.         LATC = 0X00;   
  30.         Delay1KTCYx(100);      
  31.         Inicializa_LCD();
  32.         Comando_LCD(CURSOR_OFF & BLINK_OFF);
  33. //*******************************************************
  34. //      configuración del modulo i2c
  35. //*******************************************************
  36.         OpenI2C(MASTER,SLEW_OFF);//inicializo modulo
  37.         SSPADD = 9;//100KHz para 4MHz
  38. //*******************************************************
  39.         EscribeDato_i2c_eeprom(0XA0,0X00,0X00,'@');
  40.         Ack_i2c_eeprom(0XA0);  
  41.         caracter=LeeDato_i2c_eeprom(0XA0,0X00,0X00);
  42.         Dato_LCD(caracter);
  43.         Delay1KTCYx(500);      
  44.  
  45.         EscribeDatos_i2c_eeprom(0XA0,0X00,0X10,"|||PERU|||");
  46.         Ack_i2c_eeprom(0XA0);  
  47.  
  48.         EscribeCadena_i2c_eeprom(0XA0,0X00,0X00,henry);
  49.         Ack_i2c_eeprom(0XA0);  
  50.  
  51.         Comando_LCD(0X80);
  52.         LeeDatos_i2c_eeprom(0XA0,0X00,0X10,cadena,10);
  53.         Dato_String_LCD(cadena);
  54.  
  55.         Comando_LCD(0XC0);
  56.         LeeDatos_i2c_eeprom(0XA0,0X00,0X00,cadena,15);
  57.         Dato_String_LCD(cadena);
  58.  
  59.         while(1);
  60.  
  61. //*******************************************************
  62. //*******************************************************
  63. }


Programa de Aplicacion
Este programa escribe un mensaje en una pagina de la memoria 24LC512, según el datasheet de esta memoria cada pagina tiene 128 bytes, entonces en el programa enviaremos una cadena con 128 elementos.
(http://img150.imageshack.us/img150/6281/82587195nz8.jpg)
Código: C
  1. #include <p18f2525.h>
  2. #include <delays.h>
  3. #include <i2c.h>
  4. #include "C:\PIC\18F\MEMO\memoria_externa.h"
  5. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  6. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  7. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  8. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  9. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  10. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  11. #pragma config CPB = ON,CPD = ON//CONFIG5H
  12. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  13. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  14. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  15. #pragma config EBTRB = ON//CONFIG7H
  16.  
  17. int caracter;
  18. unsigned char   henry[]="Henry Ricardo Laredo Quispe, mas conocido como el micro_cadaver! i wish i was on the top the mountain happy shinny people i want",
  19.                                 cadena[16];
  20. void main(void)
  21. {
  22.         TRISA = 0X00;
  23.         TRISB = 0X00;
  24.         TRISC = 0X18;
  25.         LATA = 0X00;
  26.         LATB = 0X00;   
  27.         LATC = 0X00;   
  28.         Delay1KTCYx(250);      
  29. //*******************************************************
  30. //      configuración del modulo i2c
  31. //*******************************************************
  32.         OpenI2C(MASTER,SLEW_OFF);//inicializo modulo
  33.         SSPADD = 9;//100KHz para 4MHz
  34. //*******************************************************
  35.         EscribeDato_i2c_eeprom(0XA0,0X00,0X00,'@');
  36.         Ack_i2c_eeprom(0XA0);  
  37.         caracter=LeeDato_i2c_eeprom(0XA0,0X00,0X00);
  38.  
  39.         EscribeCadena_i2c_eeprom(0XA0,0X00,0X00,henry);
  40.         Ack_i2c_eeprom(0XA0);  
  41.         while(1);
  42. //*******************************************************
  43. //*******************************************************
  44. }

Todos los archivos:h**p://www.box.net/shared/444hivq5fd
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 26 de Junio de 2007, 01:00:41
bueno foreros, lo que sigue es el DS1307.....  :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electronando en 26 de Junio de 2007, 02:38:48
si supiera la gente que tu no duermes Henry jaja , bueno a nosostros nos conviene  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 26 de Junio de 2007, 10:09:04
jajaj si duermo, poquito, pero luego todo el dia estoy volando.... entiendase por distraido o fuera de la realidad, además este clima me encanta (el invierno y el otoño), a ver si luego del DS1307 hacemos un panelcito de leds en C18 mostrando la hora  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 26 de Junio de 2007, 17:34:46
jajaj si duermo, poquito, pero luego todo el dia estoy volando.... entiendase por distraido o fuera de la realidad, además este clima me encanta (el invierno y el otoño), a ver si luego del DS1307 hacemos un panelcito de leds en C18 mostrando la hora  :mrgreen:

 :D  :D  eso me consta jajajaja
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 28 de Junio de 2007, 03:20:28
Libreria  ds1307.h

Ante Uds. querido publico.... la libreria ds1307.h hecha en lenguaje C para el compilador C18, provecho!
Código: C
  1. #define dispositivo  0xD0
  2. //********************************************************
  3. //********************************************************
  4. //
  5. //              Leer Byte en DS1307
  6. //
  7. //********************************************************
  8. //********************************************************
  9. unsigned int LeeDato_ds1307( unsigned char address )
  10. {
  11.   IdleI2C();                      // ensure module is idle
  12.   StartI2C();                     // initiate START condition
  13.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  14.   if ( PIR2bits.BCLIF )           // test for bus collision
  15.   {
  16.         return ( -1 );                // return with Bus Collision error
  17.   }
  18.   else
  19.   {
  20.     if ( WriteI2C( dispositivo ) )    // write 1 byte
  21.     {
  22.         return ( -3 );              // return with write collision error
  23.     }
  24.         IdleI2C();                    // ensure module is idle
  25.     if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition, if received
  26.     {
  27.         if ( WriteI2C( address ) )  // WRITE word address for EEPROM
  28.         {
  29.                 return ( -3 );            // return with write collision error
  30.         }
  31.                 //******
  32.                 IdleI2C();                  // ensure module is idle
  33.         if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition, if received
  34.         {
  35.                 RestartI2C();             // generate I2C bus restart condition
  36.                 while ( SSPCON2bits.RSEN );// wait until re-start condition is over
  37.                 if ( PIR2bits.BCLIF )     // test for bus collision
  38.                 {
  39.                         return ( -1 );          // return with Bus Collision error
  40.                 }
  41.             if ( WriteI2C( dispositivo+1 ) )// write 1 byte - R/W bit should be 1
  42.                 {
  43.                         return ( -3 );          // return with write collision error
  44.                 }
  45.                 IdleI2C();                // ensure module is idle
  46.                 if ( !SSPCON2bits.ACKSTAT )// test for ACK condition, if received
  47.                 {
  48.                   SSPCON2bits.RCEN = 1;       // enable master for 1 byte reception
  49.                   while ( SSPCON2bits.RCEN ); // check that receive sequence is over
  50.                   NotAckI2C();              // send ACK condition
  51.                   while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
  52.                   StopI2C();              // send STOP condition
  53.                   while ( SSPCON2bits.PEN ); // wait until stop condition is over
  54.                   if ( PIR2bits.BCLIF )   // test for bus collision
  55.                   {
  56.                         return ( -1 );         // return with Bus Collision error
  57.                   }
  58.                 }
  59.                 }
  60.         else
  61.         {
  62.           return ( -2 );          // return with Not Ack error
  63.         }
  64.     }
  65.     else
  66.     {
  67.       return ( -2 );              // return with Not Ack error
  68.     }
  69.   }
  70.   return ( (unsigned int) SSPBUF );     // return with data
  71. }
  72. //********************************************************
  73. //********************************************************
  74. //
  75. //              Leer Cadena en DS1307
  76. //
  77. //********************************************************
  78. //********************************************************
  79. unsigned char LeeDatos_ds1307( unsigned char address, unsigned char *rdptr, unsigned char length )
  80. {
  81.   IdleI2C();                      // ensure module is idle
  82.   StartI2C();                     // initiate START condition
  83.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  84.   if ( PIR2bits.BCLIF )           // test for bus collision
  85.   {
  86.     return ( -1 );                // return with Bus Collision error
  87.   }
  88.   else
  89.   {
  90.     if ( WriteI2C( dispositivo ) )    // write 1 byte
  91.     {
  92.       return ( -3 );              // set error for write collision
  93.     }
  94.           IdleI2C();                    // ensure module is idle
  95.       if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition, if received
  96.       {
  97.         if ( WriteI2C( address ) )  // WRITE word address for EEPROM
  98.         {
  99.                 return ( -3 );            // return with write collision error
  100.         }
  101.                 IdleI2C();                  // ensure module is idle
  102.         if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  103.         {
  104.                 RestartI2C();             // generate I2C bus restart condition
  105.                 while ( SSPCON2bits.RSEN );  // wait until re-start condition is over
  106.                 if ( WriteI2C( dispositivo+1 ) )// WRITE 1 byte - R/W bit should be 1 for read
  107.                 {
  108.                         return ( -3 );          // set error for write collision
  109.                 }
  110.                 IdleI2C();                // ensure module is idle
  111.                 if ( !SSPCON2bits.ACKSTAT )// test for ACK condition received
  112.                 {
  113.                                 if ( getsI2C( rdptr, length ) )// read in multiple bytes
  114.                         {
  115.                                 return ( -1 );        // return with Bus Collision error
  116.                         }
  117.                                 NotAckI2C();            // send not ACK condition
  118.                         while ( SSPCON2bits.ACKEN );// wait until ACK sequence is over
  119.                         StopI2C();              // send STOP condition
  120.                         while ( SSPCON2bits.PEN );// wait until stop condition is over
  121.                         if ( PIR2bits.BCLIF )   // test for bus collision
  122.                         {
  123.                                 return ( -1 );        // return with Bus Collision error
  124.                         }
  125.                 }
  126.                 else
  127.                 {
  128.                                 return ( -2 );          // return with Not Ack error
  129.                 }
  130.                 }
  131.         else
  132.         {
  133.                 return ( -2 );            // return with Not Ack error
  134.         }
  135.     }
  136.   return ( 0 );                   // return with no error
  137.   }
  138. }
  139. //********************************************************
  140. //********************************************************
  141. //
  142. //              Escribir en DS1307
  143. //
  144. //********************************************************
  145. //********************************************************
  146. //
  147. unsigned char Escribe_ds1307( unsigned char address, unsigned char data )
  148. {
  149.   IdleI2C();                      // ensure module is idle
  150.   StartI2C();                     // initiate START condition
  151.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  152.   if ( PIR2bits.BCLIF )           // test for bus collision
  153.   {
  154.     return ( -1 );                // return with Bus Collision error
  155.   }
  156.   else                            // start condition successful
  157.   {
  158.     if ( WriteI2C( dispositivo ) )    // write byte - R/W bit should be 0
  159.     {
  160.       return ( -3 );              // set error for write collision
  161.     }
  162.  
  163.     IdleI2C();                    // ensure module is idle
  164.     if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
  165.     {
  166.                 if ( WriteI2C( address ) )  // write word address for EEPROM
  167.         {
  168.                 return ( -3 );            // set error for write collision
  169.         }
  170.                         IdleI2C();                  // ensure module is idle
  171.                     if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  172.                     {
  173.                         if ( WriteI2C( data ) )   // data byte for EEPROM
  174.                                 {
  175.                           return ( -3 );          // set error for write collision
  176.                         }
  177.                     }
  178.                     else
  179.                     {
  180.                         return ( -2 );            // return with Not Ack error condition  
  181.                         }
  182.                
  183.     }
  184.     else
  185.     {
  186.         return ( -2 );              // return with Not Ack error condition  
  187.     }
  188.   }
  189.  
  190.   IdleI2C();                      // ensure module is idle  
  191.   StopI2C();                      // send STOP condition
  192.   while ( SSPCON2bits.PEN );      // wait until stop condition is over
  193.   if ( PIR2bits.BCLIF )           // test for bus collision
  194.   {
  195.     return ( -1 );                // return with Bus Collision error
  196.   }
  197.   return ( 0 );                   // return with no error
  198. }
  199. //
  200. //********************************************************
  201. //********************************************************
  202. //
  203. //              Inicializar DS1307
  204. //
  205. //********************************************************
  206. //********************************************************
  207. //
  208. unsigned char Inicializa_ds1307( unsigned char segundos,
  209.                                                                  unsigned char minutos,
  210.                                                                  unsigned char horas,
  211.                                                                  unsigned char dia,
  212.                                                                  unsigned char fecha,
  213.                                                                  unsigned char mes,
  214.                                                                  unsigned char ano,
  215.                                                                  unsigned char control)
  216. {
  217.   IdleI2C();                      // ensure module is idle
  218.   StartI2C();                     // initiate START condition
  219.   while ( SSPCON2bits.SEN );      // wait until start condition is over
  220.   if ( PIR2bits.BCLIF )           // test for bus collision
  221.   {
  222.     return ( -1 );                // return with Bus Collision error
  223.   }
  224.   else                            // start condition successful
  225.   {
  226.     if ( WriteI2C( dispositivo ) )    // write byte - R/W bit should be 0
  227.     {
  228.       return ( -3 );              // set error for write collision
  229.     }
  230.  
  231.     IdleI2C();                    // ensure module is idle
  232.     if ( !SSPCON2bits.ACKSTAT )   // test for ACK condition received
  233.         //*************************************************************************************
  234.     {
  235.                 if ( WriteI2C( 0X00 ) )  // write word address for EEPROM
  236.         {
  237.                 return ( -3 );            // set error for write collision
  238.         }
  239.                 //*************************************************************************************
  240.                 IdleI2C();                  // ensure module is idle
  241.             if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  242.             {
  243.                 if ( WriteI2C( segundos ) )   // data byte for EEPROM
  244.                         {
  245.                                 return ( -3 );          // set error for write collision
  246.                 }
  247.                         //*************************************************************************************
  248.                         IdleI2C();                  // ensure module is idle
  249.                     if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  250.                     {
  251.                         if ( WriteI2C( minutos ) )   // data byte for EEPROM
  252.                                 {
  253.                                         return ( -3 );          // set error for write collision
  254.                         }
  255.                                 //*************************************************************************************
  256.                                 IdleI2C();                  // ensure module is idle
  257.                             if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  258.                             {
  259.                                 if ( WriteI2C( horas ) )   // data byte for EEPROM
  260.                                         {
  261.                                                 return ( -3 );          // set error for write collision
  262.                                 }
  263.                                         //*************************************************************************************
  264.                                         IdleI2C();                  // ensure module is idle
  265.                                     if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  266.                                     {
  267.                                         if ( WriteI2C( dia ) )   // data byte for EEPROM
  268.                                                 {
  269.                                                         return ( -3 );          // set error for write collision
  270.                                         }
  271.                                                 //*************************************************************************************
  272.                                                 IdleI2C();                  // ensure module is idle
  273.                                             if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  274.                                             {
  275.                                                 if ( WriteI2C( fecha ) )   // data byte for EEPROM
  276.                                                         {
  277.                                                                 return ( -3 );          // set error for write collision
  278.                                                 }
  279.                                                         //*************************************************************************************
  280.                                                         IdleI2C();                  // ensure module is idle
  281.                                                     if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  282.                                                     {
  283.                                                         if ( WriteI2C( mes ) )   // data byte for EEPROM
  284.                                                                 {
  285.                                                                         return ( -3 );          // set error for write collision
  286.                                                         }
  287.                                                                 //*************************************************************************************
  288.                                                                 IdleI2C();                  // ensure module is idle
  289.                                                             if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  290.                                                             {
  291.                                                                 if ( WriteI2C( ano ) )   // data byte for EEPROM
  292.                                                                         {
  293.                                                                                 return ( -3 );          // set error for write collision
  294.                                                                 }
  295.                                                                         //*************************************************************************************
  296.                                                                         IdleI2C();                  // ensure module is idle
  297.                                                                     if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition received
  298.                                                                     {
  299.                                                                         if ( WriteI2C( control ) )   // data byte for EEPROM
  300.                                                                                 {
  301.                                                                                         return ( -3 );          // set error for write collision
  302.                                                                         }
  303.                                                                         }
  304.                                                                     else
  305.                                                                     {
  306.                                                                         return ( -2 );            // return with Not Ack error condition  
  307.                                                                         }
  308.                                                                 }
  309.                                                             else
  310.                                                             {
  311.                                                                 return ( -2 );            // return with Not Ack error condition  
  312.                                                                 }
  313.                                                         }
  314.                                                     else
  315.                                                     {
  316.                                                         return ( -2 );            // return with Not Ack error condition  
  317.                                                         }
  318.                                                 }
  319.                                             else
  320.                                             {
  321.                                                 return ( -2 );            // return with Not Ack error condition  
  322.                                                 }
  323.                                         }
  324.                                     else
  325.                                     {
  326.                                         return ( -2 );            // return with Not Ack error condition  
  327.                                         }
  328.                                 }
  329.                             else
  330.                             {
  331.                                 return ( -2 );            // return with Not Ack error condition  
  332.                                 }
  333.                         }
  334.                     else
  335.                     {
  336.                         return ( -2 );            // return with Not Ack error condition  
  337.                         }
  338.             }
  339.             else
  340.             {
  341.                 return ( -2 );            // return with Not Ack error condition  
  342.                 }
  343.     }
  344.     else
  345.     {
  346.         return ( -2 );              // return with Not Ack error condition  
  347.     }
  348.   }
  349.   IdleI2C();                      // ensure module is idle  
  350.   StopI2C();                      // send STOP condition
  351.   while ( SSPCON2bits.PEN );      // wait until stop condition is over
  352.   if ( PIR2bits.BCLIF )           // test for bus collision
  353.   {
  354.         return ( -1 );                // return with Bus Collision error
  355.   }
  356.   return ( 0 );                   // return with no error
  357. }

Veamos una descripción de las rutinas de esta libreria:

#define dispositivo 0xD0
Este codigo sirve sólo para el address device del chip ds1307, es decir su nombre o identifcación en la red I2C.

LeeDato_ds1307
Rutina que permite leer un byte de la memoria de datos del ds1307.
Sintaxis:
            unsigned int LeeDato_ds1307( unsigned char address )

Argumento de entrada:
address, refiere a la posición de memoria de que desea leer en el ds1307.

Argumento de salida:
retorna el valor del registro SPBUFF cargado con el byte leido, de lo contrario devolvera un valor negativo como consecuencia de un error durante la lectura.

LeeDatos_ds1307
Rutina que perimite leer una cantidad definida de bytes de la memoria de datos del ds1307.
Sintaxis:
            unsigned char LeeDatos_ds1307( unsigned char address, unsigned char *rdptr, unsigned char length )

Argumentos de entrada:
address, refiere a la posición de memoria de que desea leer en el ds1307.
*rdptr, es una cadena previamente definida en la memoria de datos del pic, en esta cadena se van a alojar los datos leidos desde el ds1307.
lenght, cantida dde bytes a leer, esta cantidad no puede ser mayor que la cantidad de elementos de la cadena donde se va a guardar la informacion.

Argumento de salida: retorna un valor 0 como resultado de una exitosa lectura, de lo contrario devolvera un valor negativo como consecuencia de un error durante la lectura.

Escribe_ds1307
Esta rutina permite escribir un byte a una posicion determinada de la memoria de datos del ds1307.
Sintaxis:
            unsigned char Escribe_ds1307( unsigned char address, unsigned char data )

Argumentos de entrada:
address, refiere a la posición de memoria de que desea escribir en el ds1307.
data, el byte que desea escribir en el ds1307.

Argumento de salida: retorna un valor 0 como resultado de una exitosa lectura, de lo contrario devolvera un valor negativo como consecuencia de un error durante la lectura.

Inicializa_ds1307
Esta rutina sirve para inicializar el ds1307, en ella se puede configurar la hora y la fecha y las opciones que provee el fabricante para este chip ds1307.
Sintaxis:
unsigned char Inicializa_ds1307( unsigned char segundos,
                                                unsigned char minutos,
                                                unsigned char horas,
                                                unsigned char dia,
                                                unsigned char fecha,
                                                unsigned char mes,
                                                unsigned char año,
                                                unsigned char control)


(http://img293.imageshack.us/img293/4538/10144696ez7.jpg)

Cada registro tiene su ubicacion segun la tabla de arriba, como pueden ver se trata de valores en codigo BCD, no olvidar los registros que poseen bits de configuracion.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 28 de Junio de 2007, 03:33:39
Programa de aplicacion
En el siguiente programa se implementará un circuito que mostrará a través de un LCD2x16 el tiempo referido por el ds1307.
(http://img412.imageshack.us/img412/935/83252143br4.jpg)

Código: C
  1. #include <p18f2525.h>
  2. #include <delays.h>
  3. #include <i2c.h>
  4. #include "C:\PIC\18F\RELOJ\ds1307.h"
  5. #include "C:\PIC\18F\RELOJ\LCD4b2x16.h"
  6. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  7. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  8. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  9. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  10. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  11. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  12. #pragma config CPB = ON,CPD = ON//CONFIG5H
  13. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  14. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  15. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  16. #pragma config EBTRB = ON//CONFIG7H
  17.  
  18. #define reloj   PORTBbits.RB0
  19. int caracter,temp;
  20. unsigned char cadena[8];
  21.  
  22. void Mostrar_LCD (unsigned char caracter)
  23. {
  24.    temp = (caracter >> 4)| 0x30;
  25.    Dato_LCD(temp);
  26.    temp = (caracter & 0X0F)| 0x30;
  27.    Dato_LCD(temp);
  28.    Dato_LCD(' ');
  29. }
  30.  
  31. void main(void)
  32. {
  33.    //inicializar puertoA
  34.    //todos los pines
  35.    //seran digitales
  36.    PORTA = 0X00;
  37.    LATA = 0X00;
  38.    ADCON0 = 0X00;
  39.    ADCON1 = 0X0F;
  40.    CMCON = 0X07;
  41.  
  42.    TRISA = 0X00;
  43.    TRISB = 0X01;
  44.    TRISC = 0X18;
  45.    LATA = 0X00;
  46.    LATB = 0X00;  
  47.    LATC = 0X00;  
  48.    Delay1KTCYx(250);  
  49.    Inicializa_LCD();
  50.    Comando_LCD(CURSOR_OFF & BLINK_OFF);
  51. //*******************************************************
  52. //   configuración del modulo i2c
  53. //*******************************************************
  54.    OpenI2C(MASTER,SLEW_OFF);//inicializo modulo
  55.    SSPADD = 9;//100KHz para 4MHz
  56. //*******************************************************
  57. //   configuración del reloj y calendario
  58. //*******************************************************
  59.    Inicializa_ds1307(   0X07,//segundos + ch
  60.                   0X18,//minutos
  61.                   0X45,//horas + configuracion AM/PM
  62.                   0X05,//dia
  63.                   0X07,//fecha
  64.                   0X03,//mes
  65.                   0X81,//año
  66.                   0X10);//control
  67. //*******************************************************
  68. //*******************************************************
  69.    Comando_LCD(0x80);
  70.    Datos_LCD("Hora :");
  71.    Comando_LCD(0xC0);
  72.    Datos_LCD("Fecha:");
  73.  
  74.    LeeDatos_ds1307(0x04,cadena,3);
  75.    Comando_LCD(0xC7);
  76.    Mostrar_LCD(cadena[0]);
  77.    Mostrar_LCD(cadena[1]);
  78.    Mostrar_LCD(cadena[2]);
  79.  
  80.    for(;;)
  81.    {
  82.       if(reloj==1)  
  83.       {
  84.          LeeDatos_ds1307(0x00,cadena,3);
  85.          Comando_LCD(0x87);
  86.          Mostrar_LCD(cadena[2] & 0x1F);
  87.          Mostrar_LCD(cadena[1]);
  88.          Mostrar_LCD(cadena[0] & 0x7F);
  89.          while(reloj==1);
  90.       }
  91.    }
  92. //*******************************************************
  93. //*******************************************************
  94. }

todos los archivos: h**p://www.box.net/shared/1p7re3zpvj
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 28 de Junio de 2007, 10:32:32
Bueno, hasta ahi dejaremos de analizar las características del pic para meternos de lleno en un proyecto con el C18 y asi repasar todo lo que hemos aprendido (yo también  :mrgreen:), la inicitiva es la de hacer un panel de leds que muestre la hora jalando dichos datos desde un ds1307.

La verdad que en este momento no se me ocurre mucho jiji, asi que... como todo va a ser simulado vamos primero por hacer arrancar el panel, de eso si tengo información, un amigo Electronando me recomendó usar columnas por desplazamiento con el 4094 que son registros de desplazamiento con latch, y habilitar por las filas. Como se trata simplemente de algo que va a mostrar la hora pues quisiera hacerlo de dos filas donde cada fila sera de 7x32, me imagino que ahi debe entrar la hora y si se puede la fecha del calendario  :-/, hasta se le puede poner alarmas.... jjeje mi cerebro comienza a alucinar..... bueno pero todo sera simulado en el proteus 7.1 y si alguein se anima a armarlo (si es que lo terminamos jijij) pues... sería bacan aunque tengo que la certeza que mi amigo  :twisted:Kedutpic:twisted: de hecho va a quererselo armar con su pic.

Entonces manos a la obra con los paneles....
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 29 de Junio de 2007, 10:20:14
 :D me descubristes ya estaba implementandolo para las pruebas jajajjaja  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 29 de Junio de 2007, 16:54:53
 :mrgreen: FUNCIONA !!!!  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 01 de Julio de 2007, 12:25:01
le menu d'aujourd'hui :
Reloj con Panel de Leds 2x32

ingrédients:

Acá la foto del plato listo para servir (simular  :mrgreen:)
(http://img65.imageshack.us/img65/345/40168655wc0.jpg)

Ahora lo que sigue es la programación. Es posible que algo cambie durante este proceso, no os preocupeis, las imágenes luego serán actualizadas.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 05 de Julio de 2007, 13:35:27
bueno, he modificado en algo el hardware, ya actualize las imágenes, iniciaremos por el hardware... aun estoy definiendo como explicarlo, no es nada complicado,  :mrgreen: se van a sorprender de la simpleza.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 05 de Julio de 2007, 13:41:14
eh, micro con tanto componente se va poner lento el proteus  8)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 05 de Julio de 2007, 13:56:58
si amigo, se pone lag pero depende del cristal del pic y de la cantidad de componentes, aunque te comento que en una Pentium4 a 1.8GHz memoria ram 512M, pues se llega a ver ok y no se cuelga para nada. pero si se pone a 100% aunque estaba con varios programas activos y escuchando a los Beatles  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 06 de Julio de 2007, 00:47:08
Bueno ya hemos hablado mucho sobre el PIC18F2525, y tambien sobre DS1307, toca hablar del 4094.

El integrado CD4094
Si revisamos su respectivo datasheet, observaremos que es un registro de desplazamiento serial de un solo sentido (se desplaza comenzando por el bit de menor peso) de 8 bits, con la particularidad de que posee un 3 estado (hi-z o alta impedancia) , y un latch que le permite cargar valores sin modificar la salida actual, gracias a la entrada STROBE.

En resumen, estamos usando el clock, el data y el strobe para controlar estos chips. Luego los estamos concatenando uno tras otro con su pin Q, que es el ultimo bit del latch de cada registro, y lo estamos mandando al data del siguiente chip.


Los 2 Paneles de Leds
Cada panel esta formado por 7 filas x 32 columnas, donde cada CD4094 se encarga de 8 columnas del panel. Las filas son disparadas directamente desde los pines del puerto B. Obviamente hay una gran diferencia entre la realidad y el simulador en lo que respecta a implementar un panel de leds, asi que no vayan a armarlo asi como esta en el simulador  :mrgreen: se debe tener en cuenta cosas como la potencia de los leds, su consumo, arreglos para la corriente d elos paneles, etc.


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Duende_Azul en 06 de Julio de 2007, 01:30:23
Tengo la siguiente duda:

Quiero hacer un retardo de 1seg;  dispongo de un cristal de 10MHz y según los ejemplos del manual del C18 el cálculo seria así:

cycles = (delay_time * Fosc)/4

y ese valor es el que se coloca en una de las instrucciones delayXTCYx(cycles)...

en uno de los ejemplos ponen que para obtener 5ms de retardo con un cristal de 16MHz, el número de cycles es:

cycles = (5ms * 16MHz)/4 ; multiplicando ms * MHz  :shock:  queda:
cycles = (5*E-3 * 16E+6)/4 = 20.000

y la instrucción quedaria:  Delay1KTCYx(20);   y eso es un retardo de 5ms

Ahora, siguiendo este procedimiento tengo que para 1 seg con un cristal de 10MHz sería:

cycles = (1000ms * 10MHz)/4
cycles = (1000E-3 * 10E+6)/4
cycles = 2.500.000

la instrucción sería:  Delay10KTCYx(250);    //es decir 250*10.000 = 2.500.000  => 1seg

EL asunto es que cuando simulo esto en proteus el tiempo es de 1.33 seg  y no 1 seg.

Si hago en CSS  delay_ms(1000)  la simulación me da 1 seg clavado.

La pregunta es: ¿estoy haciendo algo mal?


Código: [Seleccionar]
// Cristal 10MHz
#include <p18f452.h>
#include <stdio.h>
#include <delays.h>

#pragma config OSC=HS
#pragma config WDT = OFF
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config LVP=OFF

int i;

void main(){
TRISB =0;    //Puerto b como salidas
PORTB =0;
while (1){
Delay10KTCYx(250); //Retardo de 1 seg; con 189 si da 1 seg
    PORTB = !PORTB;  //Cambia estado del puerto
}
}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 06 de Julio de 2007, 09:28:19
hola he probado tu codigo en el MPLABSIM y si da 1seg clavadito segun el grafico,
(http://img263.imageshack.us/img263/6577/40877784md6.jpg)

ahora en el proteus pues ... tambien veo 1.33seg.

Hay cosas que suceden en el proteus que no entiendo tampoco, debe ser algun problemilla bug con el compilador, aunque en la realidad si se cumplen los tiempos, asi como en el MPLABSIM.

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 06 de Julio de 2007, 11:07:42
offtopic:

...
ahora en el proteus pues ... tambien veo 1.33seg.

Hay cosas que suceden en el proteus que no entiendo tampoco, debe ser algun problemilla bug con el compilador, aunque en la realidad si se cumplen los tiempos, asi como en el MPLABSIM.
...

ese detalle lo había oido antes, los tiempos, ahora pregunto: ¿restaste el tiempo anterior? y debe ser al ejecutar la siguiente línea, es decir, pones 2 breakpoints y al detenerte en el primero anotas el tiempo transcurrido. Luego te paras en el segundo break y ese tiempo le restas el anterior.

no olvidarse de poner la frec. del cpu del micro

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Duende_Azul en 06 de Julio de 2007, 15:07:32
He hecho unas pruebitas para no quedarme con la duda.

Compile el ejemplo de los 5ms en C18, lo simule en proteus y lo medi en un osciloscopio, luego hice lo mismo pero con CCS y los resultados que obtuve fueron estos:

Programa con 5ms de retardo:

C18:
Proteus:    7.96ms
Osciloscopio:  8ms   :?

CCS:
Proteus:  5ms
Osciloscopio: 5ms


Conclusión:  EL compilador perfecto no existe  :x
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 06 de Julio de 2007, 15:32:12
vaya de 5 a 8ms gran diferencia....
podrias subir tu codigo para mirar y ver esa falla del compilador? a eso llamo un bug.  :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 07 de Julio de 2007, 02:47:01
He hecho unas pruebitas para no quedarme con la duda.

Compile el ejemplo de los 5ms en C18, lo simule en proteus y lo medi en un osciloscopio, luego hice lo mismo pero con CCS y los resultados que obtuve fueron estos:

Programa con 5ms de retardo:

C18:
Proteus:    7.96ms
Osciloscopio:  8ms   :?

CCS:
Proteus:  5ms
Osciloscopio: 5ms


Conclusión:  EL compilador perfecto no existe  :x

bueno no hay que llegar a conclusiones aun , como henry dijo seria interesante que subas tu codigo para poder revisarlo con mayor detenimiento, y asi poder llegar a una solucion ,pero a mi me parece mucha la diferencia de 5ms a 8ms  :?.

Bueno yo tambien voy a realizar las pruebas , para verificar lo que tu estas afirmando .... asi que me pongo manos a la obra :)

PD : HENRY  ya tienes tarea que hacer :P
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 07 de Julio de 2007, 02:54:41
debido a mi bendita curiosidad quise verificar primero lo del proteus con 5ms, pues hice esto:
el codigo para xtal=10MHz:
(http://img149.imageshack.us/img149/1484/87298165xt0.jpg)
no hacer caso a los comentarios, pues habia modificado el codigo anterior del ejercicio de la primera pagina de este hilo.

el proteus:
(http://img353.imageshack.us/img353/9688/27447893xu1.jpg)

y los resultados:
(http://img75.imageshack.us/img75/1150/66015809id6.jpg)

Solo me quedaria ver en el osciloscopio, pero recien podre verlo el lunes, amigo DuendeAzul.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 07 de Julio de 2007, 02:58:31
un detalle mas, revisa tu codigo usando LATx.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Duende_Azul en 07 de Julio de 2007, 08:40:45
Revisando y revisando me he dado cuenta de que meti la pata hasta el fondo con lo que puse anteriormente  :? , en Proteus no habia cambiado la frecuencia a 16MHz, la deje en 10MHz y por eso la diferencia de 3ms. segui probando y al parecer la rutina Delay10KTCYx(cycles) es la que no da los valores correctos; 1000mSeg dan 1330mSeg, 300mSeg me dan 399mSeg, 252mSeg me dan 335mSeg.  Solo faltaria comprobar esto en un osciloscopio pero esa frecuencia tan baja no se ve bien en el que tengo.

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 07 de Julio de 2007, 10:34:15
Ah claro que si, debeis verificar antes de postear pero bueno gracias por tu auto-aclaracion, dejame decirte que yo me guio fielmente por los valores que bota el mplabSIM ahora, hay que tomar en cuenta los retardos en caso de usar LATx y PORTx,  y asi pes, pero bueno, ya todo esta resuelto para bien.

Otra cosa, es cierto que no hay compilador perfecto, nadie ha dicho que lo sea el C18, simplemente que como el C18 no es muy usado por la gente del foro " aun " no han aparecido dichos bugs (porque de que hay los hay), y siempre habrán caminos alternativos para evitar dichos bugs, en resumen, A SEGUIR DANDOLE AL C18!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 10 de Julio de 2007, 02:08:59
La Matriz de Leds 7x64
Esta matriz de leds constituye el mejor looking para muchos proyectos que podamos tener en mente, lo malo es su coste de implementación, pues el precio oscila según la calidad de led que se use, además del driver o circuiteria de potencia que en esta versión simulada no estará presente, pues en el proteus no es necesario  :mrgreen:.

Existen muchos fundamentos que ignoro en relación al tiempo óptimo de encendido y apagado del panel, aunque ya se ha hablado mucho sobre esto en varios hilos dentro del foro TODOPIC, es cuestión del interesado en recopilar dicha información, nuestro objetivo es simplemente desarrollar una aplicación para practicar el compilador C18.

Análisis in profundix:
Imaginen 7 registros constituidos por 8 bytes cada uno, si lo graficamos sería algo asi:

     1                 2                 3                4                5                 6                7                8   
00000000    00000000    00000000    00000000    00000000    00000000    00000000    00000000    Reg1
00000000    00000000    00000000    00000000    00000000    00000000    00000000    00000000    Reg2
00000000    00000000    00000000    00000000    00000000    00000000    00000000    00000000    Reg3
00000000    00000000    00000000    00000000    00000000    00000000    00000000    00000000    Reg4
00000000    00000000    00000000    00000000    00000000    00000000    00000000    00000000    Reg5
00000000    00000000    00000000    00000000    00000000    00000000    00000000    00000000    Reg6
00000000    00000000    00000000    00000000    00000000    00000000    00000000    00000000    Reg7

Ahora, esto mismo para el C18:
Código: C
  1. unsigned char panel[7][8] = { 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
  2.                               0X4E,0XAE,0XEE,0X00,0X00,0X00,0X00,0X00,
  3.                               0XC2,0XA2,0X8A,0X44,0X00,0X00,0X00,0X00,
  4.                               0X4E,0XEE,0XEE,0X00,0X00,0X00,0X00,0X00,
  5.                               0X48,0X22,0X22,0X44,0X00,0X00,0X00,0X00,
  6.                               0X4E,0X2E,0XE2,0X00,0X00,0X00,0X00,0X00,
  7.                               0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00};
Observemos que se trata nada más que de una simple matriz 7x8  :-), ahora, con un simple indexado dentro de la matriz podriamos escribir dentro de ella:

panel[2][1] = 0x00;

Y así dibujar en la matriz algún caracter o figura que deseemos mostrar en el panel de leds, esa es la manera en que vamos a atacar la matriz con el programa escrito para el C18, no obstante debido a que se trata de 2 paneles simplemente lo he partido en 2:
Código: C
  1. unsigned char panel[7][4] = { 0X00,0X00,0X00,0X00,
  2.                               0X4E,0XAE,0XEE,0X00,
  3.                               0XC2,0XA2,0X8A,0X44,
  4.                               0X4E,0XEE,0XEE,0X00,
  5.                               0X48,0X22,0X22,0X44,
  6.                               0X4E,0X2E,0XE2,0X00,
  7.                               0X00,0X00,0X00,0X00};
  8.  
  9. unsigned char mensaje[7][4] = { 0X00,0X00,0X00,0X00,
  10.                               0X4E,0XAE,0XEE,0X00,
  11.                               0XC2,0XA2,0X8A,0X44,
  12.                               0X4E,0XEE,0XEE,0X00,
  13.                               0X48,0X22,0X22,0X44,
  14.                               0X4E,0X2E,0XE2,0X00,
  15.                               0X00,0X00,0X00,0X00};
Ahora, debido al hardware que hemos implementado la forma de dibujar en el panel es la siguiente:

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 10 de Julio de 2007, 10:28:39
Entonces siguiendo este razonamiento sucedería lo siguiente al momento de escribir en el panel, digamos que tengo el siguiente mensaje dibujado:
(http://img401.imageshack.us/img401/871/42586050qk5.jpg)

Ahora veamos como lo está haciendo el programa pero en camara lenta....
Para la fila 1:
(http://img518.imageshack.us/img518/6751/94172462fx1.jpg)
Para la fila 2:
(http://img338.imageshack.us/img338/273/75791842eh7.jpg)
Para la fila 3:
(http://img378.imageshack.us/img378/1787/62242892ho2.jpg)
Para la fila 4:
(http://img261.imageshack.us/img261/7001/82304003vn1.jpg)
Para la fila 5:
(http://img361.imageshack.us/img361/5374/93884636es1.jpg)
Para la fila 6:
(http://img504.imageshack.us/img504/690/10125116qn8.jpg)
Para la fila 7:
(http://img505.imageshack.us/img505/8459/61870405gn3.jpg)

Donde cada fila tiene un retardo que puede ser digamos de 10mseg (estos tiempos no se definirlos bien, solo lo hago por prueba y fallo) luego tendriamos que el tiempo para escribir todo el panel sería de 70mseg + algunos useg de las instrucciones del pic, finalmente volver a hacer todo el bucle infinitamente.

Asi se consigue el efecto de un panel de leds, dibujando por las columnas y habilitando por las filas.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: manex_1987 en 11 de Julio de 2007, 08:14:03
Buenas

Yo tambien me he pasado al c18. Visto lo efectivo de las librerias de c18 (ni xlcd.h ni adc.h acaban de convencerme), os pongo una modificacion de xlcd.h, basandome en otras libs: 

**No olvideis definir en el programa principal las funciones de retardo, que segun la frecuencia, pueden variar:
 void Delay1u();
 void Delayms(char n);
**

Código: [Seleccionar]
#define lcd_type 2
#define lcd_line_two 0x40
#define tris_write 0x00
#define tris_read 0xF0
//Interfaz 4 bits, datos en nibble superior.
#define LCD_E PORTDbits.RD0
#define LCD_RS PORTDbits.RD1
#define LCD_RW PORTDbits.RD2
#define LCD_TRIS TRISD
#define LCD_PORT PORTD

char const INIT[4]={0x20|(lcd_type<<2),0x0c,1,6};
extern void Delay1u();
extern void Delayms(char n);

char lcd_read_byte();
void lcd_send_nibble(char n);
void lcd_CmdData(char opt,char n);
void lcd_init();
void lcd_gotoxy(char x,char y);
void lcd_putc(char c);

char lcd_read_byte()
{
char lo,hi;
LCD_TRIS=tris_read;
LCD_RW=1;
Nop();
LCD_E=1;
Nop();
hi=LCD_PORT&0xF0;
LCD_E=0;
Nop();
LCD_E=1;
Delay1u();
Delay1u();
lo=(LCD_PORT>>4)&0x0F;
LCD_E=0;
LCD_TRIS=tris_write;
return(hi|lo);
}

void lcd_send_nibble(char n)
{
LCD_PORT&=0x0F;
LCD_PORT|=((n&0x0F)<<4);
Nop();
Delay1u();
LCD_E=1;
Delay1u();
LCD_E=0;
}

void lcd_CmdData(char opt,char n)
{
LCD_RS=0;
while((lcd_read_byte()|0x7F)==0xFF);
LCD_RS=opt;
Nop();
LCD_RW=0;
Delay1u();
LCD_E=0;
lcd_send_nibble(n>>4);
lcd_send_nibble(n);
}

void lcd_init()
{
char i;
LCD_TRIS=tris_write;
LCD_RS=0;
LCD_RW=0;
LCD_E=0;
Delayms(5);
for(i=1;i<=3;++i)
{
lcd_send_nibble(3);
Delayms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_CmdData(0,INIT[i]);
}

void lcd_gotoxy(char x,char y)
{
char addr;
if(y==1)
{
addr=0x00;
}
else
{
addr=0x40;
}
addr+=x-1;
lcd_CmdData(0,0x80|addr);
}

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

Recordar tambien, que mediante la funcion fprintf (stdio.h) podemos printefear un string con formato.

Para ello, definiremos una funcion

Código: [Seleccionar]
void _user_putc(char c)
{
    lcd_putc(c);
}

y luego invocaremos fprintf, de la forma  fprintf(_H_USER,"Mi texto %d %d",num1,num2);


Espero que sirva de algo el aporte.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 11 de Julio de 2007, 11:18:53
excelente aporte manex  :-/ :-/ :-/ :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 11 de Julio de 2007, 13:52:09
una duda micro, ¿el barrido del dibujo se hace por filas o por columnas?

Cita de: micro_cadaver
...dibujando por las columnas y habilitando por las filas
...

tendrá el mismo efecto dibujando al contrario, es decir, dibujando por filas y habilitando por columnas

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 11 de Julio de 2007, 15:25:55
claro que si, son caminos distintos de hacer lo mismo. :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: caldono en 12 de Julio de 2007, 12:38:47
Hola, soy nuevo en este foro me interesa este cuento de la programacion en C quiero saber si es posible con el C18 ó el C30 programar micros de la serie 16F
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 12 de Julio de 2007, 14:17:14
hola amigo, el C30 solo sirve para la gama dspic, el C18 para la gama 18FXXXX, y nada mas.

Para la gama 16FXXX hay otros compiladores por ejemplo CCS (muy usado en el foro), HITECH PICC, MIkroC, y.. algunos más que ignoro.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 23 de Julio de 2007, 03:12:42
seguimos...

Lo primero es definir los pines que se va a utilizar en la aplicación.
Código: C
  1. #define reloj   PORTBbits.RB0
  2. //pin de entrada que recibira los pulsos del ds1307
  3. //con lo cual actualizara el panel cada 2 segundos (segun el proteus)
  4.  
  5. #define datos_4094              LATCbits.LATC0
  6. #define reloj_4094              LATCbits.LATC1
  7. #define habilita_4094           LATCbits.LATC2
  8. //estos son los pines de control de los 4094
  9.  
  10. #define fila_1  LATBbits.LATB1
  11. #define fila_2  LATBbits.LATB2
  12. #define fila_3  LATBbits.LATB3
  13. #define fila_4  LATBbits.LATB4
  14. #define fila_5  LATBbits.LATB5
  15. #define fila_6  LATBbits.LATB6
  16. #define fila_7  LATBbits.LATB7
  17. //estos son los disparos de las 7 filas del panel

Como se puede apreciar quedan muchos pines libres, lo cual permite usar un PIC de menor tamaño o sino agregarle más características.

Y que va a hacer esto?
Primero configuraremos el ds1307 con la hora deseada y setearemos el disparo de pulsos a 4.096Khz (en el proteus esto me mide 2.048..KHz), luego esta salida la conectaremos al pin de entrada RB0 y utilizaremos su interrupcion por flanco para determinar el momento en que llega a 1 segundo y con un banderin actualizamos el panel leyendo el contenido del DS1307 (en el proteus esto lo hace cada 2 segundos). Entonces el panel estará partido en 2 mitades, en los primeros 32 estará el reloj y en los otros 32 estará un mensaje predeterminado. Ahora veamos el codigo por partes, asi entenderemos mejor el uso y aplicación de todas las instrucciones del C18.


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 23 de Julio de 2007, 03:57:22
Encabezado Principal
Todo programa comienza con su encabezado, en esta parte se tiene que mencionar las librerias que vamos a utilizar, los bits de configuración (fuses) y las definiciones de los pines que se utilizará (opcional).
Código: C
  1. #include <p18f2525.h>
  2. //libreria para el pic18f2525
  3. #include <delays.h>
  4. //libreria para los retardos
  5. #include <i2c.h>
  6. //libreria para uso y configuracion del modulo I2C
  7. #include "C:\PIC\18F\RELOJ PANEL\ds1307.h"
  8. //libreria del reloj digital DS1307 se puede poner tambien solo #include "ds1307.h"
  9. pero decidi dejarlo asi para que se entienda de donde viene esta libreria
  10.  
  11. //bits de configuracion, hay otras maneras de hacerlo, esta es una de las tantas
  12. #pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
  13. #pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
  14. #pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
  15. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
  16. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
  17. #pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
  18. #pragma config CPB = ON,CPD = ON//CONFIG5H
  19. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
  20. #pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
  21. #pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
  22. #pragma config EBTRB = ON//CONFIG7H
  23.  
  24. //definicion de los pines de la aplicacion
  25. #define reloj   PORTBbits.RB0
  26. #define datos_4094              LATCbits.LATC0
  27. #define reloj_4094              LATCbits.LATC1
  28. #define habilita_4094   LATCbits.LATC2
  29.  
  30. #define fila_1  LATBbits.LATB1
  31. #define fila_2  LATBbits.LATB2
  32. #define fila_3  LATBbits.LATB3
  33. #define fila_4  LATBbits.LATB4
  34. #define fila_5  LATBbits.LATB5
  35. #define fila_6  LATBbits.LATB6
  36. #define fila_7  LATBbits.LATB7

Configuracion de Puertos
Utilizaremos la siguiente configuracion:
Código: C
  1. void main(void)
  2. {
  3.         //inicializar puertoA todos los pines seran digitales
  4.         PORTA = 0X00;ADCON0 = 0X00;
  5.         ADCON1 = 0X0F;CMCON = 0X07;
  6.  
  7.         TRISA = 0X00;TRISB = 0X01;TRISC = 0X18;
  8.         LATA = 0X00;LATB = 0X00;LATC = 0X00;   
  9.         //PORTA como salida
  10.         //PORTB como salida a excepion del RB0 que sera entrada
  11.         //PORTC salida menos los pines del modulo I2C que los pondremos como entrada
  12.  
  13.         Delay10KTCYx(250);     
  14.         //retardo= 250 * 10 000 * (4/fosc)  = 25 * 10^5 * (4/(4*10^6)) = 2.5 segundos


Configuración del Módulo I2C
Vamos a configurar el DS1307, pero antes se inicializa el módulo I2C del PIC.
Código: C
  1. //*******************************************************
  2. //      configuracion del modulo i2c
  3. //*******************************************************
  4.         OpenI2C(MASTER,SLEW_OFF);//inicializo modulo
  5.         SSPADD = 9;//100KHz para 4MHz
  6. //*******************************************************
  7. //      configuracion del reloj y calendario
  8. //*******************************************************
  9.         Inicializa_ds1307( 0X00, //segundos + ch
  10.                            0X03, //minutos
  11.                            0X52, //horas + configuracion AM/PM
  12.                            0X07, //dia
  13.                            0X01, //fecha
  14.                            0X07, //mes
  15.                            0X07, //year
  16.                            0X11); //control


La Interrupción del RB0
La característica de interrupción del pin RB0 tendrá un flanco de subida para la activación de la interrupción, en su respectiva zona de interrupción habrá un registro que permitirá conocer cuando llega a 1 segundo gracias a los pulsos de 4.096Khz que vienen de la salida del ds1307.
El contador efectuará la siguiente ecuación: (1/f reloj) * 4096 = (1/4096Hz)(4096) = 1 segundo
Código: C
  1. void interrupciones(void);//prototipo de la funcion "interrupciones"
  2.  
  3. //
  4. //******************************************************//
  5. //      Vector de Interrupcion
  6. //******************************************************//
  7. //
  8. #pragma code prioridad_nomal = 0X0008
  9. //vector para las interrupciones en modo compatible con las 16Fxxx
  10. //o mejor dicho, interrupciones sin prioridades
  11.  
  12. void interrupcion_normal (void)
  13. {
  14.         _asm goto interrupciones _endasm
  15. }
  16. #pragma code
  17. //fin de la interrupcion (retfie en el ASM)
  18.  
  19. //
  20. //******************************************************//
  21. //      Rutina de Interrupcion
  22. //******************************************************//
  23. //
  24. #pragma interrupt interrupciones
  25. //funcion "interrupciones"
  26. void interrupciones(void)
  27. {
  28.         if(INTCONbits.INT0IF) //pregunta por bandera de interrupcion
  29.         {
  30.                 ct_reloj--;
  31.                 if(ct_reloj==0)
  32.                 {
  33.                         ct_reloj=0x1000; //0x1000 = D'4096'
  34.                         marcador=0;
  35.                 }
  36.                 INTCONbits.INT0IF = 0;  //limpia bandera y salimos
  37.         }
  38. }

Luego se coloca los bits que configuran a la interrupcion
Código: C
  1. //*******************************************************
  2. //      inrterrupcion del pin RB0
  3. //*******************************************************
  4.         RCON = 0X00; //IPEN = 0 interrupciones sin prioridades
  5.         INTCON = 0X90; //configuramos la interrupcion externa del RB0
  6.         INTCON2 = 0X40; //configuramos el flanco de subida para la interrupcion
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 23 de Julio de 2007, 05:57:58
Datos en la Memoria RAM
Muchos de los procesos para el manejo del panel tienen su apoyo en registros de propósito general ubicados en esta memoria del PIC, vamos a detallar los registros, tablas y matrices que usamos en el C18. Se puede definir su tipo y también si poseen un valor inicial.

Código: C
  1. unsigned int temp,marcador=0xff;
  2. //tipo: entero sin signo, registros de 16bits
  3.  
  4. unsigned char cadena[8],numeros,i,j,k;
  5. //tipo: caracter sin signo, registros de 8 bits
  6. //cadena[8]: arreglo de 8 registros tipo unsigned char
  7. //se lee: array "cadena" tiene 8 elementos de 8 bits cada uno
  8.  
  9. volatile unsigned int ct_reloj=0x1000,ct_panel=41,caracter=0;
  10. //tipo: volatil entero sin signo, registros de 16bits utilizados dentro y fuera
  11. //de las interrupciones, de preferencia solo usarse dentro de las interrupciones

Hemos implementado unas tablas de valores que poseen la codificación de cada numero en el panel, del 0 al 9, y están ubicados desde la posicion de memoria 0x100 de la RAM. Tienen un orden tipo matriz de 7 filas por 2 columnas de tal manera que sea fácil su adquisición durante el proceso de actualizar el panel al leer el ds1307.

Como pueden notar, estamos usando la directiva #pragma para ubicar el contenido de la RAM en una posicion definida por nosotros de la siguiente manera:

#pragma idata tablas = 0X100
           //
           //registros inicializados
           //
#pragma idata

Código: C
  1. //
  2. //******************************************************//
  3. //      Ubicacion de tabla inicializada en RAM 0X100
  4. //******************************************************//
  5. //
  6. #pragma idata tablas = 0X100
  7. unsigned char numero_0[7][2] = {0X00,0X00,
  8.                                 0XE0,0X0E,
  9.                                 0XA0,0X0A,
  10.                                 0XA0,0X0A,
  11.                                 0XA0,0X0A,
  12.                                 0XE0,0X0E,
  13.                                 0X00,0X00};    
  14.  
  15. unsigned char numero_9[7][2] = {0X00,0X00,
  16.                                 0XE0,0X0E,
  17.                                 0XA0,0X0A,
  18.                                 0XE0,0X0E,
  19.                                 0X20,0X02,
  20.                                 0X20,0X02,
  21.                                 0X00,0X00};    
  22. #pragma idata

De la misma forma tendremos la organización en la RAM de los valores que se imprimiran en el panel de leds, observen las matrices "fila_reloj" y "fila_mensaje", ambos están ordenados en 7 filas por 4 columnas, si las juntamos llenarian el panel 7 x 32 bits, donde cada columna de las matrices incluye a 8 bits. También esta definida a partir de la posición 0x400.

Código: C
  1. #pragma idata panel = 0X400
  2. unsigned char fila_reloj[7][4] = {0X00,0X00,0X00,0X00,
  3.                                   0X4E,0XAE,0XEE,0X00,
  4.                                   0XC2,0XA2,0X8A,0X44,
  5.                                   0X4E,0XEE,0XEE,0X00,
  6.                                   0X48,0X22,0X22,0X44,
  7.                                   0X4E,0X2E,0XE2,0X00,
  8.                                   0X00,0X00,0X00,0X00};
  9.  
  10. unsigned char fila_mensaje[7][4] = {0X00,0X00,0X00,0X00,
  11.                                     0XEE,0XEA,0XEE,0X4E,
  12.                                     0XA8,0XAA,0X2A,0XCA,
  13.                                     0XEE,0XEA,0XEA,0X4A,
  14.                                     0X88,0XCA,0X8A,0X4A,
  15.                                     0X8E,0XAE,0XEE,0X4E,
  16.                                     0X00,0X00,0X00,0X00};
  17. #pragma idata

Lo cual permite vislumbrar la manera en que cargaremos los valores en el panel de leds.

(http://img72.imageshack.us/img72/8646/62552828ye9.jpg)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 27 de Julio de 2007, 10:31:28
Estructura Principal
Este es el proceso que está dentro del main desde la cual se llamarán a las distintas funciones que hemos programado para el manejo del panel. Observen que un bucle infinito while(1) domina a todo el proceso, dentro de él estan el manejo de panel encargado por la función " cargar_filas(); " , y la actualización del reloj leyendo cada 1 seg (en el proteus me sale cada 2seg) el chip ds1307.
Código: C
  1. while(1)
  2.         //bucle infinito que domina todo el proceso.
  3.         {
  4.                 cargar_filas();
  5.                 //funcion que escribe la matriz de registros sobre el panel
  6.                 //cada fila tiene un retardo de 5mseg, entonces como son
  7.                 //7 filas esta funcion se toma 35mseg pero más los procesos
  8.                 //de desplzamiento y busqueda, se toma 54mseg.
  9.  
  10.                 if(marcador==0)
  11.                 //registro bandera que indica el momento de actualizar
  12.                 //cada 1 seg (en proteus 2seg), es puesto a cero desde la
  13.                 //interrupcion en RB0.
  14.                 {
  15.                         marcador=0xff;
  16.                         //volvemos a cargar el registro para una posterior espera.
  17.  
  18.                         LeeDatos_ds1307(0x00,cadena,3);
  19.                         //lectura de los registros de ds1307 que corresponden a los
  20.                         //segundos, minutos, hora, y los guarda en "cadena".
  21.  
  22.                         numeros=cadena[0];j=2;//apunta al valor segundos
  23.                         actualiza_filas();//carga en matriz panel
  24.  
  25.                         numeros=cadena[1];j=1;//apunta al valor minutos
  26.                         actualiza_filas();//carga en matriz panel
  27.  
  28.                         numeros=(cadena[2] & 0x1F);j=0;//apunta al valor hora
  29.                         actualiza_filas();//carga en matriz panel
  30.                 }
  31.         }


Función cargar_filas
Esta es la función que permite visualizar el contenido de la matriz panel sobre los leds del panel, haciendo todo el proceso de desplzamiento serial a través de los CD4094, habilitando su correspondiente fila por el portB, y también incluido está el mensaje previamente definido en su respectiva matriz.
Código: C
  1. //
  2. //******************************************************//
  3. //      Funcion cargar filas
  4. //******************************************************//
  5. //
  6. void cargar_filas(void)
  7. {
  8.         for(i=0;i<=6;i++) //i : indice para las filas del panel
  9.         {
  10.                 j=3; //j : columnas del panel
  11.                 for(k=0;k<=3;k++) //k : indice para el bucle for
  12.                 {
  13.                         desplaza_filas(fila_mensaje[i][j]); //funcion de desplazamiento
  14.                         j--;
  15.                 }
  16.  
  17.                 j=3; //j : columnas del panel
  18.                 for(k=0;k<=3;k++) //k : indice para el bucle for
  19.                 {
  20.                         desplaza_filas(fila_reloj[i][j]); //funcion de desplazamiento
  21.                         j--;
  22.                 }
  23.  
  24.                 //deshabilitamos las filas del panel
  25.                 //y cargamos el desplazamiento en las
  26.                //salidas de los CD4094
  27.                 LATB=0XFF;
  28.                 Nop();
  29.                 Nop();
  30.                 habilita_4094=1;
  31.                 Nop();
  32.                 Nop();
  33.                 habilita_4094=0;
  34.                 Nop();
  35.                 Nop();
  36.  
  37.                 //ahora buscamos la fila que corresponde habilitar
  38.                 switch(i)
  39.                 {
  40.                         case 0:
  41.                         fila_1=0;break;
  42.                         case 1:
  43.                         fila_2=0;break;
  44.                         case 2:
  45.                         fila_3=0;break;
  46.                         case 3:
  47.                         fila_4=0;break;
  48.                         case 4:
  49.                         fila_5=0;break;
  50.                         case 5:
  51.                         fila_6=0;break;
  52.                         case 6:
  53.                         fila_7=0;break;
  54.                         default:
  55.                         Nop();
  56.                 }
  57.                 Delay1KTCYx(5); //retardo 5mseg
  58.         }
  59. }



Función desplaza_filas
Esta función se encarga del desplazamiento serial sobre los 8 CD4094, y requiere un valor de entrada tipo char, una vez guardado este valor en registro " fila " comenzamos la cargar por el bit de menor peso, le damos un puklso de reloj y hacemos esto 8 veces para que se desplazen los 8 bits del registro fila tipo char.
Código: C
  1. //
  2. //******************************************************//
  3. //       funcion desplaza filas
  4. //******************************************************//
  5. //
  6. void desplaza_filas(unsigned char fila)
  7. {
  8.         for(temp=8;temp>=1;temp--) //indice para repetir 8 veces
  9.         {
  10.                 datos_4094=0;
  11.                 if((fila & 0X01)== 1) //preguntamos por el bit de menor peso
  12.                         datos_4094=1;
  13.  
  14.                 //le damos un pulso de reloj
  15.                 Nop();
  16.                 Nop();
  17.                 reloj_4094=1;
  18.                 Nop();
  19.                 Nop();
  20.                 reloj_4094=0;
  21.                 Nop();
  22.                 Nop();
  23.  
  24.                 //desplazamiento a la derecha para analizar
  25.                 //el siguiente bit a desplazar del registro fila
  26.                 fila >>= 1;
  27.         }
  28. }
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 27 de Julio de 2007, 11:25:28
Funcion actualiza filas
Esta si que me salio muy larga  :mrgreen:, como recordarán antes de invocar la función "desplaza_filas" se carga un registro "numeros" con el valor de la cadena[ ]  correspendiente a la característica que corresponde, ya sea segundo o minutos u hora. Se le acompaña de un indice " j " que sirve para ubicarlo dentro la matriz en el lugar que le corresponde:
(http://img503.imageshack.us/img503/8252/79625752mc9.jpg)

Entonces una vez cargado este registro "numeros" pasamos a analizar la funcion "actualiza_filas"
Código: C
  1. numeros=cadena[0];j=2;
  2.         actualiza_filas();
  3.  
  4.         numeros=cadena[1];j=1;
  5.         actualiza_filas();
  6.  
  7.         numeros=(cadena[2] & 0x1F);j=0;
  8.         actualiza_filas();

Esta función se encarga de colocar las matrices de caracteres numéricos correspondientes al valor del registro "numero",
(http://img72.imageshack.us/img72/8646/62552828ye9.jpg)
como pueden ver cada dos digitos ocupan 8 bits y estan separados por un caracter que representan al famoso ":", entonces primero es detectar el caracter numérico que corresponde y luego escrbiirlo sobre la matriz del panel.
Código: C
  1. //
  2. //******************************************************//
  3. //******************************************************//
  4. //
  5. //      Actualiza Filas
  6. //
  7. //******************************************************//
  8. //******************************************************//
  9. //
  10. void actualiza_filas(void)
  11. {
  12.         //vamos a buscar el caracter correspondiente a las decenas
  13.         k=numeros>>4;
  14.         switch(k)
  15.         {
  16.                 case 0:
  17.                 for(i=0;i<=6;i++)
  18.                 {
  19.                         fila_reloj[i][j] = numero_0[i][0];
  20.                 }      
  21.                 break;
  22.  
  23.                 case 1:
  24.                 for(i=0;i<=6;i++)
  25.                 {
  26.                         fila_reloj[i][j] = numero_1[i][0];
  27.                 }      
  28.                 break;
  29.  
  30.                 case 2:
  31.                 for(i=0;i<=6;i++)
  32.                 {
  33.                         fila_reloj[i][j] = numero_2[i][0];
  34.                 }      
  35.                 break;
  36.  
  37.                 case 3:
  38.                 for(i=0;i<=6;i++)
  39.                 {
  40.                         fila_reloj[i][j] = numero_3[i][0];
  41.                 }      
  42.                 break;
  43.  
  44.                 case 4:
  45.                 for(i=0;i<=6;i++)
  46.                 {
  47.                         fila_reloj[i][j] = numero_4[i][0];
  48.                 }      
  49.                 break;
  50.  
  51.                 case 5:
  52.                 for(i=0;i<=6;i++)
  53.                 {
  54.                         fila_reloj[i][j] = numero_5[i][0];
  55.                 }      
  56.                 break;
  57.  
  58.                 case 6:
  59.                 for(i=0;i<=6;i++)
  60.                 {
  61.                         fila_reloj[i][j] = numero_6[i][0];
  62.                 }      
  63.                 break;
  64.  
  65.                 case 7:
  66.                 for(i=0;i<=6;i++)
  67.                 {
  68.                         fila_reloj[i][j] = numero_7[i][0];
  69.                 }      
  70.                 break;
  71.  
  72.                 case 8:
  73.                 for(i=0;i<=6;i++)
  74.                 {
  75.                         fila_reloj[i][j] = numero_8[i][0];
  76.                 }      
  77.                 break;
  78.  
  79.                 case 9:
  80.                 for(i=0;i<=6;i++)
  81.                 {
  82.                         fila_reloj[i][j] = numero_9[i][0];
  83.                 }      
  84.                 break;
  85.  
  86.                 default:
  87.                 Nop();
  88.         }
  89.  
  90.         //vamos a buscar el caracter correspondiente a las unidades
  91.         k=numeros & 0x0F;                                      
  92.         switch(k)
  93.         {
  94.                 case 0:
  95.                 for(i=0;i<=6;i++)
  96.                 {
  97.                         fila_reloj[i][j] |= numero_0[i][1];
  98.                 }      
  99.                 break;
  100.  
  101.                 case 1:
  102.                 for(i=0;i<=6;i++)
  103.                 {
  104.                         fila_reloj[i][j] |= numero_1[i][1];
  105.                 }      
  106.                 break;
  107.  
  108.                 case 2:
  109.                 for(i=0;i<=6;i++)
  110.                 {
  111.                         fila_reloj[i][j] |= numero_2[i][1];
  112.                 }      
  113.                 break;
  114.  
  115.                 case 3:
  116.                 for(i=0;i<=6;i++)
  117.                 {
  118.                         fila_reloj[i][j] |= numero_3[i][1];
  119.                 }      
  120.                 break;
  121.  
  122.                 case 4:
  123.                 for(i=0;i<=6;i++)
  124.                 {
  125.                         fila_reloj[i][j] |= numero_4[i][1];
  126.                 }      
  127.                 break;
  128.  
  129.                 case 5:
  130.                 for(i=0;i<=6;i++)
  131.                 {
  132.                         fila_reloj[i][j] |= numero_5[i][1];
  133.                 }      
  134.                 break;
  135.  
  136.                 case 6:
  137.                 for(i=0;i<=6;i++)
  138.                 {
  139.                         fila_reloj[i][j] |= numero_6[i][1];
  140.                 }      
  141.                 break;
  142.  
  143.                 case 7:
  144.                 for(i=0;i<=6;i++)
  145.                 {
  146.                         fila_reloj[i][j] |= numero_7[i][1];
  147.                 }      
  148.                 break;
  149.  
  150.                 case 8:
  151.                 for(i=0;i<=6;i++)
  152.                 {
  153.                         fila_reloj[i][j] |= numero_8[i][1];
  154.                 }      
  155.                 break;
  156.  
  157.                 case 9:
  158.                 for(i=0;i<=6;i++)
  159.                 {
  160.                         fila_reloj[i][j] |= numero_9[i][1];
  161.                 }      
  162.                 break;
  163.  
  164.                 default:
  165.                 Nop();
  166.         }
  167. }

 :mrgreen: y deberia funcionar en la realidad no?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 27 de Julio de 2007, 11:56:02
todos los archivos del ejemplo del panel:
h**p://www.box.net/shared/q90qmopnyl

Luego continuaremos con el resto de perifericos del PIC, como el A/D, mas interrupciones, EEPROM interna, y lo que se nos ocurra por ahi  :-/

PD: si alguien quiere proponer algo, que lo haga!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 27 de Julio de 2007, 12:29:41
se me ocurre algo loco  :z) un datalogger usando la e2prom como almacenamiento usando las interrupciones para el cad y la memoria.

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 27 de Julio de 2007, 12:48:08
ya pes es dificil? que nos falta saber del pic para realizar ese proyecto
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 27 de Julio de 2007, 13:36:40
se puede usar un 16f877 y montarlo en proteus
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 27 de Julio de 2007, 14:32:59
ah entonces tambien se podria en el 18f2525 para seguir con el hilo del cursillo en C18.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 27 de Julio de 2007, 16:12:37
jeje cierto cierto, se me olvidó ese detallito, que es C18  8)

Henry me estas tentando a usar ese compilador...  :lol:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 27 de Julio de 2007, 17:41:57
pues terminamos con los demás perifericos y vemos ese bootloader.  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electronando en 28 de Julio de 2007, 12:37:58
me parece interesante aca henry ya nos puso en bandeja casi todo lo necesario para empezara a trabajar por ejemplo con los modulos ad q se usan bastante en aplicaciones en la industria, y de alli para su almacenamiento seria pan comido pues tenemos ejemplos para eeprom externa ,reloj en tiempo real, comunicacion con pc ya esta casi todo solo para juntar, faltaria ver solo la emision de datos en punto flotante por ejemplo en lcd o serial cosa q no creo sea tan compleja , pero estariamos mas cerca a desarrollar rutinas de control retroalimentadas por ejemplo , creo q alli se sentiria mas el poder de estos micros y la migracion a los dspic , q muchos aun no empezamos seria mas suave , gracias de nuevo por tu aporte Henry.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 28 de Julio de 2007, 12:42:23
 :mrgreen: hay una parte que no entiendo ...
Citar
pero estariamos mas cerca a desarrollar rutinas de control retroalimentadas por ejemplo ,

como es eso de retroalimentadas?

PD: feliz dia PERU
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electronando en 28 de Julio de 2007, 13:02:24
la verdad no se pero suena bien jaja, me referia a rutinas de control digital por ejemplo filtros digitales q es una ecuacion en diferencias y que se pueden aplicar por ejemplo para control de velocidad de motores en el que necesitamos por ejemplo hacer una m,ultiplicacion con punto flotante y luego sumar varios resultados en una sumatoria cosa q con el pic 16f se podria pero solo para procesos lentos como temperatura , en si me referia para que se entienda poder desarrollar un filtro digital jaja como digo l de retroalimentado suena bien cool.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 28 de Julio de 2007, 13:22:33
seeeeeeeeeeeeee
Título: HELLP
Publicado por: Deivison en 01 de Agosto de 2007, 19:48:04
 :( :( :( :( :( :(


olha estou com uma duvida se o micro controlador que estou usando esta queimado, pois tudo o que eu tento fazer não funciona, vou falar o que tenho que faze para ligar o LED

1º primeiro fazer um include contendo o biblioteca do PIC no caso "p18f258.h".
2º depois determinar o clock do meu oscilador, falar que ele e do tipo XT.
3º depois se eu for usar delay usar a biblioteca dele que e "delays.h".
4º iniciar o programa usando o void main.
5º declarar que os portos B sÃo de saída.
6º declarar que um determinado pino esta recebendo "0".
7º fazer um while para que o programa fique executando infinitamente.
8º dentro do while fazer o pino receber "1" que significa que ele vai emitir uma corrente pelo pino que eu determinei, e "0" que determina o que nÃo vai sair corrente alguma onde eu determinei.
9º usa um contador ou delay para que a execução espere um tempo ou seja depois de ligar e desligar ele fique esperando um tempo para que ele faça outra coisa.

10º fim do programa.

ESTE EO CODIGO QUE AGORA ESTOU USANDO



#include <p18f258.h>
#include <delays.h>
#include <stdio.h>

#pragma config OSC    = XT,  OSCS = ON      // Configura oscilador para tipo xt
#pragma config PWRT   = ON                 //
#pragma config BOR    = OFF, BORV  = 45    // Desabilita Reset externo
#pragma config WDT    = OFF, WDTPS = 128   // Desabilita Watchdog
#pragma config LVP    = OFF                // Desabilita reset por 72ms (Temporizador de inicialização)
#pragma config DEBUG  = OFF                // ???
#pragma config STVR   = OFF                // ???
#pragma config WRTC   = OFF                // ???
#pragma config CPB    = ON                 // ???
#pragma config CP0    = ON, CP1 = ON,CP2 = ON,CP3 = ON   // ???
#pragma config CPD    = OFF                              // ???
#pragma config WRT0   = ON, WRT1 = ON,WRT2 = ON, WRT3 = ON  // ???
#pragma config WRTB   = ON                // ???
#pragma config WRTD   = OFF               // ???
#pragma config EBTR0  = ON, EBTR1 = ON,EBTR2 = ON, EBTR3 = ON   // ???
#pragma config EBTRB  = ON                // ???


void main(void){
 TRISA = 0X00;  // Configura os pinos como saida
 TRISB = 0X00;
 TRISC = 0X00;
  while(1){
   
   Delay1KTCYx(100); //1000 mseg
    LATA = 0X01; // Coloca o pino A1 a "0"
    LATB = 0X01;
    LATC = 0X01;
   Delay1KTCYx(100); //1000 mseg
    LATA = 0X00; // Coloca o pino A1 a "1"
    LATB = 0X00;
    LATC = 0X00;
   Delay1KTCYx(100); //1000 mseg
     
 }
}



Problema!!! o MPLAB nÃo aceita "#use delay(clock = 40000000)" entÃo eu estava tentando usar outro gravador para mais nÃo achei nem um que ajudasse a grava via porta SERIAL isso ou USB isso na placa que eu falei antes.

Segundo antes quando eu gravava pelo MPLAB sem configurara o clock do oscilador todas as pernas do PIC estÃo saindo mais ou menos 4,5V e eu alimento com 5V, no caso de todos os códigos que eu tentei nÃo consegui restringir nada
no PIC e ate agora a única coisa que eu tenho certeza e que eu nÃo to conseguindo fazer nada do que eu quero com ele e já tem muito tempo que estou com ele.

se alguem tiver duvida sobre o circuito me manda um email ai eu mando o circuito!

por favor me ajudem não tenho  mais a que recorrer.!!!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Deivison en 01 de Agosto de 2007, 19:56:02
lana.deivison@gmail.com
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 01 de Agosto de 2007, 23:31:29
hola,
#use delay(clock = 40 000 000) ,esta directiva pertenece al CCS, no al C18, es por eso que el MPLAB C18 sale Error.

#pragma config OSC    = XT,  OSCS = OFF
hay que dejar el OSCS en OFF porque estarias habilitabdo el switcheo entre el xtal común del pic y otro colocado en lso pines del oscilador externo del timer1.

luego,
Delay1KTCYx(100); //1000 mseg = 1segundo?
estas trabajando con 40Mhz? #use delay(clock = 40 000 000)?

4 * 1000 * 100 * 1 = 10 m Seg , crees poder ver un led parpadeando o flasheando a 10 milisegundos?
40 000 000            100

yo creo que no. por ahi puede esatr tus errores. saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Deivison en 02 de Agosto de 2007, 16:31:28
pelo o que eu tenho visto quando você descreve o oscilador como do tipo XT ele determina a frequencia do oscilador.
no caso eu tenho usado um oscilador de 4MHZ.

Para conseguir ligar um LED as configurações que estou sando como o MPLAB estão corretas?

e já tentei usar o CCS mas ele não grava em PIC18F258.

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 02 de Agosto de 2007, 16:37:28
4MHz ? bueno.. cambia el 40 000 000 por 4 000 000 nomas y listo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Deivison en 02 de Agosto de 2007, 17:18:05
to querendo saber se as configurações que eu fiz no MPLAB estão corretas!
Eu não sei! como posso fazer para saber se as configurações que estou fazendo estão corretas!

onde estiver com simbolo ??? se você souber o que é me fala pois eu não sei!


#pragma config OSC    = XT,  OSCS = ON      // Configura oscilador para tipo xt
#pragma config PWRT   = ON                 //
#pragma config BOR    = OFF, BORV  = 45    // Desabilita Reset externo
#pragma config WDT    = OFF, WDTPS = 128   // Desabilita Watchdog
#pragma config LVP    = OFF                // Desabilita reset por 72ms (Temporizador de inicialização)
#pragma config DEBUG  = OFF                // ???
#pragma config STVR   = OFF                // ???
#pragma config WRTC   = OFF                // ???
#pragma config CPB    = ON                 // ???
#pragma config CP0    = ON, CP1 = ON,CP2 = ON,CP3 = ON   // ???
#pragma config CPD    = OFF                              // ???
#pragma config WRT0   = ON, WRT1 = ON,WRT2 = ON, WRT3 = ON  // ???
#pragma config WRTB   = ON                // ???
#pragma config WRTD   = OFF               // ???
#pragma config EBTR0  = ON, EBTR1 = ON,EBTR2 = ON, EBTR3 = ON   // ???
#pragma config EBTRB  = ON                // ???
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 02 de Agosto de 2007, 17:54:15
añap bueno lo de los bits de configuraciones lo puedes sacar del datasheet del mismo pic, del archivo helpconfig que esta en la carpeta DOC de tu mplabC18, y del mismo mplab en la opcion Configure >> Configurations bits.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Agosto de 2007, 15:17:15
de lo que me mandastes al correo
(http://mail.google.com/mail/?realattid=f_f4vn3q9p&attid=0.1&disp=thd&view=att&th=114280d2041f5daa)

puedo ver que tu led lo estas colocando en el pin 27 que corresponde al RB6 del pic, y en tu programa solo oscilas los bits RA0 RB0 RC0, entonces como esperas que ese led oscile?

aca te mando el archivo corriendo y simulado. todo a 4MHz.

#include <p18f258.h>
#include <delays.h>
//#include <stdio.h >

#pragma config OSC    = XT,  OSCS = OFF      // Configura oscilador para tipo xt
#pragma config PWRT   = ON                 //
#pragma config BOR    = OFF, BORV  = 45    // Desabilita Reset externo
#pragma config WDT    = OFF, WDTPS = 128   // Desabilita Watchdog
#pragma config LVP    = OFF                // Desabilita reset por 72ms (Temporizador de inicialização)
#pragma config DEBUG  = OFF                // ???
#pragma config STVR   = OFF                // ???
#pragma config WRTC   = OFF                // ???
#pragma config CPB    = ON                 // ???
#pragma config CP0    = ON, CP1 = ON,CP2 = ON,CP3 = ON   // ???
#pragma config CPD    = OFF                              // ???
#pragma config WRT0   = ON, WRT1 = ON,WRT2 = ON, WRT3 = ON  // ???
#pragma config WRTB   = ON                // ???
#pragma config WRTD   = OFF               // ???
#pragma config EBTR0  = ON, EBTR1 = ON,EBTR2 = ON, EBTR3 = ON   // ???
#pragma config EBTRB  = ON                // ???

void main(void)
{
 TRISA = 0X00;  // Configura os pinos como saida
 TRISB = 0X00;
 TRISC = 0X00;

  while(1)
  {
    LATA = 0X01; // Coloca o pino A0 a "1"
    LATB = 0X01; // Coloca o pino B0 a "1"
    LATC = 0X01; // Coloca o pino C0 a "1"
   Delay10KTCYx(100); //1000 mseg
    LATA = 0X00; // Coloca o pino A0 a "0"
    LATB = 0X00; // Coloca o pino B0 a "0"
    LATC = 0X00; // Coloca o pino C0 a "0"
   Delay10KTCYx(100); //1000 mseg
  }
}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Deivison en 05 de Agosto de 2007, 17:42:36


Não eu uso os códigos desta forma mesmo , mais e só mudar o circuito( fio ) de lugar, no caso ligar na porta coreta!

o negocio e que eu não sei se as "configuraçõe de bits" estão corretas pois tenho duvidas sobre o que e cada coisa é exatamente e para que serve a "proteção de bits" no caso para que usar estes comandos

>>>>

#pragma config WRTC   = OFF                // ???
#pragma config CPB    = ON                 // ???
#pragma config CP0    = ON, CP1 = ON,CP2 = ON,CP3 = ON   // ???
#pragma config CPD    = OFF                              // ???
#pragma config WRT0   = ON, WRT1 = ON,WRT2 = ON, WRT3 = ON  // ???
#pragma config WRTB   = ON                // ???
#pragma config WRTD   = OFF               // ???
#pragma config EBTR0  = ON, EBTR1 = ON,EBTR2 = ON, EBTR3 = ON   // ???
#pragma config EBTRB  = ON     

<<<<

para que serve estas configurações além de protege contra gravações.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electronando en 05 de Agosto de 2007, 22:42:59
debes de ir a MCC18\doc

alli encontraras el documento llamado : hlpPIC18configset.chm (read :mrgreen:)

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 06 de Agosto de 2007, 01:00:00
aca te dejo un link de descarga del archivo que fernanado te indica, donde estan los bits de configuracion de todos los pics 18F para el C18.

http://www.box.net/shared/lpe642l4gm
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Deivison en 06 de Agosto de 2007, 14:41:13
Me descupem se eu não estou falando direito o que eu estou perguntando, no caso disso a minha duvida é quando eu devo habilitalos ou desabilitalos não sei quando usar estas proteções de gravação e também não exatamente para que servem.!

vocês podem me ajudar neste dilema!!!!??
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electronando en 06 de Agosto de 2007, 23:15:28
VOCE DEBES DE LEER EL DATASHEET DEL PIC QUE ESTAS USANDO NO ES UN DILEMA SI NO QUE NO QUIERES LEER LO QUE TE ESTAN POSTEANDO O QUIERES QUE TE LO LEAN Y TE LO HAGAN ENTENDER , TODO ESTA EN EL DATASHEET  8)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 07 de Agosto de 2007, 01:11:18
asi es  :o
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Deivison en 10 de Agosto de 2007, 17:40:48
Amigos Estou Procurando um Curso apra o PIC 18f vocês sabem de algum bom pode ser online!
Afinal não estou conseguindo usar o PIC ja li o dathasheet mais nada me ajuda!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 10 de Agosto de 2007, 21:02:37
http://www.micropic.es/index.php?option=com_mambowiki&Itemid=75
en la wikipic estan las definiciones para los fuses tambien, de todas formas voy a preparar uno especial para el C18. asi que paciencia....
Una sugerencia más, te recomiendo que publiques este problema tuyo en un hilo nuevo y asi tengas más posibilidades de respuesta. Saludos!!  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 14 de Agosto de 2007, 02:59:58
Los Bits de Configuracion
Configuration Bits (Fuses)

(http://img256.imageshack.us/img256/3275/55821066gi1.jpg)

Algunas veces cuando uno encuentra en los programas estos códigos llamados bits de configuración, surgen las preguntas: y de donde los saco? son lo mismo para todos los pic? porqué se pone? a esas interrogantes responderemos ahora:

- las podemos hallar en los respectivos datasheet de cada pic o sino en la carpeta doc del programa C18, el archivo
(http://img295.imageshack.us/img295/4436/74355602it4.jpg)

- no, no es lo mismo en cada pic, pues en cada micro las caracteristicas de hardware cambian, y hay que tener cuidado y leer bien el datasheet.

- se pone por la sencilla razón de que si no lo haces o lo haces incorrectamente, tu programa no puede arrancar, por más depuraciones y simulaciones que le hagas, si por ejemplo estas usando un xtal y en la configuración pones LC , jejej tu pic no arrancará ni nada de nada. o derepente le habilitastes el watchdog sin querer queriendo.... , por eso es importante conocer estos bits y mucho más en los micro de la gama 18FXXXX donde son muchos los bits de configuracion.

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 15 de Agosto de 2007, 00:03:18
Ejemplo para el 18F2525

Bueno pues como este chip es el engreido del hilo, vamos a configurarlo y ver en detalle (hasta donde mi capacidad llegue :( ) sus bits de configuracion.

Entonces cual cuento del chapulin..., cuando tenemos en nuestras manos el pic 18f2525 lo primero es ver sus bits de configuracion y donde busco esto? pues en el datasheet , pero pero el datasheet es inmenso me pierdo!!!, tranquilo... lo puedes ver aqui:

(http://img372.imageshack.us/img372/9974/54731017nl6.jpg)

Luego le das click y wala.... los bits de configuracion ordenados en bytes:

(http://img255.imageshack.us/img255/3852/27331410au0.jpg)

Como pueden ver en este pic tenemos 7 registros de configuracion, y se setea cada uno en el ASM, sin embargo en el C18 se ha ordenado todo de una forma más sencilla (aunque no muy lejos del datasheet), esta confección la ubicamos en el archivo "hlpPIC18ConfigSet" que ya explicamos arriba de donde sacarlo. Luego, una vez que escribes los configuration bits en tu programa, y si la misma configuracion sirve para tus demás programas, simplemente bastaría con un copiar y pegar.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 15 de Agosto de 2007, 00:43:01
Que encontramos ahi? La siguiente información fue adquirida del archivo " hlpPIC18ConfigSet ".

(http://img521.imageshack.us/img521/6259/44091639ff9.jpg)

OSC: seleccion del oscilador

FCMEN: permite un cambio del oscilador, el externo por el interno, en caso de fallar el externo.

IESO: permite minimizar el periodo de latencia del oscilador al inicio del programa (TwoSpeedStartUp)

PWRT: permite habilitar el PowerUpTimer

BOREN: habilita y configura el modo del BrownOutReset

BORV: seleccion los niveles del BOR

WDT: habilita el WatchDogTimer

WDTPS: selecciona el PostScaler del WDT

MCLRE: habilita el pin MCLR y deshabilita el pin RE3 o deshabilita el MCLR y habilita el pin RE3 como entrada

LPT1OSC: configura el modo de consumo del Timer1

PBADEN: configura los pines del PORTB como analogos o digitales despues del Reset.

CCP2MX: CCP2 multiplexado con RC1 o RB3

STVREN: habilita el reset del desborde de la pila (stack)

LVP: habilita ICSP.

XINST: habilita el modo de instrucciones extendidas las cuales son 8 (aparte de las 75 inst. normales).

DEBUG: habilita o deshabilita el debugger ubicado en los pines RB6 y RB7, pueden se dedicados o pines digitales.

CP0: habilita proteccion del bloque 0 de la memoria de programa

CP1: habilita proteccion del bloque 1 de la memoria de programa

CP2: habilita proteccion del bloque 2 de la memoria de programa

CPB: habilita proteccion del bloque BOOT

CPD: habilita proteccion de la memoria EEPROM

WRT0: habilita proteccion de escritura de la memoria de programa en bloque 0

WRT1: habilita proteccion de escritura de la memoria de programa en bloque 1

WRT2: habilita proteccion de escritura de la memoria de programa en bloque 2

WRTB: habilita proteccion de escritura del BOOT

WRTC: habilita proteccion de escritura de los registros de configuracion

WRTD: habilita proteccion de escritura de la memoria EEPROM

EBTR0: proteccion de lectura de tablas de la memoria de programa en el bloque 0

EBTR1: proteccion de lectura de tablas de la memoria de programa en el bloque 1

EBTR2: proteccion de lectura de tablas de la memoria de programa en el bloque 2

EBTRB: proteccion de lectura de tablas de la memoria de programa en el BOOT

(http://img183.imageshack.us/img183/827/43929871ar2.jpg)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: manuelroin24 en 27 de Septiembre de 2007, 21:44:25
Que paso con mi amigo Henry, no dejes a tus fans q quieres seguir aprendiendo el C18 seguro estas en parciales en la Univ. Un gran saludo
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Blanca Sánchez en 02 de Noviembre de 2007, 08:11:39
Hola micro_cadaver!!:

Pues quiero agradecerte la información que colocaste sobre los configs. Ignoraba por completo estos datos (y cual era su significado) y resulta que por azares de destino, tuve que regresar a mi programador del puerto serie y desconocía que era esto:

(http://img262.imageshack.us/img262/7671/configsyd4.jpg)

ya que en mis programas me limito a poner los pragmas:

Código: [Seleccionar]
#pragma config LVP = OFF
#pragma config WDT = OFF
#pragma config OSC = XT

gracias!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: proclamer en 02 de Noviembre de 2007, 10:57:14
que ventajas o desventajas hay entre el picc ccs y el c18 de hi-tech.....


ademas los primeros ejemplos esta buenos y entendibles boy viendolos uno a uno poco a poco pero nesecitava preguntar esto.....


gracias. :-/ :mrgreen: :g) :D :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Noviembre de 2007, 01:42:42
la verdad que ni metiendome a aprender los 3 compiladores puedo responder aun a esa pregunta...

solo te puedo decir que el compilador mas popular es el CCS, pero no por eso va a ser el mejor entre los 3. el C18 es entendible si conoces y manejas bien el datasheet de tu pic18F. el hitech es el más duro de digerir pero tiene mucha similitud con el c18.

al final el que decide es el programador.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: doppel en 09 de Noviembre de 2007, 08:55:31
Hola
Estoy leyendo atento este tema que está de lo mas interesante, por ahi me surgen algunas dudas debido a que no C nada de C de antes jeje como por ejemplo:

Código: C
  1. PORTA=~PORTA;

que significa exactamente el igual con el otro simbolito?

Felicitaciones a Microcadaver por este tema que a mi modo de ver tendria que estar en el post del hilo general de C como uno de los temas destacados.-

saludos

Hernán
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PalitroqueZ en 09 de Noviembre de 2007, 13:08:46
invierte los bits del puerto, o lo complementa. Por allí leí que en ccs no es aconsejable hacerlo directamente, no estoy seguro.

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 09 de Noviembre de 2007, 16:08:07
el ~ suele ser el operador lógico NOT .
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: MGLSOFT en 09 de Noviembre de 2007, 16:56:04
Es el complemento.
El operador logico NOT es !.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PerriPic en 12 de Noviembre de 2007, 09:18:19
Hola, quería preguntar por el manejo de un teclado 4x4, básicamente si existe alguna librería para su uso,una rutina ó la explicación de como se usa.

Un saludo y gracias por todo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 12 de Noviembre de 2007, 15:53:40
Es el complemento.
El operador logico NOT es !.

Eso eso, gracias por la corrección.  No se en qué estaba pensando.  En mi cabeza estába pensando en el "negado logico", osea el complemento a 1
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Kedutpic en 16 de Noviembre de 2007, 15:58:18
Henry  , creo que ya podrias empezar con el C32   no crees ??   :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Vayadespiste en 16 de Noviembre de 2007, 17:08:14
Opino como Henry pero para "C30" (aunque mi opinión no cuenta), la verdad es que hace un tiempo gracias a este Tema en concreto me inicié con el "C18" (la cual cosa estoy muy agradecido) y en estos momentos ya he realizado las mismas cosas que realizaba en Ensamblador más alguna que otra cosa.
Vamos que si alguno inicia un curso si me dejan me apunto.

Un saludo.

Edito para colocar el C30, seré bruto no me había fijado en el 2 de "C32"
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 17 de Noviembre de 2007, 01:47:17
 :shock: que?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Vayadespiste en 17 de Noviembre de 2007, 07:22:37
Si te refieres a que estoy haciendo ahora, pues lo último es este control de temperatura ambiente, si te fijas se nota mucho que soy nuevo en C18, por ejemplo en una pequeña función que hay para convertir a int16 dos registros que seguro que hay otra forma mejor de hacerlo pero voy poco a poco, otro detalle si te fijas es que imprimo en el LCD los bufer de un caracter cada vez en lugar de mandar los 2 bytes, esto último ya está solucionado en otro Tema de este foro pero aun no lo he puesto, lo importante es que funciona, otra cosa uso un LM35 y el rango de Vref es el de Vd y Vs:


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 17 de Noviembre de 2007, 09:53:48
añap osea que estas haciendo el AD del pic entre 5V y 0V para entender al LM35 .......... hay una pagina esta...
http://www.x-robotics.com/           
(http://img413.imageshack.us/img413/8353/42225683gz8.jpg)
busca en sensores y le das al LM35 que con un regulador de tension de referencia configuran el LM35 de tal manera que su lectura en el AD es directamente proporcional a los centigrados sin mas movimientos de formula ni nada , tranquilamente lo usarias con 8 bits, bueno los 10 si queires sus decimales y todo eso  :mrgreen:. saludos y me alegra mucho que te haya servido de algo esta ofrenda que hice al foro.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: KALLITOS en 29 de Noviembre de 2007, 22:07:59
Hola henry felicitaciones por tan buen aporte ke le das a la comunidad, bueno comentar ke despues de tanto luchar pude compilar uno de tus ejemplos por lo ke me he metido con el C18 aunke por el momento solo simulacion aca en chiclayo aun no llegan los 18F :(
Bueno la pregunta en concreto: deseo saber el estado de algun pin de entrada en particular por ejemplo en PBP hacia esto:

IF porta.1 = 0 then
codigo
endif

como lo hago en C18?
En ejemplos anteriores se evalua la entrada del puerto pero en forma grupal como lo hago en forma individual???

Y otra donde estan las librerias para la lcd y el ds1307??
Tengo muchas interrogantes pero poco a poco men.
Saludos sr matapix
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 29 de Noviembre de 2007, 22:33:58
eh lo del lcd y ds1307 tan en las paginas 3 y 4 ,... la verdad que aun no me dado paciencia para hacerle un índice para facilitar la busqueda de temas.

bueno en c18 es parecido

if (PORTAbits.RA0)
..
..

esos bits lo puedes encontrar en el archivo *.h del pic correspondiente.
cualquier otra duda postea amigo.  :-/


pd: :D :D :D porque matapics?

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 30 de Noviembre de 2007, 09:43:39
Una pequeña aclaración para que tal vez sea prudente hacer para que Kallitos, que viene del basic, comprenda bien


if (PORTAbits.RA0)
{
   // codigo
}



Las llaves son las que encierran el código que se ejecutará solamente si la condición del if es verdadera.

Si uno no pone las llaves  solo se ejecutaría la primera instrucción por el if y las demás se ejecutarían siempre.



if (PORTAbits.RA0)
   // linea1
   // linea 2




Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: KALLITOS en 30 de Noviembre de 2007, 17:34:19
eso es para preguntar si la entrada es 1 y si kiero saber si la entrada en 0
¿if (PORTAbits.!RA0)?
¿if (PORTAbits.RA0==0)?
o le pongo un else y alli si? creo ke sera mas memoria

gracias maunix ya le voy agarrando el hilo al C18 codigo ke kieres agrupar siempre entre {}

y me he ganado ke como en el basic en una linea puedes poner varias lineas de codigo siempre separados por el bendito ";" (":"para basic) lo compila normal , supongo ke a de tener un limite de ¿256?
seguire por aca jovenes gracias
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 30 de Noviembre de 2007, 18:13:26
para preguntar por 1

if(PORTAbits.RA0)
{
   codigo

}
.....

para preguntar por 0
if(PORTAbits.RA0==0)
{
   codigo

}
.....


saludos!  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: KALLITOS en 30 de Noviembre de 2007, 18:32:37
se agradace joven
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jfh900 en 30 de Noviembre de 2007, 21:11:57
para preguntar por 0
if(PORTAbits.RA0==0)
{
   codigo

}

Es más eficiente utilizar:

if(!PORTAbits.RA0)
{
   codigo

}

Un saludo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 01 de Diciembre de 2007, 02:03:48
sip es cierto , plofff se me paso  :mrgreen: gracias por la aclaracion. ahora lo edito.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Orcino Borges en 07 de Diciembre de 2007, 23:08:13
 micro_cadaver, muito obrigado pelo seu curso, foi muito bom. Eu não estou conseguindo baixar os exemplos os links não abrem.

                            Obrigado

                                         Orcino
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: KALLITOS en 07 de Diciembre de 2007, 23:22:09
pd1: que ya no funciona el link? a ver.... h**p://www.box.net/shared/51111xhblr si funciona, naturalmente amigo teneis que cambiar los  * *  por  t t de tal manera que diga http   :mrgreen: es un truquito para que no lo bajen bots de descargas  :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Orcino Borges en 08 de Diciembre de 2007, 12:59:56
Si meu amigo, eu estou fazendo isso. Descobri o problema, no meu  IE não funciona mas no MOZILA si.

               Gracias


                         Orcino
                         Brasil
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: pocher en 09 de Diciembre de 2007, 03:26:06
¿Os funciona este?: h**p://www.box.net/shared/1p7re3zpvj, a mí no me va.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 09 de Diciembre de 2007, 10:57:09
es cierto no funciona, además de eso entre al disco virtual donde lo tengo alojado y no esta el archivo  :shock:, lo tendre que buscar en mi pc o hacerlo denuevo  :mrgreen:, lo importante de ese ejemplo era la libreria del DS1307, ds1307.h dicha libreria la pueden encontrar en el siguiente link del ejemplo del panel con reloj, por mientras pueden obtenerlo de ahi, voy a subirlo denuevo en otro mirror y tambien en el foro. gracias.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Enrique_86 en 04 de Marzo de 2008, 04:16:33
Holaa!! que paso micro_cadaver??.. espero que continues este curso. A mi me sirvio de mucho gracias por tu aporte!!  :)
espero que publiques algo relacionado con la libreria adc.h ya que estoy teniendo problemas con ella. saludos  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 04 de Marzo de 2008, 15:15:30
hola, sino que ya no estoy en el trabajo donde estaba usando el c18, jejjeej pero dime cual es tu duda y pues lo desarrollamos. saludos. :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Enrique_86 en 04 de Marzo de 2008, 19:25:33
Bueno mi problema esta en la configuracion y uso del ADC, ya he trabajdo antes con el ADc pero en assembler y no he tenido problemas  :-) pero ahora en lenguaje C no me esta funcionanado bien y es sobre todo por que ahora son mas registros para configurar y no se que parametro adecuado es el que debo darle al Tad en el ADCON2 pues estoy trabajando con un PIC 18F4550 y un cristal de 20Mhz estuve leyendo el datasheet pero no entendi muy bien esa parte   :shock:, no se si me pudieras ayudar  :mrgreen: gracias de antemano por la atencion  :-)

                                                                                              Saludos Micro_cadaver!

PD: creo que el ejemplo de un voltimetro de 0 a 5v con un PIC seria bueno para mi duda (es lo que estado tratando de hacer para comenzar  :?)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 04 de Marzo de 2008, 19:49:24
bacan un ejemplo es una didactica muy interesante, porque no subes tu codigo y apartir de ahi avanzamos?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Enrique_86 en 05 de Marzo de 2008, 14:59:57
Hola!!  :mrgreen: aqui esta lo que he estado haciendo.. bueno como mencione antes se trata de un 18F4550 funcionando con un cristal de 20Mhz, la libreria lcd.h esta basada en la libreria xlcd.h de microchip, la encontre en otro hilo del foro  :-) funciona muy bien (ya la he probado en otros trabajos), asi que segun yo esto deberia funcionar, en proteus no me arroja ningun error, pero lo que sale en el LCD no es lo que deberia obtener  :shock: a ver si me das una mano micro. gracias de antemano!



El código:

#include<p18f4550.h>
#include<delays.h>
#include<stdlib.h>
#include<adc.h>
#include "lcd.h"

#pragma config PLLDIV = 5//CONFIG1L
#pragma config FCMEN = OFF,IESO = OFF,FOSC=HS //CONFIG1H
#pragma config PWRT = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF, CCP2MX = OFF//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF//CONFIG5L
#pragma config CPB = OFF,CPD = OFF//CONFIG5H
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF//CONFIG6L
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF//CONFIG6H
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF//CONFIG7L
#pragma config EBTRB = OFF//CONFIG7H

int v = 0;
char s[]={""};
void main(void)
{
   OpenXLCD(FOUR_BIT & LINES_5X7);
   WriteCmdXLCD(BLINK_ON);
   WriteCmdXLCD(CLEAR);
   TRISA = 0x0F;
   OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD,//Config ADCON2
            ADC_CH0 & ADC_INT_OFF,             //Config ADCON0
            12);                         //Config ADCON1
    for( ; ; )
   {   
      Delay10TCYx(5);     //Dealy de 50Ci
      ConvertADC();
      while(BusyADC());
      v = ReadADC();
      itoa(v,s);         //conversion de un entero a una cadena    
      WriteCmdXLCD(CLEAR);//visualizacion de resultado en LCD (2x16)
      putrsXLCD("V = ");
      putsXLCD(s);
      Delay10KTCYx(100); //Delay de 400ms
   }
}


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: 1mas en 05 de Marzo de 2008, 17:00:59

La librería del ADC.h también me esta volviendo loco a mi
Un par de dudas:
La función open ADC hay que ponerla una vez por cada canal que vas a usar, o con ponerla 1 sola vez ya se configura todos los canales con la misma configuración y después se cambia de canal con setchanADC :shock: :shock:
Esta duda me surge por que al hacer openADC ya estas configurando todos los registros ADCON0,ADCON1,ADCON2.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Enrique_86 en 05 de Marzo de 2008, 17:37:19
Bueno tengo entendido que la funcion OpenADC configura los registros ADCON0, ADCON1, ADCON2, y la funcion SetChanADC solo cambia el canal que vas a utilizar para la entrada al conversor, esto es en el registro ADCON0, de modo que al emplear OpenADC solo selecciona un canal para la siguiente conversion, si decides emplear otro canal para otra conversion lo haces con SetChanADC pero previamente deberias haber configurado como entrada analogica el canal que vas a utilizar y esto se hace con OpenADC ya que ahi configuras el ADCON1.  Por lo tanto la funcion OpenADC solo la pones una ves y luego utilizas SetChanADC para cambiar de canal, espero haber resuelto tu duda   :mrgreen:

                                                                                Saludos  :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: maunix en 06 de Marzo de 2008, 13:20:02
Enrique_86 está muy bien tu explicación, solo quería agregar que dependiendo del micro la función OpenADC también configurará los registros ANSEL y ANSELH.  Estos registros permiten configurar unitariamente los pines analógicos sin seguir una secuencia programada .  Si queremos que usar el AN0 y el AN7 y no queremos que entre medio estén como analógicas la entradas de AN1 a AN6 entonces en esos micros es perfectamente posible :) :)

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 07 de Marzo de 2008, 18:27:57
offtopic: hola enrique jejeje no he tenido mucho tiempo para responder a tu post del ADC, tengo unos ejemplillos por aqui lo que si me falta es tiempo por que toda la semana he estado de parranda hermano y pucha ya s eme esta borrando toda la memoria flash dde tanto reseteo que me aplico jejejej nada mas te pido un poquito de paciencia.  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Enrique_86 en 10 de Marzo de 2008, 17:03:59
Hola! bueno solucione mi problema con el ADC  :-) gracias de todas maneras micro_cadaver! y haber si sigues con cursillo que esta muy bueno   8)
               
                                                                                                             Saludosss!!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 11 de Marzo de 2008, 15:15:13
en horabuena, y porque no lo subes para que otros tambien puedan aprender. saludos!  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: RICHI777 en 11 de Marzo de 2008, 18:16:43
Estuve leyendo este post ( muy bueno por cierto ) y tengo una duda estupida, no seria mejor llamar el titulo del post "Cursillo de C utilizando el compilador C18 de MicroChip para micros de la serie PIC 18"...Porque cuando se lee el titulo parace que se hablaria de un lenguaje llamado C18 y este solo es una implementación C orientada a esos PICs y con las extensiones de lenguaje como recomienda el standart.
Saludos !
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Enrique_86 en 14 de Marzo de 2008, 00:22:28
Hola! Bueno a peticion de microcadaver  :mrgreen: subo un ejemplo utilizando la libreria adc.h, se trata de un voltimetro implementado con un 18F4550 con un cristal de 20Mhz, el funcionamiento es sencillo utiliza el ADC para captar el voltaje en el pin AN3 y luego muestra el valor captado (previamente escalado a la resolucion del ADC) en un LCD de 2x16, la libreria del LCD la saque de otro hilo y esta basada en la libreria XLCD.h de microchip, pueden reemplazarla por la libreria de manejo de LCD que utilizen o si me la piden con gusto se las paso  :-)


#include<p18f4550.h>
#include<delays.h>
#include<stdlib.h>
#include<adc.h>
#include "lcd.h"

#pragma config PLLDIV = 5//CONFIG1L
#pragma config FCMEN = OFF,IESO = OFF,FOSC=HS //CONFIG1H
#pragma config PWRT = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF, CCP2MX = OFF//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF//CONFIG5L
#pragma config CPB = OFF,CPD = OFF//CONFIG5H
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF//CONFIG6L
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF//CONFIG6H
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF//CONFIG7L
#pragma config EBTRB = OFF//CONFIG7H

unsigned float v = 0;
char s[3]={""};
void main(void)
{
   OpenXLCD(FOUR_BIT & LINES_5X7);
   WriteCmdXLCD(BLINK_ON);
   WriteCmdXLCD(CLEAR);
   TRISAbits.TRISA2 = 1;
   LATA=0x00;
   OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
         ADC_CH2 & ADC_INT_OFF,                     //Config ADCON0
         12);                                 //Config ADCON1
   ADCON1=0x0B;
    for( ; ; )
   {   
      s[0] = 0;
      s[1] = 0;
      s[2] = 0;
      SetChanADC(ADC_CH3);
      Delay10TCYx(5);     //Delay de 50Ci
      ConvertADC();
      while(BusyADC());
      v = ReadADC();
      v = v * 488 / 1000;
      ultoa(v,s);         //conversion de un entero a una cadena    
      
      WriteCmdXLCD(CLEAR);//visualizacion de resultado en LCD (2x16)
      putrsXLCD("V1 = ");
      if(s[1]==0 && s[2]==0)
      {
         s[2]=s[0];
         s[1]='0';
         s[0]='0';
      }
      if(s[2]==0)
      {
         s[2]=s[1];
         s[1]=s[0];
         s[0]='0';      
      }
      putcXLCD(s[0]);
      putcXLCD('.');
      putcXLCD(s[1]);
      putcXLCD(s[2]);

      Delay10KTCYx(50); //Delay de 100ms
   }
}



Como podran ver en el datasheet del 18F4550 al ejecutar la instruccion ADCON1=0x0B lo que hago es configurar los voltajes de referencia internos a Vss y Vdd, ademas de configurar los pines analogicos que se van a emplear, esto se tendria que hacer mediante la instruccion OpenADC pero es aqui donde tuve los problemas, lo que pasa es q la libreria adc.h para el PIC 18f4550 utiliza solo numeros enteros entre 0 y 15, que al utilizarlos no contemplan la configuracion de los voltajes de referencia para el conversor ADC, pues lo pone por defecto como las entradas a los pines AN2 y AN3, y del modo que queria hacerlo esto no me funcionaba, es por eso que añado la intruccion ADCON1=0x0B luego de utilizar la instruccion OpenADC de este modo si funciono asi que aqui esta lo que hice.. Espero les sirva   :-) 

                                                                                                                          ...Saludos... :-/

 
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: juankho en 05 de Abril de 2008, 14:05:06
hola estuve ejecutando el programa pero logicamente, me hace falta la libreria <lcd.h> sera que me la puede facilitar por favor:. :lol:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Enrique_86 en 05 de Abril de 2008, 15:22:12
Hola! claro te la paso lo saque de este hilo:

http://www.todopic.com.ar/foros/index.php?topic=17984.0 (http://www.todopic.com.ar/foros/index.php?topic=17984.0)

Bueno tienes que instalarte el MegauploadToolbar para poder bajartelo pero eso es rapido asi no que no creo q tengas inconvenientes. Saludoss :)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 05 de Abril de 2008, 17:23:38
subo el archivo del LCD por si no puedes bajarlo del megaupload.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: 1mas en 07 de Abril de 2008, 09:40:10

   OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
         ADC_CH2 & ADC_INT_OFF,                     //Config ADCON0
         12);                                 //Config ADCON1
   ADCON1=0x0B;
    
Como podran ver en el datasheet del 18F4550 al ejecutar la instruccion ADCON1=0x0B lo que hago es configurar los voltajes de referencia internos a Vss y Vdd, ademas de configurar los pines analogicos que se van a emplear, esto se tendria que hacer mediante la instruccion OpenADC pero es aqui donde tuve los problemas, lo que pasa es q la libreria adc.h para el PIC 18f4550 utiliza solo numeros enteros entre 0 y 15, que al utilizarlos no contemplan la configuracion de los voltajes de referencia para el conversor ADC, pues lo pone por defecto como las entradas a los pines AN2 y AN3, y del modo que queria hacerlo esto no me funcionaba, es por eso que añado la intruccion ADCON1=0x0B luego de utilizar la instruccion OpenADC de este modo si funciono asi que aqui esta lo que hice.. Espero les sirva   :-) 

                                                                                                                          ...Saludos... :-/

 

el registro ADCON1  si que se puede configurar con OpenADC.
OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
         ADC_CH2 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VDD,      //configuracion de los Vref alto y bajo               
         12);                                 //Config ADCON1
El problema que le veo yo es que tanto VREFPLUS_VDD como VREMINUS_VDD se asignan a VDD :shock: y no a VDD y VSS como deveria ser(por lo menos eso es lo que pone en el datasheet de la libreria) :?. Eso me desconcierta bastante pos eso yo tb incluiré después el valor de  ADCON1 .
                                                un saludo a todos :)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Enrique_86 en 07 de Abril de 2008, 14:12:55
Hola 1mas, si tienes razon, se me debe de haber pasado por alto eso  :?... uhm he revisado lo que has puesto y consegui configurar el ADCON1 sin necesidad de adicionar la instrcuccion ADCON1=0x0B :) y otra cosa al archivo lcd.h yo le agregue estos comandos pues no las tenia y creo que son de mucha utilidad  8)

#define LINEA_1    0b10000000    // Linea 1
#define LINEA_2    0b11000000    // Linea 2
#define CLEAR       0b00000001    // Clear 
#define CURSOR_HOME 0b00000010 // Inicio

Ademas de ello habras notado que en el codigo que puse anteriormente no utilice la instruccion  while(BusyXLCD()); ya que la añadi al comienzo de cada funcion que hiba a utilizar de la libreria lcd.h esto lo hice para que el codigo salga un poco mas pequeño xD pero de otro modo (sin hacer lo que menciono antes) podrias utilizar el siguiente codigo:



#include<p18f4550.h>
#include<delays.h>
#include<stdlib.h>
#include<adc.h>
#include<string.h>
#include "lcd.h"

#pragma config PLLDIV = 5//CONFIG1L
#pragma config FCMEN = OFF,IESO = OFF,FOSC=HS //CONFIG1H
#pragma config PWRT = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF, CCP2MX = OFF//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF//CONFIG5L
#pragma config CPB = OFF,CPD = OFF//CONFIG5H
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF//CONFIG6L
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF//CONFIG6H
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF//CONFIG7L
#pragma config EBTRB = OFF//CONFIG7H

unsigned float v = 0;
char s[3]={""};
void main(void)
{
   OpenXLCD(FOUR_BIT & LINES_5X7);
   WriteCmdXLCD(CURSOR_OFF);
   WriteCmdXLCD(CLEAR);
   TRISAbits.TRISA2 = 1;
   LATA=0x00;
   OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD,//Config ADCON2
         ADC_CH2 & ADC_INT_OFF & ADC_VREFMINUS_VSS & ADC_VREFPLUS_VDD,//Config ADCON0
         11); //Config ADCON1
   for( ; ; )
   {   
      s[0] = 0;
      s[1] = 0;
      s[2] = 0;
      SetChanADC(ADC_CH3);
      Delay10TCYx(5);     //Delay de 50Ci
      ConvertADC();
      while(BusyADC());
      v = ReadADC();
      v = v * 488 / 1000;
      ultoa(v,s);         //conversion de un entero a una cadena    
      while(BusyXLCD());
      WriteCmdXLCD(CLEAR);//visualizacion de resultado en LCD (2x16)
      while(BusyXLCD());
      putrsXLCD("V1 = ");
      
      if(strlen(s)==1)
      {
         while(BusyXLCD());
         putcXLCD('0');
         while(BusyXLCD());
         putcXLCD('.');
         while(BusyXLCD());
         putcXLCD('0');
         while(BusyXLCD());
         putsXLCD(s);
      }
      if(strlen(s)==2)
      {
         while(BusyXLCD());
         putcXLCD('0');
         while(BusyXLCD());
         putcXLCD('.');
         while(BusyXLCD());
         putsXLCD(s);
      }
      if(strlen(s)==3)
      {
         while(BusyXLCD());
         putcXLCD(s[0]);
         while(BusyXLCD());
         putcXLCD('.');
         while(BusyXLCD());
         putcXLCD(s[1]);
         while(BusyXLCD());
         putcXLCD(s[2]);
      }
      Delay10KTCYx(50); //Delay de 100ms
   }
}



En este codigo utilizo la funcion strlen que devuelve la longitud de una cadena. Bueno espero haber contribuido un poco mas en el foro, un saludo a todos  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: 1mas en 11 de Mayo de 2008, 20:34:30
La LCD.H me va a volver loco :( :(
no consigo que me ponga nada en la pantalla(ni un hola).
Utilizo la placa de evaluación picdem 2 plus y en ella tengo en la parte baja del puerto D los bits de datos y en la alta los de control.
mis dudas son:
Al cambiar en la librería lcd.h el puerto al  que esta conectada la lcd tengo que volver a compilarla o ya esta. Si tengo que compilar como hago?.

Como no conseguí que me funcionase intente con la libreria lcd4b2x16.h y el programa de micro cadáver ( cambiando los pines para mi placa y la cabecera).
Lo que conseguí es que me ponga unos símbolos raros y para eso tengo que encender y apagar varias veces o darle al reset para que se queden.
Con esto descarto que los pines que yo defino  son los acertados, ademas los comprobé con el polimetro 20 veces.

este es el programa:

#include <p18f4620.h>
#include <delays.h>
#include <stdio.h>
#include"C:\MCC18\Proyectos Alvaro\Librerias\LCD4b2x16.h"//ruta del archivo en mi PC
//#include <usart.h>

#pragma config OSC = HS,FCMEN = OFF,IESO = OFF //CONFIG1H
#pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = ON//CONFIG4L
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF//CONFIG5L
#pragma config CPB = OFF,CPD = OFF//CONFIG5H
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF//CONFIG6L
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF//CONFIG6H
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF//CONFIG7L
#pragma config EBTRB = OFF//CONFIG7H


char mensaje[]="Henry";


void main(void)
{
TRISA = 0X00;
TRISB = 0XF0;
TRISD = 0X00;
PORTA = 0X00;
PORTB = 0X00;
PORTD = 0X00;
Inicializa_LCD();
Comando_LCD(CURSOR_ON & BLINK_ON);
Dato_LCD('#');//un dato
Datos_LCD(" PERU ");//una cadena desde la memoria de programa
Dato_String_LCD(mensaje);//una cadena desde la memoria de datos
 
//con este comando pasamos a la linea 2 del LCD
Comando_LCD(DDRAM_LINEA_2);

Datos_LCD("micro_cadaver");
while(1);



}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 13 de Mayo de 2008, 16:05:31
vamo a ver que pasa, voy a simularlo y te comento.  :-/ saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 19 de Mayo de 2008, 00:33:57
aca esta amigo, modifique la libreria del lcd para los requerimientos del hardware. saludos.  :-/

Código: C
  1. /******************************************************/
  2. /*
  3. /* Manejo de un Display de Cristal Liquido LCD 16X4   */
  4. /* de 16 caracteres por 4 lineas, con una interface   */
  5. /* de 4 lineas:                                       */
  6. /*
  7. /*      LCD                         PIC
  8. /* ------------------------------------
  9. /*      D4  (11)                -->     RD4
  10. /*      D5  (12)                -->     RD5
  11. /*      D6  (13)                -->     RD6
  12. /*      D7  (14)                -->     RD7
  13. /*
  14. /*      RS  (4)                 -->     RD0
  15. /*      RW  (5)                 -->     RD1
  16. /*      E   (6)                 -->     RD2
  17. /*
  18. /******************************************************/
  19. /* Conexiones del LCD al Microcontrolador */
  20. #define PIN_RS  LATDbits.LATD0  // Define la Columna 1
  21. #define PIN_RW  LATDbits.LATD1  // Define la Columna 2
  22. #define PIN_E   LATDbits.LATD2  // Define la Columna 3
  23.  
  24. /* Configuracion del Display y cursor */
  25. #define DON                             0b00001111  /* Display encendido   */
  26. #define DOFF                    0b00001011  /* Display apagado     */
  27. #define CURSOR_HOME             0b00000010  /* Cursor encendido    */
  28. #define CURSOR_ON               0b00001111  /* Cursor encendido    */
  29. #define CURSOR_OFF              0b00001101  /* Cursor apagado      */
  30. #define BLINK_ON                0b00001111  /* Cursor con parpadeo */
  31. #define BLINK_OFF               0b00001110  /* Cursor sin parpadeo */
  32. #define CLEAR                   0b00000001  /* Display encendido   */
  33.  
  34. /* Modo de entrada */
  35. #define INCREMENT               0b00000110  /* Incrementa la posicion del cursor */
  36. #define DECREMENT               0b00000100  /* Decrementa la posicion del cursor */
  37.  
  38.  
  39. /* Configuracion de los desplazamientos del cursor y del Display*/
  40. #define SHIFT_CUR_LEFT          0b00010011  /* Corrimiento del cursor a la izquierda  */
  41. #define SHIFT_CUR_RIGHT         0b00010111  /* Corrimiento del cursor a la derecha    */
  42. #define SHIFT_DISP_LEFT         0b00011011  /* Corrimiento del display a la izquierda */
  43. #define SHIFT_DISP_RIGHT        0b00011111  /* Corrimiento del display a la derecha   */
  44.  
  45.  
  46. /* Funciones de inicializacion */
  47. //#define NIBLE                         0b00000010  /* interface a 4 bits */
  48. #define NIBLE                           0b00100000  /* interface a 4 bits */
  49.  
  50. #define FOUR_BIT                        0b00101111  /* Interface a 4-bit  */
  51. #define EIGHT_BIT                       0b00111111  /* Interface a 8-bit  */
  52. #define LINE_5X7                        0b00110011  /* Una linea, caracter 5x7 */
  53. #define LINE_5X10                       0b00110111  /* Una linea, caracter 5x10 */
  54. #define LINES_5X7                       0b00111011  /* Dos lineas. character 5x7 */
  55.  
  56.  
  57. /* Lineas de trabajo */
  58. #define DDRAM_LINEA_1           0b10000000      /* Linea 1 */
  59. #define DDRAM_LINEA_2           0b11000000      /* Linea 2 */
  60. #define DDRAM_LINEA_3           0b10010000      /* Linea 3 */
  61. #define DDRAM_LINEA_4           0b11010000      /* Linea 4 */
  62.  
  63.  
  64. /* Configuracion del puerto */
  65. #define Config_Puerto           0b00000000      /* RC<0:6> como salidas */
  66. #define Mascara                         0b00001111      /* Parte baja del Byte  */
  67.  
  68.  
  69. /* Prototipos de funciones */
  70. void Inicializa_LCD(void);              /* Inicializa LCD */
  71. void Comando_LCD(char);                 /* Indica al LCD un comando */
  72. void Dato_LCD(char);                    /* Indica al LCD un caracter */
  73. void Datos_LCD(const rom char *buffer); /* escribe una cadena desde la memoria de programa al LCD */
  74. void Dato_String_LCD(char *buffer);             /* escribe una cadena desde la memoria de datos al LCD */
  75.  
  76. //**********************************************************
  77. /* Inicializacion del LCD segun fabricante */
  78. //**********************************************************
  79. void Inicializa_LCD(void)
  80. {
  81.         int i;
  82.         Delay10TCYx(110);                       /* Retardo mayor a 100 useg. */
  83. //      LATD = NIBLE;                           /* Interface de 4 bits RC<0:3> */
  84.         LATD = ( (LATD & 0XF0) | NIBLE );
  85.         PIN_RS = 0;
  86.         PIN_RW = 0;
  87.         PIN_E = 1;
  88.  
  89.         Delay1KTCYx(5);                         /* Retardo de 5 mseg. */       
  90.         PIN_E = 0;
  91.         Delay1KTCYx(15);                        /* Retardo de 15 mseg. */
  92.  
  93.         /* Funcion set,  DL = 0, N = 1, F = 0 */
  94.         /* Dos lineas, caracter de 5X7 e interface a 4 bits */ 
  95.         Comando_LCD(LINES_5X7 & FOUR_BIT);
  96.  
  97.         /* Display ON, D = 1, C = 1, B = 1 */
  98.         /* Display encendido, cursor encendido con parpadeo */
  99.         Comando_LCD(DON & CURSOR_ON & BLINK_ON);
  100.  
  101.         /* limpia el display */
  102.         Comando_LCD(CLEAR);
  103.  
  104.         /* Entry Mode Set */
  105.         /* Incremento del cursor */
  106.         Comando_LCD(INCREMENT);
  107. }
  108.  
  109. //**********************************************************
  110. /* Indica al LCD comandos */
  111. //**********************************************************
  112. void Comando_LCD(char dato)
  113. {
  114.         char temp;                                              /* variable auxiliar */
  115.  
  116.         Delay1KTCYx(10);                                /* Retardo de 10 mseg. */
  117.         temp = dato;                                    /* Respaldo del dato original */
  118. //      dato = dato >> 4;                               /* Corrimiento del nible alto */
  119. //      LATD = dato;
  120.         LATD = ( (LATD & 0X0F) | (dato & 0xf0) );//se envia el nible alto
  121.  
  122.         PIN_RS = 0;
  123.         PIN_RW = 0;
  124.         PIN_E = 1;
  125.         Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  126.         PIN_E = 0;
  127. //      LATD = temp;
  128.         temp = temp << 4;
  129.         LATD = ( (LATD & 0X0f) | (temp & 0xf0) );//se envia el nible bajo
  130.  
  131.         PIN_RS = 0;
  132.         PIN_RW = 0;
  133.         PIN_E = 1;
  134.         Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  135.         PIN_E = 0;
  136. }
  137.  
  138. //**********************************************************
  139. /* Manda datos al LCD */
  140. //**********************************************************
  141. void Dato_LCD(char dato)
  142. {
  143.         char temp;                                              /* variable auxiliar */
  144.  
  145.         Delay1KTCYx(10);                                /* Retardo de 10 mseg. */
  146.         temp = dato;                                    /* Respaldo del dato original */
  147. //      dato = dato >> 4;                               /* Corrimiento del nible alto */
  148. //      LATD = dato;
  149.         LATD = ( (LATD & 0X0f) | (dato & 0xf0) );//se envia el nible alto
  150.         PIN_RS = 1;
  151.         PIN_RW = 0;
  152.         PIN_E = 1;
  153.         Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  154.         PIN_E = 0;
  155. //      LATD = temp;
  156.  
  157.         temp = temp << 4;
  158.         LATD = ( (LATD & 0X0F) | (temp & 0xf0) );//se envia el nible bajo
  159.         PIN_RS = 1;
  160.         PIN_RW = 0;
  161.         PIN_E = 1;
  162.         Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  163.         PIN_E = 0;
  164. }
  165. //**********************************************************
  166. //      Escribe una cadena desde memoria de programa al LCD
  167. //**********************************************************
  168. void Datos_LCD(const rom char *buffer)
  169. {
  170.         while(*buffer)                  // Write data to LCD up to null
  171.     {
  172.                 Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  173.         Dato_LCD(*buffer); // Write character to LCD
  174.         buffer++;               // Increment buffer
  175.         }
  176.     return;
  177. }
  178. //**********************************************************
  179. //      Escribe una cadena desde memoria de datos al LCD
  180. //**********************************************************
  181. void Dato_String_LCD(char *buffer)
  182. {
  183.         while(*buffer)                  // Write data to LCD up to null
  184.     {
  185.                 Delay1KTCYx(5);                                 /* Retardo de 5 mseg. */       
  186.         Dato_LCD(*buffer); // Write character to LCD
  187.         buffer++;               // Increment buffer
  188.         }
  189.     return;
  190. }

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dardo en 19 de Agosto de 2008, 18:10:55
Gente, quiero plantear un par de dudas que tengo con el ADC del 18f4550.

Primero que nada, me gustaria saber cual es el tiempo de conversion o como se selecciona, ya que he visto que hay un par de variables que se pueden modificar en la funcion OpenADC().
Por ejemplo yo ahora estoy trabajando con un cristal de 20MHz pero estoy usando FOSC = HS y CPUDIV = OSC4_PLL6 asi que si no me equivoco la velocidad del micro es 5Mhz. Teniendo esto en mente, para el conversor estoy usando:

OpenADC(ADC_FOSC_2 & ADC_RIGHT_JUST & ADC_0_TAD, ADC_CH0 & ADC_INT_OFF, 14);

y me funciona, pero no se que estoy haciendo! por ejemplo, ADC_Right_Just, se que es justificar a la derecha, y ADC_INT_OFF es que no uso el ADC interruptivo, y el 14 es para tener solamente AD_0 como entrada analogica, pero ADC_FoSC_32, ADC_0_TAD y sobre todo ADC_CH0 no se que significan, y no es que no se sepa que configuran, eso lo lei en el manual, pero no entendi que son.

La duda va orientada mas bien a que, en este momento estoy usando un solo canal del ADC para variar el periodo de la PWM con un Pote y me esta andando perfecto, pero voy a precisar muestrear 5 entradas analogicas mas, y no se como configurarlo para eso. Querria poder saber la velocidad de muestreo y si puede ser configurada cosa que calculo que si.
Otra duda, es que he visto en algunos ejemplos que usan un Delay entre el SetChanADC() y el ConvertADC queno se para que es, yo se lo pongo o no, y mi PWM varia igual!

Si alguien se anima a responderme estas duditas le estare eternamente agradecido!
Salu2
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: hackmanice en 21 de Septiembre de 2008, 21:49:47
HOLA MICRO CADAVER

BUENO ES LA PRIMERA VEZ QUE ENTRO AL FORO Y QUIERO SEGUIR CON LA TEMATICA QUE ES MUY INTERESANTE, ME PODRIAS INFORMAR QUE VERSION DE PROTEUS UTILIZAS POR QUE NO ME ABREN LOS EJEMPLOS EN LA VERSION 6.7 SP3.

Gracias.

Espero respuesta
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 22 de Septiembre de 2008, 00:17:10
hola, primero te teng oq pedir que leas las reglas del foro pues una de ella trata sobre no escribir en mayusculas, son las reglas del foro.

sobre la version del proteus esta hecho en la version 7.1 y si no te abre es porque no son compatibles las versiones 6.xx con las 7.xxx lo que te queda es adquirir cualqueir version del 7.xxx o la ultima que va por la 7.2 .

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: hackmanice en 22 de Septiembre de 2008, 01:18:53
hola micro cadaver

gracias por tu respuesta ahora estoy bajando la version 8.9 sabes si es compatible con los ejemplos que escribiste?

Gracias
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 22 de Septiembre de 2008, 01:41:46
hola, espero hayas leido la parte de las reglas del foro en que no se debe escribir cosas que aludan pirateria, supongo q estaras bajando la version free o demo, pero... seguro q es la version 8.9 del proteus?? tengo entendido q la version 7.3 esta en proyecto recien asi que para q salga la 8.9... supongo q falta muuuucho  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: hackmanice en 22 de Septiembre de 2008, 14:41:12
micro gracias por tu ayuda oye de casualidad no tienes un programa para 18f455o de lcd y teclado que solo muestre las teclas que uno oprime, es que lo quiero simular en proteus.

Gracias.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: MordorInc en 30 de Octubre de 2008, 16:24:14
/*
Hola a todos,
les comento mi problema, estoy aprendiendo a trabajar con el MPLAB
C18 y a usar las librerias, estoy trabajando con el PIC18F4520 a 40Mhz.

tengo el siguiente programa(segun un ejemplo de
http://www.todopic.com.ar/foros/index.php?topic=17017.msg119773#msg119773)
pero no me funciona, estoy trabajando con Hypertrerminal pero no manda
ni recibe nada el PIC, hyperterminal funciona bien ya hice las pruebas
pero no veo que estoy haciendo mal...
cualqier ayuda es bienvenida
Luis
anexo mi programa
*/
Código: [Seleccionar]
#include <p18f4520.h>
#include <delays.h>
#include <usart.h>

/* Para saber como configurar los Fusibles se debe mirar
en MPLAB -> HELP -> TOPICS -> Configuration Settings ->
y buscar el microcontrolador en nuestro caso es el 18F4520 */

#pragma config OSC = HSPLL, FCMEN = OFF, IESO = OFF                       // CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 3                      // CONFIG2L
#pragma config WDT = OFF, WDTPS = 32768                                   // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC    // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF, DEBUG = ON            // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF                 // CONFIG5L
#pragma config CPB = OFF, CPD = OFF                                       // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF             // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                         // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF         // CONFIG7L
#pragma config EBTRB = OFF                                                // CONFIG7H
//************************************************************

unsigned char recepcion;

void main(void)
{
TRISA = 0X00;
TRISB = 0X00;
TRISD = 0X00;
PORTA = 0X00;
PORTB = 0X00;
PORTD = 0X00;

/*********************************************************************
*/
Nop();
// configuramos el EUSART para 9600 baudios
/*
/* USART_TX_INT_OFF = Interrupcion de Tx apagada
/* USART_RX_INT_OFF = Interrupcion de Rx apagada
/* USART_ASYNCH_MODE = se trabajara en modo asincrono
/* USART_EIGHT_BIT = se trabajara con 8 bits
/* USART_CONT_RX = la transmision sera continua
/* USART_BRGH_HIGH = transmision y recepcion a alta velocidad
*/
OpenUSART(  USART_TX_INT_OFF &
            USART_RX_INT_OFF &
            USART_ASYNCH_MODE &
            USART_EIGHT_BIT &
            USART_SINGLE_RX &
            USART_BRGH_HIGH,
            1040); //1040 para 40mhz y 9600baudios  - Manual del PIC18F4520 - DS39631D-page 208
//BAUDCONbits.BRG16=1;
baudUSART (BAUD_IDLE_CLK_HIGH &
BAUD_16_BIT_RATE &
BAUD_WAKEUP_ON &
BAUD_AUTO_OFF);
Nop();
for (;;)
{
while(!DataRdyUSART());
recepcion = ReadUSART();


while(BusyUSART());
putcUSART('1');

}

while(1);



}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 30 de Octubre de 2008, 18:34:26
hola MordorInc

porque y como estas usando esta linea?

#pragma config OSC = HSPLL


saludos  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: MordorInc en 30 de Octubre de 2008, 20:46:16
Gracias por responder.
te comento tengo un Xtal externo de 10Mhz y la idea es usar el PLL y trabajar 1 40Mhz..
consideras que ese puede ser el error?
ya le hice unos cambios y ahora recibe en el PC pero tiene errores al principio.
Código: [Seleccionar]
OpenUSART(  USART_TX_INT_OFF &
            USART_RX_INT_OFF &
            USART_ASYNCH_MODE &
            USART_EIGHT_BIT &
            USART_SINGLE_RX &
            USART_BRGH_LOW,
            63); //64 - 1040 pa 40mhz y 9600baudios USART_SINGLE_RX por USART_CONT_RX
//BAUDCONbits.BRG16=1;
/*
baudUSART (BAUD_IDLE_CLK_HIGH &
BAUD_16_BIT_RATE &
BAUD_WAKEUP_ON &
BAUD_AUTO_OFF);
*/
le baje de USART_BRGH_HIGH a USART_BRGH_LOW
cambiandole el valor a 64.-
a 9600 a veces funciona y otras no...
Tambien quite la parte de baudUSART
cual es la diferencia de usar ambas... segun lo que entiendo deberia usarse HIGH por la frecuencia que manejo... pero me funciona mejor con LOW.
sigo dandole...
al final aportare la solucion... ;)
si la encuentro
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: raraavis en 03 de Noviembre de 2008, 16:20:17
Hola amigos, acá les dejo el código para leer y escribir la eeprom interna de los pic.

Saludos

Código: [Seleccionar]
void write_eeprom(unsigned int, unsigned char);
unsigned char read_eeprom(unsigned int);

void write_eeprom(unsigned int eeprom_addr, unsigned char eeprom_data)
{
EECON1bits.EEPGD = 0; /* Ensure EEPGD is clear for EEDATA access */
EECON1bits.CFGS=0; /* Select Data EEPROM */
EECON1bits.WREN = 1; /* Ensure WREN is set to enable EEDATA writes */
    EEADR = eeprom_addr;
EEDATA = eeprom_data; /* Set EEDATA to the value to write */
EECON2 = 0x55; /* Write 0x55 to EECON2 */
EECON2 = 0xaa; /* Write 0xAA to EECON2 */
EECON1bits.WR = 1; /* Initiate write cycle by setting the WR bit */
while (!PIR2bits.EEIF); /* Wait for the EEIF flag to be set */
PIR2bits.EEIF = 0; /* Clear the EEIF flag */
EECON1bits.WREN = 0; /* Ensure WREN is set to enable EEDATA writes */
}

unsigned char read_eeprom(unsigned int eeprom_addr)
{
    EEADR = eeprom_addr;
EECON1bits.EEPGD = 0; /* Ensure EEPGD is clear for EEDATA access */
EECON1bits.RD = 1; /* Trigger a read by setting the RD bit */
return EEDATA; /* Read the result from EEDATA register */
}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: redep en 12 de Diciembre de 2008, 08:17:42
gracias por lo de la eeprom me ha venido genial
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: mr.brett en 06 de Febrero de 2009, 04:22:42
Hola que tal, solo posteo para agradecer por este curso tan bueno que tienen acá en el foro, está genial!!

Muchas gracias a todos los que cooperaron para el curso.

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Leon Pic en 18 de Febrero de 2009, 06:02:22
Al igual que Mr. Brett, posteo para agradecer a micro_cadaver por el exelente tutorial. Estoy empezando a programar en C18 y me viene como anillo al dedo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 18 de Febrero de 2009, 11:45:01
hola León, es un gusto saber que al menos algo que hice le puede servir a demás personas, incluso gente que nunca llegare a conocer en persona.

mi cometido era intentar retomar el tutorial pero por cuestiones de trabajo me he alejado del c18, y estoy programando con el c30 para pic24xxx, pero bueno derepente alguien toma la posta.

saludos  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PHLAKO en 19 de Febrero de 2009, 14:42:07
hola León, es un gusto saber que al menos algo que hice le puede servir a demás personas, incluso gente que nunca llegare a conocer en persona.

mi cometido era intentar retomar el tutorial pero por cuestiones de trabajo me he alejado del c18, y estoy programando con el c30 para pic24xxx, pero bueno derepente alguien toma la posta.

saludos  :-/

Bueno, ami me sirvio mucho este tutorial, ahora me es mas entendible leer directamente de los manuales de microchip, muchas gracias a los foreros que han aportado con sus conocimientos :mrgreen: :-/



Una pregunta, micro_cadaver, acaso es muy distinto el C30, con el el C18?  o solo es cuestion ver el hard que trae el PIC24 y aprender el uso de sus librerias, etc. (asi como lo he estado haciendo con el C18)?

saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 19 de Febrero de 2009, 17:12:44
Una pregunta, micro_cadaver, acaso es muy distinto el C30, con el el C18?  o solo es cuestion ver el hard que trae el PIC24 y aprender el uso de sus librerias, etc. (asi como lo he estado haciendo con el C18)?

asi es, son muy similares salvo las cuestiones del hardware de cada microcontrolador, también por ejemplo en el c30 vienen nuevas formas de mencionar las interrupciones, pero siempre hay ejemplos en internet y foros donde trabajan con dichos compiladores. al fin y al cabo ambos C18 y C30 respetan el ANSI-C, creo que el C32 también.

saludos  :-/
Título: PROBLEMA RECEPCION DATOS EN PIC
Publicado por: camigod en 06 de Marzo de 2009, 21:18:49
Hola a todos, Disculpen tengo un problema con la recpecion de datos en el PIC manejando la transmision serial, segui las instrucciones del codigo posteado sobre el manejo de el modulo EUSART, y hasta el momento NO he podido recibir los datos en el PIC, estoy simulando en el proteus, utilizando el VSPD para simular los puertos COM.

Por el momento puedo recibir los datos que el micro me envia desde una aplicacion que programe en C# (tambien la tengo en C++), pero cuando le envio algo al PIC, este no recibe nada... intente usando ambos metodos:

Esta es una parte del codigo publicado por micro_cadaver.
Código: [Seleccionar]
while(BusyUSART()); //esperamos caracter del virtual terminal
while(!DataRdyUSART());
Comando_LCD(0XCC);
recepcion = getcUSART();
Dato_LCD(recepcion); //envia caracter68.
putcUSART(recepcion);
Comando_LCD(0XC3);//posicion en el LCD
Dato_LCD(recepcion); }

Alguien podria ayudarme?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 06 de Marzo de 2009, 21:35:18
puedes subir tu proyecto con simulacion y codigo para revisarlo completo. saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: camigod en 06 de Marzo de 2009, 22:42:39
Gracias por tu atencion, aca esta el codigo que estoy utilizando, adjunto la simulacion y el .c de MPLAB.
Gracias de antemano.
Código: [Seleccionar]
#include<p18f4550.h>
#include<delays.h>
#include<usart.h>
#include<xlcd.h>

void DelayFor18TCY(){Delay10TCYx(3);} //FUNCIONES PARA LCD
void DelayPORXLCD(){Delay10KTCYx(3);} //FUNCIONES PARA LCD
void DelayXLCD(){Delay10KTCYx(3);} //FUNCIONES PARA LCD

unsigned char recepcion;

void main(){
ADCON1=15;TRISC = 0;
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,25);
//OpenADC(ADC_FOSC_2 & ADC_RIGHT_JUST & ADC_2_TAD,ADC_CH0 & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,14);
OpenXLCD(FOUR_BIT & LINES_5X7);
WriteCmdXLCD(1);
Delay10KTCYx(10);
putrsXLCD("RECEPCION USART");
Delay10KTCYx(250);
while(1){
while(BusyUSART()){}
while(!DataRdyUSART()){}
recepcion = ReadUSART();
WriteDataXLCD(recepcion);
putcUSART(recepcion);
WriteCmdXLCD(192); //POSICION LCD
WriteDataXLCD(recepcion);
}
}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: handpic en 07 de Marzo de 2009, 07:18:32
Hola, estoy empezando con el C con el CCs.

El C18 es mas potente? que diferencias hay entre uno y el otro?.
 He visto que algunos os habeis pasado al C18.
Ya que estoy empezando, lo mismo me da aprender uno que el otro, no?

Saludos,
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: doppel en 07 de Marzo de 2009, 08:06:58
Hola

Con CCS puedes programar todas las gamas de pic osea 12F 16F 18f 24F etc, con C18 que es el C oficial de Microchip como su nombre lo indica es para la familia 18F además de ser ANSI C por lo que es un poquito distinto al CCS en su estructura.-
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: RedPic en 07 de Marzo de 2009, 08:26:09
La única ventaja que le podríamos ver al C18 (o al C30 para los dsPIC por ejemplo) es que cualquier recurso de un PIC18F lo explota con el conocimiento profundo del fabricante de dicho PIC, o sea del mismo Microchip.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 07 de Marzo de 2009, 11:00:21
por eso mismo aquellas personas que vienen trabajando con el assembler en la gama 16f les es màs facil migrar al c18 pues lo ùnico que les falta saber es el Ansi-C.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: camigod en 07 de Marzo de 2009, 16:39:38
Hola a todos,
Ya logre hacer funcionar la recepcion, aparentemente era un problema de conexion en la simulacion...
ahora estoy desarrollando una aplicacion en C# para comunicarme con el 18F4550, todo va bien hasta ahora manejando el estilo de programacion que mencione anteriormente, pero me gustaria utilizar la interrupcion del modulo USART que tiene este pic, podrian ayudarme un poco?

Muchas gracias. Hasta luego.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: lombanacns en 07 de Marzo de 2009, 19:03:05

Hola:
Estoy trabajando con el modulo USB del PIC18F4550 y no he podido en C18. descargue un proyecto de este link:
http://www.sixca.com/eng/articles/usbstepping/.
y no entiendo mucho. Sera que para utilizar este modulo USB solo se puede hacer con las librerias que estan en el link o hay otra manera?

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: handpic en 11 de Marzo de 2009, 12:54:21
Gracias por las respuestas.

Le echaré un vistazo al manual de C18 y ya veremos con que nos quedamos...

Saludos,
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PHLAKO en 27 de Marzo de 2009, 13:18:15
Faltan las interrupciones de la Usart en este cursillo....yame tienen loco, alguien que se apiade y ponga un ejemplo, o explique como se encuenta por la fuente de interrupcion. Saludos,

chaos :)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: camigod en 27 de Marzo de 2009, 15:54:24
Te refieres a la interrupcion por recepcion serial???
Si es asi avisame y posteo un ejemplo en C18, hasta luego
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PHLAKO en 29 de Marzo de 2009, 01:51:57
Te refieres a la interrupcion por recepcion serial???
Si es asi avisame y posteo un ejemplo en C18, hasta luego

Si es posible pudieses explicar el uso de esa interrupcion, seria genial. Por ejemplo, cuando entra a la interrupcion, en un lado lei que el bit GIE so ponia a cero automaticamente, ademas de borrar el RCIF. Lo otro es que al entrar a la interrupcion, no es posible consultar por el bit RCIF, para verificar la bandera, es mas se me ha quedado en un loop al interior de la interrupcion, saliendose solamente cuando se ejecuta un ReadUSART, mire lo que hace esta funcion y no logre desifrar el por que funciona bien solo cuando se ejecuta un ReadUSART. De antemano, gracias.

salu2:)

chaos:)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: camigod en 29 de Marzo de 2009, 20:48:47
Hola PHLAKO, disculpa la demora,

La interrupcion por transmision serial se activa cuando el buffer de recepcion se llena,  es decir, cuando recibe un dato, el microcontrolador pone en alto la bandera RCIF automaticamente para poder identificar el origen de la interrupcion.

Lo que mencionas acerca de la necesidad de llamar a la funcion ReadUSART supongo que se debe a que si no lees el buffer este seguira lleno, lo cual provocaria un llamado constante a la interrupcion convirtiendose asi en un bucle infinito. Te pongo un ejemplo para que entiendas mejor:

Código: [Seleccionar]
#include<p18f4550.h>
#include<delays.h>
#include<usart.h>       //Libreria para configurar modulo USART

void int_recepcion();          //Funcion a llamar en la interrupcion
int recepcion;

#pragma code int_alta = 0x08      //INTERRUPCION POR RECEPCION
void int_alta(){
          _asm
goto int_recepcion
          _endasm
}
#pragma code

#pragma interrupt int_recepcion
void int_recepcion(){                          //EN ESTE PUNTO SE ACABA DE RECIBIR UN DATO, EL BUFFER ESTA LLENO
recepcion = ReadUSART();  //LEEMOS EL CONTENIDO DEL BUFFER PARA LIMPIARLO AUTOMATICAMENTE
PIR1bits.RCIF = 0;              //APAGAMOS LA BANDERA PARA PERMITIR UNA FUTURA INTERRUPCION
}

void main(){
TRISC = 192; //PUERTO DE TRANSMISION
INTCONbits.GIE=1;       RCONbits.IPEN = 1;//HABILITAR INTERRUPCIONES Y PRIORIDAD
INTCONbits.PEIE = 1;                                //INTERRUPCIONES POR PERIFERICOS  (usart)
IPR1bits.RCIP=1; //PRIORIDAD INT RECEPCION
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,25);        //CONFIGURA MODULO USART
PIE1bits.RCIE = 1; //HABILITA INT RECEPCION

while(1){
//ACA PUEDES OPERAR LA VARIABLE GLOBAL 'recepcion' QUE SE ALTERA POR MEDIO DE LA INTERRUPCION...
mostrar();          //POR EJEMPLO LLAMAR UNA FUNCION QUE ME MUESTRE EL DATO RECIBIDO EN UNA LCD... O ALGO ASI
}
}

Bueno, pues esa es la estructura basica del programa, la funcion mostrar no la coloque pues requiere que configuremos la pantalla LCD... etc etc... pero en esencia el programa lo que hace es estar atento a la recepcion y cuando algun dato llegue asignarselo a la variable 'recepcion'.

Espero que te sea util, cualquier duda posteala e intentare responderte,
Hasta Luego
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PHLAKO en 30 de Marzo de 2009, 13:30:39
Hola, camigod, gracias por tu ayuda, mira, tengo exactamente hecho lo que escribes, funcionando, mi pregunta existencial es la siguiente:

si escribes:

void int_recepcion(){                   
   if(PIR1bits.RCIF){
   PIR1bits.RCIF = 0; 
                }
}


nunca se sale de la interrupcion, por que?

Saludos,

chaos :)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: camigod en 30 de Marzo de 2009, 20:20:01
No esque nunca se salga de la interrupcion, lo que pasa es q sale de ella y vuelve a entrar inmediatamente... porque?

Primero:   No es necesario que preguntes por el estado de RCIF  (  if(PIR1bits.RCIF){).... puesto que si el programa entro a esa rutina automaticamente el RCIF esta en 1... entonces esa condicion no sirve de nada hay...

Segundo:   Como te lo mencione anteriormente, la interrupcion por RX se activa cuando se recibe un dato... y no estoy seguro con lo q voy a decir... pero eso equivale a que el buffer del micro se llene. ENTONCES... si el buffer se llena, el programa llama la interrupcion, y como NUNCA lees lo que hay en el buffer, cuando pones en 0 la bandera RCIF... el programa sale de la instruccion y se va a dar cuenta que HAY OTRO DATO EN EL BUFFER (que en realidad vendria siendo el mismo que no leiste)... lo cual provocara otro llamado a la interrupcion.

Espero haberte ayudado
Hasta Luego
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PHLAKO en 31 de Marzo de 2009, 10:15:22
Como se que nunca sale?

void int_recepcion(){                   
   if(PIR1bits.RCIF){
 
  manda_datos_TX();
   
  PIR1bits.RCIF = 0; 
   }
GIE=0
}

Y en el Main un loop tirando datos. Estos datos no llegan, solo llegan los datos enviados por la funcion dentro de la interrupcion. El bit GIE, no se setea nunca mas, osea que debiese mandar solo una vez el dato de la interrupcion y despues quedar en un loop enviando el dato desde el Main.


Lo otro es que si tengo activa mas de una fuente de interrupcion, necesitare del  "if(PIR1bits.RCIF){).... ", pero si no esta funcionando, como lo encuento entonces?

Saludos y gracias por seguir el hilo.

chaos :)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: freshdesing en 07 de Abril de 2009, 07:09:24
Felicitarte por todo este trabajo. Si no lo has hecho ya, te recomendaría escribir un libro, he visto libros del 16F876/77  con menos contenido que lo que muestras aquí, y tienen éxito.

Gracias de nuevo y un saludo.

¿Para cuándo el USB?  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 07 de Abril de 2009, 11:39:55
justo voy a entrar a un proyecto con esas caracteristicas de utilizar las rutinas de microchip para usb pero en c30, supongo que pasarlo para c18 no será muy dificil, espero tener tiempo para continuar con esto y tambien seguir tu consejo. Muchas Gracias  :-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: PHLAKO en 13 de Abril de 2009, 18:38:00
seria re bueno, un colega ya le echo mano al USB y auna entrenadora con unchip ethernet, debe ser mas o menos transparente con el pic qeu tiene dicho puerto, a ver si tengo un tiempito y le pido una clasecita :)

salu2 :)

chaos :)

PD. a que nadie le ha pasado lo de la usart interrupt?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: SiO2 en 25 de Mayo de 2009, 18:01:18
Hola a todos.

   Me he resultado muy interesante este cursillo. ¿Se ha terminado? Que lastima, es realmente útil si quieres empezar, o en mi caso, migrar de los 16f a los 18f

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: elpintas en 26 de Mayo de 2009, 08:24:02
Hola a todos. no se si deberia postear esto aqui, pero no se donde ponerlo.

Os comento, resulta que quiero recibir datos, a traves de la eusart, estoy usando el pic18f97j60 para implementar un servidor web, este pic tiene dos puertos eusart, uno lo estoy usando como viene por defecto en la tpcip stack de microchip para comunicaciones 232 con el pc, el cual funciona perfectamente, porque ya viene implementado por la stack de microchip. Y el otro lo quiero comunicar con otro pic para recibir datos, para mostrar datos en mi web y estoy usando comunicacion 485.

asi que tengo una interrupcion, de este estilo, en la que recibo los datos que me llegan y los guardo en unas variables:

volatile int v;
volatile unsigned char *m;


volatile unsigned char flagGuardado;
volatile unsigned char flagEnvio;
unsigned char empieza;
volatile int temInt;
int aneInt;
int preInt;
int radInt;
int humInt;
int velInt;
int pluInt;
unsigned char ano;
unsigned char mes;
unsigned char dia;
unsigned char hora;
unsigned char min;
//unsigned char acaba;
unsigned char flagRecepcion;


void interrupciones_bajas (void);
                  //interrupcion
   #pragma code las_interrupciones_bajas = 0x18
   void interrupciones_bajas_asm (void)
      {
           _asm goto interrupciones_bajas _endasm
         
      }
      #pragma code

      #pragma interruptlow interrupciones_bajas
      void interrupciones_bajas (void){
   
         
      if(PIR1bits.RCIF==1){//confirmo que el buffer esta llenandose
                        
            while(PIR1bits.RCIF==0); //wait until you receive a character
            flagRecepcion=RCREG;
            if(flagRecepcion==0x69){   
         
      
               m = (unsigned char *)&empieza;//coloco los datos a partir de este puntero
               for (v = 0; v< 20; v++)//el for hace que se repita 21 veces y cada una de ellas incrementa el puntero
                  {
                  while(PIR1bits.RCIF==0); //wait until you receive a character
                  *m=RCREG;
                  ++m;
                  
                  }
               flagGuardado=1;
               LATCbits.LATC1=1;
               flagRecepcion=0x00;
            }
      }
   
   }

esta interrupcion funciona correctamente en un pic cualquiera, pero al intentar integrarla en la tpcip stack, me da un error de este estilo:

Error - section 'lowVector' can not fit the absolute section. Section 'lowVector' start=0x00000018, length=0x00000006

todavia no he configurado la eusart , pero no creo que tenga nada  que ver con esto.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 26 de Mayo de 2009, 16:14:26
Hola a todos. no se si deberia postear esto aqui, pero no se donde ponerlo.

Puedes ponerlo en el subforo Lenguaje C para microcontroladores, de esa manera mas personas podran revisar tu post y ayudarte mejor.

saludos  :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: gabimelgar en 19 de Septiembre de 2009, 14:00:41
Hola a todos, como va? elpintas, tengo exactamente el mismo problema q vos (comunicar el 97j60 con un pic via USART) y me estoy volviendo loco, probe cambiando el linker, reinslalando el C18, reinstalando el MPLAB y no hay forma, lo mas loco es q el mismo proyecto para el 18f2550 anda perfecto, pero cdo lo quiero adaptar para el 97j60 (le cambio el linker y el Select device) me tira un error como q no reconoce las sentencias referidas al USART (openUSART, getUSART, etc...), pudiste solucionarlo?
Muchas gracias!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: elpintas en 21 de Septiembre de 2009, 17:50:07
hola gabimelgar, perdon por el retraso en contestar. Pues la verdad es que ya hace tiempo que solucioné esto y no logro recordar donde estaba el error exactamente.

Creo recordar que es a la hora de definir la interrupcion, ya que tienes que hacerlo dentro del main.c de la TCPIP STACK incluyendola en los bloques donde se definen las interrucpciones de alta y baja prioridad de la propia Stack. Tambien recuerdo que tuve problemas al hacer esta interrupcion de baja prioridad ya que se evaluaba continuamente la condicion de recepción de datos, asi que la puse en las de altaprioridad y se solucionó este problema.
Y tambien me gustaria informarte, que intentes evitar las interrupciones en la medidad de lo posible, a mi por lo menos me han dado muchos problemas al intentar integrarlos en la stack y se acababa parando el programa.

saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: gabimelgar en 23 de Septiembre de 2009, 06:28:26
Hola a elpintas, gracias por responder, el problema es q hay q poner Open1USART, gets1usart, etc... para enviar datos con eso se soluciona, pero igualmente sigo teniendo problemas para la recepción de datos... puse este codigo:

Código: [Seleccionar]
BYTE inputstr[]="vacio";

#pragma code Interrupcion = 0X12
void VectorInterrupcion(void){
_asm goto ISRRecepcion _endasm
}
#pragma code

// Rutina de Interrupcion.-
#pragma interrupt ISRRecepcion
void ISRRecepcion(void){
if(PIR1bits.RC1IF==1){
gets1USART(inputstr, 9);
Kbhit=1; // Indicamos que se ha recibido un dato.-
PIR1bits.RC1IF=0; // Borramos bandera.-
}
}

pero no puedo leer nada.. tenes idea q puede ser?
gracias por el consejo de las interrupciones, pero creo q no nos queda otra q recurrir a ellas para recibir por usar  :?
saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Ciul en 19 de Diciembre de 2009, 19:05:02
Buenas buenas.

Soy nuevo en este foro y pues, he estado ensayando las rutinas para la memoria i2c que han posteado aqui pero, no logro hacerlas funcionar.
Estoy simulando en Protheus, por favor, podría alguien ayudarme?, a ver qué estoy haciendo mal.
luiscarlosjayk@gmail.com


Código: [Seleccionar]
/*=========================================================================

Title:

Description:






   Author: Luis Carlos Osorio Jayk


===========================================================================*/
/*===========================================================================
HEADER FILES
===========================================================================*/

#include <p18f452.h>
#include "myVars.h"
#include <delays.h>
#include <i2c.h>
#include "myI2C.h"


/*===========================================================================
CONFIGURATION BITS
===========================================================================*/

#pragma config WDT = OFF // Turn OFF Watch Dog
#pragma config WDTPS = 128 //
#pragma config OSC = XT // Oscilator selection: HS {Using 20MHz Crystal}
#pragma config PWRT = ON // Turn ON Power Up Time Delay
#pragma config LVP = OFF // Turn OFF Low Voltage Progamming
#pragma config WRTC = ON //
#pragma config WRTD = ON //
#pragma config EBTR0 = ON //
#pragma config EBTR1 = ON //
#pragma config EBTR2 = ON //
#pragma config EBTR3 = ON //
#pragma config EBTRB = ON //
#pragma config DEBUG = OFF //
#pragma config STVR = OFF //
#pragma config CP0 = ON //
#pragma config CP1 = ON //
#pragma config CP2 = ON //
#pragma config CP3 = ON //
#pragma config CPB = ON //
#pragma config CPD = ON //
#pragma config CCP2MUX = OFF //
#pragma config BOR = OFF //
#pragma config BORV = 25 //

/*===========================================================================
USER DATA
===========================================================================*/

#define LedRed PORTBbits.RB0
#define LedGreen PORTBbits.RB1
unsigned char arrayrd[20];
unsigned char *parrayrd = &arrayrd[0];

unsigned char arraywr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
unsigned char *parraywr = &arraywr[0];

//charBitVar var; // A 8bits variable with bit acces. e.g: var.bit0~var.bit7
//intBitVar leds;
/* A 16bit variable with bit and nibble acces.
e.g: leds.bit0~leds.bit15 and leds.nibble0~leds.nibble3*/



/*===========================================================================
User Functions
===========================================================================*/



/*===========================================================================
INTERRUPTION SERVICE ROUTINES
===========================================================================*/

/*High Priority Iterruption Service*/
/*---------------------------------*/
#pragma interrupt high_ISR
void high_ISR (void)
{
// Do...

}

/*Low Priority Interruption Service*/
/*---------------------------------*/
#pragma interruptlow low_ISR
void low_ISR (void)
{
// Do...




}


/*===========================================================================
INTERRUPTION CODE LOCATION
===========================================================================*/

/*High Priority Section*/
/*---------------------*/
#pragma code highPriorityVector = 0x08
void jumpHighPriority (void)
{
_asm
goto high_ISR
_endasm
}
#pragma code // End this code section

/*Low Priority Section*/
/*--------------------*/
#pragma code lowPriorityVector = 0x18
void jumpLowPriority (void)
{
_asm
goto low_ISR
_endasm
}
#pragma code // End this code section



/*===========================================================================
Main Program
===========================================================================*/

void main()
{

/*Configuration*/
/*-------------*/
//RCONbits.IPEN = 1; // Enable Interrupt Priority.

//INTCONbits.GIEH = 1; // Enable High Priority Interruptions.
//INTCONbits.GIEL = 1; // Enable Low Priority Interruptions.

/*TRISCbits.TRISC3 = 1;
TRISCbits.TRISC4 = 1;*/
TRISC = 0x18;
LATC = 0x00;
TRISB = 0; // PORTB pins -> All as Outputs.
OpenI2C(MASTER, SLEW_OFF);
SSPADD = 0x18;
/*SSPSTAT = 0x80;
SSPADD = 0x18;
SSPCON1 = 0x28;
SSPCON2 = 0x00;*/


EscribeDato_i2c_eeprom(0xA0,0x00,0x00,'@');
Ack_i2c_eeprom(0xA0);

while(1)
{

}











} /* End Main Prgram */
/*=========================================================================*/
/*=========================================================================*/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Ciul en 20 de Diciembre de 2009, 09:43:03
Buenas buenas de nuevo.

Intente hacer tal cual el ejemplo de i2c que escribe ||PERU||  :D con una ligera modificación, y pues simulando paso a paso en protheus, realiza la primera operación de escritura pero me dí cuenta que están ocurriendo errores luego: primero ocurre una falta del bit de reconocimiento por parte de la memoria i2c a partir de allí ocurren siempre error de colisión del bus.

Por favor si alguien puede ayudarme, se lo agradecería enormemente.


Código: [Seleccionar]
#include <p18f2525.h>
#include <delays.h>
#include <i2c.h>
#include "memoria_externa.h"
 
#pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
#pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
#pragma config CPB = ON,CPD = ON//CONFIG5H
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
#pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
#pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
#pragma config EBTRB = ON//CONFIG7H
 
int caracter;
unsigned char henry[]="*micro_cadaver*",
cadena[16];
void main(void)
{
TRISA = 0X00;
TRISB = 0X00;
TRISC = 0X18;
LATA = 0X00;
LATB = 0X00;
LATC = 0X00;
Delay1KTCYx(100);
//*******************************************************
// configuración del modulo i2c
//*******************************************************
OpenI2C(MASTER,SLEW_OFF);//inicializo modulo
SSPADD = 9;//100KHz para 4MHz
//*******************************************************
EscribeDato_i2c_eeprom(0XA0,0X00,0X00,'M');
EscribeDato_i2c_eeprom(0XA0,0X00,0X01,'E');
EscribeDato_i2c_eeprom(0XA0,0X00,0X02,'N');
EscribeDato_i2c_eeprom(0XA0,0X00,0X03,'S');
EscribeDato_i2c_eeprom(0XA0,0X00,0X04,'A');
EscribeDato_i2c_eeprom(0XA0,0X00,0X05,'J');
EscribeDato_i2c_eeprom(0XA0,0X00,0X06,'E');
Ack_i2c_eeprom(0XA0);
caracter=LeeDato_i2c_eeprom(0XA0,0X00,0X00);
Delay1KTCYx(500);
 
EscribeDatos_i2c_eeprom(0XA0,0X00,0X10,"|||PERU|||");
Ack_i2c_eeprom(0XA0);
 
EscribeCadena_i2c_eeprom(0XA0,0X00,0X00,henry);
Ack_i2c_eeprom(0XA0);
 
LeeDatos_i2c_eeprom(0XA0,0X00,0X10,cadena,10);
 
LeeDatos_i2c_eeprom(0XA0,0X00,0X00,cadena,15);
 
while(1);
 
//*******************************************************
//*******************************************************
}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Ciul en 20 de Diciembre de 2009, 10:07:19
Hola otra vez.

Disculpen mi desespero pero bueno...sigo intentado una y otra y otra vez.

He logrado entre comillas "resolverlo" colocando un retardo de mínimo 5000 ciclos de reloj, para un cristal de 4 MHz pues serían unos 5ms.
Pero para la aplicación que quiero desarrollar, 5ms es una eternidad. Requiero leer al menos 6 bytes de la memoria, en un lapso máximo de 1 ms.

HEEEEEEEEEEEEEEEEEEEEEEEEEEELP  :sad: :8}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 28 de Diciembre de 2009, 10:47:33
Hola otra vez.

Disculpen mi desespero pero bueno...sigo intentado una y otra y otra vez.

He logrado entre comillas "resolverlo" colocando un retardo de mínimo 5000 ciclos de reloj, para un cristal de 4 MHz pues serían unos 5ms.
Pero para la aplicación que quiero desarrollar, 5ms es una eternidad. Requiero leer al menos 6 bytes de la memoria, en un lapso máximo de 1 ms.

HEEEEEEEEEEEEEEEEEEEEEEEEEEELP  :sad: :8}

hola, el problema aun continua? nisiquiera en proteus te corre?
saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Ciul en 28 de Diciembre de 2009, 17:32:21
Ya lo resolví. Al parecer son problemas de Protheus en cuanto a la simulación de I2C.
A veces se soluciona con borrar todos los componentes y colocarlos de nuevo y ya, simula correctamente.

Acerca de los 5 ms después de la orden de escritura, nada que hacer, eso viene así en el datasheet de las memorias lo explican.
Después de cada escritura hay que esperar un tiempo.

Gracias por todo :)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: fantabuloso en 23 de Marzo de 2010, 13:45:50
Dejo Código básico, en C18, para utilizar un GLCD de 5.7" trabajando en 8 bits, con un controlador solomon SDD1963.

Saludos

Código: [Seleccionar]
#include "p18f4520.h"   
    #include <stdlib.h>
#include <stdio.h>
#include <delays.h>

#pragma config OSC = HSPLL, FCMEN = OFF, IESO = OFF                          // CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 3                      // CONFIG2L
#pragma config WDT = OFF, WDTPS = 32768                                   // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC    // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF, DEBUG = ON            // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF                 // CONFIG5L
#pragma config CPB = OFF, CPD = OFF                                       // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF             // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                         // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF         // CONFIG7L
#pragma config EBTRB = OFF                                                // CONFIG7H

    // control line pins
    #define LCD_RS PORTBbits.RB7   
    #define LCD_WR PORTBbits.RB6
    #define LCD_RD PORTBbits.RB5
    #define LCD_CS PORTBbits.RB4
    #define LCD_RES PORTBbits.RB3
   
    /*************************************************/
    void Write_Command(unsigned char command)
    {
    PORTC = command;
        LCD_RS = 0;
      LCD_WR = 0;
        LCD_WR = 1;
    }

    /*************************************************/
    void Write_Data(unsigned char data1)
    {
        PORTC = data1;
        LCD_WR = 0;
        LCD_WR = 1;
    }

    /*************************************************/
    void Command_Write(unsigned char REG,unsigned char VALUE)
    {
        Write_Command(REG);
        LCD_RS = 1;
        Write_Data(VALUE);
    }

    /*************************************************/
    void SendData(unsigned long color)
    {
        LCD_RS = 1;
        Write_Data((color)>>16);   //red
    Write_Data((color)>>8);      //green
    Write_Data(color);
    }

    /*************************************************/
    void Init_SSD1963(void)
    {
    LCD_CS = 0;
    LCD_RD = 1;
    LCD_WR = 0;
    LCD_RES = 0;
Delay10KTCYx(2);   
    LCD_RES = 1;
    Delay10KTCYx(10);
    Write_Command(0x01);      //Software Reset
    Write_Command(0x01);
Write_Command(0x01);

    Command_Write(0xe0,0x01);   //START PLL
    Command_Write(0xe0,0x03);   //LOCK PLL
    Write_Command(0xb0);      //SET LCD MODE  SET TFT 18Bits MODE
    LCD_RS = 1;
    Write_Data(0x0c);          //SET TFT MODE & hsync+Vsync+DEN MODE
    Write_Data(0x80);          //SET TFT MODE & hsync+Vsync+DEN MODE
    Write_Data(0x01);          //SET horizontal size=320-1 HightByte
    Write_Data(0x3f);          //SET horizontal size=320-1 LowByte
    Write_Data(0x00);          //SET vertical size=240-1 HightByte
    Write_Data(0xef);          //SET vertical size=240-1 LowByte
    Write_Data(0x00);          //SET even/odd line RGB seq.=RGB
    Command_Write(0xf0,0x00);   //SET pixel data I/F format=8bit
    Command_Write(0x3a,0x60);   // SET R G B format = 6 6 6
    Write_Command(0xe6);        //SET PCLK freq=6.4MHz  ; pixel clock frequency
    LCD_RS = 1;
    Write_Data(0x00);
Write_Data(0xe7);
Write_Data(0x4f);
Write_Command(0xb4);      //SET HBP,
    LCD_RS = 1;
Write_Data(0x01); //SET HSYNC Total 440
Write_Data(0xb8);
Write_Data(0x00); //SET HBP 68
Write_Data(0x44);
Write_Data(0x0f); //SET VBP 16=15+1
Write_Data(0x00); //SET Hsync pulse start position
Write_Data(0x00);
Write_Data(0x00); //SET Hsync pulse subpixel start position
    Write_Command(0xb6);        //SET VBP,
    LCD_RS = 1;
    Write_Data(0x01); //SET Vsync total 265=264+1
Write_Data(0x08);
Write_Data(0x00); //SET VBP=19
Write_Data(0x13);
Write_Data(0x07); //SET Vsync pulse 8=7+1
Write_Data(0x00); //SET Vsync pulse start position
Write_Data(0x00);
    Write_Command(0x2a);      //SET column address
    LCD_RS = 1;
    Write_Data(0x00);          //SET start column address=0
    Write_Data(0x00);
    Write_Data(0x01);         //SET end column address=319
    Write_Data(0x3f);
    Write_Command(0x2b);      //SET page address
    LCD_RS = 1;
    Write_Data(0x00);         //SET start page address=0
    Write_Data(0x00);
    Write_Data(0x00);         //SET end page address=239
    Write_Data(0xef);
    Write_Command(0x13);      //SET normal mode
    Write_Command(0x29);      //SET display on
    }

/*************************************************/
    void WindowSet(unsigned int s_x,unsigned int e_x,unsigned int s_y,unsigned int e_y)
    {
    Write_Command(0x2a);      //SET page address
    LCD_RS = 1;
    Write_Data((s_x)>>8);         //SET start page address=0
    Write_Data(s_x);
    Write_Data((e_x)>>8);         //SET end page address=319
    Write_Data(e_x);

    Write_Command(0x2b);      //SET column address
    LCD_RS = 1;
    Write_Data((s_y)>>8);         //SET start column address=0
    Write_Data(s_y);
    Write_Data((e_y)>>8);         //SET end column address=239
    Write_Data(e_y);
    }

    /*************************************************/
    void FULL_ON(unsigned long dat)
    {
    unsigned x,y;
    WindowSet(0x0000,0x013f,0x0000,0x00ef);
    Write_Command(0x2c);
    for(x=0;x<240;x++)
    {
    for(y= 0;y<320;y++)
    {
        SendData(dat);
    }
    }
    }

    /*************************************************/
    void QUADS(void)
    {
    unsigned i,j;
    WindowSet(0x0000,0x013f,0x0000,0x00ef);
    Write_Command(0x2c);
    for(j= 0 ;j<120;j++)
      {
        for(i=0;i<160;i++)
        {
        SendData(0x0000FF);             //blue
        }
        for(i=0;i<160;i++)
        {
        SendData(0xFF0000);             //red
        }
    }
    for(j= 0 ;j<120;j++)
      {
        for(i=0;i<160;i++)
        {
        SendData(0xFFFF00);             //yellow
        }
        for(i=0;i<160;i++)
        {
        SendData(0x00FF00);             //green
        }
    }
    }

 /*************************************************/
    void main(void)
    {
TRISA = 0b00000000;
        PORTA = 0b00000000;
        TRISB = 0b00000000;
        PORTB = 0b00000000;
        TRISC = 0b00000000;
        PORTC = 0b00000000;
   
Delay10KTCYx(50);
Delay10KTCYx(50);
Init_SSD1963(); // Initialize the display
while(1)
{
Delay10KTCYx(50);
  Delay10KTCYx(50);
QUADS();
          Delay10KTCYx(50);
  Delay10KTCYx(50);
Delay10KTCYx(50);
  Delay10KTCYx(50);
FULL_ON(0xff0000); //red
Delay10KTCYx(50);
  Delay10KTCYx(50);
  Delay10KTCYx(50);
  Delay10KTCYx(50);
FULL_ON(0x00ff00); //green
  Delay10KTCYx(50);
  Delay10KTCYx(50);
Delay10KTCYx(50);
  Delay10KTCYx(50);
  FULL_ON(0x0000ff); //blue
  Delay10KTCYx(50);
  Delay10KTCYx(50);
  Delay10KTCYx(50);
  Delay10KTCYx(50);
        }
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 23 de Marzo de 2010, 16:09:38
gracias por tu aporte, estoy seguro que a muchos les ayudará.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: fantabuloso en 30 de Marzo de 2010, 11:11:56
Navegando encontré este manulacito muy básico para principiantes, por ahí le sirve a alguien:

Manual C18 (http://informatica.uv.es/iiguia/SBM/manual.pdf)

Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 02 de Abril de 2010, 23:59:34
Recién empezando con C18, no está nada mal el lenguaje, se parece a cualquier C :mrgreen:

Solo que la forma de usar las interrupciones y el uso de 232, adc, i2c, me parece que son algo diferentes al CCS que hasta hace poco era mi único usado.

En fin, quisiera preguntarles a los entendidos en C18 y como todo buen fanático o quizá más por costumbre sobre una librería lcd_flex, en la que se pueda definir cualquier pin para el uso del LCD, casi sin restricción, como las buenas librerías flex que para CCS hay. O la librería xLCD.h que lleva el C18 se puede configurar a cualquier pin, si así fuera como lo hago?

De no ser así, quisiera tratar de adaptar a C18 una librería flex_lcd.c para CCS, y vi que puede ser un trabajo complicado, al menos con mis recientes pocos conocimientos sobre el C18.

Existen algunas funciones propias del C18, como en el caso del CCS, un output_bit por ejemplo, o un output_high? En caso de existir donde puedo encontrar su ayuda correspondiente?

Bueno, seguiré leyendo a ver que pillo, muchas gracias

saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 03 de Abril de 2010, 01:03:51
xLCD.h no es tan flexible como flex_lcd, se puede seleccionar entre usar el nible bajo o alto de un puerto (No cualquier pin) para los datos y cualquier pin para los pines de control.

Para trabajar con 8 pines de datos hay que sacar los comentarios a #define BIT8.

Para trabajar con 4 pines y en el nible alto del puerto hay que sacar el comentario a #define UPPER.

Que puerto utilizar para los datos se define en las siguientes lineas:

Código: C
  1. /* DATA_PORT defines the port to which the LCD data lines are connected */
  2.  #define DATA_PORT                      PORTB
  3.  #define TRIS_DATA_PORT                 TRISB

y los pines de control:

Código: C
  1. #define RW_PIN   LATBbits.LATB6                 /* PORT for RW */
  2.  #define TRIS_RW  TRISBbits.TRISB6      /* TRIS for RW */
  3.  
  4.  #define RS_PIN   LATBbits.LATB5                /* PORT for RS */
  5.  #define TRIS_RS  TRISBbits.TRISB5      /* TRIS for RS */
  6.  
  7.  #define E_PIN    LATBbits.LATB4                /* PORT for D  */
  8.  #define TRIS_E   TRISBbits.TRISB4      /* TRIS for E  */

Ya definido esto, hay que agregar al proyecto el archivo xLCD.h y todos los archivos fuente ubicados en C:\MCC18\src\pmc_common\XLCD para que los compile y genere los archivos objetos con las modificaciones.


Citar
Existen algunas funciones propias del C18, como en el caso del CCS, un output_bit por ejemplo, o un output_high? En caso de existir donde puedo encontrar su ayuda correspondiente?

No, se trabaja con las estructuras definidas para cada registro, por ejemplo:

Código: C
  1. extern volatile near union {
  2.   struct {
  3.     unsigned RB0:1;
  4.     unsigned RB1:1;
  5.     unsigned RB2:1;
  6.     unsigned RB3:1;
  7.     unsigned RB4:1;
  8.     unsigned RB5:1;
  9.     unsigned RB6:1;
  10.     unsigned RB7:1;
  11.   };
  12.   struct {
  13.     unsigned INT0:1;
  14.     unsigned INT1:1;
  15.     unsigned INT2:1;
  16.     unsigned CCP2:1;
  17.     unsigned :1;
  18.     unsigned PGM:1;
  19.     unsigned PGC:1;
  20.     unsigned PGD:1;
  21.   };
  22. } PORTBbits;

Para leer el estado de un pin se colocaría:

Código: C
  1. if(PORTBbits.RB0==1){....}


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 03 de Abril de 2010, 14:13:14
ok, me tendré que conformar entonces jeje.

Entonces no creo que haya una forma, al menos sencilla, de pasar librería de CCS a C18.

Seguiré estudiando el C18, que con la costumbre al CCS, cuesta un poco... :(

saludos, gracias por responder suky.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 03 de Abril de 2010, 14:40:04
ok, me tendré que conformar entonces jeje.

Entonces no creo que haya una forma, al menos sencilla, de pasar librería de CCS a C18.

Seguiré estudiando el C18, que con la costumbre al CCS, cuesta un poco... :(

saludos, gracias por responder suky.

hola Cryn,
de hecho que es un poco forzado el moverte de CCS a C18 o viceversa, el C18 practicamente no tiene un manual tan explicito como lo tiene CCS (es un problema de los de microchips), personalmente sufri mucho cuando pase de CCS a C18, esperaba un entorno muy similar al CCS e inclusive los comandos y ejemplos y todo eso, por ello me anime hace 3 años a realizar estos ejemplos de aplicacion. Dejame decirte que lo mismo sucede en los demàs compiladores C30 y C32, solo hay librerias pero para cosas más grandes como por ejemplo procesamiento de voz, audio, o el famoso USB HOST para pendrives, o sino librerias para manejar FAT32, codigos que estilan esas magnitudes.

paciencia, mucha paciencia estimado Cryn y que la fuerza te acompañe !!!!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 03 de Abril de 2010, 14:45:03
Entonces no creo que haya una forma, al menos sencilla, de pasar librería de CCS a C18.

Si, y es sencillo teniendo una idea de C18, déjame hacerme un tiempo y la hago para que vean que modificaciones hay que ir teniendo en cuenta.  ;-)


Saludos!
Título: Re: Cursillo en C18. Flex_lcd y utilización de printf.-
Publicado por: Suky en 03 de Abril de 2010, 19:09:51
Bueno, aquí les dejo una librería realizada a partir de flex_lcd utilizada en CCS en donde se puede definir cualquier pin para su utilización. Se tiene 2 archivos, flex_lcd_c18.h y flex_lcd_c18.c, ambos debemos colocarlos en la carpeta del proyecto y agregarlos al proyecto. El archivo *.h tiene las definiciones de pines, y para modificarlos debemos cambiar las siguientes lineas:

Código: C
  1. #define DATA_PIN_7      LATBbits.LATB7
  2. #define DATA_PIN_6      LATBbits.LATB6
  3. #define DATA_PIN_5      LATBbits.LATB5
  4. #define DATA_PIN_4      LATBbits.LATB4
  5.        
  6. #define READ_PIN_7      PORTBbits.RB7
  7. #define READ_PIN_6      PORTBbits.RB6
  8. #define READ_PIN_5      PORTBbits.RB5
  9. #define READ_PIN_4      PORTBbits.RB4
  10.        
  11.        
  12. #define TRIS_DATA_PIN_7       TRISBbits.TRISB7
  13. #define TRIS_DATA_PIN_6       TRISBbits.TRISB6
  14. #define TRIS_DATA_PIN_5       TRISBbits.TRISB5
  15. #define TRIS_DATA_PIN_4       TRISBbits.TRISB4
  16.        
  17.        
  18. #define E_PIN   LATBbits.LATB2
  19. #define RS_PIN  LATBbits.LATB0
  20. #ifdef USE_RW
  21.         #define RW_PIN  LATBbits.LATB1
  22. #endif
  23.        
  24. #define TRIS_E  TRISBbits.TRISB2
  25. #define TRIS_RS TRISBbits.TRISB0  
  26. #ifdef USE_RW
  27.         #define TRIS_RW TRISBbits.TRISB1
  28. #endif

Parecen muchos pero es sencillo.
Además agregue typedef para usar int8, int16 y int32 y no se pierde la costumbre  :D

Código: C
  1. /* ** Definicion de tipo de variables **/
  2. typedef unsigned char       int8;
  3. typedef unsigned int            int16;
  4. typedef unsigned long       int32;
  5. /* ** No olvidarse de short long de 24-bits ** */

Otro detalle que he colocado es mediante un define FCY indicar que frecuencia va a trabajar el microcontrolador para calcular las demoras necesarias para la librería:

Código: C
  1. #define FCY 20000000UL
  2. #define _delay_100us() Delay100TCYx(FCY/4000000UL)
  3. #define _delay_5ms() Delay1KTCYx(FCY/800000UL)



Ejemplo de utilización:

Código: C
  1. #include "flex_lcd_c18.h"
  2.  
  3.  
  4. void main(void){
  5. char Buffer[12]={"\n2 linea..."};
  6.  
  7.         lcd_init();
  8.        
  9.         lcd_putrs("\f1 Linea."); // El string se almacena en la rom
  10.         lcd_puts(Buffer);// El string proviene de un arreglo en ram
  11.  
  12.         while(1){}
  13.  
  14. }



Ahora para utilizar printf con el lcd no es tan directo como en CCS, hay que trabajar un poquito más  :mrgreen: C18 para seleccionar la función que utilizará para enviar datos a través de printf utiliza una variable definida como *stdout en el archivo stdout.c. Dependiendo del valor que posea seleccionará entre enviar datos por el puerto seríal (valor default) o utilizar la función que el usuario decida modificando el archivo _user_putc.c.
Entonces debemos agregar al proyecto el archivo _user_putc.c ubicado en ..\MCC18\src\extended\stdclib

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=17017.0;attach=11653)

y a él hacerle las siguientes modificaciones:

Código: C
  1. extern lcd_putc(unsigned char c);
  2.  
  3. void
  4. _user_putc (unsigned char c)
  5. {
  6.         lcd_putc(c);
  7. }

Con esto ya podemos, modificando el valor de stdout, seleccionar entre escribir en el LCD o enviar por el puerto serial al utilizar la función printf. Veamos un ejemplo:

Código: C
  1. #include "flex_lcd_c18.h"
  2. #include <usart.h>
  3. #include <stdio.h>
  4.  
  5. void main(void){
  6. char Buffer[12]={"\n2 linea..."};
  7. unsigned char Variable=125;
  8.  
  9.         lcd_init();
  10.         OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
  11.         USART_CONT_RX & USART_BRGH_HIGH,129); // 9600,8,n,1
  12.  
  13.         // Modificamos para utilizar función del usuario, o sea escribir en LCD.-
  14.         stdout =_H_USER;
  15.         printf("Var= %u",Variable);
  16.  
  17.         // Modificamos para utilizar nuevamente puerto serial.
  18.         stdout =_H_USART;
  19.         printf("Var= %u",Variable);
  20.  
  21.         while(1){}
  22.  
  23. }


Adjunto proyecto.


Saludos!
 

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: cristiancrm en 22 de Mayo de 2010, 12:19:24
Hola, amigos;

Disculpen la ignorancia, pero recién acabo de comenzar con C18 y me gustaría adentrarme de manera de poder gestionarlo favorablemente.
Mi duda es la siguiente; cómo se setea la frecuencia del Xtal con la que trabajará el micro? Estuve viendo en el MPLAB 8.46, pero no encontré dicha opción.
Alguien podrá ayudarme?

Muchas gracias!!

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 23 de Mayo de 2010, 16:30:55
Tu pregunta puede ser respondida de la siguiente manera :P:

- Si te refieres a configurar una velocidad para que el programa una vez grabado al micro corra a esa velocidad, no es necesario hacerlo, pues el MPLAB no configura eso, es más ningún compilador sabe a que frecuencia va a trabajar tu micro, simplemente se hace algunas veces alguna referencia para saber la velocidad y de esta manera calcular los retardos o algunas configuraciones en temporizaciones.
Uno al hablar de código se puede referir a configurar el tipo de Oscilador:
*INTERNO
*LP valores menores a 1MHz
*XT Mayores a 1MHz pero menores a 4MHz
*HS Mayores a 4MHz
*Con PLL , etc...

- Si te refieres a la velocidad para la simulación con MPLAB SIM, una vez que selecciones en el menú debbuger MPLAB SIM, te vas a Setting dentro de ese mismo menú y en la pestaña OSC/TRACE colocas el valor de frecuencia para la simulación.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 25 de Mayo de 2010, 11:45:26
Hola, amigos;

Disculpen la ignorancia, pero recién acabo de comenzar con C18 y me gustaría adentrarme de manera de poder gestionarlo favorablemente.
Mi duda es la siguiente; cómo se setea la frecuencia del Xtal con la que trabajará el micro? Estuve viendo en el MPLAB 8.46, pero no encontré dicha opción.
Alguien podrá ayudarme?

Muchas gracias!!

Saludos.

te refieres a esto?

#define FCY 20000000UL

por ejemplo ahi se setea que el cristal del chip sera de 20MHZ.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 26 de Mayo de 2010, 10:26:44
Hola, amigos;

Disculpen la ignorancia, pero recién acabo de comenzar con C18 y me gustaría adentrarme de manera de poder gestionarlo favorablemente.
Mi duda es la siguiente; cómo se setea la frecuencia del Xtal con la que trabajará el micro? Estuve viendo en el MPLAB 8.46, pero no encontré dicha opción.
Alguien podrá ayudarme?

Muchas gracias!!

Saludos.

te refieres a esto?

#define FCY 20000000UL

por ejemplo ahi se setea que el cristal del chip sera de 20MHZ.

En ese caso es solo una definición, para utilizarla despues en algun calculo que realice el programador. C18 no es como CCS.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: efrenn3000 en 02 de Junio de 2010, 14:22:27
Hola a todos...

alguien me podria ayudar a saber como calcular la resolucion del ADC si utilizo 10 bits y otra cosa si alguien sabe utilizar bien el PWM como calculo al Duty Cycle, o si tienen algun programa sencillo que me sirva de ejemplo, estoy usando el pic18f4550 y programo en C18

muchas gracias.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 02 de Junio de 2010, 15:44:05
Hola a todos...

alguien me podria ayudar a saber como calcular la resolucion del ADC si utilizo 10 bits y otra cosa si alguien sabe utilizar bien el PWM como calculo al Duty Cycle, o si tienen algun programa sencillo que me sirva de ejemplo, estoy usando el pic18f4550 y programo en C18

muchas gracias.

En el datasheet se provee de la formula para calcular resolución. Dale una revisada al foro, y con ayuda del buscador vas a encontrar bastante información de PWM.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dani en 29 de Junio de 2010, 15:33:11
Buenos dias a todos
soy un novato en pics... he iniciado hace poco a estudiarlo y provando el pic 18f2550 y usando el compilador c18. Quiero leer un dato que recibo en serial (db9+max232), quiero realizar esta lectura tramite interrupt. Leyendo las librerias, tengo una duda, tengo que usar la uart o la usart? :shock: disculpen mi ignorancia
les agradezco de antemano por la ayuda :)

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 30 de Junio de 2010, 12:17:56
Buenos dias a todos
soy un novato en pics... he iniciado hace poco a estudiarlo y provando el pic 18f2550 y usando el compilador c18. Quiero leer un dato que recibo en serial (db9+max232), quiero realizar esta lectura tramite interrupt. Leyendo las librerias, tengo una duda, tengo que usar la uart o la usart? :shock: disculpen mi ignorancia
les agradezco de antemano por la ayuda :)

hola, la ignorancia no tiene porque ser disculpada, todos nacemos con ella, lo que se tiene que disculpar es no querer dejar de serlo.

bueno a tu pregunta, tienes que utiliar UART, porque? porque tus datos sin asincronos. es decir suceden en cualquier momento (para ponerlo en terminos sencillos).
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 11 de Septiembre de 2010, 01:30:10
Micro_cadaver:
                   podrías subir nuevamente de ser posible el archivo que citas en la siguiente respuesta:

http://www.todopic.com.ar/foros/index.php?topic=17017.msg121438#msg121438

respuesta #84 : 28 de Junio de 2007, 03:33:39 »
todos los archivos: h**p://www.box.net/shared/1p7re3zpvj
                             Gracias .
                               Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 13 de Septiembre de 2010, 00:54:32
Hola amigos del foro:
                        Estoy tratando de inicializar el reloj de tiempo real ds1307 y no lo consigo.
El hardware anda bien porque en lenguaje c de ccs lo activo y puedo hacerlo funcionar correctamente.
                        El ds1307 está conectado a un pic18f4550 mediante los pines rb0 en sda y rb1 en scl. Uso un cristal de 4mhz.
                        El código que estoy usando es el que sigue más abajo.
                        Ni siquiera puedo activar la salida de onda cuadrada de 1hz.
                        Si alguien me puede dar una mano se lo agradezco.
                               Saludos.
                                        Jukinch
                       


Código: [Seleccionar]
/*

Nombre del Programa: reloj.c

Compilador: c18

Fecha:

Autor: Terodáctilo y Jukinch

Descripción: uso de rtc con placa entrenadora

------------------------------------------------------------
CONEXIONES:

lcd conectado en PUERTO D

bus de datos en el nible alto conector idc rb 4 a 7

DATA7    PUERTO D.7
DATA6    PUERTO D.6
DATA5    PUERTO D.5
DATA4    PUERTO D.4


bus de control en el nible bajo conector idc rb 0 a 3

E_PIN    PUERTO D.3
RS_PIN   PUERTO D.2
RW_PIN   PUERTO D.1

------------------------------------------------------------

MODULO I2C conector idc rb 0 a 3

en RB0 está el SDA SERIAL CLOCK
en RB1 está el SCL SERIAL DATA

------------------------------------------------------------
PULSADOR DE control RC0 en conector idc rC 0 a 3
LED DE CONTROL RC1 en conector idc rC 0 a 3


------------------------------------------------------------
*/



/*Includes*/
#include "p18F4550.h"
#include "xlcd.h"
#include "delays.h"
#include <stdlib.h> //Libreria para conversiones.
#include <i2c.h> //Libreria para bus i2c





/* Bits de configuración*/

#pragma config FOSC = XTPLL_XT,FCMEN = OFF,IESO = OFF,PLLDIV = 1, CPUDIV = OSC1_PLL2
#pragma config PWRT = ON,BOR = OFF,BORV = 0
#pragma config WDT = OFF,WDTPS = 32768
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = OFF
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF
#pragma config CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF
#pragma config EBTRB = OFF




/*declaración de DEFINICIONES*/
#define CLOCK 4000000
#define TCY 1/CLOCK
#define BITRATE 100000

#define teclaDebugger PORTCbits.RC0 // tecla para avanzar en programa para controlar errores


/*declaración de variables*/
unsigned char hour=0;
unsigned char minutes=0;
unsigned char seconds=0;
unsigned char day=0;
unsigned char month=0;
unsigned char year=0;
unsigned char texto=0;



/*declaración de funciones*/

void DelayFor18TCY(void);
void DelayPORXLCD(void);
void DelayXLCD(void);
void EsperaBotonDebugger(void);


/*****Programa principal******/
/********************************************************************/
void main (void)
{


/*****configuro los puertos******/

TRISBbits.TRISB7=7; // B0=salida
TRISBbits.TRISB6=6; // B0=salida
TRISBbits.TRISB5=5; // B0=salida
TRISBbits.TRISB4=4; // B0=salida
TRISBbits.TRISB3=3; // B0=salida
TRISBbits.TRISB2=2; // B0=salida

TRISBbits.TRISB0=1; // B0=ENTRADA SDA SERIAL CLOCK
TRISBbits.TRISB1=1; // B1=ENTRADA SCL SERIAL DATA


TRISD=0b00000000;      // Puerto D7:0 como salidas
 LATD=0b00000000;      //todas las salidas abajo

TRISCbits.TRISC0=1; // C0=ENTRADA // botón para hacer control del programa
TRISCbits.TRISC1=0; // C1=salida // led para control del programa




/***** preparo lcd para escribir ******/
Delay10KTCYx(10000);    //Retardo para esperar que pase cualquier transitorio
OpenXLCD(FOUR_BIT&LINES_5X7);   //inicializamos LCD con varias lineas y caracteres 5x7
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}


putrsXLCD("PRUEBA RTC");

while(BusyXLCD()){}
WriteCmdXLCD(0xC0); //Nos posicionamos en la posición 8
while(BusyXLCD()){}

putrsXLCD("PULSE RC.0");


EsperaBotonDebugger();



Delay10KTCYx(100000);    //Retardo para esperar que pase cualquier transitorio
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("PULSE para init");


EsperaBotonDebugger();






/***** rutina de inicialización de rtc ***************************************/

OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz

ADCON0 = 0X00;
ADCON1 = 0X0F;
CMCON = 0X07;



SSPADD =9; // ((CLOCK/BITRATE)/4)-1 = 9 for 100kHz @ 20MHz


IdleI2C();
StartI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
                      //  y le dice que se va a escribir con el bit0 en 0
IdleI2C();
 WriteI2C(0b00000000); // pone el puntero del rtc en dirección 00h
StartI2C();
WriteI2C(0b00000000); // GRABAMOS EN EL PRIMER REGISTRO 00 SEGUNDOS
                      // Y HABILITAMOS EL OSCILADOR con el octavo bit apagado
IdleI2C();
WriteI2C(0b00000010); // GRABAMOS EN EL SEGUNDO REGISTRO 23 MINUTOS
IdleI2C();
WriteI2C(0b00010000); // GRABAMOS EN EL TERCER REGISTRO configura reloj formato 24 hs
IdleI2C();
WriteI2C(0b00000110); // GRABAMOS EN EL CUARTO REGISTRO EL NOMBRE DE DIA DE LA SEMANA
IdleI2C();
WriteI2C(0b00011000); // GRABAMOS EN EL QUINTO REGISTRO EL NUMERO DE DIA DEL MES
IdleI2C();
WriteI2C(0b00000110); // GRABAMOS EN EL SEXTO REGISTRO EL MES
IdleI2C();
WriteI2C(0b00010000); // GRABAMOS EN EL SÉPTIMO REGISTRO EL AÑO
IdleI2C();
WriteI2C(0b00010000); // GRABAMOS EL OCTAVO Y ULTIMO REGISTRO
              // Configura la salida del oscilador de onda cuadrada en 1hz
IdleI2C();
StopI2C();




Delay10KTCYx(100000);    //Retardo para esperar que pase cualquier transitorio
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("YA INICIALIZO");

EsperaBotonDebugger();

// ********************************** rutina de init rtc *********************
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("i2c cargado");
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);

Delay10KTCYx(100000);    //Retardo para ver lo escrito en lcd

EsperaBotonDebugger();

while(1)
{


WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}

putrsXLCD("Lectura i2c");
EsperaBotonDebugger();
IdleI2C();
StartI2C();
WriteI2C(0b11010001); // escribe dirección del rtc y le dice que se va a leer
WriteI2C(0x00); // pone el puntero del rtc en dirección 00h
seconds=ReadI2C();

      AckI2C();


minutes=ReadI2C();

        AckI2C();

hour=ReadI2C();

AckI2C();

minutes=ReadI2C();

AckI2C();

seconds=ReadI2C();

AckI2C();


day=ReadI2C();

AckI2C();

month=ReadI2C();

AckI2C();


year=ReadI2C();

NotAckI2C();

StopI2C();

WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("termino lectura");
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
EsperaBotonDebugger();



WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("comienza display");
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
EsperaBotonDebugger();



WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0

EsperaBotonDebugger();
// btoa(hour,texto); // convierto 8 bits a caracter ascii
while(BusyXLCD()){}
putsXLCD(texto);

while(BusyXLCD()){}
EsperaBotonDebugger();
putrsXLCD(":");

while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 

btoa(minutes,texto); // convierto 8 bits a caracter ascii
while(BusyXLCD()){}
putsXLCD(texto);
while(BusyXLCD()){}
EsperaBotonDebugger();
putrsXLCD(":");
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 

btoa(seconds,texto); // convierto 8 bits a caracter ascii
while(BusyXLCD()){}
putsXLCD(texto);
while(BusyXLCD()){}


WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);

Delay10KTCYx(500);    //Retardo para poder refrescar pantalla

WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado 
WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("termino display");
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
EsperaBotonDebugger();



}











}// final de main


/*Funciones*/

void DelayFor18TCY(void)
{
Delay1KTCYx(1); //Retardo de 1mSeg
}

void DelayPORXLCD(void)
{
Delay1KTCYx(180); //Delay 15 mSeg
}

void DelayXLCD(void)
{
Delay1KTCYx(60);
}


void EsperaBotonDebugger(void)
{
while (PORTCbits.RC0==0)
{
}
Delay10KTCYx(10000);    //Retardo para ver lo escrito en lcd
LATCbits.LATC1=1; // ENCIENDO LED C1
Delay10KTCYx(10000);    //Retardo para ver lo escrito en lcd
LATCbits.LATC1=0; // APAGO LED C1
Delay10KTCYx(10000);    //Retardo para ver lo escrito en lcd
LATCbits.LATC1=1; // ENCIENDO LED C1
Delay10KTCYx(10000);    //Retardo para ver lo escrito en lcd
LATCbits.LATC1=0; // APAGO LED C1
Delay10KTCYx(10000);    //Retardo para ver lo escrito en lcd
LATCbits.LATC1=1; // ENCIENDO LED C1
Delay10KTCYx(10000);    //Retardo para ver lo escrito en lcd
LATCbits.LATC1=0; // APAGO LED C1
Delay10KTCYx(10000);    //Retardo para ver lo escrito en lcd


}




Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 13 de Septiembre de 2010, 10:24:11
 :rolleyes:  Justo ayer estaba migrando la librería de RedPIC realizada para CCS. Solo la probé en proteus, la adjunto.

Para usarla se debe iniciar I2C a la velocidad de 100kHz. Por ejemplo para 40MHz:

Código: C
  1. #include "ds_1307.h"
  2.  
  3. UINT8 Dia,Fecha,Mes,Anio,Hora,Minuto,Segundo;
  4.  
  5. void main(){
  6.  
  7.         OpenI2C(MASTER,SLEW_OFF);
  8.         SSPADD=99;                                      // 100kHz. Max de DS1307
  9.        
  10.         vDS1307Init(DS1307_OUT_ENABLED | DS1307_OUT_1_HZ);
  11.         vDS1307_Set_Date_Time(10,8,10,1,19,42,1);
  12.        
  13.         vDS1307_Get_Date(&Fecha,&Mes,&Anio,&Dia);
  14.         vDS1307_Get_Time(&Hora,&Minuto,&Segundo);
  15.        
  16.        
  17.         while(1){}
  18. }


Para usarla, copiarlo los 3 archivos a la carpeta del proyecto e incluirlos en el proyecto.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 13 de Septiembre de 2010, 10:49:36
Gracias Suky por el gesto  ;-). a la noche los pruebo y te comento como me fue.
          Saludos.
             Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 13 de Septiembre de 2010, 12:58:55
En hardware, funciona!  :-/  :mrgreen:



Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 13 de Septiembre de 2010, 13:21:41
Bien ahí Suky!  :-/
Sería bueno que se agregue al índice del tema la librería esta también.
         Saludos.
              Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 13 de Septiembre de 2010, 13:58:57
Sería bueno que se agregue al índice del tema la librería esta también.

Hecho! Espero a micro_cadaver no le moleste  :oops: Si hay alguna otra librería, avisan  ;-)


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micro_cadaver en 20 de Septiembre de 2010, 20:17:17
Sería bueno que se agregue al índice del tema la librería esta también.

Hecho! Espero a micro_cadaver no le moleste  :oops: Si hay alguna otra librería, avisan  ;-)


Saludos!

holas, me parece excelente que continuen contribuyendo, por mi lado no tengo ningun inconveniente, y ni motivo tendria para tenerlo. la idea es que todos aporten!!!!


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: facuenta en 18 de Diciembre de 2010, 04:42:16
Dónde consigo la biblioteca flex_lcd.c para C18? pero ojo que en la simulación se queda la biblioteca flex_lcd.c como si hubiera un lazo infinito cuando se simula en MPLAB SIN para calcular los tiempos en CCS. Toma al LCD como si estuviera apagado(el MPLAB SIM) pero se queda en esa biblioteca(flex_lcd.c) tiene un bug ahí. La que se consigue en C18 no tendrá el mismo error? nunca programé en C18.


Saludos,
Facundo
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 18 de Diciembre de 2010, 10:00:20
Éste hilo es de C18, pregunta en un hilo adecuado.


Saludos!
Título: Re: Cursillo en C18. Flex_lcd y utilización de printf.-
Publicado por: Cryn en 20 de Diciembre de 2010, 18:22:42
Bueno, aquí les dejo una librería realizada a partir de flex_lcd utilizada en CCS en donde se puede definir cualquier pin para su utilización. Se tiene 2 archivos, flex_lcd_c18.h y flex_lcd_c18.c, ambos debemos colocarlos en la carpeta del proyecto y agregarlos al proyecto.

Hola gran suky he estado viendo la genial librería que pusiste por acá, va muy bien, como viento en popa :mrgreen:, lo estoy utilizando para un 18LF46J11 conectado a un LCD 16x2 compatible con HD44780 y tengo un pequeño problema y una duda:

-Mi problema es que tengo que colocar:

lcd_putrs("\f          Prueba LCD16x2");
Y solo así puedo ver el mensaje "Prueba LCD16x2" en la 1racolumna y 1ra fila del LCD, caso contrario si no coloco los 10espacios:

lcd_putrs("\fPrueba LCD16x2");
El mensaje se verá desde el décimo primer caracter, veo solo: "16x2"

Al parecer me sucede eso cuando uso '\f' al principio del mensaje, ya que si coloco el mensaje después de inicializar el LCD, sale tal como se desea.

He ahí mi dilema, que pasa con el '\f' que me come 10 columnas?

Con el \n va bien, pasa a la segunda línea y primera columna ;-)


-Mi duda es como incluir la librería. Según vi en la libreria flex_lcd_c18.c está incluído "flex_lcd_c18.h" y según mi intuición se debería colocar "flex_lcd_c18.c" en el main, pero tu tienes el .h incluído, y funciona muy bien, pero pues me hice bolas...

Ya que si coloco el .c incluido en el main, aparece un mensaje de error en la última función del .c
Además para q todo funcione bien se debe colocar en "header files" del proyecto en MPLAB el .h de la lib del LCD y en "source files" deben estar el main y el .c de la lib del LCD.

Saludos suky y muchas gracias por la excelente libreria flex! :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 20 de Diciembre de 2010, 20:03:47
Hola Cryn!! Estás usando el pin RW? Porque en tal caso se testea la condición del LCD y no deberia de tener problemas  :? Pero si no utilizas este pin, habría que agregar una demora luego de enviar el comando \f, o sea en flex_lcd_c18.c la función lcd_putc tiene que quedar así:

Código: C
  1. void lcd_putc(int8 c){
  2.         switch(c){
  3.                 case '\f':
  4.                         lcd_send_byte(0,1);
  5.                         _delay_5ms();   /// <<<>>>
  6.                 break;
  7.                 case '\n':
  8.                         lcd_gotoxy(1,2);
  9.                 break;
  10.                 case '\b':
  11.                 lcd_send_byte(0,0x10);
  12.                 break;
  13.                 default:
  14.                         lcd_send_byte(1,c);
  15.                 break;
  16.   }
  17. }

Respecto a que archivo agregar, en los compiladores de Microchip (Ansi C) se llama al archivo cabecera (*.h), él cual indica que funciones se implementan y algunas definiciones. Y en la estructura del proyecto se debe agregar ambos archivos para que sean compilados.

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 21 de Diciembre de 2010, 16:46:43
Hola suky, gracias por responder.

No estoy usando el pin RW

He aumentado el retardo a la librería y ahora si el \f va bien.

Respecto a que archivo agregar, en los compiladores de Microchip (Ansi C) se llama al archivo cabecera (*.h), él cual indica que funciones se implementan y algunas definiciones. Y en la estructura del proyecto se debe agregar ambos archivos para que sean compilados.
Entonces al agregar el .c de la lib del LCD al proyecto ya es parte del código y no hace falta q haya un #include "flex_lcd_c18.c" e incluyendo el .h de la librería es suficiente?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 21 de Diciembre de 2010, 19:00:09
Respecto a que archivo agregar, en los compiladores de Microchip (Ansi C) se llama al archivo cabecera (*.h), él cual indica que funciones se implementan y algunas definiciones. Y en la estructura del proyecto se debe agregar ambos archivos para que sean compilados.
Entonces al agregar el .c de la lib del LCD al proyecto ya es parte del código y no hace falta q haya un #include "flex_lcd_c18.c" e incluyendo el .h de la librería es suficiente?

Exactamente!

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 29 de Diciembre de 2010, 13:33:16
Hola, he estado viendo sobre I2C y memorias eeprom por acá (http://www.todopic.com.ar/foros/index.php?topic=17017.msg121087#msg121087) y lo he entendido y probado todo con buenos resultados.

Estoy usando un micro 18lf46j11 trabajando a 20MHz, y debo usar el segundo módulo I2C, I2C2, esto quiere decir que uso las funciones de la libreria i2c.h, todas las que acaban con 2, como OpenI2C2(); StopI2C2(); etc. Hice los cambios correspondientes y ha funcionado todo bien, ahora lo que pretendí también es cambiar la sintaxis de las funciones para leer y escribir en la eeprom y hacerlos similares a los que en CCS usé, es decir de esto:
Código: C
  1. unsigned char EscribeDato_i2c_eeprom(unsigned char control,unsigned char address1,unsigned char address2,unsigned char data){
llevarlo a esto:
Código: C
  1. unsigned char write_ext_eeprom(unsigned int address,unsigned char data){

Este cambio a usar una variable int(16bits) para el address porque utilizaré muchos datos de la eeprom, y creo que sería más fácil manejarlo en una variable de 16bits directamente, ya que tendré varias funciones que incrementarán la dirección de 1 en 1, o de 10 en 10, etc.

Lo que me quedó es así:

Código: C
  1. #define control 0x0a
  2.  
  3. //      Escribir un byte en Memoria EEPROM 24LC512
  4. unsigned char write_ext_eeprom(unsigned int address,unsigned char data){
  5.   IdleI2C2();                                                           // ensure module is idle
  6.   StartI2C2();                                                          // initiate START condition
  7.   while(SSP2CON2bits.SEN);                              // wait until start condition is over
  8.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  9.     return(-1);                                                 // return with Bus Collision error
  10.   else{                                                                         // start condition successful
  11.     if(WriteI2C2(control))                              // write byte - R/W bit should be 0
  12.       return(-3);                                                       // set error for write collision
  13.     IdleI2C2();                                                 // ensure module is idle
  14.     if(!SSP2CON2bits.ACKSTAT){          // test for ACK condition received
  15.                 if(WriteI2C2(*((char*)(&address+1))))                   // write word address for EEPROM
  16.                 return(-3);                                             // set error for write collision
  17.            IdleI2C2();                                                  // ensure module is idle
  18.            if(!SSP2CON2bits.ACKSTAT){           // test for ACK condition received
  19.                 if(WriteI2C2(*((char*)(&address))))             // write word address for EEPROM
  20.                         return(-3);                                     // set error for write collision
  21.                         IdleI2C2();                                             // ensure module is idle
  22.                    if(!SSP2CON2bits.ACKSTAT){   // test for ACK condition received
  23.                         if(WriteI2C2(data))             // data byte for EEPROM
  24.                          return(-3);                            // set error for write collision
  25.                    }
  26.                    else
  27.                         return(-2);                                     // return with Not Ack error condition  
  28.                 }
  29.     }
  30.     else
  31.         return(-2);                                                     // return with Not Ack error condition  
  32.   }
  33.   IdleI2C2();                                                           // ensure module is idle  
  34.   StopI2C2();                                                           // send STOP condition
  35.   while(SSP2CON2bits.PEN);                              // wait until stop condition is over
  36.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  37.      return(-1);                                                        // return with Bus Collision error
  38.   return(0);                                                            // return with no error
  39. }
  40.  
  41. //      Escribir Pagina en Memoria EEPROM 24LC512 desde una Cadena
  42. unsigned char write_string_eeprom(unsigned int address,unsigned char *wrptr){
  43.   IdleI2C2();                                                           // ensure module is idle
  44.   StartI2C2();                                                          // initiate START condition
  45.   while(SSP2CON2bits.SEN);                              // wait until start condition is over
  46.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  47.     return(-1);                                                 // return with Bus Collision error
  48.   else{                                                                         // start condition successful
  49.     if(WriteI2C2(control))                              // write byte - R/W bit should be 0
  50.        return(-3);                                              // set error for write collision
  51.     IdleI2C2();                                                 // ensure module is idle
  52.     if(!SSP2CON2bits.ACKSTAT){          // test for ACK condition received
  53.                 if(WriteI2C2(*((char*)(&address+1))))                   // write word address for EEPROM
  54.                 return(-3);                                             // set error for write collision
  55.            IdleI2C2();                                                  // ensure module is idle
  56.            if(!SSP2CON2bits.ACKSTAT){           // test for ACK condition received
  57.                 if(WriteI2C2(*((char*)(&address))))             // write word address for EEPROM
  58.                         return(-3);                                     // set error for write collision
  59. //*******************************************************************************
  60. //*******************************************************************************
  61.                         IdleI2C2();                                             // ensure module is idle
  62.                    if(!SSP2CON2bits.ACKSTAT){   // test for ACK condition received
  63.                         if(putsI2C2(wrptr))             // data byte for EEPROM
  64.                         return(-4);                             // set error for write collision
  65.                    }
  66. //*******************************************************************************
  67. //*******************************************************************************
  68.                    else
  69.                       return(-2);                                       // return with Not Ack error condition  
  70.                 }
  71.     }
  72.     else
  73.         return(-2);                                                     // return with Not Ack error condition  
  74.   }
  75.   IdleI2C2();                                                           // ensure module is idle  
  76.   StopI2C2();                                                           // send STOP condition
  77.   while(SSP2CON2bits.PEN);                              // wait until stop condition is over
  78.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  79.     return(-1);                                                 // return with Bus Collision error
  80.   return(0);                                                            // return with no error
  81. }
  82.  
  83. //      Lectura de un byte en Memoria EEPROM 24LC512
  84. unsigned char read_ext_eeprom(unsigned int address){
  85.   IdleI2C2();                                                           // ensure module is idle
  86.   StartI2C2();                                                          // initiate START condition
  87.   while(SSP2CON2bits.SEN);                              // wait until start condition is over
  88.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  89.     return(-1);                                                 // return with Bus Collision error
  90.   else{
  91.     if(WriteI2C2(control))                              // write 1 byte
  92.       return(-3);                                                       // return with write collision error
  93.     IdleI2C2();                                                 // ensure module is idle
  94.     if(!SSP2CON2bits.ACKSTAT){          // test for ACK condition, if received
  95.       if(WriteI2C2(*((char*)(&address+1))))                     // WRITE word address for EEPROM
  96.         return(-3);                                             // return with write collision error
  97.           IdleI2C2();                                                   // ensure module is idle
  98.      if(!SSP2CON2bits.ACKSTAT){         // test for ACK condition, if received
  99.         if(WriteI2C2(*((char*)(&address))))             // WRITE word address for EEPROM
  100.                   return(-3);                                   // return with write collision error
  101.                   IdleI2C2();                                           // ensure module is idle
  102.         if(!SSP2CON2bits.ACKSTAT){      // test for ACK condition, if received
  103.                   RestartI2C2();                                // generate I2C bus restart condition
  104.                   while(SSP2CON2bits.RSEN);// wait until re-start condition is over
  105.                   if(PIR3bits.BCL2IF)           // test for bus collision
  106.               return(-1);                               // return with Bus Collision error
  107.            if(WriteI2C2(control+1))     // write 1 byte - R/W bit should be 1
  108.                   return(-3);                           // return with write collision error
  109.                   IdleI2C2();                                   // ensure module is idle
  110.                   if(!SSP2CON2bits.ACKSTAT){    // test for ACK condition, if received
  111.                   SSP2CON2bits.RCEN=1;  // enable master for 1 byte reception
  112.                   while(SSP2CON2bits.RCEN);     // check that receive sequence is over
  113.                   NotAckI2C2();                                 // send ACK condition
  114.                   while(SSP2CON2bits.ACKEN);// wait until ACK sequence is over
  115.                   StopI2C2();                           // send STOP condition
  116.                   while(SSP2CON2bits.PEN);      // wait until stop condition is over
  117.                   if(PIR3bits.BCL2IF)           // test for bus collision
  118.                         return(-1);                             // return with Bus Collision error
  119.                 }
  120.                   }
  121.         else
  122.           return(-2);                                   // return with Not Ack error
  123.       }
  124.       else
  125.         return(-2);                                             // return with Not Ack error
  126.     }
  127.     else
  128.       return(-2);                                                       // return with Not Ack error
  129.   }
  130.   return((unsigned int)SSP2BUF);                // return with data
  131. }
  132.  
  133. //      Esperar Ack en Memoria EEPROM 24LC512
  134. unsigned char ack_ext_eeprom(){
  135.   IdleI2C2();                                                           // ensure module is idle
  136.   StartI2C2();                                                          // initiate START condition
  137.   while(SSP2CON2bits.SEN);                              // wait until start condition is over
  138.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  139.     return(-1);                                                 // return with Bus Collision error
  140.   else{
  141.     if(WriteI2C2(control))                              // write byte - R/W bit should be 0
  142.       return(-3);                                                       // set error for write collision
  143.     IdleI2C2();                                                 // ensure module is idle  
  144.     if(PIR3bits.BCL2IF)                                 // test for bus collision
  145.       return(-1);                                                       // return with Bus Collision error
  146.     while(SSP2CON2bits.ACKSTAT){                // test for ACK condition received
  147.       RestartI2C2();                                            // initiate Restart condition
  148.       while(SSP2CON2bits.RSEN);         // wait until re-start condition is over
  149.       if(PIR3bits.BCL2IF)                               // test for bus collision
  150.         return(-1);                                             // return with Bus Collision error
  151.       if(WriteI2C2(control))                    // write byte - R/W bit should be 0
  152.         return(-3);                                             // set error for write collision
  153.       IdleI2C2();                                                       // ensure module is idle
  154.     }
  155.   }
  156.   StopI2C2();                                                           // send STOP condition
  157.   while(SSP2CON2bits.PEN);                              // wait until stop condition is over        
  158.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  159.     return(-1);                                                 // return with Bus Collision error
  160.   return(0);                                                            // return with no error    
  161. }

Hasta ahí todo bien, al parecer no ha habido ningún error, pues he escrito en la posicion 0 y en la posición 1 de la eeprom y los datos se han guardado correctamente, he leído la memoria con mi clone del pickit2.

Lo que pretendo ahora es realizar funciones que guarden y lean en la eeprom i2c variables float, long (32bits) e int(16bits), entonces copie la idea de un archivo de ejemplo de CCS e hice esto:

Código: C
  1. void write_float_eeprom(unsigned int address,float data){
  2.    char i;
  3.  
  4.    for(i=0;i<4;++i){
  5.         write_ext_eeprom(address+i,*((char*)(&data)+i));
  6.         ack_ext_eeprom();
  7.         Delay10KTCYx(4);//8ms
  8.    }
  9. }
  10.  
  11. float read_float_eeprom(unsigned int address){
  12.    char i;
  13.    float data;
  14.  
  15.    for(i=0;i<4;++i){
  16.         *((char*)(&data)+i)=read_ext_eeprom(address+i);
  17.    }
  18.    return data;
  19. }
  20.  
  21. void write_long_eeprom(unsigned int address,long data){
  22.    char i;
  23.  
  24.    for(i=0;i<4;++i){
  25.         write_ext_eeprom(address+i,*((char*)(&data)+i));
  26.         ack_ext_eeprom();
  27.         Delay10KTCYx(4);//8ms
  28.    }
  29. }
  30.  
  31. long read_long_eeprom(unsigned int address){
  32.    char i;
  33.    long data;
  34.  
  35.    for(i=0;i<4;++i){
  36.            *((char*)(&data)+i)=read_ext_eeprom(address+i);
  37.    }
  38.    return data;
  39. }
  40.  
  41. void write_int_eeprom(unsigned int address,int data){
  42.    char i;
  43.  
  44.    for(i=0;i<2;++i){
  45.         write_ext_eeprom(address+i,*((char*)(&data)+i));
  46.         ack_ext_eeprom();
  47.         Delay10KTCYx(4);//8ms
  48.    }
  49. }
  50.  
  51. int read_int_eeprom(unsigned int address){
  52.    char i;
  53.    int data;
  54.  
  55.    for(i=0;i<2;++i){
  56.         *((char*)(&data)+i)=read_ext_eeprom(address+i);
  57.    }
  58.    return data;
  59. }
Un detalle más debo colocar además de ack un retardo después de cada escritura... Delay10KTCYx(4);//8ms

Tras hacer esto para el main, con las funciones de la memoria tambien escritas en el código:
Código: C
  1. #include <p18lf46j11.h>
  2. #include <stdio.h>
  3. #include <i2c.h>
  4. #include "flex_lcd_c18.h"
  5. #pragma config WDTEN=OFF,XINST=OFF,CP0=OFF
  6. #pragma config OSC=HS,T1DIG=OFF,LPT1OSC=ON,FCMEN=OFF,IESO=OFF
  7. #pragma config RTCOSC=T1OSCREF,IOL1WAY=OFF
  8. #pragma config WPCFG=OFF,WPDIS=OFF
  9.  
  10. //stdout =_H_USER; antes de un printf para LCD
  11. //stdout =_H_USART; antes de un printf para puerto serie
  12.  
  13. #define NDecimas 100   // Para 2 decimas.-
  14.  
  15. unsigned char a,Entero,String[4];
  16. unsigned int b=0xabcd,c,Decimal;
  17. unsigned long d=0xef123456,e;
  18. unsigned float f=1.38,g;
  19.  
  20. void pic_init(void){
  21.         ADCON0=0b00000000;
  22.         ANCON0=0b11111111;
  23.         ANCON1=0b11111111;
  24.         TRISA=0b11111000;
  25.         TRISB=0b00001111;
  26.         TRISC=0b10101010;
  27.         TRISD=0b00000011;
  28.         TRISE=0b11111111;
  29.         lcd_init();
  30.         LATA=0;
  31.         LATB=0;
  32.         LATC=0;
  33.         LATD=0;
  34.         LATE=0;
  35.         OpenI2C2(MASTER,SLEW_ON);
  36.         SSP2ADD=12;            //400KHz con 20MHz
  37.         write_int_eeprom(0,b);
  38.         write_long_eeprom(2,d);
  39.         write_float_eeprom(6,f);
  40.         c=read_int_eeprom(0);
  41.         e=read_long_eeprom(2);
  42.         g=read_float_eeprom(6);
  43.         Entero=g;
  44.         Decimal=(int)(g*NDecimas)%NDecimas;
  45.         sprintf(String,"%u.%02u",Entero,Decimal);
  46.         stdout =_H_USER;
  47.         printf("%4X %lu\n%s",c,e,String);
  48. }
  49.  
  50. void main(void){
  51.         pic_init();
  52.         while(true){
  53.                
  54.         }
  55. }
No obtengo lo que necesito, en el LCD veo:
3736 4294967295
127.67

Y tras leer la memoria con el pickit2 clone veo:
Posición 0500    CD AB FF FF FF FF FF FF FF FF FF FF FF FF FF FF
//esta el int a=abcd

Posición 0700    FF FF 56 34 12 EF D7 A3 B0 3F FF FF FF FF FF FF
//esta el long d=0xef123456(4010947670d) y el float f=1.38

El int tiene entonces un desplazo de 500h al momento de escribir en la eeprom, y los float y long un desplazo de 700h

Y las lecturas de int, float y long no tengo idea de que es lo que estan leyendo.

A donde apuntaría *((char*)(&data)) siendo data una variable de 16bits? apunta al LSB o al MSB?

Lamentablemente no existe este pic en el proteus para poder depurar, y no lo puedo probar ahí, he buscado en proteus otro pic con 2 puertos i2c y al hacer los cambios necesarios, el proteus parece no simular el segundo puerto i2c de un pic =(. Y para rematar dentro MPLAB con C18, no puedo depurar con el pickit2 porque al colocar en los config DEBUG=ON, el compilador saca un mensaje de error y no compila

Alguien me podría ayudar con este problema??

Muchas gracias, saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 29 de Diciembre de 2010, 17:42:49
Bueno, pensaba que haciendo *((char*)(&address+1)) se podría también, resultó que no, hice lo mismo que en CCS address>>8  y ahora si funciona bien, ya no hay desplazamientos, se guarda todo en donde corresponde.

Sobre el Debug, todavía no di con la respuesta =(

Ahora tengo un problema mostrando una variable de 16bits por el LCD, estoy haciendo:

int c=0x7788;

stdout =_H_USER;       //modifique _user_putc.c y lo agregue al proyecto
                               //como menciona suky en mensajes anteriores.
printf("%u",c);

Y solo me muestra el MSB, en el LCD veo:
30464 que equivale a 0x7700

Supongo que con el itoa y lcd_puts funcionaría, pero que paso con el printf?

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 29 de Diciembre de 2010, 19:13:14
Supongo que el parentesis está mal implementado, seria algo así:

*((char *)&address + 1 )
*((char *)&address + i )


Luego en printf prueba con % lu  :shock:


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 29 de Diciembre de 2010, 19:45:22
Lo del parentesis lo cambie por >> como se usa en muchas librerias de memorias en CCS, y ha funcionado bien.

Use también el %lu y salia como si fuera de 32bits y se veían muchos datos raros. He estado urgando cambiando de aca para allá y al final he podido ver bien el int (16bits), no me preguntes q hice, porque ni yo mismo se que habrá pasado, porque tengo el código igual que antes...

Ahora tengo un problema con incluir esta librería nueva de funciones de lectura/escritura de bytes, ints, longs, floats, strings en el proyecto. copio todas las funciones a un archivo .h, lo incluyo en el main y lo incluyo en el proyecto y no da =( aparecen 2 tipos de mensajes de error:

1. cuando coloco en el main:
#include <p18lf46j11.h>
#include "flex_lcd_c18.h"
#include <i2c.h>
#include "eep.h"     //entre comillas
#include <stdio.h>
#pragma config WDTEN=OFF,XINST=OFF,CP0=OFF,STVREN=OFF
#pragma config OSC=HS,T1DIG=OFF,LPT1OSC=ON,FCMEN=OFF,IESO=OFF
#pragma config RTCOSC=T1OSCREF,IOL1WAY=OFF
aparece un error de sintaxis en la última linea de mi lib eep.h

2.cuando coloco todo igual exepto:
#include <eep.h>     //entre mayor menor
aparece un mensaje de error que no se encuentran las funciones de la librería que voy colocando en el main.

Como puedo hacer que el proyecto tome bien las funciones de esta nueva librería??

Muchas gracias por la ayuda, saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 29 de Diciembre de 2010, 21:25:21
Me faltó colocar:

#ifndef __EPP_H
#define __EPP_H
...
...
#endif

en mi archivo epp.h, ahora incluyéndolo con comillas va todo bien

 :-/ :-/
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 29 de Diciembre de 2010, 22:40:49
Ahora tengo otra pregunta.

Cual es el valor tamaño más grande que puede tener un arreglo? según mi deducción es de 256, pero a q se debe eso? yo en CCS he usado una vez un arreglo de más de 2500bytes claro que colocandolo como const.

En C18 he intentado hacer lo mismo y no puedo pasar más de 256bytes por arreglo =(

Y hay algo más si declaro así:

unsigned char const arreglo[256];
Y va bien ya que compila

Pero si quiero colocar valores por defecto, los 256 no me deja:
unsigned char const arreglo[256]={1,2,3,4,5,6,7,8,9,0,11,23,45,65,.......}

Aparece un mensaje de error al compilar:
Error - section '.idata_eeprom.o' can not fit the section. Section '.idata_eeprom.o' length=0x000001d4

eeprom es mi archivo main.

Caray que este C18 me esta dando más dolores de cabeza que satisfacciones =(

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 30 de Diciembre de 2010, 01:09:42
Por defecto 256, pero se puede modificar el archivo *.lkr. En el tutorial de C18 se explica eso  ;-)


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 30 de Diciembre de 2010, 15:07:44
Saqué un par de paréntesis que estaban demás y que hacían que el cast fuera incorrecto y por ello un mal direccionamiento dentro de la memoria. Las funciones quedarían así:

Código: C
  1. #define control 0x0a
  2. //      Escribir un byte en Memoria EEPROM 24LC512
  3. unsigned char write_ext_eeprom(unsigned int address,unsigned char data){
  4.   IdleI2C2();                                                           // ensure module is idle
  5.   StartI2C2();                                                          // initiate START condition
  6.   while(SSP2CON2bits.SEN);                              // wait until start condition is over
  7.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  8.     return(-1);                                                 // return with Bus Collision error
  9.   else{                                                                         // start condition successful
  10.     if(WriteI2C2(control))                              // write byte - R/W bit should be 0
  11.       return(-3);                                                       // set error for write collision
  12.     IdleI2C2();                                                 // ensure module is idle
  13.     if(!SSP2CON2bits.ACKSTAT){          // test for ACK condition received
  14.                 if(WriteI2C2(*((char *)&address+1)))                    // write word address for EEPROM
  15.                 return(-3);                                             // set error for write collision
  16.            IdleI2C2();                                                  // ensure module is idle
  17.            if(!SSP2CON2bits.ACKSTAT){           // test for ACK condition received
  18.                 if(WriteI2C2(*((char *)&address)))              // write word address for EEPROM
  19.                         return(-3);                                     // set error for write collision
  20.                         IdleI2C2();                                             // ensure module is idle
  21.                    if(!SSP2CON2bits.ACKSTAT){   // test for ACK condition received
  22.                         if(WriteI2C2(data))             // data byte for EEPROM
  23.                          return(-3);                            // set error for write collision
  24.                    }
  25.                    else
  26.                         return(-2);                                     // return with Not Ack error condition  
  27.                 }
  28.     }
  29.     else
  30.         return(-2);                                                     // return with Not Ack error condition  
  31.   }
  32.   IdleI2C2();                                                           // ensure module is idle  
  33.   StopI2C2();                                                           // send STOP condition
  34.   while(SSP2CON2bits.PEN);                              // wait until stop condition is over
  35.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  36.      return(-1);                                                        // return with Bus Collision error
  37.   return(0);                                                            // return with no error
  38. }
  39.  
  40. //      Escribir Pagina en Memoria EEPROM 24LC512 desde una Cadena
  41. unsigned char write_string_eeprom(unsigned int address,unsigned char *wrptr){
  42.   IdleI2C2();                                                           // ensure module is idle
  43.   StartI2C2();                                                          // initiate START condition
  44.   while(SSP2CON2bits.SEN);                              // wait until start condition is over
  45.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  46.     return(-1);                                                 // return with Bus Collision error
  47.   else{                                                                         // start condition successful
  48.     if(WriteI2C2(control))                              // write byte - R/W bit should be 0
  49.        return(-3);                                              // set error for write collision
  50.     IdleI2C2();                                                 // ensure module is idle
  51.     if(!SSP2CON2bits.ACKSTAT){          // test for ACK condition received
  52.                 if(WriteI2C2(*((char *)&address+1)))                    // write word address for EEPROM
  53.                 return(-3);                                             // set error for write collision
  54.            IdleI2C2();                                                  // ensure module is idle
  55.            if(!SSP2CON2bits.ACKSTAT){           // test for ACK condition received
  56.                 if(WriteI2C2(*((char *)&address)))              // write word address for EEPROM
  57.                         return(-3);                                     // set error for write collision
  58. //*******************************************************************************
  59. //*******************************************************************************
  60.                         IdleI2C2();                                             // ensure module is idle
  61.                    if(!SSP2CON2bits.ACKSTAT){   // test for ACK condition received
  62.                         if(putsI2C2(wrptr))             // data byte for EEPROM
  63.                         return(-4);                             // set error for write collision
  64.                    }
  65. //*******************************************************************************
  66. //*******************************************************************************
  67.                    else
  68.                       return(-2);                                       // return with Not Ack error condition  
  69.                 }
  70.     }
  71.     else
  72.         return(-2);                                                     // return with Not Ack error condition  
  73.   }
  74.   IdleI2C2();                                                           // ensure module is idle  
  75.   StopI2C2();                                                           // send STOP condition
  76.   while(SSP2CON2bits.PEN);                              // wait until stop condition is over
  77.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  78.     return(-1);                                                 // return with Bus Collision error
  79.   return(0);                                                            // return with no error
  80. }
  81.  
  82. //      Lectura de un byte en Memoria EEPROM 24LC512
  83. unsigned char read_ext_eeprom(unsigned int address){
  84.   IdleI2C2();                                                           // ensure module is idle
  85.   StartI2C2();                                                          // initiate START condition
  86.   while(SSP2CON2bits.SEN);                              // wait until start condition is over
  87.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  88.     return(-1);                                                 // return with Bus Collision error
  89.   else{
  90.     if(WriteI2C2(control))                              // write 1 byte
  91.       return(-3);                                                       // return with write collision error
  92.     IdleI2C2();                                                 // ensure module is idle
  93.     if(!SSP2CON2bits.ACKSTAT){          // test for ACK condition, if received
  94.       if(WriteI2C2(*((char *)&address+1)))                      // WRITE word address for EEPROM
  95.         return(-3);                                             // return with write collision error
  96.           IdleI2C2();                                                   // ensure module is idle
  97.      if(!SSP2CON2bits.ACKSTAT){         // test for ACK condition, if received
  98.         if(WriteI2C2(*((char *)&address)))              // WRITE word address for EEPROM
  99.                   return(-3);                                   // return with write collision error
  100.                   IdleI2C2();                                           // ensure module is idle
  101.         if(!SSP2CON2bits.ACKSTAT){      // test for ACK condition, if received
  102.                   RestartI2C2();                                // generate I2C bus restart condition
  103.                   while(SSP2CON2bits.RSEN);// wait until re-start condition is over
  104.                   if(PIR3bits.BCL2IF)           // test for bus collision
  105.               return(-1);                               // return with Bus Collision error
  106.            if(WriteI2C2(control+1))     // write 1 byte - R/W bit should be 1
  107.                   return(-3);                           // return with write collision error
  108.                   IdleI2C2();                                   // ensure module is idle
  109.                   if(!SSP2CON2bits.ACKSTAT){    // test for ACK condition, if received
  110.                   SSP2CON2bits.RCEN=1;  // enable master for 1 byte reception
  111.                   while(SSP2CON2bits.RCEN);     // check that receive sequence is over
  112.                   NotAckI2C2();                                 // send ACK condition
  113.                   while(SSP2CON2bits.ACKEN);// wait until ACK sequence is over
  114.                   StopI2C2();                           // send STOP condition
  115.                   while(SSP2CON2bits.PEN);      // wait until stop condition is over
  116.                   if(PIR3bits.BCL2IF)           // test for bus collision
  117.                         return(-1);                             // return with Bus Collision error
  118.                 }
  119.                   }
  120.         else
  121.           return(-2);                                   // return with Not Ack error
  122.       }
  123.       else
  124.         return(-2);                                             // return with Not Ack error
  125.     }
  126.     else
  127.       return(-2);                                                       // return with Not Ack error
  128.   }
  129.   return((unsigned int)SSP2BUF);                // return with data
  130. }
  131.  
  132. //      Esperar Ack en Memoria EEPROM 24LC512
  133. unsigned char ack_ext_eeprom(){
  134.   IdleI2C2();                                                           // ensure module is idle
  135.   StartI2C2();                                                          // initiate START condition
  136.   while(SSP2CON2bits.SEN);                              // wait until start condition is over
  137.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  138.     return(-1);                                                 // return with Bus Collision error
  139.   else{
  140.     if(WriteI2C2(control))                              // write byte - R/W bit should be 0
  141.       return(-3);                                                       // set error for write collision
  142.     IdleI2C2();                                                 // ensure module is idle  
  143.     if(PIR3bits.BCL2IF)                                 // test for bus collision
  144.       return(-1);                                                       // return with Bus Collision error
  145.     while(SSP2CON2bits.ACKSTAT){                // test for ACK condition received
  146.       RestartI2C2();                                            // initiate Restart condition
  147.       while(SSP2CON2bits.RSEN);         // wait until re-start condition is over
  148.       if(PIR3bits.BCL2IF)                               // test for bus collision
  149.         return(-1);                                             // return with Bus Collision error
  150.       if(WriteI2C2(control))                    // write byte - R/W bit should be 0
  151.         return(-3);                                             // set error for write collision
  152.       IdleI2C2();                                                       // ensure module is idle
  153.     }
  154.   }
  155.   StopI2C2();                                                           // send STOP condition
  156.   while(SSP2CON2bits.PEN);                              // wait until stop condition is over        
  157.   if(PIR3bits.BCL2IF)                                   // test for bus collision
  158.     return(-1);                                                 // return with Bus Collision error
  159.   return(0);                                                            // return with no error    
  160. }

Código: C
  1. void write_float_eeprom(unsigned int address,float data){
  2.    char i;
  3.  
  4.    for(i=0;i<4;++i){
  5.         write_ext_eeprom(address+i,*((char *)&data+i));
  6.         ack_ext_eeprom();
  7.         Delay10KTCYx(4);//8ms
  8.    }
  9. }
  10.  
  11. float read_float_eeprom(unsigned int address){
  12.    char i;
  13.    float data;
  14.  
  15.    for(i=0;i<4;++i){
  16.         *((char *)&data+i)=read_ext_eeprom(address+i);
  17.    }
  18.    return data;
  19. }
  20.  
  21. void write_long_eeprom(unsigned int address,long data){
  22.    char i;
  23.  
  24.    for(i=0;i<4;++i){
  25.         write_ext_eeprom(address+i,*((char *)&data+i));
  26.         ack_ext_eeprom();
  27.         Delay10KTCYx(4);//8ms
  28.    }
  29. }
  30.  
  31. long read_long_eeprom(unsigned int address){
  32.    char i;
  33.    long data;
  34.  
  35.    for(i=0;i<4;++i){
  36.            *((char*)&data+i)=read_ext_eeprom(address+i);
  37.    }
  38.    return data;
  39. }
  40.  
  41. void write_int_eeprom(unsigned int address,int data){
  42.    char i;
  43.  
  44.    for(i=0;i<2;++i){
  45.         write_ext_eeprom(address+i,*((char *)&data+i));
  46.         ack_ext_eeprom();
  47.         Delay10KTCYx(4);//8ms
  48.    }
  49. }
  50.  
  51. int read_int_eeprom(unsigned int address){
  52.    char i;
  53.    int data;
  54.  
  55.    for(i=0;i<2;++i){
  56.         *((char*)&data+i)=read_ext_eeprom(address+i);
  57.    }
  58.    return data;
  59. }

Para guardar un arreglo de variables contante en la memoria de programa:
Código: C
  1. #pragma romdata TablaConstante
  2.         rom const char Buffer[2048]={"Probando ....."};
  3. #pragma romdata

Otra cosa, puedes usar directamente la función write_string_eeprom( sin agregar la palabra reservada rom para guardar el buffer. Pero ten en cuenta que el largo de la cadena (debe tener el carácter '/0' para finalización de cadena) no puede ser mayor al largo de la página de la memoria que estas usando, sino se perderán datos  :?

Saludos!

Título: C18 CAD con interrupción
Publicado por: umalrovi en 03 de Febrero de 2011, 06:12:54
Hola compañeros!!!

En primer lugar daros las gracias por la info que habéis posteado en el foro de todopic en especial a microcadaver. Yo era un programador de CCS pero me ha dado tanto por.... los bugsss que al final he pasado al C18 ya que pienso que si microchip da este lenguaje, será por algo.

Había mandado un privado a nuestro compañero microcadaver, pero hablando con otro del foro, Azicuetano, me dijo que lo postease directamente.

Estoy intentando hacer un proyecto en el cual necesito hacer conversiones por medio de interrupción y me gustaría si me pudierais verificar este código. Os lo paso y me dicís que opinas al respecto.

Un saludo y muchas gracias por vuestra ayuda ayuda!
Código: C
  1. #include <p18f4550.h>   // Definimos el Pic a utilizar.
  2. #include <adc.h>                // Librería del ADC
  3.  
  4. #pragma config PLLDIV=5, CPUDIV=OSC1_PLL2, USBDIV=1
  5.  
  6. #pragma config FOSC=XT_XT, FCMEN=OFF, IESO=OFF
  7.  
  8. #pragma config PWRT=ON, BOR=OFF, BORV=0, VREGEN=OFF
  9.  
  10. #pragma config WDT=OFF, WDTPS=32768
  11.  
  12. #pragma config CCP2MX=OFF, PBADEN=OFF, LPT1OSC=OFF, MCLRE=ON
  13.  
  14. #pragma config STVREN=OFF, LVP=OFF, XINST=OFF, DEBUG=OFF
  15.  
  16. #pragma config CP0=ON, CP1=ON, CP2=ON, CP3=ON
  17.  
  18. #pragma config CPB=ON, CPD=ON
  19.  
  20. #pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON
  21.  
  22. #pragma config WRTC=ON, WRTB=ON, WRTD=ON
  23.  
  24. #pragma config EBTR0=ON, EBTR1=ON, EBTR2=ON, EBTR3=ON
  25.  
  26. #pragma config EBTRB=ON
  27.  
  28.  
  29. #define Pulsador                PORTAbits.RA2
  30. #define ApagarLeds              PORTB=0x00
  31.  
  32.  
  33. unsigned        int     Valor_CAD_CH0=0x00; // Valor del ADC del canal 0
  34.  
  35.  
  36.  
  37. void interrupciones(void);      //prototipo de la interrupcion
  38.  
  39.  
  40.  
  41. #pragma code prioridad_alta = 0X0008
  42. void interrupcion_alta (void)
  43. {
  44.         _asm goto interrupciones _endasm
  45. }
  46. #pragma code//fin de la interrupcion
  47.  
  48.  
  49. #pragma interrupt interrupciones
  50. void interrupciones(void)
  51. {
  52.         if(PIR1bits.ADIF)//pregunta por bandera de interrupcion CAD
  53.         {
  54.                 Valor_CAD_CH0=ReadADC();
  55.                 PIR1bits.ADIF=0;//limpia bandera y salimos
  56.         }
  57. }
  58.  
  59.  
  60.  
  61. void main(void){
  62.        
  63. //      Configuración ADC del compilador
  64.  
  65.  
  66.         OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_20_TAD,       //Config
  67.                         ADC_CH0 & ADC_INT_ON & ADC_REF_VDD_VSS,         //Config2
  68.                         ADC_2ANA);// PortConfig
  69.  
  70.  
  71.        
  72.         INTCONbits.PEIE=1; // Habilitamos interrupcion de perifericos.
  73.         INTCONbits.GIE=1; // Habilitamos interrupcion Global.  
  74.        
  75.         TRISA=0xFF;             //RA0:12 --> ENTRADA
  76.         TRISB=0X00;             //RB0:8 --> SALIDA
  77.         ApagarLeds;
  78.         ConvertADC(); // Empieza a realizar conversiones
  79.  
  80. while(1){
  81.  
  82.         if(Pulsador==1){//Para escribir valor en puerto LAT y para leer varlor con PORT
  83.              PORTB=Valor_CAD_CH0;// Si hemos pulsado --> copiamos el valor del CAD en el puerto B
  84.         }
  85.   }
  86. }
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: umalrovi en 03 de Febrero de 2011, 07:22:08
buenas enqique_86, respecto al problema que tuviste con el ADC del pic18f4550 añadiendo despues de configurar la función OpenADC tal y como pusiste,

Código: C
  1. OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
  2.          ADC_CH2 & ADC_INT_OFF,                     //Config ADCON0
  3.          12);                                 //Config ADCON1
  4.    ADCON1=0x0B;

Te confirmo que el problema está en el tercer argumento de la función OpenADC, pusiste un 12 en decimal que corresponde 1100, es decir AN0:AN2 analógicas y luego pusiste un ADCON1=0x0B para corregir tu problema ya que necesitabas AN0:AN3 analógicas, eso se soluciona configurando la función OpenADC de la siguientes maneras (las dos son válidas):

1.-
Código: C
  1. OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
  2.          ADC_CH2 & ADC_INT_OFF,                     //Config ADCON0
  3.          11);                                 //Config ADCON1

2.- Mira la ayuda en C:\MCC18\doc\periph-lib, este micro corresponde a V5, mira el archivo pconfig.h y viene definido ( /* ADC */
#define ADC_V5).

Código: C
  1. OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
  2.          ADC_CH2 & ADC_INT_OFF,                     //Config ADCON0
  3.          ADC_4ANA);         //       analog:AN0-AN3     digital:AN4-AN15


Un saludete!!!


Hola! Bueno a peticion de microcadaver  :mrgreen: subo un ejemplo utilizando la libreria adc.h, se trata de un voltimetro implementado con un 18F4550 con un cristal de 20Mhz, el funcionamiento es sencillo utiliza el ADC para captar el voltaje en el pin AN3 y luego muestra el valor captado (previamente escalado a la resolucion del ADC) en un LCD de 2x16, la libreria del LCD la saque de otro hilo y esta basada en la libreria XLCD.h de microchip, pueden reemplazarla por la libreria de manejo de LCD que utilizen o si me la piden con gusto se las paso  :-)


#include<p18f4550.h>
#include<delays.h>
#include<stdlib.h>
#include<adc.h>
#include "lcd.h"

#pragma config PLLDIV = 5//CONFIG1L
#pragma config FCMEN = OFF,IESO = OFF,FOSC=HS //CONFIG1H
#pragma config PWRT = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF, CCP2MX = OFF//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF//CONFIG5L
#pragma config CPB = OFF,CPD = OFF//CONFIG5H
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF//CONFIG6L
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF//CONFIG6H
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF//CONFIG7L
#pragma config EBTRB = OFF//CONFIG7H

unsigned float v = 0;
char s[3]={""};
void main(void)
{
   OpenXLCD(FOUR_BIT & LINES_5X7);
   WriteCmdXLCD(BLINK_ON);
   WriteCmdXLCD(CLEAR);
   TRISAbits.TRISA2 = 1;
   LATA=0x00;
   OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
         ADC_CH2 & ADC_INT_OFF,                     //Config ADCON0
         12);                                 //Config ADCON1
   ADCON1=0x0B;
    for( ; ; )
   {   
      s[0] = 0;
      s[1] = 0;
      s[2] = 0;
      SetChanADC(ADC_CH3);
      Delay10TCYx(5);     //Delay de 50Ci
      ConvertADC();
      while(BusyADC());
      v = ReadADC();
      v = v * 488 / 1000;
      ultoa(v,s);         //conversion de un entero a una cadena    
      
      WriteCmdXLCD(CLEAR);//visualizacion de resultado en LCD (2x16)
      putrsXLCD("V1 = ");
      if(s[1]==0 && s[2]==0)
      {
         s[2]=s[0];
         s[1]='0';
         s[0]='0';
      }
      if(s[2]==0)
      {
         s[2]=s[1];
         s[1]=s[0];
         s[0]='0';      
      }
      putcXLCD(s[0]);
      putcXLCD('.');
      putcXLCD(s[1]);
      putcXLCD(s[2]);

      Delay10KTCYx(50); //Delay de 100ms
   }
}



Como podran ver en el datasheet del 18F4550 al ejecutar la instruccion ADCON1=0x0B lo que hago es configurar los voltajes de referencia internos a Vss y Vdd, ademas de configurar los pines analogicos que se van a emplear, esto se tendria que hacer mediante la instruccion OpenADC pero es aqui donde tuve los problemas, lo que pasa es q la libreria adc.h para el PIC 18f4550 utiliza solo numeros enteros entre 0 y 15, que al utilizarlos no contemplan la configuracion de los voltajes de referencia para el conversor ADC, pues lo pone por defecto como las entradas a los pines AN2 y AN3, y del modo que queria hacerlo esto no me funcionaba, es por eso que añado la intruccion ADCON1=0x0B luego de utilizar la instruccion OpenADC de este modo si funciono asi que aqui esta lo que hice.. Espero les sirva   :-) 

                                                                                                                          ...Saludos... :-/

 
Título: Re: C18 CAD con interrupción
Publicado por: Suky en 03 de Febrero de 2011, 12:49:40
Estoy intentando hacer un proyecto en el cual necesito hacer conversiones por medio de interrupción y me gustaría si me pudierais verificar este código. Os lo paso y me dicís que opinas al respecto.

Hola! Cual es el problema?  :rolleyes:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: umalrovi en 03 de Febrero de 2011, 14:34:27
Hola Suky, gracias por contestar. Mi problema es que cuando simulo en MPLAB, y termina de realizar la conversión lo que hago es copiar el resultado de la convesión en el puerto B. Primero hago un estimulo en el pulsador y pongo el An0 a 5Vdc para que se meta dentro del bucle y ponga el valor del CAD en el puerto B. Pues leo ese valor y me da 0. Ese es mi problema y no se si hago hago mal o que es lo que ocurre.

Un saludo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 03 de Febrero de 2011, 19:54:40
No he utilizado MPLAB para hacer ese tipo de simulaciones, estas seguro que lo hace correctamente? Puede que proteus sea mejor para ese caso.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: umalrovi en 04 de Febrero de 2011, 05:28:29
Buenas Suky,

Intentaré bajarme la versión DEMO del proteus ya que no dispongo de ella. Un factor en contra, es que no tengo pleno control sobre el Proteus. He visto que hay muchos tutoriales el este foro pero tardare un tiempo en hacerme con ellos. T

Te agradecería muchísimo que mirases el código por si pudiera mejorar la interrupción del CAD y si está bien implementado.

Muchas gracias por tu ayuda!
Título: OFFTOPIC Re: C18 CAD con interrupción
Publicado por: micro_cadaver en 16 de Febrero de 2011, 16:31:09
Hola compañeros!!!

En primer lugar daros las gracias por la info que habéis posteado en el foro de todopic en especial a microcadaver. Yo era un programador de CCS pero me ha dado tanto por.... los bugsss que al final he pasado al C18 ya que pienso que si microchip da este lenguaje, será por algo.

Había mandado un privado a nuestro compañero microcadaver, pero hablando con otro del foro, Azicuetano, me dijo que lo postease directamente.

Hola umalrovi, me disculpo publicamente por no poder ayudarte, que bien que decidistes postearlo, siempre es mejor asi pues mucha gente lo puede ver y responder a mayor probabilidad que una sola persona.

La vida de casado te absorbe bastante jejeje  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: micronet3 en 08 de Marzo de 2011, 20:10:38
Hola microcadaver que tal, hasta ahora e usado el ccs, pero he decido cambiarme a c18 o a mikroc, felicitaciones por el trabajo, con tu tutorial aprendo en una  semana  c18 jejeje

saludos y felicitaciones
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 10 de Marzo de 2011, 17:14:49
El aporte que hacen es genial para los que estamos empezando con este lenguaje :mrgreen: :mrgreen: , al momento de realizar mis primeras experiencias(sin mucho exito) me encuentro que al momento de compilar el programa me aparece un mensaje(esta en adjuntos, aun no aprendi a insertar imagenes jejeje), el cual al parecer avisa(segun mi pobre ingles :D) de que se esta ejecutando el modo extendido pero que no he habiltado tal modo para la compilacion lo cual puede que mi codigo no se ejecute correctamente, no se en cuanto puede afectar esto a mi programa y como pudiera arreglarlo  :-/ :-/ :-/

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 10 de Marzo de 2011, 18:31:19
Hola c@Lic_0:
                    el compilador te está alertando sobre el uso del modo extendido cuando tu programa lo has hecho para no usar dicho modo. Si bien vas a tener un archivo *.hex como resultado, el compilador te alerta que el programa va a tener un mal funcionamiento.
                    Posiblemente tengas mal configurados los fuses.
EN especial este: #pragma config XINST = OFF
                    Si puedes muestra tu código para ver en donde está el error.

Mientras mira esta información:
http://www.microchip.com/forums/m460560.aspx

http://www.todopic.com.ar/foros/index.php?topic=24296.0

http://old.nabble.com/Turning-off-extended-CPU-mode-configuration-bit-td8777884.html

                   Saludos.
                             Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 10 de Marzo de 2011, 20:13:27
pues le diste en el clavo :D :D :D le puse XINST=OFF y todo andó ok, aunque sucede algo raro, me creo otro proyecto en el cual nisiquiera configuro el bit ese y me compila sin problema, en el anterior programa(en el cual tenia el problema) la linea:
Código: [Seleccionar]
#pragma config XINST = OFF
//ON:Instruction set extension and Indexed Addressing mode enabled

la comento eh igualmente me vuelve a aparecer el mensaje, algo nu anda bien, pero lo bueno es que se que para que no haya problema mejor le pongo no mas el XINST=OFF (aunque lueguito lo usare :-/ :-/) grax por la ayuda.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 10 de Marzo de 2011, 20:24:21
Fijate en este otro proyecto que mencionas que no hayas seleccionado en el menú
del proyecto en:

Project > Build > Options > project
          la opción de modo extendido. 'Extended Mode'
               Saludos.
                     Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 11 de Marzo de 2011, 14:59:23
hay algo que no entiendo :( :(, estoy haciendo pruebas con el LCD y hay funciones que se deben de agregar(para que puedan funcionar)al proyecto y hay otras que no es necesario agregarlas para que funcionen:
(http://img834.imageshack.us/img834/6177/funciones.jpg)
Como se obserrva en la grafica necesito agregar tanto la funcion gotoXLCD.c y putrxlcd.c para que estas funcionen de no hacerlo me aparecen errores, como se ve en el programa uso tambien otras funciones(Openxlcd(),WriteCmdXLCD(),etc.) que se encuentran en el mismo drirectorio que putrxlcd.c y no necesito agregarlas para que estas funcionen.
Por que sucede esto o como se que funciones debo colocarlas(cargarlas) y cuales no o tal vez hay alguna forma de direccionarlas en el proyecto 

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 15 de Marzo de 2011, 16:05:00
Una ayuda con las interrupciones.
Situacion:
Tengo la interrupcion de tx y rx del eusart ambas con alta prioridad activas,  me llega la interrupcion de trasmision TXIF y salta a la interrupcion, ejecuto mi programa de la interrupcion(de TXIF) y antesitos de salir :D :D de esta interrupcion se activa la bandera de RCIF(indicando que me llego un dato), despues de salir de la interrupcion volveria a entrar(a la interrupcion) por la activacion de la bandera de RCIF ?¡

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 15 de Marzo de 2011, 16:43:54
Una ayuda con las interrupciones.
Situacion:
Tengo la interrupcion de tx y rx del eusart ambas con alta prioridad activas,  me llega la interrupcion de trasmision TXIF y salta a la interrupcion, ejecuto mi programa de la interrupcion(de TXIF) y antesitos de salir :D :D de esta interrupcion se activa la bandera de RCIF(indicando que me llego un dato), despues de salir de la interrupcion volveria a entrar(a la interrupcion) por la activacion de la bandera de RCIF ?¡

Saludos.


Exactamente, sale y inmediatamente salta al vector de interrupción nuevamente.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 16 de Marzo de 2011, 18:39:51
Hola compañeros, no entiendo esto:  :oops:
 
El operador & es utilizado generalmente para llevar a cero ciertos bits. Por ejemplo:

k=0xA5;
a=0xF0 & k; // a = 0xA0, k= 0xA5

¿Porque a = 0xA0 y k no varia?
¿Como se que bits se pondran a 0?

El operador | es utilizado para setear ciertos bits. Por ejemplo:

k=0x03;
a=0x40 | k; // a = 0x43, k = 0x03

¿Porque a = 0x43 y k no varia?
¿Como se que bits se van a setear?

Quiero dejar constancia del buen hacer de Suky con su tutorial C18 del cual saco dichas dudas.

Saludos y GRACIAS.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 16 de Marzo de 2011, 18:59:16
Hola Miquel_s.

¿Porque a = 0x43 y k no varia?
porque estás asignando a la variable    a     el resultado de sumar a+k. Y k no se altera.
Para que la variable   k   cambie deberías igualarla a algo. Para que se le asigne un valor. Por ejemplo k=1;


El operador AND "&" compara dos bits; si los dos son 1 el resultado es 1, en otro caso el resultado será 0.

Para aprender mejor los operadores a nivel de bits te recomiendo que trabajes en formato binario. Así ves mas claras las cosas y los cambios que se hacen.

El operador AND funciona como un colador que deja pasar únicamente los bits que están en uno.

k =  0xA5=10100101
a =  0xA0=10100000
-------------------------
k & a       =10100000
( en este ejemplo dejó pasar únicamente los bits 7 y 5)



otro Ejemplo:

        c1 = 0x45      --> 01000101
        c2 = 0x71      --> 01110001
                 ---------------------------
      c1 & c2 = 0x41 --> 01000001



El operador OR  "|" compara dos bits; si cualquiera de los dos bits es 1, entonces el resultado es 1; en otro caso será 0. Ejemplo:

        i1 = 0x47      --> 01000111
        i2 = 0x53      --> 01010011
        ---------------------------
       i1 | i2 = 0x57 --> 01010111


Para convertir los números de hexadecimal a binario podés usar la calculadora de windows en modo científico o programador (windows 7) y listo. o usá
http://easycalculation.com/hex-converter.php

              Saludos.
                  Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 17 de Marzo de 2011, 05:22:02
Mira que soy BURRO, llevaba dos dias dandole vueltas y no lo veia, pues claro, en la puerta AND todo debe ser 1 para que su salida tambien sea 1 y con la OR con que solo uno de ellos sea 1 su salida sera 1.
Eso de tantos años sin estudiar electronica digital tiene sus consecuencias  :x

Gracias jukinch.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 17 de Marzo de 2011, 17:47:48
Tengo un problema con la definicion y declaracion de variables en los .c y .h, tengo entendido que:

fileA.h:
extern char variable;

fileA.c:
#include "fileA.h"
char variable;

fileB.c
#include "fileA.h"
variable=50;

hasta ahi todo bien, pero si quiero usar la misma variable en otro archivo .c no puedo hacerlo...

como se hace? es todo un rollo esto de los .c y .h, alguien conoce una guia para saber q se hace y que no con estos archivos?

Lo q nose hacer es crear una variable en un archivo C, y este se incluya en un archivo B y el archivo B se incluya en el archivo A, por tanto A tendrá las variables de B y C. como hacer?

gracias.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 17 de Marzo de 2011, 17:52:22
Tengo un problema con la definicion y declaracion de variables en los .c y .h, tengo entendido que:

fileA.h:
extern char variable;

fileA.c:
#include "fileA.h"
char variable;

fileB.c
#include "fileA.h"
variable=50;

hasta ahi todo bien, pero si quiero usar la misma variable en otro archivo .c no puedo hacerlo...

como se hace? es todo un rollo esto de los .c y .h, alguien conoce una guia para saber q se hace y que no con estos archivos?

Lo q nose hacer es crear una variable en un archivo C, y este se incluya en un archivo B y el archivo B se incluya en el archivo A, por tanto A tendrá las variables de B y C. como hacer?

gracias.
No, no es así, sería de la siguiente manera:

fileA.h:
Nada

fileA.c:
#include "fileA.h"
char variable;

fileB.c
#include "fileA.h"
extern char variable;
variable=50;


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 17 de Marzo de 2011, 17:56:53
ok muchas gracias por la pronta respuesta.

que es lo que se coloca en los .h entonces?

como hago para tener la misma varible en 3 o más .c??
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 17 de Marzo de 2011, 18:00:46
ok muchas gracias por la pronta respuesta.

que es lo que se coloca en los .h entonces?

como hago para tener la misma varible en 3 o más .c??

En el .h se incluyen otras librerías necesarias para el .c, se realizan los defines, los typedef, ect.

En el .c que quieras usar una variable externa a él debes declararla como extern. Otra opción es crear funciones que escriban o lean sobre la variable, y solo te dedicas a llamar dichas funciones, pero es mucho menos eficaz en el sentido de tiempo de ejecución.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 17 de Marzo de 2011, 18:39:33
como harías tu para tener una variable global para tres o mas archivos .c?

y para definir constantes, sería la misma idea?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 17 de Marzo de 2011, 19:26:00
como harías tu para tener una variable global para tres o mas archivos .c?

y para definir constantes, sería la misma idea?

Para definir constantes que utilizaras en varios archivos creas un solo *.h que lo llamas donde lo necesites. (#include "definiciones.h")

definiciones.h
Código: [Seleccionar]
typedef unsigned char UINT8
typedef unsigned int UINT16


Para definir declarar variables, en un *.c las creo y en los demás que las necesite las definís declaras como extern.

fuente1.c
Código: [Seleccionar]
#include "definiciones.h"

UINT8 myVar8;
UINT16 myVar16;

fuente2.c
Código: [Seleccionar]
#include "definiciones.h"

extern UINT8 myVar8;
extern UINT16 myVar16;

fuente3.c
Código: [Seleccionar]
#include "definiciones.h"

extern UINT8 myVar8;
extern UINT16 myVar16;

Saludos!


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 18 de Marzo de 2011, 10:21:08
genial! como siempre ídolo! gracias :-/ yo lo estaba haciendo a la inversa, colocaba solo un extern.

un malentendido de conceptos... definir es:
extern char variable;??

y declarar es:
char variable;??

y en funciones, definir es:
void funcionx(void);??

y declara es:
void funcionx(void){
...
}??

estoy bien?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 18 de Marzo de 2011, 12:30:20
Perdón, yo he confundido los terminos anteriormente  :oops: Pero declarar es dar a conocer al compilador la función, su definición puede estar en cualquier lado, entonces:

void vMyFuncion(char); Es una declaración y

void vMyFuncion(char Data){

// ....
}

Es la definición de la función.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 18 de Marzo de 2011, 13:27:11
Gracias,

En caso de las funciones, si voy a usarlas en distintos .c, tambien se debe hacer lo mismo con extern?
donde defino y donde declaro las funciones??

Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 18 de Marzo de 2011, 13:32:40
Gracias,

En caso de las funciones, si voy a usarlas en distintos .c, tambien se debe hacer lo mismo con extern?
donde defino y donde declaro las funciones??

Saludos

Si se puede usar extern, o podes llamar al *.h en donde se declaran las funciones.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 18 de Marzo de 2011, 18:20:35
 :-/ :-/ entendido, muchas gracias por toda la ayuda.

grande suky!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 22 de Marzo de 2011, 16:32:21
Nuevamente con una duda, quisiera guardar datos por defecto en la eeprom de un 1826k22, hice esto:

#pragma romdata eedata_scn=0xf00000
rom unsigned char eedata_values[]={1};
#pragma romdata

Pero no se ha guardado, como se hace ello?

Gracias.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 22 de Marzo de 2011, 17:43:30
Ufff!  :z) Ni idea! Averiguando!  :undecided:


He probado esto en un 18F14K50 y funciona:
Código: C
  1. #pragma romdata EEDATA=0xF00000
  2.         rom const char buff[]={0xAA,0x55,0x33};
  3. #pragma romdata

 :rolleyes:


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 23 de Marzo de 2011, 13:48:14
Hola compañeros, tengo una duda con lo de las interrupciones, para cargar un valor dentro del TIMER0 con CCS se usa la instruccion:

set_TIMER0();

en C18 ¿es el mismo procedimiento?
Código: CSS
  1. /* ** Rutina de Interrupcion ** */
  2.  
  3. #pragma interrupt Temporizacion
  4. void Temporizacion (void)
  5. {
  6.         ++contadorRTCC;
  7.         if(contadorRTCC==4)
  8.         {
  9.   [color=red]set_TIMER0();[/color]
  10.         }
  11.         if(contadorRTCC==5)
  12.         {
  13.                 flagRTCC=1;
  14.                 contadorRTCC=0x00;
  15.         }      
  16. }

Alguien sabe de algun manual donde se pueda aprender esto del TIMER0 y mas, una especie del manual de CCS

Gracias.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 23 de Marzo de 2011, 16:04:13
Perdon otra vez  :mrgreen:

Seria correcto de esta manera:
Código: CSS
  1. TIMER0(30)

Gracias de nuevo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 23 de Marzo de 2011, 19:09:04
Puede ser

TMR0=30

o según librería: C:/MCC18/doc/periph-lib/Timer.htm

WriteTimer0(30)



Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 24 de Marzo de 2011, 04:37:05
Gracias Suky por tu respuesta, no habia mirado estos documentos de la carpeta que indicas. :x

Saludos.
 
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 24 de Marzo de 2011, 10:03:58
He probado esto en un 18F14K50 y funciona:
Código: C
  1. #pragma romdata EEDATA=0xF00000
  2.         rom const char buff[]={0xAA,0x55,0x33};
  3. #pragma romdata
Si funciona, lo pude ver en el .hex, lo que me extraña es q grabo la posición0 con el dato 0x01, tengo las funciones de lectura y escritura como las desarrollaron anteriormente en un otro post (http://www.todopic.com.ar/foros/index.php?topic=17017.msg190008#msg190008) acá en el mismo hilo. Salvo q en la addres,como el pic q uso usa 10bits para direccionar hago:
EEADRH=eeprom_addr>>8;        //Colocar parte alta de la direccion a escribir en EEPROM
EEADR=eeprom_addr;            //Colocar parte baja de la direccion a escribir en EEPROM

Leo esa misma posición al inicializar el pic y me lee cero :shock:, después vuelvo a escribir y leer y recién va bien. Muy extraño... y de paso el grabador esta dejando de grabar... ando con una suerte...

Seguiré probando, espero todo marche bien
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 24 de Marzo de 2011, 12:10:46
Probaste de usar la librería eep.h ? Allí tienes las funciones Write_b_eep(...)  y Read_b_eep(....)


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 24 de Marzo de 2011, 12:37:31
No las conocía, las probare entonces...

Pero primero esta este grabador que ya no quiere reconoces los micros =(

Gracias
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 30 de Marzo de 2011, 17:48:19
Hola compañeros, necesito de vuestra ayuda:
Estoy compilando este codigo y me sale error de sintaxis en la linea 49 #pragma code PrioridadBaja = 0x18  y no consigo verlo :shock:

Código: CSS
  1. /*-----------------------------------------------------------------------------------------*/
  2. /* ** INTERRUPCION DEL TIMER0 USADA PARA CONTROLAR UN SERVO FUTABA S3003 **
  3. -----------------------------------------------------------------------------------------*/
  4.  
  5. /* ** Archivo con definicion de registros y bits del microcontrolador elegido ** */
  6.  
  7. #include <p18f4550.h>
  8.  
  9. /* ** Libreria para incluir demoras en nuestro codigo
  10.                 Delay10TCYx(i) --> 10.Tcy.i
  11.                 Delay100TCYx(i) --> 100.Tcy.i
  12.                 Delay1KTCYx(i) --> 1000.Tcy.i
  13.                 Delay10KTCYx(i) --> 10000.Tcy.i
  14. Donde Tcy es 4/Fosc, e i es un escalar que puede tomar valores entre 0 y 255 ** */
  15.  
  16. #include <delays.h>
  17.  
  18. /* ** Libreria destinada al uso del Timer0 ** */
  19.  
  20. #include <timers.h>
  21.  
  22. /* ** Configuracion de los fuses del microcontrolador ** */
  23.  
  24. #pragma config FOSC=XT_XT,FCMEN=OFF,IESO=OFF,CPUDIV=OSC1_PLL2
  25. #pragma config PWRT=OFF,BOR=OFF,BORV=0,WDT=OFF,MCLRE=OFF
  26. #pragma config LPT1OSC=OFF,PBADEN=OFF,LVP=OFF,DEBUG=OFF
  27. #pragma config CCP2MX=OFF,STVREN=OFF,XINST=OFF
  28. #pragma config CP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF,CPB=OFF
  29. #pragma config CPD=OFF,WRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF
  30. #pragma config WRTC=OFF,WRTB=OFF,WRTD=OFF
  31. #pragma config EBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTR3=OFF,EBTRB=OFF
  32.  
  33. /* ** Definiciones de Preprocesador ** */
  34.  
  35. //#define PIN_SERVO1    LATBbits.LATB0
  36.  
  37. /* ** Definicion de Variables Globales ** */
  38.  
  39. int contadorRTCC = 0;
  40. int flagRTCC = 0;
  41.  
  42. /* ** Declaracion de Funciones a usar ** */
  43.  
  44. void Temporizacion (void)
  45.  
  46. /* ** Vector de Interrupcion ** */
  47.  
  48. #pragma code PrioridadBaja = 0x18               // Se apunta al Vector de Baja Prioridad
  49. void VectorPrioridadBaja(void)
  50. {
  51.         _asm
  52.                 goto Temporizacion              // Indicamos al compilador donde esta la interrupcion
  53.         _endasm
  54. }
  55. #pragma code
  56.  
  57. /* ** Rutina de Interrupcion ** */
  58.  
  59. #pragma interrupt Temporizacion
  60. void Temporizacion (void)
  61. {
  62.         ++contadorRTCC;
  63.         if(contadorRTCC==4)
  64.         {
  65.                 WriteTimer0(30);                        // Ajuste fino del RTCC
  66.         }
  67.         if(contadorRTCC==5)
  68.         {
  69.                 flagRTCC=1;
  70.                 contadorRTCC=0x00;
  71.         }      
  72. }
  73.  
  74. /* **  M A I N  ** */
  75.  
  76. void main(void)
  77. {
  78.         ADCON1=0x0F;            // Todos entradas/salidas digitales
  79.         TRISA=0XFF;                     // Todos como entradas
  80.         TRISB=0xF0;                     // Nible bajo como salida
  81.         PORTB=0x00;                     // Salidas apagadas
  82.         T0CON=0xC3;                     // Configuramos Timer0
  83.         WriteTimer0(0);         // Inicializamos registros del Timer0
  84.         INTCON=0xA0;            // Configuramos la Interrupcion del Timer0     
  85.         RCONbits.IPEN=0;                // Desabilitamos Prioridades
  86.  
  87. while(1);
  88.        
  89. }
  90.  
  91. /* **  F U N C I O N E S  ** */

Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 30 de Marzo de 2011, 20:35:03
hola Miquel_S:
   Si no me equivoco , el error está más arriba en la línea que aparece en geshi como 44.

void Temporizacion (void)

faltaría al final de esa línea un     ;       y por eso el compilador cree que la línea sigue más abajo y te muestra el error allí.
      Saludos.
          Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 30 de Marzo de 2011, 20:35:27
Eso! Eso! Falta el ;  :mrgreen:

jukinch 20s más rápido  :undecided: :laugh:

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 30 de Marzo de 2011, 20:56:27
Eso! Eso! Falta el ;  :mrgreen:

jukinch 20s más rápido  :undecided: :laugh:

Saludos!

Que halago de un maestro como vos Suky ;) Mis conocimientos de c18 salieron de tu manual!!! Un abrazo desde San Nicolás.-
         Jukinch


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 31 de Marzo de 2011, 03:16:42
 :oops: :oops: :D

Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 08 de Abril de 2011, 18:36:29
Saludos de nuevo, sigo intentando aprender en C18  :shock: Estoy intentando una temporizacion de 4,096ms pero no consigo entrar en la interrupcion y no veo el porque, si alguien pudiera decir el fallo lo agradeceria.
Código: CSS
  1. //********************************************************************************
  2. /* ** Programa para generar una Interrupcion cada 4,096ms usando el TIMER0 ** */
  3. //********************************************************************************
  4.  
  5. /* ** Archivo con definicion de registros y bits del microcontrolador elegido ** */
  6.  
  7. #include <p18f4550.h>
  8.  
  9. /* ** Include para realizacion de Demoras ** */
  10.  
  11.  
  12.  
  13. /* ** Include para Timer0 ** */
  14.  
  15. //#include <timers.h>
  16.  
  17. /* ** Configuracion de los Fuses del microcontrolador ** */
  18.  
  19. #pragma config FOSC = XT_XT,FCMEN = OFF,IESO = OFF,CPUDIV = OSC1_PLL2
  20. #pragma config PWRT = ON,BOR = OFF,BORV =0,WDT = OFF
  21. #pragma config WDTPS = 32768,CCP2MX = OFF,PBADEN = OFF,LPT1OSC = OFF
  22. #pragma config MCLRE = ON,STVREN = OFF,LVP = OFF,ICPRT = OFF
  23. #pragma config XINST = OFF,DEBUG = OFF,CP0 = OFF,CP1 = OFF
  24. #pragma config CP2 = OFF,CP3 = OFF,CPB = OFF,CPD = OFF
  25. #pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
  26. #pragma config WRTC = OFF,WRTB = OFF,WRTD = OFF,EBTR0 = OFF
  27. #pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF,EBTRB = OFF
  28.  
  29. /* ** Directivas de Preprocesador ** */
  30.  
  31. //#define LED_ROJO              LATBbits.LATB0
  32. //#define LED_VERDE             LATBbits.LATB1
  33.  
  34. /* ** Declaracion de Funciones a utilizar ** */
  35.  
  36. void Temporizacion(void);
  37.  
  38. /* ** Variables de uso General ** */
  39.  
  40. volatile int tiempo;
  41.  
  42. /* ** Seccion de codigo a partir de la direccion 0x18 ** */
  43.  
  44. #pragma code interrupcion = 0x0018
  45. void VectorInterrupcion(void)
  46. {
  47.         _asm goto Temporizacion _endasm
  48. }
  49. #pragma code    // Cerramos seccion.-
  50.  
  51. /* ** Rutina de Interrupcion ** */
  52.  
  53. #pragma interrupt Temporizacion
  54. void Temporizacion(void)
  55. {
  56.         if(INTCONbits.TMR0IF==1)
  57.         {
  58.                 //PORTB=1;
  59.                 tiempo++;
  60.                 INTCONbits.TMR0IF=0;
  61.         }
  62.         //else
  63.         //{
  64.                 //LED_ROJO=1;
  65.         //}
  66. }
  67.  
  68.  
  69. /* ** Main ** */
  70.  
  71. void main(void)
  72. {
  73.  
  74. ADCON1 = 0X0F;
  75. TRISB = 0X00;
  76. PORTB = 0X00;
  77. T0CON = 0XC3;           //configuramos el timer0
  78. TMR0H = 0X00,TMR0L = 0X00;              //inicializamos registros del timer0
  79. RCONbits.IPEN=0;               
  80. INTCON = 0XA0;          //configuramos la interrupcion del timer0
  81.        
  82.         while(1);
  83. }

Gracias de nuevo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 08 de Abril de 2011, 19:15:45
se me hace que las interrupciones saltan por defecto a la direccion 0x08 y no a la 0x018 talvez sea ese tu problema.

#pragma code interrupcion = 0x0008

en vez de:

#pragma code interrupcion = 0x0018

si usas 0x0018 seguramente tendrías q ver el las configuraciones de las prioridades
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 09 de Abril de 2011, 04:39:42
Hola Cryn, gracias por la respuesta, tenia entendido que la direccion 0x018 era la de baja prioridad y la 0x08 la de alta, y si no me equivoco lo tengo bien configurado de todos modos volvere a revisar el codigo en su parte de configuracion.

Gracias de nuevo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 09 de Abril de 2011, 09:37:29
Pero tienes des-habilitadas las prioridades...



Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 09 de Abril de 2011, 10:59:08
Hola Suky gracias por tu respuesta, pero aunque ponga el bit IPEN a 1 (Enable priority levels on interrupts) sigo con el mismo fallo, solo me funciona con 0x0008 que seria la de alta prioridad.

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 09 de Abril de 2011, 12:18:11
Debes configurar TMR0IP a 0, pues INTCON2 por default tiene 0xFF según veo en el datasheet.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 09 de Abril de 2011, 12:54:18
Gracias maestro Suky por la respuesta.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 09 de Abril de 2011, 21:33:24
Hola de nuevo, no doy pie con bola, estoy seguro que es una tonteria en la configuracion, pero no consigo que funcione con la interrupcion de baja prioridad  :5]
Código: CSS
  1. //********************************************************************************
  2. /* ** Programa para generar una Interrupcion cada 4,096ms usando el TIMER0 ** */
  3. /* ** Con Interrupcion de Baja Prioridad ** */
  4. //********************************************************************************
  5.  
  6. /* ** Archivo con definicion de registros y bits del microcontrolador elegido ** */
  7.  
  8. #include <p18f4550.h>
  9.  
  10. /* ** Include para realizacion de Demoras ** */
  11.  
  12.  
  13.  
  14. /* ** Include para Timer0 ** */
  15.  
  16. #include <timers.h>
  17.  
  18. /* ** Configuracion de los Fuses del microcontrolador ** */
  19.  
  20. #pragma config FOSC = XT_XT,FCMEN = OFF,IESO = OFF,CPUDIV = OSC1_PLL2
  21. #pragma config PWRT = ON,BOR = OFF,BORV =0,WDT = OFF
  22. #pragma config WDTPS = 32768,CCP2MX = OFF,PBADEN = OFF,LPT1OSC = OFF
  23. #pragma config MCLRE = ON,STVREN = OFF,LVP = OFF,ICPRT = OFF
  24. #pragma config XINST = OFF,DEBUG = OFF,CP0 = OFF,CP1 = OFF
  25. #pragma config CP2 = OFF,CP3 = OFF,CPB = OFF,CPD = OFF
  26. #pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
  27. #pragma config WRTC = OFF,WRTB = OFF,WRTD = OFF,EBTR0 = OFF
  28. #pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF,EBTRB = OFF
  29.  
  30. /* ** Directivas de Preprocesador ** */
  31.  
  32. //#define LED_ROJO              LATBbits.LATB0
  33. //#define LED_VERDE             LATBbits.LATB1
  34.  
  35. /* ** Declaracion de Funciones a utilizar ** */
  36.  
  37. void Temporizacion(void);
  38.  
  39. /* ** Variables de uso General ** */
  40.  
  41. volatile int Cont = 0;
  42.  
  43. /* ** Seccion de codigo a partir de la direccion 0x18 ** */
  44.  
  45. #pragma code interrupcion = 0x18
  46. void VectorInterrupcion(void)
  47. {
  48.         _asm goto Temporizacion _endasm
  49. }
  50. #pragma code    // Cerramos seccion.-
  51.  
  52. /* ** Rutina de Interrupcion ** */
  53.  
  54. #pragma interrupt Temporizacion
  55. void Temporizacion(void)
  56. {
  57.         if(INTCONbits.TMR0IF==1)
  58.         {
  59.                 PORTB=~PORTB;
  60.                 Cont++;
  61.                 INTCONbits.TMR0IF=0;
  62.         }
  63. }
  64.  
  65.  
  66. /* ** Main ** */
  67.  
  68. void main(void)
  69. {
  70.  
  71. ADCON1 = 0X0F;
  72. TRISB = 0X00;
  73. PORTB = 0X00;
  74. OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_16);
  75. INTCON2bits.TMR0IP = 0;         // Prioridad baja.-
  76. RCONbits.IPEN = 0;              // Desabilitamos nivel de Prioridad.-
  77. INTCONbits.GIE = 1;
  78. INTCONbits.TMR0IE = 1;
  79. WriteTimer0(0);         // Inicializamos el Timer0.-
  80.        
  81. while(1);
  82. }

Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 09 de Abril de 2011, 22:36:09
Pero si es con prioridades tenes que colocar:

RCONbits.IPEN=1;         // Habilitamos prioridades.-
INTCONbits.GIEL=1;         // Habilitamos interrupciones de baja prioridad.-

Vector 0x0018

Sino:

RCONbits.IPEN=0;    // Deshabilitamos Prioridades
INTCONbits.PEIE=1;    // Habilitamos interrupcion de perifericos .-
INTCONbits.GIE=1;    // Habilitamos interrupcion Global .

Vector 0x0008

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 10 de Abril de 2011, 13:07:38
Gracias Suky por tu tiempo, lei lo del PEIE/GIEL pero entendi que era para configurar las interrupciones donde uses perifericos.
When IPEN = 1 (1= Enables all low-priority peripheral interrupts)

Gracias de nuevo.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 10 de Abril de 2011, 13:14:26
 :oops: Perdon se me habia olvidado,  para realizar un ciclo for para que repita la interrupcion un cierto numero de veces, es mejor hacerlo dentro de la misma interrupcion o por el contrario hacerlo en el main.

Miquel_S
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 11 de Abril de 2011, 10:07:36
Lo mejor es tener el menor código posible dentro de una interrupción, setear banderas o algun proceso corto, preferiblemente dejar de lado ciclos largos y retardos del orden de los milisegundos. Ya en el main, a partir de las banderas cambiadas, realizar lo procesos necesarios.

No he trabajado con las interrupciones de baja prioridad todavía, seguramente es algún detallito en las configuraciones, revisa con más detenimiento la hoja de datos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 11 de Abril de 2011, 13:15:59
No entendí, sigue sin funcionar?

El tema de las interrupciones, depende de que se trate... Pero lo mejor es como dice Cryn, activar una bandera y tratarla en el bucle principal.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 11 de Abril de 2011, 16:43:48
Miquel_S :
         Puntualmente en esto no entiendo a que te referís:
...repita la interrupcion un cierto numero de veces..
              Saludos a todos.
               Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 11 de Abril de 2011, 16:47:41
Gracias por vuestras respuestas, de funcionar me funciona, despues de configurar lo que Suky me dijo, preguntaba lo del ciclo for porque me interesaba repetir hasta conseguir 20ms,  pero lo hice con do while, pero necesita terminar de pulir.

De nuevo Muchas Gracias.
Código: CSS
  1. //********************************************************************************
  2. /* ** Programa para generar una Interrupcion cada 4,096ms usando el TIMER0 ** */
  3. /* ** Con Interrupcion de Baja Prioridad ** */
  4. //********************************************************************************
  5.  
  6. /* ** Archivo con definicion de registros y bits del microcontrolador elegido ** */
  7.  
  8. #include <p18f4550.h>
  9.  
  10. /* ** Include para realizacion de Demoras ** */
  11.  
  12.  
  13.  
  14. /* ** Include para Timer0 ** */
  15.  
  16. #include <timers.h>
  17.  
  18. /* ** Configuracion de los Fuses del microcontrolador ** */
  19.  
  20. #pragma config FOSC = XT_XT,FCMEN = OFF,IESO = OFF,CPUDIV = OSC1_PLL2
  21. #pragma config PWRT = ON,BOR = OFF,BORV =0,WDT = OFF
  22. #pragma config WDTPS = 32768,CCP2MX = OFF,PBADEN = OFF,LPT1OSC = OFF
  23. #pragma config MCLRE = ON,STVREN = OFF,LVP = OFF,ICPRT = OFF
  24. #pragma config XINST = OFF,DEBUG = OFF,CP0 = OFF,CP1 = OFF
  25. #pragma config CP2 = OFF,CP3 = OFF,CPB = OFF,CPD = OFF
  26. #pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
  27. #pragma config WRTC = OFF,WRTB = OFF,WRTD = OFF,EBTR0 = OFF
  28. #pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF,EBTRB = OFF
  29.  
  30. /* ** Directivas de Preprocesador ** */
  31.  
  32. //#define LED_ROJO              LATBbits.LATB0
  33. //#define LED_VERDE             LATBbits.LATB1
  34.  
  35. /* ** Declaracion de Funciones a utilizar ** */
  36.  
  37. void Temporizacion(void);
  38.  
  39. /* ** Variables de uso General ** */
  40.  
  41. volatile int Cont = 0;
  42. int FlagRTCC=0;
  43.  
  44. /* ** Seccion de codigo a partir de la direccion 0x0018 ** */
  45.  
  46. #pragma code interrupcion = 0x0018
  47. void VectorInterrupcion(void)
  48. {
  49.         _asm goto Temporizacion _endasm
  50. }
  51. #pragma code    // Cerramos seccion.-
  52.  
  53. /* ** Rutina de Interrupcion ** */
  54.  
  55. #pragma interrupt Temporizacion
  56. void Temporizacion(void)
  57. {
  58.         if(INTCONbits.TMR0IF==1)
  59.         {
  60.                 Cont++;
  61.                         if(Cont==4)
  62.                         {
  63.                                 WriteTimer0(52);
  64.                         }
  65.                         if(Cont==5)
  66.                         {
  67.                                 FlagRTCC=1;
  68.                                 Cont=0;
  69.                         }
  70.                 INTCONbits.TMR0IF=0;
  71.         }
  72. }
  73.  
  74.  
  75. /* ** Main ** */
  76.  
  77. void main(void)
  78. {
  79.  
  80. ADCON1 = 0X0F;
  81. TRISB = 0X00;
  82. PORTB = 0X00;
  83. OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_16);        // Config.Timer0.-
  84. INTCON2bits.TMR0IP = 0;         // Prioridad baja.-
  85. RCONbits.IPEN = 1;              // Habilitamos nivel de Prioridad.-
  86. INTCONbits.GIEL = 1;            // Habilitamos todas las Interrupt de baja prioridad.-
  87. INTCONbits.GIE = 1;             // Permite todas las interrupt de alta Prioridad.-
  88. INTCONbits.TMR0IE = 1;          // Habilitamos Interrupt por overflow .-
  89. WriteTimer0(0);         // Inicializamos el Timer0.-
  90.        
  91. do
  92. {
  93.         if(FlagRTCC==1)
  94.         {
  95.                 FlagRTCC=0;
  96.                 PORTB=~PORTB;
  97.         }
  98.                
  99. } while (1);
  100. }
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 18 de Abril de 2011, 16:56:38
Hola de nuevo, me surge otra duda, quisiera hacer dos interrupciones una para el TMR0 la cual la tengo funcionando, y otra para el control del RS232.
Teniendo esta parte de codigo:
Código: CSS
  1. /* ** Seccion de codigo a partir de la direccion 0x0018 ** */
  2.  
  3. #pragma code interrupcion = 0x0018
  4. void VectorInterrupcion(void)
  5. {
  6.         _asm goto Temporizacion _endasm
  7. }
  8. #pragma code    // Cerramos seccion.-
  9.  
  10. /* ** Rutina de Interrupcion ** */
  11.  
  12. #pragma interrupt Temporizacion
  13. void Temporizacion(void)
  14. {
  15.         if(INTCONbits.TMR0IF==1){
  16.                 Cont++;
  17.                         if(Cont==4){
  18.                                 WriteTimer0(AJUSTE_FINO);
  19.                         }
  20.                         if(Cont==5){
  21.                                 FlagRTCC=1;
  22.                                 Cont=0;
  23.                         }
  24.                 INTCONbits.TMR0IF=0;
  25.         }
  26. }
Seria correcto poner otro  _asm goto Interrupt_RS232 _endasm dentro del mismo #pragma code interrupcion = 0x0018, o por el contrario debo crear otro #pragma code usando la misma direccion del vector de interrupcion que estoy usando.

Gracias

Miquel_S
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 18 de Abril de 2011, 17:53:17
No, ahora es como en ASM, si tienen la misma prioridad pregunta por la bandera xxIF para saber cual interrupción se ha activado.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 18 de Abril de 2011, 18:05:10
Hola Suky, gracias por tu pronta respuesta, no estoy seguro de entender lo que propones pero lo intentare, entiendo lo de explorar la bandera,  pero seria escribiendo otro #pragma code en la misma direccion.
 
Gracias.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 18 de Abril de 2011, 18:35:42
Hola Suky, gracias por tu pronta respuesta, no estoy seguro de entender lo que propones pero lo intentare, entiendo lo de explorar la bandera,  pero seria escribiendo otro #pragma code en la misma direccion.
 
Gracias.

No, Así:

Código: C
  1. #pragma code interrupcion = 0x0018
  2. void VectorInterrupcion(void)
  3. {
  4.         _asm goto Interrupcion _endasm
  5. }
  6. #pragma code    // Cerramos seccion.-
  7. /* ** Rutina de Interrupcion ** */
  8.  
  9. #pragma interrupt  Interrupcion
  10. void  Interrupcion(void)
  11. {
  12.         if(INTCONbits.TMR0IF==1){
  13.                 Cont++;
  14.                         if(Cont==4){
  15.                                 WriteTimer0(AJUSTE_FINO);
  16.                         }
  17.                         if(Cont==5){
  18.                                 FlagRTCC=1;
  19.                                 Cont=0;
  20.                         }
  21.                 INTCONbits.TMR0IF=0;
  22.         }
  23.         if(PIR1bits.....){
  24.        
  25.         }
  26.         if(PIR1bits....){
  27.  
  28.         }
  29. }

No hay que confundir el tema de los #pragma code, alli solo estás diciendo que en el vector 0x0018 se coloque un goto a la función ISRxxx, en tu caso la llamaste Temporización. Si colocas otro #pragma code con la misma dirección el compilador debe indicar error o sobre-escribir el anterior.





Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 18 de Abril de 2011, 18:48:04
Hola suky, tengo una pregunta, como se convierte 2 variables de 8 bits a una de 16bits?

Esto lo quisiera para convertir los 2 datos leídos del ADC, y colocarlos a una solo variable INT.

muchas gracias, un saludo
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 18 de Abril de 2011, 21:30:34
Hola suky, tengo una pregunta, como se convierte 2 variables de 8 bits a una de 16bits?

Esto lo quisiera para convertir los 2 datos leídos del ADC, y colocarlos a una solo variable INT.

muchas gracias, un saludo

Lo más fácil es crear un typedef con una estructura para poder cargar cada byte por separado, o usar punteros:

Código: C
  1. typedef union{
  2.      unsigned int Val;
  3.      struct{
  4.           unsigned char LB;
  5.           unsigned char HB;
  6.      };
  7. }VAL_INT16;
  8.  
  9. VAL_INT16 myVar;
  10.  
  11. myVar.LB=0x16;
  12. myVar.HB=0x56;

O con punteros;

Código: C
  1. unsigned char myVar;
  2.  
  3. *((char *)&myVar)=0x16;
  4. *((char *)&myVar+1)=0x56;


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 19 de Abril de 2011, 04:22:31
Gracias Suky, tan atento como siempre, voy a ver si consigo hacerlo funcionar.

Miquel_S
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 19 de Abril de 2011, 17:19:25
O con punteros;

Código: C
  1. unsigned char myVar;
  2.  
  3. *((char *)&myVar)=0x16;
  4. *((char *)&myVar+1)=0x56;
Los punteros son la clave; generan 4 lineas de ASM, lo estaba haciendo con una multiplicacion y una suma, q genera algo de 14 instrucciones ASM.

Solo aclarar, que unsigned char myVar; debería ser unsigned int myVar;

Muchas gracias suky.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 22 de Abril de 2011, 13:38:51
Hola, sigo estudiando el USART y por lo que veo en esta parte del codigo copiado del tutorial de Suky no se esta habilitando el bit de recepcion:
RCIE: EUSART Receive Interrupt Enable bit
1 = Enables the EUSART receive interrupt
0 = Disables the EUSART receive interrupt

Código: CSS
  1. void main(void){
  2.     unsigned int Canal0, Canal1;
  3.     char String[4];
  4.     OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE &
  5.                   USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH,25);
  6.     Kbhit=0;
  7.     RCONbits.IPEN=0;
  8.     INTCONbits.PEIE=1;
  9.     INTCONbits.GIE=1;
  10. }

He revisado en el datasheet como se queda dicho bit despues de un reset y se lee como 0, alguien podria explicarme porque no habilitamos dicho bit.

Gracias
Miquel_S
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 22 de Abril de 2011, 14:35:42
Con USART_CONT_RX se habilita la recepción por el módulo UART, luego la interrupción por recepción es otra cosa y se usa USART_RX_INT_ON que actúa sobre el bit RCIE.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 22 de Abril de 2011, 16:05:29
Nuevamente gracias Suky, todo esto que explicas esta en el datasheet o de donde lo sacas, porque yo nunca encuentro la info que busco en C18  :(

Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 22 de Abril de 2011, 16:31:43
Otra pregunta tonta  :oops:
En esta parte de codigo:

SetChanADC(0);
No deberia de poner:
SetChanADC(ADC_CH0);

Lo pregunto porque de la primera manera da error de compilacion.
Miquel_S

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 22 de Abril de 2011, 18:29:00
Nuevamente gracias Suky, todo esto que explicas esta en el datasheet o de donde lo sacas, porque yo nunca encuentro la info que busco en C18  :(

Saludos.

Hay mucho en C:\MCC18\doc\periph-lib, después es instinto, practica y estudiar los archivos fuentes  ;-)

Otra pregunta tonta  :oops:
En esta parte de codigo:

SetChanADC(0);
No deberia de poner:
SetChanADC(ADC_CH0);

Lo pregunto porque de la primera manera da error de compilacion.
Miquel_S



Lo más adecuado es colocar ADC_CH0. Pero mirando el adc.h, dependiendo del microcontrolador da lo mismo usar 0 o ADC_CH0, pero no es lo más adecuado, por portabilidad  ;-)


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 22 de Abril de 2011, 18:43:48
Contigo el que no aprende C18 es porque no quiere.
GRACIAS SUKY

Miquel_S
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 23 de Abril de 2011, 06:56:48
 ;-) Sigo intentando entender el ADC junto con el datasheet PIC 18f4550
En el include del adc tengo esto:
Código: CSS
  1. #if     defined (ADC_V1) || defined (ADC_V2) || defined (ADC_V3) || defined (ADC_V4) ||\
  2.     defined (ADC_V5) || defined (ADC_V6) || defined (ADC_V8) || defined (ADC_V9) ||\
  3.         defined (ADC_V11) || defined (ADC_V12)
  4. /* ***** clock source ***** */
  5. #ifdef USE_OR_MASKS
  6. #define ADC_FOSC_2       0b00000000 // A/D clock source Fosc/2
  7. #define ADC_FOSC_4       0b01000000 // A/D clock source Fosc/4
  8. #define ADC_FOSC_8       0b00010000 // A/D clock source Fosc/8
  9. #define ADC_FOSC_16      0b01010000 // A/D clock source Fosc/16
  10. #define ADC_FOSC_32      0b00100000 // A/D clock source Fosc/32
  11. #define ADC_FOSC_64      0b01100000 // A/D clock source Fosc/64
  12. #define ADC_FOSC_RC      0b01110000 // A/D clock source Internal RC OSC
  13. #define ADC_FOSC_MASK    (~ADC_FOSC_RC)        
  14. /* ***** acquisition time ***** */
  15. #define ADC_0_TAD        0b00000000
  16. #define ADC_2_TAD        0b00000010
  17. #define ADC_4_TAD        0b00000100
  18. #define ADC_6_TAD        0b00000110
  19. #define ADC_8_TAD        0b00001000
  20. #define ADC_12_TAD       0b00001010
  21. #define ADC_16_TAD       0b00001100
  22. #define ADC_20_TAD       0b00001110
  23. #define ADC_TAD_MASK    (~ADC_20_TAD)          
  24. /********interrupt enable********/
  25. #define ADC_INT_ON       0b10000000
  26. #define ADC_INT_OFF      0b00000000
  27. #define ADC_INT_MASK     ~ADC_INT_ON
  28. //-------------------------------------------------
  29. #else // USE_OR_MASKS
  30. #define ADC_FOSC_2       0b10001111 // A/D clock source Fosc/2
  31. #define ADC_FOSC_4       0b11001111 // A/D clock source Fosc/4
  32. #define ADC_FOSC_8       0b10011111 // A/D clock source Fosc/8
  33. #define ADC_FOSC_16      0b11011111 // A/D clock source Fosc/16
  34. #define ADC_FOSC_32      0b10101111 // A/D clock source Fosc/32
  35. #define ADC_FOSC_64      0b11101111 // A/D clock source Fosc/64
  36. #define ADC_FOSC_RC      0b11111111 // A/D clock source Internal RC OSC
  37. /* ***** acquisition time ***** */
  38. #define ADC_0_TAD        0b11110001
  39. #define ADC_2_TAD        0b11110011
  40. #define ADC_4_TAD        0b11110101
  41. #define ADC_6_TAD        0b11110111
  42. #define ADC_8_TAD        0b11111001
  43. #define ADC_12_TAD       0b11111011
  44. #define ADC_16_TAD       0b11111101
  45. #define ADC_20_TAD       0b11111111
  46. /********interrupt enable********/
  47. #define ADC_INT_ON       0b11111111
  48. #define ADC_INT_OFF      0b01111111
  49. #endif // USE_OR_MASKS
  50.  
  51. #endif
Sin embargo la configuracion del oscilador interno no coincide con el datasheet.
#define ADC_FOSC_RC      0b01110000 // A/D clock source Internal RC OSC
#define ADC_FOSC_RC      0b11111111 // A/D clock source Internal RC OSC

Alguien podria decirme donde me pierdo.
Gracias.

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 23 de Abril de 2011, 10:28:50
Hay que mirar los 2 archivos fuentes para ver como lo tratan. Fijate que en la función OpenADC tiene:

ADCON2 = (config & 0b10000000)   |   // RESULT
             ((config >> 4) & 0b00000111) |   // CONV CLK
             ((config << 2) & 0b00111000);   // ACQ TIME


Y las definiciones son

// USE_OR_MASKS
#define ADC_FOSC_RC      0b01110000 // A/D clock source Internal RC OSC

#define ADC_FOSC_RC      0b11111111 // A/D clock source Internal RC OSC


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 24 de Abril de 2011, 06:03:46
OK, Gracias.

Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 02 de Mayo de 2011, 22:43:12
hola, necesito una pequeña aclaracion, la situacion es:

unsigned char mensaje[2][3];      //

void funcionX(char dato, unsigned char *puntero){
      //lineas de codigo
}

ahora llamo a esa funcion:

funcionX(0x50, &mensaje);       intente tambien con esta      funcionX(0x50, &mensaje[0]);

y me aparece la siguiente advertencia:

D:\Diseño Digital\18FXXXX\C18\diseños.c:122:Warning [2054] suspicious pointer conversion

como le hago para corregirla, o es que no tiene ningun efecto en el codigo
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 02 de Mayo de 2011, 23:25:18
Lo correcto seria funcionX(0x50, &mensaje[0][0]) o funcionX(0x50, &mensaje[1][0])


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 02 de Mayo de 2011, 23:42:15
lo intente y me salio este otro mensajito:

D:\Diseño Digital\18FXXXX\C18\diseños.c:121:Warning [2066] type qualifier mismatch in assignment

 :shock: :shock:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 03 de Mayo de 2011, 10:05:37
 :roll: Seguro que pusiste unsigned en las dos ocasiones? no veo nada raro.


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 05 de Mayo de 2011, 10:37:17
te cuento que lo solucione :-/ :-/  el problema fue que la variable la declare como near
 
ram near unsigned char mensaje[2][3];

y en las funciones tambien tenia que ponerlas

void funcionX(char dato, near unsigned char *puntero){
      //lineas de codigo
}

e hice lo que me dijiste funcionX(0x25, &mensaje[0][0]) y funciono  :o :o gracias y saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 09 de Mayo de 2011, 16:58:32
Necesito vuestra yuda, no me queda claro el paso de punteros:

char *ptr;

void miFuncion(char *puntero){
         puntero+=5;      //le incremeto 5 a la direccion del puntero
        //resto del codigo...
        //...
}

char * buscarDireccion(char dato){   //busca la direccion de dato enviado como parametro
    //codigo
}

ptr=buscarDireccion(0x4f);
//aqui ptr apunta a una direccion, digamos 0x121

miFuncion(ptr);

//despues de llamar a la funcion a que direccion estaria apuntando mi ptr, a la direccion 0x121 o a la direccion 0x126

Gracias y Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Cryn en 09 de Mayo de 2011, 17:20:07
debería apuntar a la dirección 0x126, pero creo que sería mejor colocar:

miFuncion(&ptr);
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 09 de Mayo de 2011, 19:33:23
Podrías hacer un debug en MPLAB SIM  :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 13 de Mayo de 2011, 15:47:22
hola, ando probando el modulo spi y sus librerias y me aparecio algo curioso:

Cuando transmito byte por byte en diferentes todo ok :-/ :-/

sucede algo raro :x cuando trasmito(master) cadenas putsSPI(mensaje) y la recibo desde el otro lado(slave) con
getsSPI(msn_rx,6) bueno lo que pasa es que la PRIMERA LETRA DEL MENSAJE se cambia, por decir envio 'a' y recibe una 'c'  :shock: y el resto del mensaje todo bien, ahora si transmito una 'b' recibe una 'b'  :shock: si trasmito una 'e' recibo una 'g'  :shock:y asi sucesivamente.
Bueno siguiendo este patron y teniendo el valor de los codigos ascii vi que el problema esta en el bit2 de la primera letra y es que siempre estaria llegando con valor '1' sin importa que valor tenga este bit2(0 o 1)

      a: 01100001    llega -->  c:01100011
      b: 01100010    llega -->  b:01100010
      e: 01100101    llega -->  g:01100111
      p: 01110000    llega -->  r:01110010

alguien sabe a que se debe esta situacion :D :D :D
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 26 de Julio de 2011, 12:23:00
Disculpen es una pregunta algo tonta seguro pero es lo mismo el compilador Hi-Tech que C18 que PICC18 ?? La verdad estoy muy confundido y no encuentro información al respecto si alguien pudiera guiarme. Actualmente programo en CCS y me gustaria pasarme, supuestamente el C que ofrecia microchip era el mejor pero no se con esto de Hi-Tech y C18 la verdad muy perdido ando...

Muchas Gracias!!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: rivale en 26 de Julio de 2011, 13:06:15
El c18 es el lenguaje de C diseñado para los micros de gama alta(18f), mientras que el hitech es para los micros de gama media y baja(16f y 12f)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 26 de Julio de 2011, 13:57:35
...mientras que el hitech es para los micros de gama media y baja(16f y 12f)

También existe la versión para pic18.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 26 de Julio de 2011, 18:52:56
Entonces son 2 cosas diferentes ?? Cual es el tan famoso ?? O sea que este tutorial no es para hi-tech ??
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: rivale en 26 de Julio de 2011, 18:55:33
Entonces son 2 cosas diferentes ?? Cual es el tan famoso ?? O sea que este tutorial no es para hi-tech ??

este tutorial es para el C18, no para el hitech, el "famoso" es el c18 para los PIC18F :mrgreen:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 26 de Julio de 2011, 21:14:18
Gracias che por la ayuda pero sigo confundido, es decir que Hi-Tech no es de Microchip ? Así como viene C18 viene para dsPIC, 24F y 32F ? Pasa que me quiero salir de CCS por los bugs en 24F en adelante y quiero algun compilador bueno y siempre leí del C18 de Microchip pero ahora me vengo a enterar de que no es lo mismo que Hi-Tech... Es mucha la diferencia ? Hi-Tech no es gratis el otro si ?

Saludos y disculpen las molestias
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: rivale en 26 de Julio de 2011, 21:22:42
microchip tiene varios Cs para sus diferentes familias, si quieres usar para el 24F, el que se usa es el C30(otro C diferente).
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 26 de Julio de 2011, 21:39:16
O sea que por cada Gama de pic que quiera programar debo aprender un C ? No es todo lo mismo ? Perdón por tantas preguntas
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: rivale en 26 de Julio de 2011, 21:44:38
O sea que por cada Gama de pic que quiera programar debo aprender un C ? No es todo lo mismo ? Perdón por tantas preguntas

si, cada gama tiene un C, pero todos los C de microchip estan estandarizados, entonces no hay muchas diferencias entre los Cs. no es muy dificil pasarte de uno a otro, soy hay que tomar algunas consideraciones.

en el foro puedes encontrar tutoriales para C18(este post) y para C30
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 26 de Julio de 2011, 21:48:53
Ok gracias che y nada de hi-tech ?? Estuve viendo y no hay compilador para 16F o sea como un C16 o si ??
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: rivale en 27 de Julio de 2011, 00:18:07
Ok gracias che y nada de hi-tech ?? Estuve viendo y no hay compilador para 16F o sea como un C16 o si ??

no existe un C16, ese es el hitech, no se si haya algun tutorial, pero hay muchos ejemplos en el foro. usa el buscador para ver si encuentras algun tutorial.

tambien te podrian ayudar los manuales de microchip de cada compilador.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 30 de Julio de 2011, 14:09:30
Muchas gracias por toda la ayuda ya empecé a usar el C18 y aunque varía mucho del CCS ya le agarré la mano cuando te acostumbras esta bueno. Solo tengo una duda... Yo creé un archivo .h y un .c donde voy poniendo mis librerias pero veo que las funciones que no uso nunca me ocupan memoria también, en CCS cuando no usabas una función no ocupaba memoria es posible esto en C18 ?

Gracias !!!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 30 de Julio de 2011, 14:21:18
Podes utilizar #defines para indicar que nivel de tu librería vas a usar o que funciones. Esto lo hace Microchip en sus librerías definiendo un config....h en donde se configura, por ejemplo:


Código: C
  1. #define USE_READ
  2. #define USE_WRITE
  3. //#define USE_PAGES

y en el *.c:

Código: C
  1. #if defined(USE_READ)
  2. .......
  3. #endif
  4.  
  5. #if defined(USE_WRITE)
  6. .......
  7. #endif
  8.  
  9. #if defined(USE_PAGES)
  10. .......
  11. #endif

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 30 de Julio de 2011, 14:22:59
Muchas gracias suky te agradezco  ;-)
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 30 de Julio de 2011, 14:34:48
Suky me supera el C18  :D. Mira hice lo que me dijiste en el .c y .h:

.c:

Código: [Seleccionar]
//Librerías varias
#include <adc.h>
#include <math.h>
#include <stdio.h>

#if defined ADC_FUNC
/***********************************************************************************/
//Lectura completa del ADC, toma la conersion, espera y lee los registros
int Read_ADC (void){
ConvertADC(); //conversion
while(BusyADC()); //espero a que termine
return ReadADC(); //tomo el valor y lo retorno
}
/***********************************************************************************/
#endif

#if defined FLOAT2STR
/***********************************************************************************/
void float2str(char *buffer, float f){
float fenteros;
float fdecimales;
int entero, decimal;

fenteros = floor(f);
fdecimales = f - fenteros;
entero = (int)fenteros;
decimal = (int)1000 * fdecimales;
    sprintf(buffer, "%d.%03i", entero, decimal);
}
/***********************************************************************************/
#endif

.h:

Código: [Seleccionar]
#ifndef mylibs
#define mylibs

#define ADC_FUNC
#define FLOAT2STR

/***********************************************************************************/
int Read_ADC (void);
void float2str(char *buffer, float f);
/***********************************************************************************/

/***********************************************************************************/
//Frecuencia del cristal externo (no divido internamente) en [Hz]
//Baudios para el USART
#define XTAL 4000000
#define baud 9600
/***********************************************************************************/

/***********************************************************************************/
//Macro para el calculo de baudios automatico
//Hay que colocar el define BAUDIOS en la funcioón OpenUSART
//donde pide el valor de "spbrg" y SPEED_MODE donde pide modo
//high o low speed:
//Ejemplo a 9600 baudios:
//OpenUSART(USART_ASYNCH_MODE & USART_EIGHT_BIT & SPEED_MODE, BAUDIOS);
#if((((XTAL/baud)/16)-1)<255 && (((XTAL/baud)/16)-1)>0)
#define SPEED_MODE USART_BRGH_HIGH
    #define BAUDIOS (unsigned int)(((XTAL/baud)/16)-1)
#elif((((XTAL/baud)/64)-1)<255 && (((XTAL/baud)/64)-1)>0)
    #define SPEED_MODE USART_BRGH_LOW
    #define BAUDIOS (unsigned int)(((XTAL/baud)/64)-1)
#else
    #error No se pudo establecer un rate correcto: baudio = baud
#endif
/***********************************************************************************/

#endif

Y al momento de compilar me da un error y me da finalizar tarea el compilador C18:

Código: [Seleccionar]
Clean: Deleting intermediary and output files.
Clean: Deleted file "C:\Disco local Andrés (C)\Electrónica\Pruebas C18\Prueba 1\Main.o".
Clean: Deleted file "C:\Disco local Andrés (C)\Electrónica\Pruebas C18\Prueba 1\mylibs.o".
Clean: Done.
Executing: "C:\MCC18\bin\mcc18.exe" -p=18F4520 "..\..\Escuela Cena\Prueba 1\Main.c" -fo="Main.o" -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Disco local Andrés (C)\Electrónica\Escuela Cena\Prueba 1\Main.c:26:Warning [2066] type qualifier mismatch in assignment
C:\Disco local Andrés (C)\Electrónica\Escuela Cena\Prueba 1\Main.c:32:Warning [2066] type qualifier mismatch in assignment
C:\Disco local Andrés (C)\Electrónica\Escuela Cena\Prueba 1\Main.c:37:Warning [2066] type qualifier mismatch in assignment
Executing: "C:\MCC18\bin\mcc18.exe" -p=18F4520 "..\..\Escuela Cena\Prueba 1\mylibs.c" -fo="mylibs.o" -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Disco local Andrés (C)\Electrónica\Escuela Cena\Prueba 1\mylibs.c:31:Error [1020] unexpected input following '#endif'
Halting build on first failure as requested.
----------------------------------------------------------------------
Debug build of project `C:\Disco local Andrés (C)\Electrónica\Pruebas C18\Prueba 1\Prueba ADC.mcp' failed.
Language tool versions: mpasmwin.exe v5.30.01, mplink.exe v4.30.01, mcc18.exe v3.30
Preprocessor symbol `__DEBUG' is defined.
Sat Jul 30 14:34:48 2011
----------------------------------------------------------------------
BUILD FAILED

No se por que dice que no espera el #endif si esta justo despues del #if defined
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Leon Pic en 30 de Julio de 2011, 14:43:48
Disculpame que me meta.
El error está en la librería mylibs.c, más precisamente en la línea 1020

Y prestá atención a los Warnings (precauciones), en la línea 2066 del archivo main.c, dice que "type qualifier mismatch in assignment" que traducido sería algo así, "no coinciden los tipos de clasificación con la asignación"
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 30 de Julio de 2011, 14:49:48
Sisi el Error me lleva justo donde esta el último #endif y los Warning me llevan a los printf que no la verdad que ni idea de lo que este mal ahí. Este es el main:

Código: [Seleccionar]
#include <p18f4520.h>
#include <adc.h>
#include <usart.h>
#include <stdio.h>
#include <math.h>
#include <delays.h>
#include <timers.h>
#include <pwm.h>

#include "mylibs.h"

#pragma config WDT = OFF //WDT apagado

int result;
char string[20];

void main (void){
TRISA = 0xFF; TRISB = 0b00000001; PORTB = 0x00; TRISC = 0x00;
OpenADC(ADC_FOSC_RC & ADC_RIGHT_JUST,ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, ADC_1ANA);
SetChanADC(ADC_CH0);
OpenUSART(USART_ASYNCH_MODE & USART_EIGHT_BIT & SPEED_MODE, BAUDIOS);

OpenTimer2(TIMER_INT_OFF & T2_PS_1_16 & T2_POST_1_1);
OpenPWM1(10);
SetDCPWM1(5);
printf("Prueba de C18 con PIC18F4520\n\r");
while(1){

if(PORTBbits.RB0 == 1){
result = Read_ADC();
float2str(string,(float)result*5.0/1024.0);
printf("ADC = %u VOLT = %s\n\r",result,string);
Delay10KTCYx(20);
}
else{
if(DataRdyUSART()){
printf("Recibido = %c\n\r",ReadUSART());
}
}
}
}
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: marvicdigital en 02 de Agosto de 2011, 12:00:03
Hola..
Como me han regalado unos 18F2550, he querido mirar un poco estos micros a ver si los adopto algún día :)  he mirado este hilo, algunos ejemplos, tambien el PDF de nuestro amigo Suky(mil gracias amigo, por compartir tu valioso trabajo) , arme una plaquita con LCD y teclado y varias cositas adicionales solo para experimentar...y bueno tengo un problema con la libreria delay.h por que según los cálculos no me dan los ms que pretendo.. a ver lo que entendí es que el cálculo es así:
Mi cristal es de 20mhz,

Delay10KTCYx(250);     // 10.000 * (4/20.000.000) * 250 = 500ms

Tengo conflicto de entendimiento con respecto a la configuración en C18 del oscilador, ya he leído la explicación maravillosa de RedPic, el help del C18 pero no logro los 500ms, ya que me da mucho menos..esta es mi configuración, según lo leído:

Código: C
  1. #pragma config FOSC=HS,FCMEN=OFF,IESO=OFF,CPUDIV=OSC4_PLL6      //HS 20MHZ ClockCPU 5 MHZ
  2. #pragma config PWRT=ON,BOR=OFF,BORV=0,WDT=OFF,WDTPS=32768
  3. #pragma config MCLRE=OFF,LPT1OSC=OFF,PBADEN=OFF,CCP2MX=OFF
  4. #pragma config STVREN=OFF,LVP=OFF,XINST=OFF,DEBUG=OFF
  5. #pragma config CP0=OFF,CP1=OFF,CP2=OFF,CPB=OFF,CPD=OFF
  6. #pragma config WRT0=OFF,WRT1=OFF,WRT2=OFF
  7. #pragma config WRTB=OFF,WRTC=OFF,WRTD=OFF
  8. #pragma config EBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTRB=OFF

A ver según lo que quiero es 5MHZ en clock en CPU...con un cristal de 20MHZ , no uso el PLL y divido en el osc postcaler por 4 dandome 5Mhz...
En que estoy equivocado?

Agradezco su valiosa ayuda..como siempre.

Saludos


 
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 02 de Agosto de 2011, 12:03:18
Pero si divides la frecuencia de Fosc por 4, los cálculos de delay debes hacerlo con 5MHz  ;-)


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: marvicdigital en 02 de Agosto de 2011, 12:57:22
Pero si divides la frecuencia de Fosc por 4, los cálculos de delay debes hacerlo con 5MHz  ;-)


Saludos!

Gracias Suky,  ha funcionado bien..ahora estoy probando el LCD que lo conecté los datos al puerto A el nibble bajo, previa configuración del ADCON1  y  los controles en PTA4 , PTA5 y PTC0(upss!! eran RA RC )  todo configurado en xlcd.h, pero no ha fucnionado, se me queda el programa colgado al ejecutar la rutina :

OpenXLCD(FOUR_BIT & LINES_5X7);

voy a revisar que pasa, una última pregunta, si los tiempos de los ms para el correcto funcionamiento del LCD no estan exactos no es motivo para que se quede el programa en esa rutina?..

Saludos y gracias de nuevo
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 02 de Agosto de 2011, 13:26:38
Hay que configurar el xLCD.h y agregar los archivos fuentes de la librería para que sean compilados y se hagan efectivos los cambios, lo hiciste?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: marvicdigital en 02 de Agosto de 2011, 13:43:41
Hay que configurar el xLCD.h y agregar los archivos fuentes de la librería para que sean compilados y se hagan efectivos los cambios, lo hiciste?

Los archivos fuentes no los encuentro, estoy usando MPLABX en Linux Mint 10, el xlcd.h lo modifiqué para los puertos que estoy usando...pero me hacen falta los archivos fuentes, no encuento openxlcd.c ni busyxlcd.c ni niguno de los que aparecen en la imagen de tu PDF...creo que algo me hace falta por instalar o no los trae, o será por la lisencia, ya que cuando instalé el C18 no me pidió nada de lisencia ni seleccionara si era demo o lite como si pasó con el Hi-tech..tendrá algo que ver esto?

Gracias Suky por tu tiempo para ayudarme.

Saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 02 de Agosto de 2011, 15:07:46
Aaa! Mplab ide x! Ahí a remarla solito  :tongue: No se como trabajará ese. En todo caso los archivos fuentes están en ..\MCC18\src\pmc_common\XLCD


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: marvicdigital en 02 de Agosto de 2011, 16:03:51
Aaa! Mplab ide x! Ahí a remarla solito  :tongue: No se como trabajará ese. En todo caso los archivos fuentes están en ..\MCC18\src\pmc_common\XLCD


Saludos!

Muchas gracias maestro, de todas formas se que al estar en linux estoy un poco solo, pero que sería el aprendizaje sin estos retos?..

Gracias y

saludos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: dragondgold en 02 de Agosto de 2011, 18:31:14
Nadie sabe por que no funciona el codigo que coloqué arriba ?
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 02 de Agosto de 2011, 18:58:47
Nadie sabe por que no funciona el codigo que coloqué arriba ?

Tiene que existir una linea en blanco al final de cada archivo  :shock:
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: marvicdigital en 04 de Agosto de 2011, 07:24:20
Hola.
Amigo Suky, decidí usar tu valiosa librería, la LCDGenérica y bueno puse los puertos que voy a usar, comenté la linea de usar 3 pines, pero tengo una duda con respecto a los tiempos, el cristal o la frecuencia que usas en la librería es de 20MHZ? la frecuencia de la CPU me imagino...es que no me cuadrán los tiempos o los cálculos no me dan los 100uS...como se nota que apenas estoy comenzando con el C18 :)
Gracias Suky por tu guía y paciencia.

Saludos

PD: Me aclaro a ver si es asi:

Delay100TCYx(FCY/4000000UL)  

Sería 100*(4/20000000)*(20000000/4000000) = 0.0001 segundos  osea 100uS..esto es correcto?
Ahora la configuración la tengo asi:

#pragma config FOSC=HS,FCMEN=OFF,IESO=OFF,CPUDIV=OSC1_PLL2     //HS 20MHZ ClockCPU 20 MHZ

Es correcta mi configuración, para poder usar la librería?..es que no me funciona..o algo me hace falta comentar que no he visto....valla, que me va  servir estos días de paro que llevo..

Gracias de nuevo

Las lineas que modifiqué, aparte de la use RW y comentar la de use 3pines

Código: [Seleccionar]
#ifndef LCD_USE_3PINES
/* ** Pines tolerables a 5V para usar RW ** */
#define LCD_DATA_PIN_7 LATAbits.LATA3
#define LCD_DATA_PIN_6 LATAbits.LATA2
#define LCD_DATA_PIN_5 LATAbits.LATA1
#define LCD_DATA_PIN_4 LATAbits.LATA0

#define LCD_READ_PIN_7 PORTAbits.RA3
#define LCD_READ_PIN_6 PORTAbits.RA2
#define LCD_READ_PIN_5 PORTAbits.RA1
#define LCD_READ_PIN_4 PORTAbits.RA0


#define LCD_TRIS_DATA_PIN_7       TRISAbits.TRISA3
#define LCD_TRIS_DATA_PIN_6       TRISAbits.TRISA2
#define LCD_TRIS_DATA_PIN_5       TRISAbits.TRISA1
#define LCD_TRIS_DATA_PIN_4       TRISAbits.TRISA0


#define LCD_E_PIN LATCbits.LATC0
#define LCD_RS_PIN LATAbits.LATA4
#ifdef LCD_USE_RW
#define LCD_RW_PIN LATAbits.LATA5
#endif

#define LCD_TRIS_E TRISCbits.TRISC0
#define LCD_TRIS_RS TRISAbits.TRISA4
#ifdef LCD_USE_RW
#define LCD_TRIS_RW TRISAbits.TRISA5
#endif

Y este el código de prueba:

Código: [Seleccionar]
void main(void){
    ADCON1=0x0F;
    TRISC=0xF0;
    LATC=0x00;
    LedLCDOn;
    test();
    vInitLCD();
    stdout=_H_USER;
    printf("\fProbando LCD\nSegunda linea");
    LedLCDOn;
    
    for(;;){
  
                  
}
}

Alguna sugerencia a revisar? :)  Gracias de nuevo

PD2: Sigue sin funcionar, ya agregue la linea de CMCON=0x07 y nada aun..se nota que el display funciona por que al aumentar el VO con el potenciometro de ve las 2 lineas bien, pero no tengo caracteres, uso el pin RW en PORTC0 que no tiene nada que configurar adicional..la verdad que leo y releo y n l eveo la falla, salvo los tiempos pero ya he verificado haciendo rutinas para hacer un blink en intervalos y los cálculos me dan con la FOSC a 20MHZ de la CPU...alguna sugerencia más?


gracias d enuevo


Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 07 de Agosto de 2011, 00:32:13
El problema es con printf, porque si logras ver las dos lineas significa que el LCD se inicializado. Prueba con las otras funciones propias del LCD para escribir, por ejemplo para C18 puede agregar la siguiente:

Código: C
  1. void vPutrs_LCD(rom UINT8 *buffer){
  2.         UINT8 Data;
  3.        
  4.         while(*buffer != '\0'){
  5.                 Data=*buffer++;
  6.                 vLCD_Putc(Data);
  7.    }
  8.  
  9. }

y escribir:

Código: C
  1. vPutrs_LCD("\fProbando LCD\nSegunda linea");


Con eso pruebas que funciona. Después hay que seguir unos pasos para poder usar printf, pero no se como será en MPLAB X

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 25 de Abril de 2012, 16:02:03
hola quisiera que me hechen una manita estoy teniendo un inconveniente con las directivas del preprocesado, lo que quiero hacer es poder escoger entre 2 microcontroladores para hacer uso de sus puertos ya que ambos presentan diferencias en sus pines, el codigo es el siguiente:


#ifndef   __LETRERO_H
   #define   __LETRERO_H
   #include "p18cxxx.h"

//----------------------------------------------------------
//         Definicion de pines
//----------------------------------------------------------


   #ifdef __18F13K50
   //definimos pines pra el pic 18f13k50
      #define      DATA_PIN                 LATAbits.LATA4
      #define      CLOCK_PIN         LATAbits.LATA5
      #define      TRIS_DATA         TRISAbits.TRISA4
      #define      TRIS_CLOCK         TRISAbits.TRISA5

      #define      PORTA_CONTROL
//para que las entradas del porta sean degitales si se usa otro
//puerto para el control desabilitar esta definicion

      #define      PORT_MATRIZ      LATC
      #define      TRIS_PORT      TRISC

   #elif __18f2550
   //definimos pines para el pic 18f2550
      #define      DATA_PIN         LATAbits.LATA0
      #define      CLOCK_PIN         LATAbits.LATA1
      #define      TRIS_DATA         TRISAbits.TRISA0
      #define      TRIS_CLOCK         TRISAbits.TRISA1

      #define      PORTA_CONTROL
//para que las entradas del porta sean degitales si se usa otro
//puerto para el control desabilitar esta definicion


      #define      PORT_MATRIZ      LATB
      #define      TRIS_PORT      TRISB

   #endif

#define      F      1
#define      W      0
#define      A      0   //esto en el caso en que lleguemos a usar codigo en asm
//----------------------------------------------------------
//               Constantes
//----------------------------------------------------------      
#define      FILAS_M         8      
#define      COLUMNAS_M      32      
#define     MODULO_M      8


Pues bien la situacion es la siguiente: en el programa principal  quiero usar una de estas constantes definidas ya sea el pic que este utilizando pero el compilador me dice que no reconoce estas constantes(PORT_MATRIZ, TRIS_PORT, etc), y solo me reconoce estas 6: FILAS_M, COLUMNAS_M, MODULOS_M, F, W, A; quisiera saber si estoy usando bien las directivas de preprocesado o en que estoy fallando

PD: en el programa principal esta agregado el: #include <letrero.h>

Gracias y saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 25 de Abril de 2012, 18:49:12
Pareciera que el preprocesador no está tomando los PREDEFINED MACRO NAMES
__18F13K50 y __18f2550

probá usar la directiva #error para sacar un mensaje de texto en la compilación y ver si pasa o no pasa por los dos trozos de código. Y no olvides de seleccionar el tipo de microcontrolador en el mplab.

#ifdef __18F13K50
#error "el compilador pasó por acá"
#endif

la otra opción es que vos crees tus propios identificadores:

extraído de la página 17 del manual c18 user guide


1.2.3 Defining Macros
The -D command-line option allows a macro to be defined. The -D command-line
option can be specified in one of two ways: -Dname or -Dname=value. -Dname
defines the macro name with 1 as its definition. -Dname=value defines the macro
name with value as its definition. For example:
mcc18 -DMODE
defines the macro MODE to have a value of 1, whereas:
mcc18 -DMODE=2
defines the macro MODE to have a value of 2.
An instance of utilizing the -D command-line option is in conditional compilation of
code. For example:
#if MODE == 1
x = 5;
#elif MODE == 2
x = 6;
#else
x = 7;
#endif
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: EduSky en 26 de Abril de 2012, 16:11:51
Buenas tardes a todos!. Primer post en el foro. Estuve leyendo el post porque quiero hacer algo con el C18 y PIC18f4550 (aclaro que son mis primeros en la progamacion de pic's). Concretamente lo que quiero hacer es prende y apagar un LED cada 2seg. El codigo que use pero no sirvio de mucho es:

#include <p18f4550.h>
#include <delays.h>

#pragma config WDT=OFF
#pragma config PLLDIV = 5 // (20 MHz crystal)
#pragma config FOSC = HSPLL_HS
#pragma config MCLRE = OFF

void main()
{
 TRISA = 0x00;  //define los pines del puerto A todos como salidas
 while(1)
 {
  LATAbits.LATA0 = 1;
  Delay10KTCYx(200);
  LATAbits.LATA0 = 0;
  Delay10KTCYx(200);
 };
}

Como ven estoy usando un cristal de 20MHz. El Led se prende cuando alimento el pic, luego se apaga, se vuelve a prender y se queda prendido. Talvez no estoy utilizando de forma correcta la funcion delay o si la configuracion del pic es el problema para poder arrancar con lo basico.
Cualquier  respuesta que ayude a aclarar el problema sera bien recibida.
Saludos!!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 26 de Abril de 2012, 18:00:09
EduSky:

te falta poner el puerto A como digital. Ya que por defecto arranca en analógico.

agregale esto.
ADCON1=0x0F;//Todos entrada/salida digitales. - equivalente en binario ADCON1= 0b00001111

         Saludos.
                Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: EduSky en 26 de Abril de 2012, 22:17:50
Jukinch, gracias por responder. Hice la modificacion que recomendaste y ahora el comportamiento es distinto. Ahora el LED blinkea (no se queda prendido de forma permanente) por 6 seg (aproximadamente), despues se apaga por 14 seg y se vuelve a preder repitiendo el mismo comportamiento. Tiene cierta cadencia, pero no se prende 2 seg y se apaga 2 seg como esperaba.
La funcion que use de Delay10TKY ¿calcula el delay con el oscilador externo de 20MHz o utiliza tambien algun otro parametro?
Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 27 de Abril de 2012, 11:05:49
EduSky:
probá con este código:
Código: C
  1. /*Includes*/
  2. #include "p18F4550.h"
  3. #include "delays.h"
  4.  
  5. /* Para utilizar demoras en nuestro código debemos incluir la librería delays.h. En ella tenemos 4 funciones:
  6. Delay10TCYx(i)      -> 10.Tcy.i     genera una demora de 10 ciclos de instrucciones * i
  7. Delay100TCYx(i)   -> 100.Tcy.i      genera una demora de 100 ciclos de instrucciones  * i
  8. Delay1KTCYx(i)      -> 1000.Tcy.i   genera una demora de 1000 ciclos de instrucciones * i
  9. Delay10KTCYx(i)   -> 10000.Tcy.i    genera una demora de 10000 ciclos de instrucciones  * i
  10. i puede tomar un valor de 1 a 255. Si se toma valor 0 i es 256
  11.  
  12. Para calcular el tiempo que queremos debemos tener en cuenta la frecuencia a la que trabaja el pic
  13. (la frecuencia del cristal de cuarzo).
  14.  
  15. TCY se calcula como 4/fosc
  16.  
  17. donde fosc = frecuencia de oscilador
  18.  
  19. Ejemplo con cristal de 4mhz
  20.  
  21. En este caso 4*10^6(4MHz),
  22.  
  23.  por lo tanto TCY 4/4000000 = 1/10^6 = 0,000001sec
  24.  
  25.         1 TCY = 0,000001seg
  26. 1.000.000 TCY= 1 seg
  27.  
  28. para calcular un segundo
  29.  
  30.   1seg * 1 TCY
  31. ------------------- = 1.000.000 TCYs
  32. 0,000001seg
  33.  
  34.  
  35. calculo del valor de i usando la función Delay10KTCYx(i)= i equivale a 10000 TCYs
  36.  
  37. 1.000.000 TCYs
  38. ------------------- = 100i
  39.    10.000 TCY
  40.  
  41. Delay10KTCYx(100); //dura 1 seg
  42.  
  43.  
  44. ejemplo con cristal de 20mhz
  45.  
  46. TCY se calcula como 4/fosc
  47. En este caso 20*10^6(20MHz), por lo tanto TCY = 4/20*10^6 = 0,0000002
  48.         1 TCY = = 0,0000002seg
  49.  
  50. para calcular un segundo
  51.  
  52.   1seg * 1 TCY
  53. ------------------- = 5.000.000 TCYs
  54. 0,0000002seg
  55.  
  56. calculo del valor de i usando la función Delay10KTCYx(i)= i equivale a 10000 TCYs
  57.  
  58. 5.000.000 TCYs
  59. ------------------- = 500i
  60.    10.000 TCY
  61.  
  62. divido 500 entre 255 para separar el tiempo en n Delay10KTCYx(i) ya que i puede tomar valores de 1 a 255
  63.  
  64.  
  65. Delay10KTCYx(255); // usando los dos delay llego al segundo
  66. Delay10KTCYx(245); //
  67.  
  68. para medio segundo uso 250 y 250
  69.  
  70.  
  71.  
  72. */
  73.  
  74.  
  75. /* Bits de configuración*/
  76.  
  77. #pragma config PLLDIV = 5 // 20 MHz crystal on board
  78. #pragma config FOSC = HS // using an external, high speed crystal, PLL module is disabled
  79.  
  80. #pragma config FCMEN = OFF // Fail-safe clock monitor disabled
  81. #pragma config IESO = OFF // Internal/External Oscillator switchover disabled
  82. #pragma config PWRT = OFF // Power-up Timer disabled
  83. #pragma config BOR = OFF // Brown-out reset disabled
  84. #pragma config BORV = 3 // Brown-out voltage at minimum setting
  85. #pragma config VREGEN = ON // USB voltage regulator enabled
  86. #pragma config WDT = OFF // Watchdog timer hardware disabled, software controlled
  87. #pragma config WDTPS = 32768 // Watchdog timer postscale 1:32768 (max)
  88. #pragma config MCLRE = OFF // MCLR pin disabled, RE3 input pin disabled
  89. #pragma config LPT1OSC = OFF // Low power timer 1 oscillator bit low-- timer 1 configured for higher power operation
  90. #pragma config PBADEN = OFF // PORTB <4:0> pins are configured as digitial I/O on reset
  91. #pragma config CCP2MX = ON // CCP2 input/output is multiplexed with RC1 (vs RB3)
  92. #pragma config STVREN = ON // Stack full/underflow will cause reset
  93. #pragma config LVP = OFF // Single supply ICSP disabled
  94. #pragma config XINST = OFF // Instruction set extension and indexed addressing mode disabled (legacy mode)
  95. #pragma config DEBUG = OFF // Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
  96. #pragma config CP0 = OFF // Code protection bits-- Block 0 (000800 - 001FFFh) not code-protected
  97. #pragma config CP1 = OFF // (002000 - 003FFFh)
  98. #pragma config CP2 = OFF // (004000 - 004FFFh)
  99. #pragma config CPB = OFF // Boot block (000000 - 0007FFh) not code-protected
  100. #pragma config CPD = OFF // Data EEPROM not code-protected
  101. #pragma config WRT0 = OFF // Block 0 not write-protected
  102. #pragma config WRT1 = OFF
  103. #pragma config WRT2 = OFF
  104. #pragma config WRTB = OFF // Boot block not write-protected
  105. #pragma config WRTC = OFF // Configuration register not write-protected
  106. #pragma config WRTD = OFF // EEPROM not write-protected
  107. #pragma config EBTR0 = OFF // Block 0 not protected from table reads executed in other blocks
  108. #pragma config EBTR1 = OFF
  109. #pragma config EBTR2 = OFF
  110. #pragma config EBTRB = OFF
  111.  
  112.  
  113. /*declaración de variables*/
  114. unsigned char i;        //Para contar 0 titilaciones.-
  115.  
  116.  
  117. /*declaración de funciones*/
  118.  
  119.  
  120. /*****Programa principal******/
  121.  
  122. void main(void)
  123. {
  124. ADCON1=0x0F;//Todos entrada/salida digitales. - equivalente en binario ADCON1= 0b00001111
  125. TRISA=0x00; //Todos como salida-                          -     equivalente en binario TRISA = 0b00000000
  126.  
  127. LATA=0x00; //Leds apagados.-                  - equivalente en binario LATA  = 0b00000000
  128. while(1)
  129.         {
  130.        
  131.                 for(i=1;i<=100;++i)
  132.                         {
  133.                         LATA=0xfF; // equivalente en binario LATA  = 0b11111111
  134.                                                 Delay10KTCYx(250); // espero medio segundo
  135.  
  136.                         LATA=0x00; // equivalente en binario LATA  = 0b00000000
  137.                                                 Delay10KTCYx(250); // espero medio segundo
  138.  
  139.                                                 LATB=0xfF; // equivalente en binario LATB  = 0b11111111
  140.                                                 Delay10KTCYx(250); // espero medio segundo
  141.  
  142.  
  143.                         }
  144.           }
  145. }
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: EduSky en 28 de Abril de 2012, 01:07:53
Jukinch, muchas gracias por ese aporte ahora el LED se prende como de la forma que pretendia. De verdad muchas gracias.
Queriendo avanzar un poco mas sobre el pic18f4550 tengo una consulta sobre el SPI. Si el SPI esta en master mode y el pic esta a su vez conectado con otro pic como muestra un grafico del datasheet (pag 199) donde el pin SCK (serial clock) es utilizado por el maestro para controlar el envio de datos al otro pic (segun entendi). Si por ejemplo queres que en el SCK el clock sea de 8MHz, podria llegar ser esta la configuracion del bloque oscilador del pic?:

#pragma config FOSC = HSPLL_HS
#pragma config PLLDIV = 5 // (20 MHz crystal)
#pragma config CPUDIV = OSC2_PLL3

Todavia no me meti con el USB
¿De esta forma el pic estaria trabajando con un clock interno de 32MHz? Despues SCK se divide por 4 y se obtiene 8.
La consulta es porque todavia no me claro el bloque oscilador con las opciones que tiene (xt, hs, hspll, etc). La configuracion la hice en base a una tabla del datasheet.

Saludos y buen fin de semana para toda la gente del foro.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 28 de Abril de 2012, 10:11:03
EduSky:
             En el foro hay mucha información sobre spi. Mirá este hilo en donde Suky explica el origen de la información
http://www.todopic.com.ar/foros/index.php?topic=34319.0

Hola!

Para utilizar el módulo dedicado a SPI existe librería, <spi.h> la cual tiene funciones para configurar y trabajar con el módulo. Información de como se usa en C:\MCC18\doc\periph-lib, el spi.h en C:\MCC18\h, y los archivos fuente en C:\MCC18\src\pmc_common\SPI

Saludos!


sobre el tema del oscilador te recomiendo leas el datasheet del pic que uses.
Te envío una guía de estudio (básicamente una traducción del capitulo de osciladores del datasheet del 18f4550.)
link de descarga de la guia (https://www.dropbox.com/s/f7f5ko80hq2bbcd/guia%20de%20osciladores.pdf)
Saludos.
        Jukinch

Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: EduSky en 28 de Abril de 2012, 20:03:31
Jukinch, gracias por la data. Voy a leer un poco a ver si se aclaran las dudas.

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: c@Lic_0 en 07 de Mayo de 2012, 16:41:24
Gracias por la ayuda Jukinch, pues afectivamente no reconoce las predefiniciones ya que no me mostro ninguna advertencia de error en el compilado segun me indicaste, muy raro pues con la anterior version que tenia el programa corria sin problemas, la definicion de las macros que me indicaste van en un archivo aparte?¡ como un .h o van el el programa principal

mcc18 -DMODE
defines the macro MODE to have a value of 1, whereas:
mcc18 -DMODE=2
defines the macro MODE to have a value of 2.
An instance of utilizing the -D command-line option is in conditional compilation of
code. For example:
#if MODE == 1
x = 5;
#elif MODE == 2
x = 6;
#else
x = 7;
#endif


ya que trate de hacerlo correr de las 2 formas y ninguna me funciona, lo que hice fue crearme otro archivo .h con valores de cada pic y a partir de ahi hice las seleciones apropiadas
Gracias y Saludos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 07 de Mayo de 2012, 18:13:39
c@Lic_0: El -D es un parámetro del compilador. debés ponérselo al compilador mcc18 desde las opciones del Mplab o sinó directamente desde la línea de comandos. No a tu código. Ni en ningún archivo *.h. Ya que es una opción de línea de comando (command-line option).-
            Saludos.
                 Jukinch

La otra opción que podés usar es comentar y descomentar un define.
En un proyecto que comparto con mi amigo pacman tenemos pulsadores pull up y pull down en cada una de nuestras placas y lo usamos así para no tener que cambiar toda la lógica:

Código: [Seleccionar]
#define microcontrolador1
//#define microcontrolador2

#define teclaDebugger PORTCbits.RC5 // tecla para avanzar en programa para controlar errores
// recordar configurar el tris del puerto correspondiente como entrada

#define ledDebugger  LATBbits.LATB4   // led para controlar estado del programa
      // recordar configurar el tris del puerto correspondiente como salida


#ifdef microcontrolador1
#define nopulsoboton 0
                                   
#else
#define nopulsoboton 1
#endif

//#define nopulsoboton 0




/****************** espera se pulse boton de debugger ************************************/

void EsperaBotonDebugger(void)
{
LATBbits.LATB4=1;
Delay10KTCYx(200);    //Retardo para ver lo escrito en lcd
LATBbits.LATB4=0;
Delay10KTCYx(200);    //Retardo para ver lo escrito en lcd
LATBbits.LATB5=1;
Delay10KTCYx(200);    //Retardo para ver lo escrito en lcd
LATBbits.LATB5=0;
Delay10KTCYx(200);    //Retardo para ver lo escrito en lcd
LATBbits.LATB6=1;
Delay10KTCYx(200);    //Retardo para ver lo escrito en lcd
LATBbits.LATB6=0;
Delay10KTCYx(200);    //Retardo para ver lo escrito en lcd
LATBbits.LATB7=1;
Delay10KTCYx(200);    //Retardo para ver lo escrito en lcd
LATBbits.LATB7=0;





while (teclaDebugger==nopulsoboton)
{
}
Delay10KTCYx(10);    //Retardo para ver lo escrito en lcd
ledDebugger=1; // ENCIENDO LED
Delay10KTCYx(10);    //Retardo para ver lo escrito en lcd
ledDebugger =0; // APAGO LED
Delay10KTCYx(10);    //Retardo para ver lo escrito en lcd
ledDebugger =1; // ENCIENDO LED
Delay10KTCYx(10);    //Retardo para ver lo escrito en lcd
ledDebugger=0; // APAGO LED

}
/****************** fin espera se pulse boton de debugger ************************************/

             
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: thomas666 en 30 de Agosto de 2012, 16:25:10
buenas tardes

soy nuevo utilizando c18............ estoy programando un pic 18f4550 y tengo este programa

#include <p18f4550.h>
#include <delays.h>            //libreria de retardo
#include <math.h>
#include <stdio.h>

//configuracion de bits
#pragma config FOSC=INTOSC_EC   //CONFIGURACION DEL OSCILADOR 
#pragma config WDT=OFF         //configuracion de Watchdog "desabilitado"
#pragma config MCLRE=OFF      //configuracion del MCLRE "desabilitado"
#pragma config LVP=OFF         //configuracion del single supply "desabilitado"
#pragma config PBADEN=OFF      //configuracion del puerto I/O digitales PORTB<0:4>
unsigned char N,X,Y;
void main (void)         //inicio del programa
{
TRISB=0X00;                     


for(N=0;N=3;N++)
{
LATB++;
Delay1KTCYx(10);
}

LATB=255;

}

el problema es el siguiente :
cuando lo simulo en proteus el programa cargado no sale de la secuencia de for aunque se supone que deba solamente llegar hasta N=3 y salir no lo hace y sigue la secuencia hasta completar los 8 bits de salida (255) y vuelve a comenzar desde 0 no se porque no sale de ese bucle
que tengo mal............

gracias..............
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: thomas666 en 30 de Agosto de 2012, 16:27:08
buenas tardes

soy nuevo utilizando c18............ estoy programando un pic 18f4550 y tengo este programa

#include <p18f4550.h>
#include <delays.h>            //libreria de retardo
#include <math.h>
#include <stdio.h>

//configuracion de bits
#pragma config FOSC=INTOSC_EC   //CONFIGURACION DEL OSCILADOR 
#pragma config WDT=OFF         //configuracion de Watchdog "desabilitado"
#pragma config MCLRE=OFF      //configuracion del MCLRE "desabilitado"
#pragma config LVP=OFF         //configuracion del single supply "desabilitado"
#pragma config PBADEN=OFF      //configuracion del puerto I/O digitales PORTB<0:4>
unsigned char N,X,Y;
void main (void)         //inicio del programa
{
TRISB=0X00;                     


for(N=0;N=3;N++)
{
LATB++;
Delay1KTCYx(10);
}

LATB=255;

}

el problema es el siguiente :
cuando lo simulo en proteus el programa cargado no sale de la secuencia de for aunque se supone que deba solamente llegar hasta N=3 y salir no lo hace y sigue la secuencia hasta completar los 8 bits de salida (255) y vuelve a comenzar desde 0 no se porque no sale de ese bucle
que tengo mal............

gracias..............
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Suky en 30 de Agosto de 2012, 18:00:23
Tiene que ser N<=3 o N<4... Es una comparación y no una asignación lo que debe hacerse  ;-)


Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Micom en 04 de Marzo de 2013, 02:19:36
No se cual sea la politica o la forma que utilizan los moderadores para escoger a que conjunto de post le ponen un chincheta, pero en mi humilde opinion creo seria bueno que se le pusiera a este tema una chincheta ya que esta muy orientado a la programacion en C18 y el trabajo del amigo Henry esta muy bien explicado. Bueno no pretendo ser un gran conocedor del tema y me estoy iniciando en la programacion del C18, Tampoco pretendo ser un mandon. Solo expreso mi humilde opinion. 
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: alvaro2043 en 25 de Julio de 2013, 01:43:31
Buenas noches.. tengo una pequeña duda... En CCS para definir una variables que solo presenta 2 estados 1 ó 0 de define con : int1 Nombre_constante.. en C18 como puedo definir esa misma variable, he mirado el manual y existe una que se llama BIT, pero al utilizarla me aparece error.. como puedo definir ese tipo de variable en C18.

Gracias.

Éxitos a todos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 25 de Julio de 2013, 08:52:52
Hola Alvaro2043. En C18 no existe el tipo de dato bit o int1.
Sólo está disponible como bit en el nuevo compilador de microchip XC8.
Saludos.
Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: alvaro2043 en 26 de Julio de 2013, 02:54:37
Gracias jukinch.

Ando trabajando en la generación de una señal pwm desde hace uuff jeje  con el timer 0 la idea es ir variando el ciclo de trabajo, no voy a utilizar los modulos CCP por que necesito generar mas de 2 señales pwm, para arrancar he estado cacharreando con el timer 0 generando una señal cuadrada de frecuencia de 20kHZ, en el momento de hacer el codigo y simularlo en proteus, no concuerda con los calculos hechos.. Quiero un desbordamiento de 25us PERO al poner los cursores en el osciloscopio en proteus me sale de 30us Aprox. No se que ando haciendo mal, espero me puedan ayudar anexo codigo

Código: [Seleccionar]
#include <p18f4550.h>
#include <delays.h>

//////////////////Configuaracion de bits//////////////////////////

#pragma config PLLDIV = 1 //En este caso no importa por que vamos a utilizar Oscilador Interno
#pragma config CPUDIV = OSC1_PLL2 ////En este caso no importa por que vamos a utilizar Oscilador Interno
#pragma config USBDIV = 1   /////En este caso no importa por que vamos a utilizar Oscilador Interno
#pragma config FOSC = INTOSCIO_EC  //Configurando oscilador interno
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 16384
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = ON
#pragma config CCP2MX = OFF
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF

#define  bandera INTCONbits.TMR0IF

void Interrupt_isr_TMR0(void);

//-------------------------------------------------------

void main (void)
{
 //------------Configuracion de puertos--------------------------
    TRISB=0x00;
    LATB=0x00;
    ADCON1=0x0F;  //Todos los pines digitales.

//----------------Configuracion de oscilador interno------------------
    OSCCON=0b01110110;  //Oscilador Interno a 8Mhz
//--------------------------------------------------------
    RCONbits.IPEN=1; //Habilito prioridad de interrupcion.
    INTCONbits.GIE_GIEH=1; //Habilito todas las interrupciones de alta prioridad
    INTCONbits.TMR0IE=1; //Habilito Interrupcion TMR0 por desbordamiento
    bandera=0; //Pongo a cero la bandera de desbordamiento.
//-------------------------------------------------------------
//------------Configurando el Timer0--------------------------
    T0CON=0b11001000;   //Configurado a 8 bits sin prescales
    TMR0L=00;

    while(1){}

    
}

#pragma code HighVector = 0x08

void high_ISR(void){
    _asm goto Interrupt_isr_TMR0 _endasm
}
//Rutina de Interrupciones de alta prioridad

#pragma code
#pragma interrupt Interrupt_isr_TMR0

void Interrupt_isr_TMR0 (void){
    TMR0L=206;   // 256-206= 50 paso: Como se sabe que cada paso es de 500ns 500ns*50=25us el desbordamiento.
    if(bandera==1){
        bandera=0;
        LATBbits.LATB0=!LATBbits.LATB0;
        
    }

 }
    


Gracias y Exitos a todos
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: Miquel_S en 26 de Julio de 2013, 04:36:23
Hola alvaro2043, te comento dos cosas por si las hubieras pasado por alto, ten en cuenta que la simulación no deja de ser una simulación, lo mas correcto seria probarlo en la vida real. Otra cosa a tener en cuenta es que el valor de tus cálculos nunca serán los mismos a los que usas en el programa, ten presente que al programar en C y compilar el código el compilador crea instrucciones adicionales las cuales te variaran el valor.
Recuerdo haber hecho alguna temporización y tener que hacerla en ASM ajustando el valor a cargar en TMR0 y aun así tener que poner algún que otro NOP dentro de la interrupción. 

Saludos!
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: alvaro2043 en 26 de Julio de 2013, 09:39:02
Gracias miguel por responder. Voy a probar esto en la vida real y les voy a comentar.

En el caso que no me de el valor esperado como puedo hacer que el desbordamiento sea exactamente los 25us.. ¿Me tocaria a prueba y error cargando TMR0L hasta llegar a los 25us?

He mirado el diagrama de bloques del timer0 y existe un bloque (SYNC WITH INTERNAL CLOCK) y habla de  un delay (2Tcy delay) si dado el caso esto tiene que ver algo.
 Me nace otra pregunta. Inicialmente yo puse mi TMR0L=0 osea que se desbordaría a 128us -> (8Mhz/4)-> Tcy=500ns-> 500ns*256 ya que es de 8bits y al simularlo me da exactamnte los 128us.. No se por que al cargar el TMR0L=206 no obtengo el valor calculado :(

Gracias.

Éxitos a Todos.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: jukinch en 26 de Julio de 2013, 10:20:20
Alvaro2043:
Además de lo que indica el amigo Miquel_S dale una leída a este hilo.
http://www.todopic.com.ar/foros/index.php?topic=37217.0
Prestale atención a lo que indica Reiniertl.
Perdón por lo breve pero estoy / móvil.
Saludos.
Jukinch
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: hector915 en 06 de Octubre de 2013, 03:12:29
Me he leido las 21 paginas desde el inicio ( :)me tomo cuatro dias) de este cursillo gracias a microcadaver pude ampliar mis conocimientos,a suky por las dudas que me despejo en cuanta a las estructuras de los archivos...Definitivamente que foro Son unos cracks.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: electroipod en 30 de Octubre de 2013, 16:10:41
Le pido al moderador de este foro que este cursillo lo ponga en la parte superior de este mismo foro para que sea mas accesible para todos aquellos que comienzan con c18, es un cursillo bastante didactico y no quisiera que se pierda en las profundidades del olvido.
Título: Re: Cursillo en C18 para PICS DESDE CERO
Publicado por: nitsuga2585 en 21 de Enero de 2015, 16:51:43
hola que tal, estoy tratando de comunicar 2 pic por i2c en c18. puedo mandar mensajes del master al esclavo pero del esclavo al master no puedo, les agradeceria si me puedieran ayudar.
El codigo del maestro es:
Código: [Seleccionar]
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include <i2c.h>
#include <delays.h>
#include <string.h>
#include <stdlib.h> //Libreria para conversiones a string
#include <stdio.h>

        #pragma config PLLDIV   = 5         // (20 MHz crystal on PICDEM FS USB board)
        #pragma config CPUDIV   = OSC1_PLL2   
        #pragma config USBDIV   = 2         // Clock source from 96MHz PLL/2
        #pragma config FOSC     = HSPLL_HS
        #pragma config FCMEN    = OFF
        #pragma config IESO     = OFF
        #pragma config PWRT     = OFF
        #pragma config BOR      = ON
        #pragma config BORV     = 3
        #pragma config VREGEN   = ON      //USB Voltage Regulator
        #pragma config WDT      = OFF
        #pragma config WDTPS    = 32768
        #pragma config MCLRE    = ON
        #pragma config LPT1OSC  = OFF
        #pragma config PBADEN   = OFF
//      #pragma config CCP2MX   = ON
        #pragma config STVREN   = ON
        #pragma config LVP      = OFF
//      #pragma config ICPRT    = OFF       // Dedicated In-Circuit Debug/Programming
        #pragma config XINST    = OFF       // Extended Instruction Set
        #pragma config CP0      = OFF
        #pragma config CP1      = OFF
//      #pragma config CP2      = OFF
//      #pragma config CP3      = OFF
        #pragma config CPB      = OFF
//      #pragma config CPD      = OFF
        #pragma config WRT0     = OFF
        #pragma config WRT1     = OFF
//      #pragma config WRT2     = OFF
//      #pragma config WRT3     = OFF
        #pragma config WRTB     = ON       // Boot Block Write Protection
        #pragma config WRTC     = OFF
//      #pragma config WRTD     = OFF
        #pragma config EBTR0    = OFF
        #pragma config EBTR1    = OFF
//      #pragma config EBTR2    = OFF
//      #pragma config EBTR3    = OFF
        #pragma config EBTRB    = OFF


/** V A R I A B L E S ********************************************************/
#pragma udata
unsigned char ENVIO_I2C[10];
#pragma udata

unsigned char DATO;

/** P R I V A T E  P R O T O T Y P E S ***************************************/
void YourHighPriorityISRCode();
void YourLowPriorityISRCode();
unsigned char escribirI2C(unsigned char DIRECCION);
unsigned char leerI2C(unsigned char slave_addr, unsigned char direcc);

/** V E C T O R  R E M A P P I N G *******************************************/

#pragma code HIGH_INTERRUPT_VECTOR = 0x08
void High_ISR (void) {
_asm goto YourHighPriorityISRCode _endasm
}
#pragma code LOW_INTERRUPT_VECTOR = 0x18
void Low_ISR (void){
_asm goto YourLowPriorityISRCode _endasm
}

#pragma code


#pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode(){
#if defined(USB_INTERRUPT)
USBDeviceTasks();
    #endif
}

#pragma interruptlow YourLowPriorityISRCode
void YourLowPriorityISRCode(){

}

/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
 * Function:        void main(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Main program entry point.
 *
 * Note:            None
 *****************************************************************************/
/** L E D ***********************************************************/
void main(void)
{
TRISD=0x00;

CloseI2C();

//Iniciamos I2C
    OpenI2C(MASTER, SLEW_ON); //MASTER, 400KHZ
    SSPADD = 119; // I2C_clock = FOSC/(4 * (SSPADD + 1)) => FOSC = 20MHz y Scl=100KHz  //119


// escribirI2C(0xA2);

//ESPERO UN TIEMPO GRANDE ANTES DE LLER
// Delay10KTCYx(200);

DATO = leerI2C(0xA2, 0x40);

while(1){
PORTD = DATO;
}
}

unsigned char leerI2C(unsigned char slave_addr, unsigned char direcc) {
    //slave_addr => Direccion de Escritura del dispositivo I2C
    unsigned char reg,reg2;
    IdleI2C(); // Esperar a que el periferico esté disponible
    StartI2C(); // Generar condicion Start
    while (SSPCON2bits.SEN); // Espera a que se inicie la condicion START en los pines SDA y SCL
    WriteI2C(slave_addr); // Slave address to SSPBUF (Dummy Write)
    WriteI2C(direcc); // Word address to SSPBUF
    RestartI2C(); // Generar condicion Restart
    while (SSPCON2bits.RSEN); // Espera a que se inicie la condicion RESTART en los pines SDA y SCL
    WriteI2C(slave_addr | 0x01); // Slave address to SSPBUF (Read)
// while(!DataRdyI2C());
    reg = ReadI2C(); // Leer dato de Memoria I2C
while (SSPSTATbits.BF == 1)
    NotAckI2C(); // Generar condicion NACK
    while (SSPCON2bits.ACKEN); // Espera a que se inicie la condicion NACK en los pines SDA y SCL
    StopI2C(); // Generar condicion STOP
    while (SSPCON2bits.PEN); // Espera a que se inicie la condicion STOP en los pines SDA y SCL
    Delay1KTCYx(25);
    return (reg);
}

y el codigo del esclavo es:
Código: [Seleccionar]
#include <p18f4620.h>
#include <delays.h>
#include <usart.h>
#include <stdio.h>
#include <string.h>
#include <i2c.h>

#pragma config OSC=HSPLL
#pragma config IESO=OFF
#pragma config PWRT=ON
#pragma config WDT=OFF
#pragma config MCLRE=ON
#pragma config XINST=OFF
#pragma config DEBUG=ON
#pragma config FCMEN = OFF
#pragma config LVP=OFF
#pragma config BOREN=OFF

/** V A R I A B L E S ********************************************************/
unsigned int ADDR,DATO,KBIT,i,j,k,L;

#pragma udata
unsigned char ENVIO_I2C[10];
#pragma udata

/** P R I V A T E  P R O T O T Y P E S ***************************************/
void low_isr(void);
void high_isr(void);
unsigned char escribirI2C ( unsigned char slave_addr);
unsigned char leerI2C ( unsigned char slave_addr, unsigned char direcc);

/** V E C T O R  R E M A P P I N G *******************************************/
//Vector de interrupcion de baja prioridad
#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
 _asm GOTO low_isr _endasm
}
#pragma code /* Regresa al lugar de donde dio el salto */
#pragma interruptlow low_isr
void low_isr (void)
{
 //En esta secccion se coloca las lineas de codigo
 //con grado de baja prioridad
}
 
 
//Vector de interrupcion de alta prioridad
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
 _asm GOTO high_isr _endasm
}
#pragma code /* Regresa al lugar de donde dio el salto */
#pragma interrupt high_isr
void high_isr (void)
{
//VERIFICA SI SALTO INTERRUPCION, SI EL SSPBUF ESA COMPLETO (BF) Y SI SE TRATA DE LA DIRECCION(D_A)
if (PIR1bits.SSPIF == 1 && SSPSTATbits.BF == 1 && SSPSTATbits.D_A == 0){
ADDR = SSPBUF; //LEO LA DIRECCION
PIR1bits.SSPIF = 0; //BAJO BANDERA
SSPSTATbits.BF = 0;     //BAJO DATO DE SSPBUF LLENO
}

//Esto comprueba si una interrupción ha sido recibido, SSPBUF es realmente completo de nuevo,
//y SSPBUF contiene datos (no una dirección). Si todos los cheques que puede leer el byte de datos:
if (PIR1bits.SSPIF == 1 && SSPSTATbits.BF == 1 && SSPSTATbits.D_A == 1){
DATO = SSPBUF;
//Ahora que tenemos nuestros datos tenemos que hacer un poco de limpieza adicional:
PIR1bits.SSPIF = 0; // interrupción clara
SSPSTATbits.D_A = 0; // establecer D_A poco a 0 para que podamos comprobar si el byte posterior es más datos.
}
if (PIR1bits.SSPIF == 1 && SSPSTATbits.BF == 0 && SSPSTATbits.D_A == 0){
WriteI2C(0xA2);
  }
PIR1bits.SSPIF = 0; // interrupción clara
}


/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
 * Function:        void main(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Main program entry point.
 *
 * Note:            None
 *****************************************************************************/
/************************************************************************************************/
/*************************************************************************************************************/
//PROGRAMA PRINCIPAL
void main(void)
{
TRISD=0x00;

ADCON1 = 0xFF;  //DESHABILITA ENTRADAS ANALOGICAS

RCONbits.IPEN = 1; // habilitamos Prioridades
IPR1bits.SSPIP = 1; //PRIORIDAD ALTA AL I2C
// Configuracion de las interrupciones.
PIE1bits.SSPIE = 1; // Habilita la interrupcion del modulo SSP
INTCONbits.PEIE = 1; // Habilita las interrupciones de los perifericos
INTCONbits.GIE = 1; // Habilita las interrupciones globales!

PIR1bits.SSPIF = 0; // BORRO LA BANDERA DE LA INTERRUPCION

    //Iniciamos I2C
OpenI2C(SLAVE_7,SLEW_ON);//MASTER, 400KHZ
SSPADD = 0xA2;

//CONDICIONES INICIALES
i = j = KBIT = 0;
k = 1;

while(1){


}
}

unsigned char escribirI2C(unsigned char DIRECCION) {
    //slave_addr => Direccion de Escritura del dispositivo I2C
    IdleI2C(); // Esperar a que el periferico esté disponible
    StartI2C(); // Generar condicion Start
    while (SSPCON2bits.SEN); // Espera a que se inicie la condicion START en los pines SDA y SCL
    WriteI2C(DIRECCION); // Slave address to SSPBUF (Write)
    //WriteI2C(30); // Write Data to SSPBUF
    StopI2C(); // Generar condicion Stop
    while (SSPCON2bits.PEN); // Espera a que se inicie la condicion STOP en los pines SDA y SCL
    //while (EEAckPolling(slave_addr_w));  //Espera que se complete escritura.
}

como no me ha salido, trate de empezar con spi pero ni siquiera he podido mandar un dato ajja, por favor ayuda!!!!!!
Título: Re:Cursillo en C18 para PICS DESDE CERO
Publicado por: syndu en 05 de Mayo de 2016, 01:23:24
Buenas, mi problema es este: yo genero una señal onda cuadrada de 8,30 ms, y vario su duty cicle a travez de un potenciometro, la cosa es que a medida que vario se cambia la amplitud de mi señal y deja de ser 5 volts,, no se porque sucede esto!! la señal debe variar el ciclo de trabajo de 0 a 180!! esto es lo llevo! espero pronta respuesta!

#include <p18cxxx.h>
#include <delays.h>
#include <stdlib.h>
#include "lcd.h"
#pragma config PLLDIV = 5 // (20 MHz crystal)
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2
#pragma config FOSC = HSPLL_HS //HSPLL_HS
#pragma config WDT = OFF
//variable lcd
CHAR lcd[16];
CHAR msg[]="% Alfa= ";

unsigned long n=0;
unsigned long conta=0;
float constante=17.64;            // valor calculado por regla de tres
unsigned int ADC,Alfa;
unsigned long Valor_Escalado;
unsigned int adc_read(unsigned char ch);
// variable interrupcion
unsigned int count=0;
void initTimer (void);
void InterruptHandlerHigh (void);
// High priority interrupt vector
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{
_asm
goto InterruptHandlerHigh //jump to interrupt routine
_endasm
}
// High priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh ()
{
if (PIR1bits.TMR2IF == 1)
{
PIR1bits.TMR2IF = 0;
count++;
if(count==n)
PORTC=0;
if(count==512)
{
PORTC=0xFF;
count=0;
}
}
}
void main()
{
TRISB=TRISC=TRISD = 0x00; // set direction to be output
PORTC=0x0;
ADCON1 = 0x0F;
INTCONbits.GIE = 1; //enable global interrupts
INTCONbits.PEIE = 1; //enable peripherical interrupts
   lcd_init();
   TRISAbits.TRISA0 = 1;
   initTimer();
do{
      lcd_clear();
      ADC = adc_read(0);                  // Read from channel 0 (AN0)
      lcd_display(1,1,msg);                // Display "mV = "
      Valor_Escalado=ADC;
      Valor_Escalado = constante*Valor_Escalado;                   // Scale up the result
      Alfa = Valor_Escalado / 100;               // Decimal part
      itoa(Alfa,lcd);                   // Convert Vdec to string in "lcd"
      lcd_display(1,8,lcd);                // Output to LCD
      Delay10KTCYx(250);
   n=Alfa*2.85-1;
      //initTimer();

}while(1);
}
void initTimer (void)
{
PR2 = 194; // T = (PR2+1) * 4 *(1/Fosc)*PRESCALER
// 16.25us= (PR2+1)* 4*(1/Fosc)*PRESCALER : Fosc=48Mhz : PRESCALER=1
T2CON=0;
T2CONbits.T2CKPS1 = 0;
T2CONbits.T2CKPS0 = 0; // 1:1 - prescaler
IPR1bits.TMR2IP = 1; // high priority
PIR1bits.TMR2IF = 0;
PIE1bits.TMR2IE = 1; //1=enable Interrupt
T2CONbits.TMR2ON = 1;
}

unsigned int adc_read(unsigned char ch){
   unsigned int result;
   ADCON0 = (ch & 0x0F) << 2;
   ADCON1 = 0x0B;   //RA0-RA3 Analog inputs.
   ADCON2 = 0x96;   // right justify,TACQ=4*TAD, TAD=1/(FOSC/64)
   ADCON0bits.ADON = 1; // ADC on
   ADCON0bits.GO_DONE = 1; // start
   while (ADCON0bits.GO_DONE == 1);
   result = ((unsigned int)(ADRESH) << 8) + ADRESL;
   ADCON0bits.ADON = 0;   // ADC Off
   return result;
}
Título: Re:Cursillo en C18 para PICS DESDE CERO
Publicado por: stk500 en 05 de Mayo de 2016, 04:03:58
Hola syndu!
por favor no repita mensaje, leerte las Reglas de nuestros foro, si nadie contesta es porque nadie sabe de tu problema y aqui nadie esta para resolver problema Urgente de nadie.
espero que lo comprenda al leer nuestras Reglas.

un Saludos