Autor Tema: Mini curso "Programación en XC8"  (Leído 455500 veces)

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

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: Mini curso "Programación en XC8"
« Respuesta #60 en: 04 de Junio de 2013, 16:29:41 »
Genial, Sander  ((:-))
Por eso tenía que habilitar las interrupciones de nuevo.
Muchas gracias y un saludo.

Desconectado yamilongiano

  • PIC10
  • *
  • Mensajes: 37
Re: Mini curso "Programación en XC8"
« Respuesta #61 en: 04 de Junio de 2013, 18:37:16 »
1.4. Utilizando PWM

Vamos a utilizar una señal PWM de 8 bits para controlar el brillo de un LED. Para configurar el módulo CCP1 en modo PWM solo basta con escribir 0x0C en el registro CCP1CON.

Frecuencia PWM: el periodo de la onda PWM lo determina el tiempo que dura el conteo del Timer2 desde 0 hasta el valor cargado en el registro PR2. Y como la frecuencia es la inversa del período podemos deducir:




Donde:

* PR2 es el valor del registro PR2 (entre 0 y 255)
* FOSC es la frecuencia del cristal utilizado
* Prescaler es el prescaler del Timer2 (1, 4 ó 16). Se configura en el registro T2CON.

Ciclo de trabajo (duty cicle): es la cantidad de tiempo que en un periodo la salida PWM permanece en estado alto. El valor es determinado por el contenido del registro CCPR1L. Podemos deducir el tiempo utilizando la formula:




Donde:

* CCPR1L es el valor del registro CCPR1L (entre 0 y 255)
* FOSC es la frecuencia del cristal
* Prescaler   es el prescaler del Timer2 (1, 4 ó 16)

Ejemplo dimerizado de un LED conectado a RB3

Código: C
  1. /*
  2.  * File:   main.c
  3.  * Author: lucas
  4.  * Created on 1 de abril de 2013, 22:20
  5.  * Microcontrolador: PIC16F648A
  6.  *
  7.  * Utilizando PWM para dimerizar un LED
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <xc.h> // Librería XC8
  13.  
  14. #define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro
  15.  
  16. // PIC16F648A Configuration Bit Settings
  17. #pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
  18. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
  19. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
  20. #pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
  21. #pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
  22. #pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
  23. #pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
  24. #pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
  25.  
  26. // FUNCION PRINCIPAL
  27. void main(void) {
  28.     TRISB = 0;                  // Puerto B como salidas
  29.     PORTB = 0;                  // Limpio el puerto B
  30.  
  31. // CONFIGURANDO PWM  
  32.     CCP1CON = 0b00001100;       // Activamos el modo PWM
  33.     PR2 = 250;                  // Frecuencia 250Hz
  34.     T2CONbits.T2CKPS = 0b10;    // Prescaler del timer 2 en 1:16
  35.     T2CONbits.TMR2ON = 1;       // Arranca el PWM      
  36.  
  37. // BUCLE INFINITO
  38.     unsigned char i;           // Declaramos una variable
  39.     while (1){
  40.     for(i=0; i=50; i++)
  41.     {
  42.       CCPR1L = CCPR1L++;        // Seteando el ciclo de trabajo
  43.       __delay_ms (100);    
  44.     }
  45.     i=0;                       // Reiniciamos la variable para comenzar el ciclo de nuevo
  46.     }
  47.     }

queria preguntar, por que no se como hacerlo, como puedo dejar el el tiempo de encendido del PWM en un estado fijo. que no varie contantemente ya que este PWM esta oscilante y no podemos dejar un T1 y T2 en tiempo fijo.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Mini curso "Programación en XC8"
« Respuesta #62 en: 04 de Junio de 2013, 20:19:08 »
  yamilongiano, fíjate con atención en el mensaje de lmtreser que justamente indica muy bien que el ciclo de trabajo está dado por CCPR1L. Si el valor asignado a dicho registro se deja fijo, pues el duty cicle no variará.

  En el programa que él da de muestra, el duty varía porque está cargando al registro CCPR1L con un valor variable.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Mini curso "Programación en XC8"
« Respuesta #63 en: 07 de Junio de 2013, 00:11:21 »
BITS DE CONFIGURACION - Generador de código

Mplab X nos brinda una herramienta que nos permite generar el código para el seteo de los bits de configuración del pic seleccionado en nuestro proyecto en forma automática.

Para acceder a la misma seleccionamos desde el menú principal, Windows, Pic Memory Views, Configuration bits.
Como se muestra en la siguiente figura:






En la parte inferior de la pantalla se abrirá la ventana "Configuration Bits".
Ver flecha negra en la siguiente figura:



Hacemos doble click en el título de la ventana para maximizarla.

Allí tendremos todas las opciones disponibles para nuestro pic.

Luego haciendo click en cualquier valor de la columna option (opción) se abrirá un combo para elegir los valores a setear.



Y por último apretamos el botón que dice Generate Source Code to Output para generar nuestro código en la consola de salida.

Como se ve en la siguiente figura el código ha sido generado en la parte inferior de la pantalla con todos los bits de configuración de nuestro pic. (si no hacemos cambios el código se genera igualmente con todos los valores por defecto del pic)

En este caso para un pic16f84a.




Una vez que hemos generado el código lo podemos copiar y pegar en nuestro programa como se ve en la siguiente figura:




En la pantalla siguiente se ven a modo de ejemplo los bits de configuración de un pic18F4550



En esta otra pantalla se ve el código generado para el pic18F4550




Cuando vi por primera vez todas las opciones del 4550 me recordaron el tablero de un helicóptero...



Espero les sea de utilidad.
  Saludos
            Jukinch

fuente: http://microchip.wikidot.com/mplab:how-to-view-and-set-configuration-bits
« Última modificación: 07 de Junio de 2013, 00:44:15 por jukinch »
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Mini curso "Programación en XC8"
« Respuesta #64 en: 07 de Junio de 2013, 22:09:33 »
  Jukinch, muchas gracias por la info... cada vez que hice algo con un 18F4550, me volví chango entre el datasheet, y los docs del compilador.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Mini curso "Programación en XC8"
« Respuesta #65 en: 08 de Junio de 2013, 08:00:59 »
Hola Angelgris. Que bueno poder ayudarte. Y aprovecho para agradecer todas las manos que nos has dado en el foro.
Un abrazo
        Jukinch
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Mini curso "Programación en XC8"
« Respuesta #66 en: 08 de Junio de 2013, 15:57:06 »
  Aquí comparto una librería muy básica para usar I2C por software. La simulé en ISIS y pude manejar una 24C04. Ya se me está ocurriendo una modificación de la rutina i2cs_write, para que devuelva un bit para saber si hubo o no ack por parte del dispositivo.
Otra posible modificación es la utilización de los registros LAT en el caso de los PIC que los posean, pero eso se podría hacer en el header... iré haciendo algunas pruebas.
  También podría agregarse alguna función para chequear el estado del bus antes de intentar comenzar una comunicación.

  En el .h hay que definir algunos parámetros para el manejo de la librería y también hay que definir _XTAL_FREQ de acuerdo al valor de frecuencia de oscilación del cristal. En realidad sería la frecuencia de funcionamiento del núcleo del PIC, ya que si se usa un 18F a 48MHz, ese sería el valor para _XTAL_FREQ.

  En la librería se incluyen dos mensajes de error que evitará que el programa compile si no se han definido los pines a utilizar por SDA y SCL o si no se han definidos los registros de dirección (TRIS) de los pines a utilizar.

swi2c.h
Código: C
  1. #ifndef SWI2C_H
  2. #define SWI2C_H
  3.  
  4. #ifndef _XC_H_
  5.   #include <xc.h>
  6. #endif
  7.  
  8. #define _XTAL_FREQ 20000000
  9.  
  10. #define SDAPIN PORTBbits.RB0
  11. #define SCLPIN PORTBbits.RB1
  12. #define SDADIR TRISBbits.TRISB0
  13. #define SCLDIR TRISBbits.TRISB1
  14.  
  15. void i2cs_start(void);
  16. void i2cs_stop(void);
  17. void i2cs_write(unsigned char);
  18. unsigned char i2cs_read(void);
  19. void i2cs_nack(void);
  20. void i2cs_ack(void);
  21.  
  22. #endif  /* SWI2C_H */

swi2c.c
Código: C
  1. #ifndef SWI2C_H
  2.   #include "swi2c.h"
  3. #endif
  4.  
  5. #if !defined(SDAPIN) || !defined(SCLPIN)
  6.   #error Falta definir los pines SDA y SCL
  7. #elif !defined(SDADIR) || !defined(SCLDIR)
  8.   #error Falta definir los registros de direccion
  9. #else
  10. void i2cs_start(void)
  11. {
  12.     SDADIR = 1;
  13.     SCLDIR = 1;
  14.     __delay_us(5);
  15.     SDAPIN = 0;
  16.     SDADIR = 0;
  17.     __delay_us(4);
  18.     SCLPIN = 0;
  19.     SCLDIR = 0;
  20. }
  21.  
  22. void i2cs_stop(void)
  23. {
  24.     SDAPIN = 0;
  25.     SDADIR = 0;
  26.     SCLPIN = 0;
  27.     SCLDIR = 0;
  28.     __delay_us(1);
  29.     SCLDIR = 1;
  30.     __delay_us(5);
  31.     SDADIR = 1;
  32. }
  33.  
  34. void i2cs_write(unsigned char _data)
  35. {
  36.     unsigned char _bits;
  37.  
  38.     __delay_us(5);
  39.     for (_bits = 8; _bits > 0; _bits--)
  40.     {
  41.         if ((_data & 0x80) == 0)
  42.         {
  43.             SDAPIN = 0;
  44.             SDADIR = 0;
  45.         }
  46.         else
  47.             SDADIR = 1;
  48.         _data = _data << 1;
  49.         __delay_us(1);
  50.         SCLDIR = 1;
  51.         __delay_us(4);
  52.         SCLPIN = 0;
  53.         SCLDIR = 0;
  54.         __delay_us(5);
  55.     }
  56.     SDADIR = 1;
  57.     __delay_us(1);
  58.     SCLDIR = 1;
  59.     __delay_us(4);
  60.     SCLPIN = 0;
  61.     SCLDIR = 0;
  62. }
  63.  
  64. unsigned char i2cs_read(void)
  65. {
  66.     unsigned char _data;
  67.     unsigned char _bits;
  68.  
  69.     for (_bits = 8; _bits > 0; _bits--)
  70.     {
  71.         __delay_us(5);
  72.         _data = _data << 1;
  73.         SCLDIR = 1;
  74.         __delay_us(2);
  75.         if (SDAPIN == 1) _data |= 1;
  76.         __delay_us(2);
  77.         SCLPIN = 0;
  78.         SCLDIR = 0;
  79.     }
  80.     return _data;
  81. }
  82.  
  83. void i2cs_nack(void)
  84. {
  85.     __delay_us(5);
  86.     SDADIR = 1;
  87.     __delay_us(1);
  88.     SCLDIR = 1;
  89.     __delay_us(4);
  90.     SCLPIN = 0;
  91.     SCLDIR = 0;
  92.     __delay_us(5);
  93.     SDAPIN = 0;
  94.     SDADIR = 0;
  95. }
  96.  
  97. void i2cs_ack(void)
  98. {
  99.     __delay_us(5);
  100.     SDAPIN = 0;
  101.     SDADIR = 0;
  102.     __delay_us(1);
  103.        SCLDIR = 1;
  104.     __delay_us(4);
  105.     SCLPIN = 0;
  106.     SCLDIR = 0;
  107.     __delay_us(5);
  108.     SDAPIN = 0;
  109.     SDADIR = 0;
  110. }
  111. #endif

Programa de ejemplo. Comunicación entre 16F648A y 24C04
Código: C
  1. #include <xc.h>
  2.  
  3. #pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
  4. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
  5. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
  6. #pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
  7. #pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
  8. #pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
  9. #pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
  10. #pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
  11.  
  12.  
  13. #include "swi2c.h"
  14.  
  15.  
  16. void main(void)
  17. {
  18.     unsigned char data;
  19.  
  20.     i2cs_start();            //comienzo comunicacion
  21.     i2cs_write(0b10100001);  //accedo a la memoria para lectura (posicion actual)
  22.     i2cs_read();             //leo la memoria
  23.     i2cs_nack();             //no respondo
  24.     i2cs_stop();             //termino comunicacion
  25.  
  26.     i2cs_start();            //comienzo comunicacion
  27.     i2cs_write(0b10100000);  //accedo a la memoria para escritura
  28.     i2cs_write(0x02);        //direccion que quiero escribir
  29.     i2cs_write(0x05);        //dato a escribir
  30.     i2cs_stop();             //termino comunicacion
  31.  
  32.     __delay_ms(5);           //espero para que se grabe el dato en la memoria
  33.  
  34.     i2cs_start();            //comienzo comunicacion
  35.     i2cs_write(0b10100000);  //accedo a la memoria para escritura
  36.     i2cs_write(0x02);        //direccion que quiero escribir
  37.     i2cs_start();            //comienzo comunicacion (para leer la posicion)
  38.     i2cs_write(0b10100001);  //accedo a la memoria para lectura (posicion actual)
  39.     i2cs_read();             //leo la memoria
  40.     i2cs_nack();             //no respondo
  41.     i2cs_stop();             //termino comunicacion
  42.  
  43.     while(1);
  44. }
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Mini curso "Programación en XC8"
« Respuesta #67 en: 09 de Junio de 2013, 03:08:52 »
CONVERSORES ADC - PWM

En el siguiente ejemplo se utilizan dos potenciómetros para controlar la intensidad de 2 leds por pwm.
Los valores de la conversión de cada canal (de 0 a 1023) se visualizan en un LCD.

Para mostrar en el LCD los valores leídos de los ADC se utiliza la función itoa. La misma convierte un valor entero en cadena de caracteres. En xc8 la función itoa recibe 3 parámetros en vez de 2 como era en c18.

Los nuevos parámetros de itoa    ahora son     (char * buf, int val, int base)


Código: C
  1. /*
  2. Mini curso "Programación en XC8"
  3.  
  4. programa: ejemplo módulo conversor adc
  5.  
  6. pic: 18f4550
  7. Ejemplo XC8 - LCD + Conversor AD + PWM. Uso de la nueva función itoa.
  8.  
  9. HARDWARE: Entrenadora Multiboard Pictrainer 2.0 Felixls
  10. Microcontrolador: pic18f4550
  11. cristal: 20mhz
  12.  
  13. CONEXIONES: Módulo LCD conectado en PUERTO D.
  14. El módulo LCD utilizado en este programa no es el standard de felixls.
  15. Quité el cd4094 y se utiliza el pin de RW
  16.  
  17. bus de datos en el nible alto conector IDC7 (rb 4 a 7)
  18.  
  19. DATA7    PUERTO D.7
  20. DATA6    PUERTO D.6
  21. DATA5    PUERTO D.5
  22. DATA4    PUERTO D.4
  23.  
  24.  
  25. bus de control en el nible bajo conector IDC4 (rb 0 a 3)
  26.  
  27. E_PIN    PUERTO D.3
  28. RS_PIN   PUERTO D.2
  29. RW_PIN   PUERTO D.1
  30.  
  31.  
  32.  
  33. Módulo Analógico conectado en conector IDC 2 (conector idc e0-e3) a P0
  34. POT1=E0
  35. POT2=E1
  36.  
  37.  
  38. Módulo IO digital conectado en conector IDC2
  39.  
  40. led pwm1 conector IDC2 (c0-c3)   EN RC2
  41. led pwm2 conector idc (C0-C3)   EN RC1
  42.  
  43.  
  44. Moviendo los potenciómetros del módulo analógico se controla la intensidad
  45. de 2 leds por pwm y se visualizan en el LCD los valores de 0 a 1023.
  46.  
  47. */
  48.  
  49. #define _XTAL_FREQ 20000000 // Linea necesaria para los cálculos de la función
  50.                            // de delay. CUIDADO. no es para la configuración
  51.                            // de la frecuencia de trabajo del cpu del pic.
  52.                            // eso se determina en otro lado. :)
  53.  
  54.  
  55.  
  56. /*Includes globales*/
  57. #include <xc.h>
  58. #include <pic18.h>
  59. #include <delays.h> /* Para utilizar demoras en nuestro código debemos incluir la librería delays.h.*/
  60. #include <plib/adc.h> // libreria para conversor ADC
  61. #include <plib/timers.h>
  62. #include <plib/pwm.h>
  63. #include <stdlib.h> // librería para poder usar itoa ?
  64.  
  65. /*Includes locales*/
  66. #include "configuracion_de_fuses.c"
  67. #include "xlcd_portd.h" // librería modificada para puerto D. Con dolor de cabeza solucionado. :)
  68.  
  69.  
  70. /*declaración de variables globales*/
  71.  
  72. /*declaración de funciones*/
  73. void myMsDelay(int ms);
  74.  
  75. void DelayFor18TCY(void);
  76. void DelayPORXLCD(void);
  77. void DelayXLCD(void);
  78.  
  79.  
  80. ///////////////////////////////////////////////////////////////////////////////
  81. //                     Programa Principal                                    //
  82. ///////////////////////////////////////////////////////////////////////////////
  83.  
  84.  
  85. void main(void)
  86. {
  87. unsigned int Canal5, Canal6;
  88. char cadena_de_texto[5];
  89.  
  90.  
  91.  
  92. TRISB=0b00000000;      // Puerto B como salidas
  93. LATB=0b00000000;      //todas las salidas abajo
  94.  
  95. TRISC=0b00000000;      // Puerto c como salidas
  96. LATC=0b00000000;      //todas las salidas abajo
  97.  
  98. Delay10KTCYx(255);    //Retardo para esperar que pase cualquier transitorio
  99.  
  100.  
  101.  
  102. OpenXLCD(FOUR_BIT&LINES_5X7);   //inicializamos LCD con varias lineas y caracteres 5x7
  103. WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
  104. Delay10KTCYx(255);    //Retardo
  105. WriteCmdXLCD(LINE_0); // Nos posicionamos en la posición 0
  106.  
  107. putrsXLCD("MULTIBOARD");
  108. WriteCmdXLCD(NEXT_LINE+3);
  109. myMsDelay(500);
  110. putrsXLCD("PICTRAINER"); //escribe en lcd cadena de texto guardada en rom
  111. myMsDelay(500);
  112. WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  113. putrsXLCD("      XC8       ");
  114. myMsDelay(500);
  115.  
  116. WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  117.  
  118.  
  119.  
  120.  
  121.  
  122. WriteCmdXLCD(0x01);     // Borra pantalla y vuelve al origen.-
  123. while(BusyXLCD()){}
  124. WriteCmdXLCD(0x80); // LINE_0
  125. while(BusyXLCD()){}
  126. putrsXLCD("CONV5 = "); //escribe en lcd cadena de texto guardada en rom
  127. while(BusyXLCD()){}
  128. WriteCmdXLCD(NEXT_LINE);        //NEXT_LINE Nos posicionamos en la posición 8
  129. while(BusyXLCD()){}
  130. putrsXLCD("CONV6 = "); //escribe en lcd cadena de texto guardada en rom
  131.  
  132. while(1)
  133.         {   // rutina de conversión ADC
  134.                 OpenADC(ADC_FOSC_RC & ADC_2_TAD & ADC_RIGHT_JUST, ADC_REF_VDD_VSS & ADC_INT_OFF, ADC_7ANA);
  135.                 SetChanADC(ADC_CH5);    // Selecciono canal a convertir.-
  136.                                 Delay10TCYx(1); // Retardo para que se cargue el  capacitor sample&hold  (Solo cuando se selecciona ADC_0_TAD).-
  137.                                 ConvertADC();           // Comienza conversión.-
  138.                                 while(BusyADC()){}      // Hasta que se finalice conversión.-
  139.                                 Canal5= ReadADC();      // Realizo lectura.-
  140.  
  141.                 SetChanADC(ADC_CH6);    // Selecciono canal a convertir.-
  142.                                 Delay10TCYx(1); // Retardo para que se cargue el  capacitor sample&hold  (Solo cuando se selecciona ADC_0_TAD).-
  143.                                 ConvertADC();           // Comienza conversión.-
  144.                                 while(BusyADC()){}      // Hasta que se finalice conversión.-
  145.                                 Canal6= ReadADC();      // Realizo lectura.-
  146.  
  147.             // escribimos valores leidos en el LCD
  148.                 while(BusyXLCD()){}
  149.                 WriteCmdXLCD(0x87); // Nos posicionamos en la posición 8 de la linea 1
  150.                 while(BusyXLCD()){}
  151.                 putrsXLCD("        "); //escribe en lcd cadena de texto guardada en rom
  152.                 while(BusyXLCD()){}
  153.                 WriteCmdXLCD(0x87); // Nos posicionamos en la posición 0
  154.                
  155.                 itoa( cadena_de_texto, Canal5, 10 ); // Convertimos entero a cadena de texto.-
  156.                                                      // Tener en cuenta que en XC8 la función itoa recibe tres
  157.                                                      // parámetros (char * buf, int val, int base)
  158.  
  159.                 while(BusyXLCD()){}
  160.                 putsXLCD(cadena_de_texto); // escribe en lcd variable canal 5 guardada en ram
  161.  
  162.                 itoa( cadena_de_texto, Canal6, 10 );            // Convertimos entero a cadena de texto.-
  163.                 while(BusyXLCD()){}
  164.                 WriteCmdXLCD(0xC7); // Nos posicionamos en la posición 8
  165.                 while(BusyXLCD()){}
  166.                 putrsXLCD("        ");//escribe en lcd cadena de texto guardada en rom
  167.                 while(BusyXLCD()){}
  168.                 WriteCmdXLCD(0xC7); // Nos posicionamos en la posición 0
  169.                 putsXLCD(cadena_de_texto); // escribe en lcd variable canal 6 guardada en ram
  170.                 while(BusyXLCD()){}
  171.                 WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
  172.  
  173.                 // rutina cambio de intencidad de leds por PWM
  174.                 OpenTimer2( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_8 );
  175.  
  176.                 OpenPWM1(0xff);
  177.                 SetDCPWM1 (Canal6);
  178.  
  179.                 OpenPWM2(0xff);
  180.                 SetDCPWM2 (Canal5);
  181.  
  182.                 Delay10KTCYx(50);    //Retardo para evitar parpadeo en lcd.
  183.  
  184.         } //final del while
  185. } //final de main
  186.  
  187.  
  188. /*desarrollo de Funciones*/
  189. void myMsDelay(int ms)
  190. {
  191.     while(ms--)
  192.     {
  193.         __delay_ms(1);
  194.     }
  195. }
  196.  
  197.  
  198.  
  199. void DelayFor18TCY(void)
  200. {
  201. Delay1KTCYx(1); //provides a 20 Tcy delay
  202. }
  203.  
  204. void DelayPORXLCD(void)
  205.     {
  206.      Delay1KTCYx(180);
  207.     }
  208.  
  209.  
  210. void DelayXLCD(void)
  211. {
  212. Delay1KTCYx(60);
  213. }

« Última modificación: 09 de Junio de 2013, 03:18:20 por jukinch »
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Mini curso "Programación en XC8"
« Respuesta #68 en: 10 de Junio de 2013, 15:40:02 »
Hola Amigos ....alguno de uds me puede explicar por favor si existe la forma de hacer una funcion que devuelva dos valores ...de este tipo
creo que estas estan escritas en css ...las quiero hacer porsupuesto en xc8


prototipo de la funcion

void bmp085Convert(long *temperature, long *pressure,unsigned char readings);


y para usar en el main asi :

void bmp085Convert(float *temperature, float *pressure)


Muchas gracias

Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Mini curso "Programación en XC8"
« Respuesta #69 en: 10 de Junio de 2013, 16:01:00 »
Hola Amigos ....alguno de uds me puede explicar por favor si existe la forma de hacer una funcion que devuelva dos valores ...de este tipo
creo que estas estan escritas en css ...las quiero hacer porsupuesto en xc8


prototipo de la funcion

void bmp085Convert(long *temperature, long *pressure,unsigned char readings);


y para usar en el main asi :

void bmp085Convert(float *temperature, float *pressure)


Muchas gracias



  La llamada a la función tiene que coincidir con el prototipo. Si necesitas llamarla y obtener valores float, debes crearla también con float dentro de los paréntesis.

  Creo que deberías leer un poco más respecto a la creación de funciones. Para refrescar y/o aclarar algunos conceptos.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Mini curso "Programación en XC8"
« Respuesta #70 en: 10 de Junio de 2013, 16:07:00 »
Hola Amigos ....alguno de uds me puede explicar por favor si existe la forma de hacer una funcion que devuelva dos valores ...de este tipo
creo que estas estan escritas en css ...las quiero hacer porsupuesto en xc8


prototipo de la funcion

void bmp085Convert(long *temperature, long *pressure,unsigned char readings);


y para usar en el main asi :

void bmp085Convert(float *temperature, float *pressure)


Muchas gracias



  La llamada a la función tiene que coincidir con el prototipo. Si necesitas llamarla y obtener valores float, debes crearla también con float dentro de los paréntesis.

  Creo que deberías leer un poco más respecto a la creación de funciones. Para refrescar y/o aclarar algunos conceptos.



Perdon perdon me equivoque ....si es cierto al escribirla aca me equivoque  esta con float y long , pero no es eso lo que buscaba ...me referia a otra cosa

me referia a que esa funcion esta para css y yo quiero usarla en xc8

Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Mini curso "Programación en XC8"
« Respuesta #71 en: 10 de Junio de 2013, 19:17:34 »
  Rseliman, efectivamente se puede hacer ya que se le pasarían dos punteros como parámetros de la función y es a través de ellos mismo que el dato es devuelto.

  Aquí hay un ejemplo muy muy muy sencillo de la definición y utilización de una función que devuelve un valor a través del puntero.

Código: C
  1. #include <xc.h>
  2.  
  3. void funcion(long *_variable)
  4. {
  5.     *_variable = 55;  //valor apuntado por _variable
  6. }
  7.  
  8. void main(void)
  9. {
  10.     long *datoptr;
  11.     long dato;
  12.  
  13.     dato = 5;
  14.  
  15.     datoptr = &dato;  //el puntero "datoptr" apunta a la variable dato
  16.  
  17.     funcion (datoptr);
  18.  
  19.     while(1);
  20. }

  La función "funcion" recibe un puntero del tipo "long" en el cual devuelve el valor.

  Primeramente la variable "dato" toma el valor 5. Luego hago que el puntero "datoptr" apunte a "dato". Al ingresar a "funcion", "_variable" apunta a la dirección de "datoptr" y por lo tanto a "dato". Dentro de la función al hacer *_variable = 55 indicamos que el dato apuntado por "_variable" será 55. Por lo tanto el valor de "dato" también sera 55.

  Será cuestión de modificar la función según la necesidad.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: Mini curso "Programación en XC8"
« Respuesta #72 en: 17 de Junio de 2013, 15:40:54 »
INTERRUPCIONES.

Me surge un problema. Al llamar a una función desde la rutina de interrupciones me da error de compilación:

Código: [Seleccionar]
void interrupt low_priority low_isr(void) {

   // CCP1 interrupt
   if (PIR1bits.CCP1IF == 1) {
      PIR1bits.CCP1IF = 0;
      PIE1bits.CCP1IE = 0;
      timer_read();                      // Esta instrucción da error
      st.timer_read = 1;
   }
}


La función se compila y funciona sin problemas si se la llama fuera de la interrupción.
En el programa actual sólo la llamo desde la rutina de interrupción.
El error que aparece es el siguiente:

Código: [Seleccionar]
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12522. undefined symbol "?i1_sl48"
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12614. undefined symbol "??i1_timer_read"
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12717. undefined symbol "?i1___wmul"
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12893. undefined symbol "i1___wmul@product"
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12904. undefined symbol "i1___wmul@multiplier"
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12913. undefined symbol "i1___wmul@multiplicand"
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 13008. undefined symbol "i1sl48@a"

¿Alguna idea?
Saludos.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Mini curso "Programación en XC8"
« Respuesta #73 en: 17 de Junio de 2013, 19:18:12 »
  ¿Podrías mostrar tu programa? Aunque sea la parte de los include y tanto la interrupción como la función que te genera problemas.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: Mini curso "Programación en XC8"
« Respuesta #74 en: 18 de Junio de 2013, 14:55:31 »
El programa es bastante grande, pero he conseguido acotar el problema a unas pocas instrucciones.

Si ejecuto lo siguiente dentro de la rutina de interrupción no me da error:

Código: [Seleccionar]
void interrupt low_priority low_isr(void) {

   // CCP1 interrupt
   if (PIR1bits.CCP1IF == 1) {
      PIR1bits.CCP1IF = 0;

      for(char i=0; i<BUF_LEN; ) {
         time_buf[i++] = time_buf[i];
      }
   }
}


Por el contrario, si lo ejecuto en una función separada, me da error:

Código: [Seleccionar]

void interrupt low_priority low_isr(void) {

   // CCP1 interrupt
   if (PIR1bits.CCP1IF == 1) {
      PIR1bits.CCP1IF = 0;

      fill_buffer();
   }
}


void fill_buffer(void) {
   for(char i=0; i<BUF_LEN; ) {
      time_buf[i++] = time_buf[i];
   }
}

El error es:


Microchip MPLAB XC8 C Compiler V1.12
Copyright (C) 2012 Microchip Technology Inc.
License type: Node Configuration

Advisory[1233] Employing 18F2550 errata work-arounds:
Advisory[1234]  * Corrupted fast interrupt shadow registers
Warning [1273] ; . Omniscient Code Generation not available in Free mode
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s368.; 11618. undefined symbol "??_fill_buffer"
Error   [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s368.; 11620. undefined symbol "fill_buffer@i"
(908) exit status = 1

********** Build failed! **********


Saludos.