# Programas hechos en C18 compiler



## george.manson.69 (Jun 19, 2010)

Bueno aqui les traigo unas cuantas practicas hechas con el compilador de microchip C18, Y sus respectivas simulaciones.

Algunas veces he notado que en las simulaciones no funciona correctamente, pero una veez armado fisicamente este funciona si ningun problema esto lo digo ya que simule un circuito que utilizaba una memoria eeprom 24c01B y en proteus no lo simulaba correctamente entonces me decidi armarlo y funciono perfectamente....Pero bueno empezare a poner mas programas cada vez que valla aprendiendo hacer mas interfaces tanto para i2c,spi,usart etc...ya que este compilador no ofrece tantas librerias, y uno tendra que hacerlas... pero es muy bueno ya que  cuando te familiarisas seras un dotado en la programacion de microcontroladores...

Me cambie al C18 y ya que algunas cosas no entendia a cuanto a las librerias como GLCD, FAT16 etc del compilador CCS C.

Espero que sea de gran ayuda estos programas

Parpadeo de led...

```
#include<p18F2550.h>
#include <delays.h>

#pragma config FOSC = XT_XT,FCMEN = OFF,IESO = OFF, 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 = ON,CP1 = ON,CP2 = ON 
#pragma config CPB = ON,CPD = ON 
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON 
#pragma config WRTB = ON,WRTC = ON,WRTD = ON 
#pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON 
#pragma config EBTRB = ON


void main (void)
{
    TRISB=0x00;
    while (1){
        PORTB=0x00;
        Delay10KTCYx(30);//Demora 300ms
        PORTB=0x01;
        Delay10KTCYx(30);//Demora 300ms
    }
}
```

Configuracion del oscilador INterno y uso de la libreria USART


```
#include<p18F2550.h>
#include<timers.h>


//Fuses para trabajar con 48Mhz/////////
#pragma config FOSC   = INTOSCIO_EC        //usamos 8Mhz internos
#pragma config PLLDIV = 5                //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2         //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 1                //tRABAJAMOS CON USB CLOCK divido en 1
#pragma config VREGEN = OFF                //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN  = OFF, IESO    = OFF 
#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    = ON, CPD     = ON 
#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

//Prototipos de funciones        ///////
/*------------------------------------------*/
void ISRTimer0(void);            //Funcion de Interrupcion
void config(void);                //Funcion de Configuraciones de puertos, Timer
/*------------------------------------------*/
/*------------------------------------------*/
//Inicio de la interrupcion por timer 0//////
//                                       //////
//0x08 es la posicion de alta prioridad//////
//0x18 es posicion de baja prioridad   //////
#pragma code Interrupcion = 0X0008
void VectorInterrupcion(void){
    _asm goto ISRTimer0 _endasm
}
#pragma code
//Funcion de Interrupcion/////////////
#pragma interrupt ISRTimer0
void ISRTimer0(void){
    if(INTCONbits.TMR0IF==1){
        PORTBbits.RB0=~PORTBbits.RB0;
        INTCONbits.TMR0IF=0;
    }
    WriteTimer0(61629);    //Cargamos el timer0
}

//Fin de Interrupcion por timer0
//Funcion de Configuracion
void config(void){
    TRISB=0x00;    //Puerto b como salida
    CMCON&=0x07;//Apagamos comparadores
    ADRES=0x00; //Salida/entradas digitales
    //Configuramos TIMER0
    OpenTimer0(TIMER_INT_ON &     //Interrupciones por timer0 activado
               T0_16BIT     &    //16-bit
               T0_SOURCE_INT&     //Contar los ciclos internos 48Mhz/4
               T0_EDGE_FALL &     //~~_
               T0_PS_1_256);    //Preescalar =256
                //Interrupcion timpo=(1/(FOSC/4))*preescalar*(65536-timer0)
                //               .500s=tiempo maximo
                //               timer0=-{tiempo/[(1/(FOSC/4))*preescalar]}+65536
    WriteTimer0(61629);                //Cargamos el timer0=0
    RCONbits.IPEN=0;            //Deshabilitamos prioridades
    INTCONbits.PEIE=1;            //Activamos Interrupciones por Timer0
    INTCONbits.GIE=1;            //Interrupciones global Activadas
}

void main(void){
    OSCCON=0b01110000;    //Corriendo a 8Mhz
    config();

    while(1);
}
```

uso simple del xlcd


```
/////////////////////////////////////////////////////////////
//                        USO DEL LCD                         /
//Hecho por: george.manson.69                                /
//contacto: george.manson.69@gmail.com                        /
/////////////////////////////////////////////////////////////

#include<p18F2550.h>
#include<delays.h>    //tiempos 
#include<stdlib.h>
#include<xlcd.h>
#define LCD_4X20    //usamos un LCD4x20
                    //Si usamos un LCD 16x2 quitamos el #define

//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC        //usamos 8Mhz internos
#pragma config PLLDIV = 5                //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2         //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 1                //tRABAJAMOS CON USB CLOCK divido en 1
#pragma config VREGEN = OFF                //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN  = OFF, IESO    = OFF 
#pragma config PWRT   = ON, BOR     = OFF,BORV   = 0
#pragma config WDT    = OFF,WDTPS   = 32768 
#pragma config MCLRE  = ON, LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON 
#pragma config STVREN = OFF,LVP     = OFF,XINST  = OFF,DEBUG  = OFF 
#pragma config CP0    = OFF,CP1     = OFF,CP2    = OFF
#pragma config CPB    = ON, CPD     = ON 
#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

char buf[10];
int z,a=1,b=66;

////Funciones necesarias para uso del LCD /////
void DelayFor18TCY(void){
    Delay10TCYx(4);
}

void DelayPORXLCD (void){
  Delay1KTCYx(30); // Delay of 15ms
  return;          // Cycles = (TimeDelay * Fosc) / 4
                   // Cycles = (15ms * 8MHz) / 4
                   // Cycles = 30,000 
}
void DelayXLCD (void){
  Delay1KTCYx(10); // Delay of 5ms
  return;          // Cycles = (TimeDelay * Fosc) / 4
                   // Cycles = (5ms * 8MHz) / 4
                   // Cycles = 10,000
}
////Funcion de configuracion /////
void config(void){
    OpenXLCD(FOUR_BIT &     //4-bit
             LINES_5X7);    //
}
////Funcion de comandos para lcd/////
///    cd=0x01 clear screen        /////
/// cd=0x0c ON creen            /////
void cmdXLCD(unsigned char cd){
    while(BusyXLCD());
    WriteCmdXLCD(cd);
}
///Funcion de posicionamiento    /////
/// x=renglon                    /////
///    y=columna                    /////
///Si queremos usar un lcd4x20  /////
///definimos despues del        /////
///#include<xlcd.h>                /////
///#define LCD_4X20                /////
#ifndef    LCD_4X20
void gotoXYLCD(unsigned char x,unsigned char y){
    unsigned char adr;

    if(y!=1) adr=0x40;
    else     adr=0;

    adr+=x-1;
    cmdXLCD(0x80|adr);
}
#else
void gotoXYLCD(unsigned char x,unsigned char y){
    unsigned char adr;
   switch(y) {
     case 1 : adr=0x80;break;
     case 2 : adr=0xc0;break;
     case 3 : adr=0x94;break;
     case 4 : adr=0xd4;break;
   }
   adr+=x-1;
   cmdXLCD(adr);
}
#endif


void main(void){
    OSCCON=0x70;
    config();
    cmdXLCD(0x01);
    
    putrsXLCD("A=1\n");
    putrsXLCD("B=66");
    gotoXYLCD(1,3);
    putrsXLCD("z=A+B");
    gotoXYLCD(1,4);
    putrsXLCD("z=");
    z=a+b;
    itoa(z,buf);
    gotoXYLCD(3,4);
    putsXLCD(buf);
    while(1);
}
```

Otro uso del lcd con ADC


```
/////////////////////////////////////////////////////////////
//                        USO DEL LCD                         /
//Hecho por: george.manson.69                                /
//contacto: george.manson.69@gmail.com                        /
/////////////////////////////////////////////////////////////

#include<p18F2550.h>
#include<delays.h>    //tiempos 
#include<stdio.h>    //uso de conversiones printf
#include<adc.h>
#include<xlcd.h>
#define LCD_4X20    //usamos un LCD4x20
                    //Si usamos un LCD 16x2 quitamos el #define

//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC        //usamos 8Mhz internos
#pragma config PLLDIV = 5                //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2         //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 1                //tRABAJAMOS CON USB CLOCK divido en 1
#pragma config VREGEN = OFF                //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN  = OFF, IESO    = OFF 
#pragma config PWRT   = ON, BOR     = OFF,BORV   = 0
#pragma config WDT    = OFF,WDTPS   = 32768 
#pragma config MCLRE  = ON, LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON 
#pragma config STVREN = OFF,LVP     = OFF,XINST  = OFF,DEBUG  = OFF 
#pragma config CP0    = OFF,CP1     = OFF,CP2    = OFF
#pragma config CPB    = ON, CPD     = ON 
#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
//Funciones prototipos                    ////////
void cmdXLCD(unsigned char cd);
void gotoXYLCD(unsigned char x,unsigned char y);
////////////////////////////////////////////////
///Variables globales                    ////////
////////////////////////////////////////////////
char buf[15];
char buf2[15];
const char adc[15]={"valor de ADC:"};
const char yo[20]={"Hecho en Mexico"};
char email[20]={"george.manson.69"};
unsigned int value1,value2,ch;
/////////////////////////////////////////////////
////Funciones necesarias para uso del LCD ///////
/////////////////////////////////////////////////
void DelayFor18TCY(void){
    Delay10TCYx(4);
}

void DelayPORXLCD (void){
  Delay1KTCYx(30); // Delay of 15ms
  return;          // Cycles = (TimeDelay * Fosc) / 4
                   // Cycles = (15ms * 8MHz) / 4
                   // Cycles = 30,000 
}
void DelayXLCD (void){
  Delay1KTCYx(10); // Delay of 5ms
  return;          // Cycles = (TimeDelay * Fosc) / 4
                   // Cycles = (5ms * 8MHz) / 4
                   // Cycles = 10,000
}
///////////////////////////////////
////Funcion de configuracion /////
///////////////////////////////////
void config(void){
    TRISA=0x03;//RA0=e,RA1=e
    OpenXLCD(FOUR_BIT &     //4-bit
             LINES_5X7);    //
    //Configuramos ADC
    OpenADC(ADC_FOSC_RC     &    //Clock Interno
            ADC_RIGHT_JUST    &    //10bit
            ADC_20_TAD        ,    //20TAD
            ADC_CH0            &    //CANAL0
            ADC_CH1            &    //CANAL1
            ADC_INT_OFF        &    //INTERRUPCIONES OFF
            ADC_REF_VDD_VSS ,    //+5,GND
            ADC_2ANA);            //canal 0,1 analogo, resto digital
}

////Funcion de comandos para lcd/////
///    cd=0x01 clear screen        /////
/// cd=0x0c ON creen            /////
void cmdXLCD(unsigned char cd){
    while(BusyXLCD());
    WriteCmdXLCD(cd);
}

///Funcion de posicionamiento    /////
/// x=renglon                    /////
///    y=columna                    /////
///Si queremos usar un lcd4x20  /////
///definimos despues del        /////
///#include<xlcd.h>                /////
///#define LCD_4X20                /////
#ifndef    LCD_4X20
void gotoXYLCD(unsigned char x,unsigned char y){
    unsigned char adr;

    if(y!=1) adr=0x40;
    else     adr=0;

    adr+=x-1;
    cmdXLCD(0x80|adr);
}
#else
void gotoXYLCD(unsigned char x,unsigned char y){
    unsigned char adr;
   switch(y) {
     case 1 : adr=0x80;break;
     case 2 : adr=0xc0;break;
     case 3 : adr=0x94;break;
     case 4 : adr=0xd4;break;
   }
   adr+=x-1;
   cmdXLCD(adr);
}
#endif

void main(void){
    /*Calibramos el oscilador Interno del PIC*/
    OSCCON=0x70;
    /*Llamamos la funcion de configuracion*/
    config();

    cmdXLCD(0x0c);    //
    cmdXLCD(0x01);    //

    gotoXYLCD(1,1);
    putsXLCD(adc);
    gotoXYLCD(1,3);
    putsXLCD(yo);
    gotoXYLCD(1,4);
    putsXLCD(email);

    while(1){
        Delay100TCYx(0);
        SetChanADC(ADC_CH0);//canal ch empieza la conversion
        ConvertADC();        //start convert
        while(BusyADC());    //Ha terminado?
        value1=ReadADC();
        Delay100TCYx(0);
        SetChanADC(ADC_CH1);//canal ch empieza la conversion
        ConvertADC();        //start convert
        while(BusyADC());    //Ha terminado?
        value2=ReadADC();

        sprintf(buf,"VAL=%i  ",value1);    //string"buf"="VALUE=value"
        sprintf(buf2,"VAL2=%i ",value2);    //string"buf2"="VALUE=value2"
        gotoXYLCD(1,2);        //segunda linea
        putsXLCD(buf);        //imprime
        gotoXYLCD(10,2);    //segunda linea
        putsXLCD(buf2);        //imprime
    }
        
}
```

uso del usart con oscilador interno


```
#include<p18F2550.h>
#include<delays.h>
#include<stdio.h>
#include<usart.h>

//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC        //Usamos UN CRISTAL DE 20MHZ JUNTO CON UN PLL
#pragma config PLLDIV = 5                //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2         //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 2                //tRABAJAMOS CON USB CLOCK divido en dos
#pragma config VREGEN = OFF                //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN = ON,IESO = ON 
#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 = ON,CPD = ON 
#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

void config(void){
    TRISC&=0x80;    
    OpenUSART(    USART_TX_INT_OFF    &    //Disable Interrupts
                USART_RX_INT_OFF    &    //----------------
                USART_ASYNCH_MODE    &    //Modo asincronico
                USART_EIGHT_BIT        &    //8 bit
                USART_CONT_RX        &    //resepcion continua
                USART_BRGH_HIGH,
                25);                //FOSC / (16 * (spbrg + 1))
                                    //spbrg=((FOSC/BAUD)/16)-1
                                    //25=((8Mhz/19200)/16)-1
}

void main(void){
    OSCCON=0x70;
    config();

    printf("HOLA PIC18\r\nCorriendo a 8Mhz\r\n");

    while(1){
        printf("Velocidad a 8Mhz/4\r\n");
        Delay10KTCYx(255);
    }
}
```


otro uso del usart y pwm


```
#include<p18F2550.h>
#include <usart.h>
#include<stdio.h>
#include<pwm.h>
#include<timers.h>

#pragma config FOSC = XT_XT,FCMEN = OFF,IESO = OFF, 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 = ON,CP1 = ON,CP2 = ON 
#pragma config CPB = ON,CPD = ON 
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON 
#pragma config WRTB = ON,WRTC = ON,WRTD = ON 
#pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON 
#pragma config EBTRB = ON

void main(void){

    char string[6];
    unsigned int value;
    TRISC=0x80;
    OpenUSART(    USART_TX_INT_OFF    &    //Disable Interrupts
                USART_RX_INT_OFF    &    //----------------
                USART_ASYNCH_MODE    &    //Modo asincronico
                USART_EIGHT_BIT        &    //8 bit
                USART_CONT_RX        &    //resepcion continua
                USART_BRGH_HIGH,
                25);                //FOSC / (16 * (spbrg + 1))
                                    //
    OpenTimer2(    TIMER_INT_OFF         &
                T2_PS_1_16            &
                T2_POST_1_16);
    OpenPWM1(255);
    SetDCPWM1(100);
    printf("HOLA MUNDO!!!\r\n");
    getsUSART(string,5);
    if(string[0]=='A') PORTC=0x01 & 0x0F;
    printf("\r\n%s",string);
    
    while(1);
}
```

Otro uso del pwm,usart y adc

```
/////////////////////////////////////////////////////////////
//                USO DEL PWM CON ADC Y USART                    /
//Hecho por: george.manson.69                                /
//contacto: george.manson.69@gmail.com                        /
/////////////////////////////////////////////////////////////

#include<p18F2550.h>
#include<delays.h>    //tiempos 
#include<timers.h>    //USAREMOS INTERRUPCION POR TIMERS
#include<pwm.h>        //PWM LIBRARY
#include<adc.h>        //Trabajamos con ADC
#include<usart.h>    //Incluimos usart 
#include<stdio.h>    //uso de conversiones printf

//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC        //usamos 8Mhz internos
#pragma config PLLDIV = 5                //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2         //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 1                //tRABAJAMOS CON USB CLOCK divido en 1
#pragma config VREGEN = OFF                //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN  = OFF, IESO    = OFF 
#pragma config PWRT   = ON, BOR     = OFF,BORV   = 0
#pragma config WDT    = OFF,WDTPS   = 32768 
#pragma config MCLRE  = ON, LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON 
#pragma config STVREN = OFF,LVP     = OFF,XINST  = OFF,DEBUG  = OFF 
#pragma config CP0    = OFF,CP1     = OFF,CP2    = OFF
#pragma config CPB    = ON, CPD     = ON 
#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

/////Declaracion de variables    ///////
/*------------------------------------------*/
unsigned int adc;
unsigned char cont;
unsigned int percent;
unsigned char flag=0;

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

//Prototipos de funciones        ///////
/*------------------------------------------*/
void ISRTimer0(void);            //Funcion de Interrupcion
void config(void);                //Funcion de Configuraciones de puertos, Timer,pwm,usart,adc

/*------------------------------------------*/
//Inicio de la interrupcion por timer 0//////
//                                       //////
//0x08 es la posicion de alta prioridad//////
//0x18 es posicion de baja prioridad   //////
#pragma code Interrupcion = 0X0008
void VectorInterrupcion(void){
    _asm goto ISRTimer0 _endasm
}
#pragma code
//Funcion de Interrupcion/////////////
#pragma interrupt ISRTimer0
void ISRTimer0(void){
    cont++;
    if(INTCONbits.TMR0IF==1 && cont==2){
        flag=1;
        INTCONbits.TMR0IF=0;
        cont=0;
    }
    WriteTimer0(61629);
}
//Fin de la interrupcion            //////////
/*------------------------------------------*/
//Incio de la funcion de configuracion///////
void config(void){
    TRISA=0x01;
    TRISC=0X80;
    //Configuramos UART
    OpenUSART(    USART_TX_INT_OFF    &    //Disable Interrupts
                USART_RX_INT_OFF    &    //----------------
                USART_ASYNCH_MODE    &    //Modo asincronico
                USART_EIGHT_BIT        &    //8 bit
                USART_CONT_RX        &    //resepcion continua
                USART_BRGH_HIGH        ,
                25);                //FOSC / (16 * (spbrg + 1))
                                    //spbrg=((FOSC/BAUD)/16)-1
                                    //25=((8Mhz/19200)/16)-1

    //Configuramos TIMER0
    OpenTimer0(TIMER_INT_ON &     //Interrupciones por timer0 activado
               T0_16BIT     &    //16-bit
               T0_SOURCE_INT&     //Contar los ciclos internos 48Mhz/4
               T0_EDGE_FALL &     //~~_
               T0_PS_1_256);    //Preescalar =256
                //Interrupcion timpo=(1/(FOSC/4))*preescalar*(65536-timer0)
                //               .500s=tiempo maximo
                //               timer0=+65536-{tiempo/[(1/(FOSC/4))*preescalar]}
    WriteTimer0(61629);                //Cargamos el timer0=0
    //Configuramos ADC
    OpenADC(ADC_FOSC_RC     &    //Clock Interno
            ADC_RIGHT_JUST    &    //10bit
            ADC_20_TAD        ,    //20TAD
            ADC_CH0            &    //CANAL0
            ADC_INT_OFF        &    //INTERRUPCIONES OFF
            ADC_REF_VDD_VSS ,    //+5,GND
            ADC_1ANA);            //canal 0 analogo, resto digital
    //Configuramos PWM        
    OpenTimer2(TIMER_INT_OFF     &//Interrupcion timer2 OFF
               T2_PS_1_16        &//preescalar = 16
               T2_POST_1_1);     //POst escalar=1
                                //
    OpenPWM1(124);
                    //PWM period =   [(period  ) + 1] x 4 x Tosc x TMR2 prescaler
                    //PWM period =   [(255)+1]x(4/8Mhz)x16
                    // [.001s/((4/8Mhz)*16)]-1=period 
                    // [1/(f*(4/Tosc)*preescalar)]-1=period
    OpenPWM2(124);
    SetDCPWM1(127);
    SetDCPWM2(127);
    //Habilitamos interrupciones
    RCONbits.IPEN=0;            //Deshabilitamos prioridades
    INTCONbits.PEIE=1;            //Activamos Interrupciones por Timer0
    INTCONbits.GIE=1;            //Interrupciones global Activadas
    
}

void main(void){
    OSCCON=0x70;                //Oscilador a 8Mhz
                                //Se tiene que poner antes de todas las funciones
    config();                    //Funcion de configuracion

    while(1){//bucle infinito
        if(flag==1){            //Ha desbordado?        
            INTCONbits.PEIE=0;    //Desactivamos TIMER0
            flag=0;                //TOGGLE timer0
            Delay1KTCYx(1);        //500uS
            SetChanADC(0);        //canal 0 empieza la conversion
            ConvertADC();        //start convert
            while(BusyADC());    //Ha terminado?
            adc=ReadADC();        //lee dato
            printf("ADC = %i\r\n",adc);    //IMPRIME ADC
            SetDCPWM1(adc);        //CAMBIA VALORES DEL duty
            SetDCPWM2(adc);        //------------------------
            INTCONbits.PEIE=1;    //Activamos adc
        }
    }
}
```

uso de memorias eeprom 24c01B

```
/////////////////////////////////////////////////////////////
//                USO DEL I2C EN UNA MEMORIA EEPROM 24C01B    /
//Hecho por: george.manson.69                                /
//contacto: george.manson.69@gmail.com                        /
//Problemas:
//    Si se manda una cadena sin temporizacion osea sin tiempo
//    de transiscion puede fallar fisicamente.
//    POR EJEMPLOS
//        ENVIAR DATO                                            /
//        RETARDO DE 200mS                                    /
//        ENVIAR DATO                                            /
//        RETARDO DE 200mS                                    /
//        y asi                                                /
/////////////////////////////////////////////////////////////
#include<p18F2550.h>
#include"eepromdr.h"
#include<i2c.h>
#include<usart.h>
//#include<stdio.h>    //uso de conversiones printf
#include<delays.h>    //libreria para retardos


//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC        //usamos 8Mhz internos
#pragma config PLLDIV = 5                //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2         //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 1                //tRABAJAMOS CON USB CLOCK divido en 1
#pragma config VREGEN = OFF                //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN  = OFF, IESO    = OFF 
#pragma config PWRT   = ON, BOR     = OFF,BORV   = 0
#pragma config WDT    = OFF,WDTPS   = 32768 
#pragma config MCLRE  = ON, LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON 
#pragma config STVREN = OFF,LVP     = OFF,XINST  = OFF,DEBUG  = OFF 
#pragma config CP0    = OFF,CP1     = OFF,CP2    = OFF
#pragma config CPB    = ON, CPD     = ON 
#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


//Variables a usar//////
unsigned char msje;

////////////////////////////////////////////
//Funcion de configuracion
//USART    I2C
////////////////////////////////////////////
void config(void){
    TRISC=0X80;
    //Configuramos UART
    OpenUSART(    USART_TX_INT_OFF    &    //Disable Interrupts
                USART_RX_INT_OFF    &    //----------------
                USART_ASYNCH_MODE    &    //Modo asincronico
                USART_EIGHT_BIT        &    //8 bit
                USART_CONT_RX        &    //resepcion continua
                USART_BRGH_HIGH        ,
                51);                //FOSC / (16 * (spbrg + 1))
                                    //spbrg=((FOSC/BAUD)/16)-1
                                    //51=((8Mhz/9600)/16)-1
    //cONFIGURACION DEL I2C
    OpenI2C(MASTER    ,    //I2C como master
            SLEW_ON        //a 400khz
           );
    SSPADD=4;    //CLOCK=FOSC/(4*(SSPADD+1)
                //SSPADD=[(FOSC/CLOCK)/4]-1
                //Velocidad de 400khz de 8Mhz
    INTCONbits.GIE=0;    //Desactivamos interrupciones globales
}


////////////////////////////////////////////
//FUNCION PRINCIPAL
///////////////////////////////////////////
void main(void){
    OSCCON=0x70;        //EMPIEZA A CORRER A FOSC=8Mhz

    config();
    
    putrsUSART("Programa para leer y escribir en una memoria eeprom \r\n");
    putrsUSART("Escribiendo....\r\n");
    Delay1KTCYx(100);
    //--------Guarda datos en la eeprom--------------///
    WriteEE(0X02,'O');
    putrsUSART("LEIENDO.....\r\n");
    //--------LEE MEMORIA EEPROM---------------------///
    msje=ReadEE(0x02);
    putcUSART(msje);
    while(1);
}
```

He invito a otras personas a colaborar en la programacion de este compilador tanto de uso de librerias hechas para este lenguaje ASCII, para que fuera una gran ayuda para llegar a programar  correctamente estos  pic18 y  entender mas  porque de  las cosas....
Ya que tengo unas cuantas dudas en la programacion...como son

*Como importar librerias o hacer librerias para nuestros programas
*intruccion de lcd : putrsXLCD(const char*buffer), no funciona en proteus(no aparece nada escrito)
....


----------



## Pablet (Jun 19, 2010)

Por fin un tema dedicado exclusivamente a C18!! todo lo que hay por ahi es CCS y yo prefiero mucho mas el C18,  yo también tengo bastantes proyectos hechos con C18, con la diferencia de que yo no utilizo librerias, tan solo las he utilizado para el LCD, pero todo lo demás lo hago por registros. Cuando pueda pondré unos cuantos.
Un saludo


----------



## george.manson.69 (Jun 21, 2010)

Bueno aqui les traigo como crear una libreria facil y sencilla, y a la vez como hcaer una matriz de led mas que nada en la programacion.

Programa en c18


```
/////////////////////////////////////////////////////////////
//    USO DE UNA MATRIX 8x8      /
//Hecho por: george.manson.69        /
//contacto: [EMAIL="george.manson.69@gmail.com"]george.manson.69@gmail.com[/EMAIL]      /
/////////////////////////////////////////////////////////////
#include<p18F2550.h>
#include<delays.h> //libreria para retardos

//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC  //usamos 8Mhz internos
#pragma config PLLDIV = 5    //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2   //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 1    //tRABAJAMOS CON USB CLOCK divido en 1
#pragma config VREGEN = OFF    //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN  = OFF, IESO    = OFF 
#pragma config PWRT   = ON, BOR     = OFF,BORV   = 0
#pragma config WDT    = OFF,WDTPS   = 32768 
#pragma config MCLRE  = ON, LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON 
#pragma config STVREN = OFF,LVP     = OFF,XINST  = OFF,DEBUG  = OFF 
#pragma config CP0    = OFF,CP1     = OFF,CP2    = OFF
#pragma config CPB    = ON, CPD     = ON 
#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
////////////////////////////////////////
//Funciones prototipos
/////////////////////////
void SEND_DATA(unsigned char DATA);
void CLEAR(void);
void HABILITO(void);
///////////////////////////////////////
//Definiciones
////////////////////////
#define CLOCK PORTCbits.RC1
#define DATO  PORTCbits.RC2
#define RESET PORTCbits.RC0
//---------------------------------------------------------
//VARIABLES DONDE SE ENCUENTRA LAS LETRAS      /
//---------------------------------------------------------
const rom unsigned char ALFA[]={0xFC,0xFE,0x1B,0x19,0x1B,0xFE,0xFC,0x00};//A
//---------------------------------------------------------
//VARIABLES A USAR EN EL PROYECTO        /
//---------------------------------------------------------
unsigned char MAX;  //Variable que se va usar en la funcion "CLEAR"
unsigned char CONT=0; //variable que se va usar en la funcion "HABILITO"
unsigned char Letra;
unsigned char C=0;
//---------------------------------------------------------
//FUNCION DE TE PERIMITE ENVIAR UN CERO O UNO     /
//---------------------------------------------------------
void SEND_DATA(unsigned char DATA){
 DATO=DATA;
 CLOCK=0;
 Nop();
 Nop();
 Nop(); //Retardo de 2uS
 Nop();
 CLOCK=1;
}
//----------------------------------------------------------
//FUNCION DE BORRADO          /
//----------------------------------------------------------
void CLEAR(void){
 for(MAX=1;MAX<=8;MAX++){  //8 ES EL MAXIMO DE->
  SEND_DATA(1);    //->COLUMNAS
 }
}
//-----------------------------------------------------------
//  HABILITADOR           /
//-----------------------------------------------------------
void HABILITO(void){
  if(CONT==0) SEND_DATA(1); //ENVIO DATA 0 O 1
  else SEND_DATA(0);
}
void main(void){
 OSCCON=0x70;
 while(OSCCONbits.IOFS);  //Es estable la frecuencia seleccionada?
 TRISC=0x00;
 TRISB=0x00;
 CMCON&=0x07;
 RESET=1;
 CLEAR();
 SEND_DATA(0);
 while(1){
  for(Letra=0;Letra<8;Letra++){ //Ciclo demuestra de cada fila 0 a 7
   PORTB=~ALFA[Letra];   //Muestra lo que corresponde
   Delay10KTCYx(1);   //5mS con 8Mhz
   SEND_DATA(1);    //Para corrimiento de dato
  }
  SEND_DATA(0);     //Envia un CERO para volver a 
 }         //Corrimiento
}
```


----------



## george.manson.69 (Jun 24, 2010)

Ahora entraremos a usar la interrupcion por timer1, simeplemente controlas dos display de 7 segementos que empieza a contar en segundo hasta llegar a 99, este caso se esta usando la tecnica de multiplexor para prender ambos led casi al mismo tiempo.


```
/////////////////////////////////////////////////////////////
//    USO DE DISPLAY CON TIMER1     /
//Hecho por: george.manson.69        /
//contacto: [EMAIL="george.manson.69@gmail.com"]george.manson.69@gmail.com[/EMAIL]      /
/////////////////////////////////////////////////////////////
#include<p18F2550.h>
#include<delays.h> //libreria para retardo
#include<timers.h>
//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC  //usamos 8Mhz internos
#pragma config PLLDIV = 5    //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2   //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 1    //tRABAJAMOS CON USB CLOCK divido en 1
#pragma config VREGEN = OFF    //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN  = OFF, IESO    = OFF 
#pragma config PWRT   = ON, BOR     = OFF,BORV   = 0
#pragma config WDT    = OFF,WDTPS   = 32768 
#pragma config MCLRE  = ON, LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON 
#pragma config STVREN = OFF,LVP     = OFF,XINST  = OFF,DEBUG  = OFF 
#pragma config CP0    = OFF,CP1     = OFF,CP2    = OFF
#pragma config CPB    = ON, CPD     = ON 
#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
/////////////////////////////////////
//Funciones prototipos
/////////////////////////////////////
void ISRTimer1(void);
void config(void);
///////////////////////////////////////
///Definiciones usadas en el programa
//-----------------------------------///
#define TRUE  1
#define FALSE  0
#define ENABLE_2 PORTCbits.RC0
#define ENABLE_1 PORTCbits.RC1
//---------------------------------------------------------------------//
//Variable que contiene los valores para mostrar los numeros en los
//Display de 7 segmentos
//---------------------------------------------------------------------//
const rom unsigned char mostrar[10]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,
               0b10010010,0b10000011,0b11111000,0b00000000,0b00011000};
//---------------------------------------------------------------------//
//Variables Gblobales para mantener la cuenta
//Display de 7 segmentos
//---------------------------------------------------------------------//
unsigned int cont_int=0;
unsigned char S1=0,S2=0;
/*------------------------------------------*/
//Inicio de la interrupcion por timer 1//////
//            //////
//0x08 es la posicion de alta prioridad//////
//0x18 es posicion de baja prioridad   //////
/////////////////////////////////////////////
#pragma code Interrupcion = 0X0008
void VectorInterrupcion(void){
 _asm goto ISRTimer1 _endasm
}
#pragma code
//Funcion de Interrupcion/////////////
#pragma interrupt ISRTimer1
void ISRTimer1(void){
 cont_int++;        //Suma +1
 if(PIR1bits.TMR1IF==1 && cont_int>5){ //Esta en interrupcion y variable llego mas de 5
  cont_int=0;       //variable a cero
  S1++;        //Digito uno suma +1
  if(S1==10){       //Ha llegado a 10?
   S1=0;       //Resetea digito a cero
   S2++;       //Digito 2 suma +1
   if(S2==10){      //Ha llegado a 10?
    S2=0;      //Resetea digito a cero
   }
  }
 }
 PIR1bits.TMR1IF=0;
 WriteTimer1(15536);
}
////////////////////////////////////////////////
//Funcion de Configruacion
////////////////////////////////////////////////
void config(void){
//-------------------------------//
//PORTB=como salida    ///
//PORTC=como salida    ///
//-------------------------------//
 TRISB=0x00;
 TRISC=0x00;
 CMCON&=0x07;//Comparadores apagados
//-------------------------------//
//Configuramos TIMER1   ///
//-------------------------------//
 OpenTimer1(TIMER_INT_ON  & //Interrupcion activada por timer1
      T1_16BIT_RW  & //modo de 16 bit
      T1_SOURCE_INT & //Usando el oscilador interno 8Mhz/4=2Mhz
      T1_PS_1_8  & //PreScalar de 8
      T1_OSC1EN_OFF & //Desactivamos el uso del oscilador timer1
      T1_SYNC_EXT_OFF); //
    
 WriteTimer1(15536); //Interrupcion timpo=(1/(FOSC/4))*preescalar*(65536-timer1)
      //      200mS=tiempo maximo
      //      timer1=+65536-{tiempo/[(1/(FOSC/4))*preescalar]}

 INTCONbits.PEIE=1;   //Activar perifericos de interrupciones
 INTCONbits.GIE=1;   //Interrupciones global Activadas
 
}
////////////////////////////////////////////////
//Funcion Principal
////////////////////////////////////////////////
void main(void){
 OSCCON=0x70; //A 8Mhz el oscilador interno
 Nop();Nop();Nop();Nop();//Retardo de 2uS
 config();
 while(TRUE){
  ENABLE_2=0;   //Desactiva display 1
  PORTB=mostrar[S1]; //Toma el valor para display 2
  ENABLE_1=1;   //Activa el display 2
  Delay1KTCYx(20); //pausa de 10mS [1/(FOSC/4)]*20Kcycles
  ENABLE_1=0;   //Desactiva display 2
  PORTB=mostrar[S2]; //Toma el valor para display 1
  ENABLE_2=1;   //Activa el display 1
  Delay1KTCYx(20); //pausa de 10mS [1/(FOSC/4)]*20Kcycles
 }
}
```


----------



## george.manson.69 (Jun 25, 2010)

Ahora para aprender a programar en Hi tech compiler para microcontroladores 10/12/16 podre algunos programas hechos en este compilador.

Simple uso del Serial USART


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL SERIAL                                 ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>        //Incluimos libreria del micro a usar
#include<stdio.h>    //libreria para trabajar con conversiones
#include"lib/usartdr.h" //Libreria creada para uso del usart

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

unsigned int i=0,cont;
const unsigned char dato=255,dato1=255;

void main(void){
    TRISB=0x02;                //RB1=RX,RB2=TX
    //Configuracion del USART
    OpenUSART(25,OFF,OFF);    //value=(FOSC/(baud*16))-1
                            //SIN INTERRUPCIONES
                            //a 9600 baudios
    GIE=0;                    //INTERRUPCIONES GLOBALES DesACTIVADAS
    PEIE=0;                    //DesACTIVA INTERURPCIONES POR PERIFERICOS

    printf("Uso del Printf en Hi-tech PIC 16\r\n");
    printf("Usando la libreria del USART\r\n");
    cont=dato+dato1;

    printf("Suma de 255 + 255 = %u\r\n",cont);

    while(1);
    
}
/*
static void interrupt
isr(void){
    if(RCIF){
        dato=getch();
        dato1=getch();
        RCIF=0;
        i=1;
    }
}*/
```

USO DEL PWM


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL PWM                                     ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>        //Incluimos libreria del micro a usar
#include<stdio.h>    //libreria para trabajar con conversiones
#include"timer2/timer2.h"//LLama la libreria de usar Timer2
#include"pwmdr/pwm.h"//LLama libreria para usar PWM

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

void main(void){
    TRISB=0;
    //Configuramos TIMER 2 para PWM
    OpenTimer2(PRESCALE_16);
    //Usamos libreria PWM
    OpenPwm(61);
    //PWM period =   [(period  ) + 1] x 4 x Tosc x TMR2 prescaler
    //PWM period =   [(255)+1]x(4/4Mhz)x16
    // [.001s/((4/4Mhz)*16)]-1=period 
    // [1/(f*(4/Tosc)*preescalar)]-1=period
    PwmDuty(127); //255=100% 127=50% de duty

    GIE=0;                    //INTERRUPCIONES GLOBALES DesACTIVADAS
    PEIE=0;                    //DesACTIVA INTERURPCIONES POR PERIFERICOS

    while(1);
    
}
/*
static void interrupt
isr(void){
    if(RCIF){
        dato=getch();
        dato1=getch();
        RCIF=0;
        i=1;
    }
}*/
```

Uso de la interrupcion por timer0


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL Interrupcion por timer 0                 ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>        //Incluimos libreria del micro a usar
#include<stdio.h>    //libreria para trabajar con conversiones
#include"timer0/OpenTimer0.h"//Incluimos libreria de timer0

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

void main(void){
    TRISB=0;
    OpenTIMER0(prescalar_128,ON);
    //Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer1)
    //               500uS=tiempo maximo
    //               timer0=+256-{tiempo/[(1/(FOSC/4))*preescalar]}
    TMR0=253;

    GIE=1;                    //INTERRUPCIONES GLOBALES ACTIVADAS
    PEIE=1;                    //ACTIVA INTERURPCIONES POR PERIFERICOS

    while(1);
    
}
////////////////////////////////////
///Interrupcion Por timer0
////////////////////////////////////
static void interrupt
isr(void){
    if(T0IF){
        RB0=~RB0;//Cmabia de estado cada vez ejecuta esta accion //amado TOGGLE
        T0IF=0;     //Camabia flag de interrupcion
        TMR0=253;//Carga otra vez el timer 0
    }
}
```

Otro uso del Usart y timer0


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL Interrupcion por timer 0                 ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>        //Incluimos libreria del micro a usar
#include<stdio.h>    //libreria para trabajar con conversiones
#include"timer0/OpenTimer0.h"//Incluimos libreria de timer0
#include"lib/usartdr.h"    //Incluimos libreria del serial

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
////////////////////////////////////////////
//Variables a usar
////////////////////////////////////////////

unsigned char  cont=0,seg=0;
unsigned int numero;

void main(void){
    TRISB=0;
    OpenTIMER0(prescalar_256,ON);
    //Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer1)
    //               65mS=tiempo maximo
    //               timer0=+256-{tiempo/[(1/(FOSC/4))*preescalar]}
    TMR0=2;
    //Configuracion del USART
    OpenUSART(25,OFF,OFF);    //value=(FOSC/(baud*16))-1
                            //SIN INTERRUPCIONES
                            //a 9600 baudios

    GIE=1;                    //INTERRUPCIONES GLOBALES ACTIVADAS
    PEIE=1;                    //ACTIVA INTERURPCIONES POR PERIFERICOS

    while(1){
        if(seg){            //Ha lledo a 1 seg
            printf("Contando = %u\r\n",numero++); //Imprime y suma +1
            seg=0;            //Reset flag de segundo
        }
    }
    
}
////////////////////////////////////
///Interrupcion Por timer0
////////////////////////////////////
static void interrupt
isr(void){
    if(T0IF){        //Ha surguido una interrupcion?
        cont++;        //Cuenta mas +1
        if(cont==15){//Ha llegado a 1 seg?
            seg=1;   //Pone flag de segundo
            cont=0;  //Vuelve a contar
        }
        T0IF=0;        //Rest falg de interrupcion por timer0
        TMR0=2;        //Carga timer0 para dar 65mS*15=1seg
    }
}
```

Recuerde para poder simlar correctamente se debe de tener proteus 7.7


----------



## Moyano Jonathan (Jun 25, 2010)

Muy interesante el post últimamente el uso de CCS no me había convencido debido a que no se rije por el standar ansi C89 y por lo tanto los programas perdían mucha portabilidad entre compiladores ...ejempolo CCS y GCC para micros AVR ahora con C18 o C30 no pasa esto por eso me parece mucha mejor opción aunque CCS para muchas cosas "simples" es más comodo de usar.


----------



## george.manson.69 (Jun 26, 2010)

Moyano Jonathan dijo:


> Muy interesante el post últimamente el uso de CCS no me había convencido debido a que no se rije por el standar ansi C89 y por lo tanto los programas perdían mucha portabilidad entre compiladores ...ejempolo CCS y GCC para micros AVR ahora con C18 o C30 no pasa esto por eso me parece mucha mejor opción aunque CCS para muchas cosas "simples" es más comodo de usar.



Yo use el CCS C para aprender C jejje...ahora que ya agarre la onda al 99.99% pienso entrar a la programacion de dsPIC, PIC24, Y POR ULTIMO al PIC32...pero necesito acoplarme a la programacion en C18 para migarar facilmente al C32...
Por ahora se me ha facilitado mucho el uso  de C18 gracias al CCS C...jeje...pero apenas estoy haciendo libreria y programas....y subir info sobre el compilador C18 y HI TECH ya que no hay mucha info en comparacion con el CCS C...

saludos!


----------



## george.manson.69 (Jun 28, 2010)

usando el compilador hi tech he programado mi pic16f648a para hacer una matriz de de 8x24 que contara de 000 a 999.


```
//////////////////////////////////////////////////////////////
//TITULO: Contador 000-999 con matriz de 8x24    //
//AUTOR: george.manson.69         //
//COMPILADOR: HI TECH (LITE MODE)       //
//Este contador tiene una precision de 993.837uS~1Seg  //
//Consta de 3 Matrices de 8x8 que forma una matriz de  //
//8x24, este es un algoritmo para poner aprueba un contador //
//que valla desde 000 a 999.        //
//               //
//Nota: Esta matriz fue 100% comprobada fisicamente   //
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#include<htc.h>  //Incluimos libreria del micro a usar
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS = Watch Dog Timer Desactivado
//PWRTEN = Power Activado
//INTIO  = Osiclador interno
//MCLREN = Activamos Master Clear
//LVPDIS = Low Voltage Porgramming Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
#define CLOCK RA0
#define DATO  RA1
#define RESET RA2

//---------------------------------------------------------
//VARIABLES DONDE SE ENCUENTRA LOS NUMEROS      /
//---------------------------------------------------------
const unsigned char ALFA[10][8]={0X00,0X3C,0X7E,0XC3,0XC3,0XC3,0X7E,0X3C,  //0
         0X00,0X00,0XC4,0XC6,0XFF,0XFF,0XC0,0XC0,  //1
         0X00,0X00,0XCE,0XE7,0XF3,0XDB,0XCF,0XE6,  //2
         0X00,0X00,0X42,0XDB,0XDB,0XDB,0XFF,0X7E,  //3
         0X00,0X10,0XD8,0XDC,0XD6,0XFF,0XFF,0XD8,  //4
         0X00,0X00,0XCE,0XDF,0XDB,0XDB,0XF3,0X73,  //5
         0X00,0X00,0X7E,0XFF,0XD3,0XD3,0XF7,0X66,  //6
         0X00,0X00,0XC3,0XE3,0X73,0X3B,0X1F,0X0F,  //7
         0X00,0X00,0X66,0XFF,0XDB,0XDB,0XFF,0X66,  //8
         0X00,0X00,0X4E,0XDF,0XDB,0XDB,0XFF,0X7E}; //9
//---------------------------------------------------------
//VARIABLES A USAR EN EL PROYECTO        /
//---------------------------------------------------------
unsigned char MAX;  //Variable que se va usar en la funcion "CLEAR"
unsigned char CONT=0; //variable que se va usar en la funcion "HABILITO"
unsigned char Fila;  //Para mostrar FILA
unsigned char columna=0;//Varibale para controlar columnas en la matriz
unsigned int time,overload=0;
//time=para un retardo de visualizacion,
//overload variable para alcanzar 1seg con ayuda de la variable
//time
unsigned char dato3,dato2,dato1;
//dato3 para la vizualizacion de la matriz 0xx
//dato2 para ============================= x0x
//dato1 para ============================= xx0
//---------------------------------------------------------
//FUNCION DE TE PERIMITE CONFIGURAR PUERTOS      /
//---------------------------------------------------------
void config(void){
 TRISB=0x00; 
 PORTB=0x00;
 TRISA=0x20;
 PORTA=0x00;
 CMCON=0x07;
}
//---------------------------------------------------------
//FUNCION DE TE PERIMITE ENVIAR UN CERO O UNO     /
//---------------------------------------------------------
void SEND_DATA(unsigned char DATA){
 DATO=DATA;
 CLOCK=0;
 CLOCK=1;
}
//----------------------------------------------------------
//FUNCION DE BORRADO          /
//----------------------------------------------------------
void CLEAR(void){
 for(MAX=1;MAX<=24;MAX++){  //24 ES EL MAXIMO DE->
  SEND_DATA(0);    //->COLUMNAS
 }
}
//-----------------------------------------------------------
//   PROGRAMA PRINCIPAL        /
//-----------------------------------------------------------
void main(void){
  config(); //Configuramos puertos
  RESET=1; 
  //Ya que el 74HC164 contiene un pin de reset que puede ir directamente
  //al POSITIVO pero se puede poner directo al micro para manipular
  //el encendido y apagado de la matriz
  CLEAR();
  //Al inicializar la matriz apagada
  overload=113;  
  //1mS*8=8mS para un segundo=113
  //Con la ayuda de MPLAB SIM se puede apreciar el un retardo de 
  //993.837uS~1Seg
  SEND_DATA(1);
  //Al inicializar la matriz se envia el dato para proceder a vizualizar 
  //cada numero.
  //Se puede decir que este incio es muy importante
  while(1){
   for(dato3=0;dato3<10;dato3++){
   //ciclo de vizializacion de centenas
    for(dato2=0;dato2<10;dato2++){
   //ciclo de vizualizacion de decenas
     for(dato1=0;dato1<10;dato1++){
   //ciclo de vizializacion de unidades
      for(time=0;time<overload;time++){
   //tiempo de retardo de vizualizacion que conlleva al timepo de 1segundo
       for(Fila=0;Fila<8;Fila++){
   //ciclo para mostrar filas, por mientras se switchean cada matriz para
   //mostrar en cada matriz el numero correspondiente.
        if(columna<8){
         //Mostrar DATO3
   //Cuando se encuentre empezando en la columna de la izquierda ya que es la primera en
   //encender empezara a vizualizar el dato3 que contiene las centenas.
   //Ya que cada matriz es de 8x8, al alcanzar la columna 8 este pasara a la suiguiente matriz
         PORTB=ALFA[dato3][Fila];
         __delay_ms(1);
         PORTB=0;   
        }else if(columna<16){
         //Mostrar DATO2
   //Que contedra el valor ddecenas ya que el valor de dos matrices es de 16 la variable
   //columna llega a 16 pasara a la suiente matriz
         PORTB=ALFA[dato2][Fila];
         __delay_ms(1);
         PORTB=0;
        }else if(columna<24){
         //Mostrr DATO1
   //Que contendra las unidades, al llegar al maximo de columnas que son 24 ya que 
   //es la union de 3 matrices de 8x8, que correponden a 24 columnas
   //al llegar al maximo este enviara un dato 1 para inicializar toda la matriz...
         PORTB=ALFA[dato1][Fila];
         __delay_ms(1);
         PORTB=0;
        }
   //Cuando llega la columna maxima ya que es 24 columnas se inicializa varibale 
   //"Columna" para empezar de nuevo.
        if(++columna<24){
   //Dato 0 para corrimiento
         SEND_DATA(0);
        }else{
   //Dato 1 para inicializar matriz
         SEND_DATA(1);
         columna=0;
        }   
       } 
      }
     }
    }
   }
  }
}
```


----------



## george.manson.69 (Jul 8, 2010)

He desarrollado una libreria para trbajar con LCD en el entorno de HI TECH
Espero que sea de ayuda


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL ADC y LCD        ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
#include<htc.h>  //Incluimos libreria del micro a usar
#include<stdio.h> //libreria para trabajar con conversiones
#include<math.h> //para uso del float
#include"liblcd/lcddr.h" //Libreria creada para uso del lcd
#include"libADC/adcdr.h"//Inluimos libreria de trabajo con ADC
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT = Codigo no Potegido
//WDTDIS = Watch Dog Timer Desactivado
//PWRTEN = Power Activado
//INTIO  = Osiclador interno
//MCLREN = Activamos Master Clear
//LVPDIS = Low Voltage Porgramming Desactivado
//DEBUGDIS = Desactiva Debug
//BOR  = Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 4000000 //Oscilador Interno de 8MHZ
////////////////////////////////////////////////
//Variables Globales
////////////////////////////////////////////////
//unsigned int adc;
float adc;
unsigned char y;
unsigned int word[25];
int lengh;
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
 TRISA=0x01;
 TRISB=0x00;//Puerto para PINES DE E,RS,RW del LCD
 //Configuracion del ADC
 OpenADC(FOSC_FRC,AN0,OFF);
       //Oscilador interno
       //AN0 como entrada analogo
       //PORTB sin analoga
 //Inicializamos LDC
 lcd_init(CURSOR_OFF);
       //Inicializa Cursor APAGADO
 GIE=0;     //INTERRUPCIONES GLOBALES DesACTIVADAS
 PEIE=0;     //DesACTIVA INTERURPCIONES POR PERIFERICOS
 writeRSLCD("Lectura de ADC");
 while(1){
  __delay_ms(100);
  channelADC(0);  //Canal 0
  startADC();   //Empieza Conversion
  while(GODONE!=0); //Ha terminado
  adc=readADC();  //lee dato de 10 bit
  adc=(adc*5)/1024; //
  sprintf(word,"AN0=%.2f volts",adc);//Cambia todo a un string completo
  gotoXYLCD(1,2);  //Segunda Linea
  writeSLCD(word); //Escribe la conversion del LCD
 }
 
}
```


----------



## george.manson.69 (Jul 9, 2010)

Programa sencillo que muestra como usar el LCD Y TECLADO 4X4 en el compilador HI TECH para PIC10-12-16. espero que sea de ayuda.


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL LCD y TECLADO 4X4                            ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>            //Incluimos libreria del micro a usar
#include<stdio.h>        //libreria para trabajar con conversiones
#include"liblcd/lcddr.h"//Libreria para trabajar con Lcd
#include"libkey/keydr.h"//Libreria para trabajar con teclado 4x4
#include"libADC/adcdr.h"//Libreria para trabajar con ADC

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
//DEBUGDIS    = Desactiva Debug
//BOR        = Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

//////////////////////////////////////////////////
//VARIBALES GLOBALES
//////////////////////////////////////////////////
unsigned char value,x;
unsigned int ADC,analogo;
unsigned char word[25];
//////////////////////////////////////////////////
//Funcion de segundo
//////////////////////////////////////////////////
void DELAY1S(void){
    unsigned char seg;
    for(seg=0;seg<100;seg++){
        __delay_ms(10);
    }
}
///////////////////////////////////////////////////
//FUNCION DE TENER CANAL ANALOGO
///////////////////////////////////////////////////
unsigned int LEEADC(unsigned char y){
        channelADC(y);
        __delay_ms(1);
        startADC();
        while(GODONE!=0);
        ADC=readADC();
        return ADC;
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
/////////////////////////////////////////////////
//Funcion Principal
/////////////////////////////////////////////////
void main(void){
//Configuramos El puerto A como nibble alto como Salida y nibble Bajo como entrada
    TRISA=0x0F;
//Inicializamos teclado 4x4
    key_init();
//Inicializamos LCD 16X2 con cursor apagado
    lcd_init(CURSOR_OFF);
//Inicializamos Convertidor Analogo AN0->AN4 puerto B no analogo
    OpenADC(FOSC_FRC,AN0_AN3,OFF);

    GIE=0;                    //INTERRUPCIONES GLOBALES DesACTIVADAS
    PEIE=0;                    //DesACTIVA INTERURPCIONES POR PERIFERICOS
    
    while(1){
//Parte del Programa que menciona que canal queremos ver;
        send_byte(CLEAR);
        gotoXYLCD(1,1);
        writeRSLCD("CANAL ANALOGO");
        gotoXYLCD(1,2);
        writeRSLCD("A0, A1, A2, A3");
        value=0;
        while(value==0)value=getkey(0);
//Funcion que te deja ver el canal analogo que hallamos elegido
        switch(value){
            case '0':
                    send_byte(CLEAR);
                    gotoXYLCD(1,1);
                    writeRSLCD("CANAL CERO");
        //Ver canal Canal analogo 0
                    while(1){
                        analogo=LEEADC(0);
                        gotoXYLCD(1,2);
                        sprintf(word,"%i  Salir(A)   ",analogo);
                        writeSLCD(word);
                        value=getkey(0);
                        if(value=='A') break;
                    }
                    break;
                        
            case '1':
                    send_byte(CLEAR);
                    gotoXYLCD(1,1);
                    writeRSLCD("CANAL UNO");
        //Ver canal Canal analogo 1
                    while(1){
                        analogo=LEEADC(1);
                        gotoXYLCD(1,2);
                        sprintf(word,"%i  Salir(A)   ",analogo);
                        writeSLCD(word);
                        value=getkey(0);
                        if(value=='A') break;
                    }
                    break;
            case '2':
                    send_byte(CLEAR);
                    gotoXYLCD(1,1);
                    writeRSLCD("CANAL DOS");
        //Ver canal Canal analogo 2
                    while(1){
                        analogo=LEEADC(2);
                        gotoXYLCD(1,2);
                        sprintf(word,"%i  Salir(A)   ",analogo);
                        writeSLCD(word);
                        value=getkey(0);
                        if(value=='A') break;
                    }
                    break;
            case '3':
                    send_byte(CLEAR);
                    gotoXYLCD(1,1);
                    writeRSLCD("CANAL TRES");
        //Ver canal Canal analogo 3
                    while(1){
                        analogo=LEEADC(3);//Llama a la funcion de llamar analogo
                        gotoXYLCD(1,2);      //Posiciona Cursor en coordenadas seleccionadas
                        //Convierte a la variable a un string
                        sprintf(word,"%i  Salir(A)   ",analogo);
                        //Escribe en el LCD
                        writeSLCD(word);
                        //lee teclado
                        value=getkey(0);
                        //Si presionamos 'A' salimos 
                        if(value=='A') break;
                    }
                    break;
            default:
                    //Sino se presiono una de las letras que deben
                    send_byte(CLEAR);
                    writeRSLCD("Intente Otra vez");
                    DELAY1S();
                    break;
        }
    }
}
```


----------



## george.manson.69 (Jul 10, 2010)

Este es un simple convertidor de PWM que corre a 1kHz y en convertido a analogo de 0 a 5v.
El software fue hecho en C# express 2010, tambien subo todo el proyecto del software.


```
/////////////////////////////////////////////////////////////
//                        USO DEL DAC    con PWM                    /
//Hecho por: george.manson.69                                /
//contacto: george.manson.69@gmail.com                        /
/////////////////////////////////////////////////////////////

#include<p18F2550.h>
#include<delays.h>    //tiempos 
#include<stdio.h>    //uso de conversiones printf
#include<usart.h>    //Libreria para trabajar con el serial
#include<timers.h>    //USAREMOS INTERRUPCION POR TIMERS
#include<pwm.h>        //PWM LIBRARY

//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC        //usamos 8Mhz internos
#pragma config PLLDIV = 5                //PLL DIV 20Mhz/5=4Mhz
#pragma config CPUDIV = OSC1_PLL2         //CPUDIV1 96Mhz/2=48Mhz
#pragma config USBDIV = 1                //tRABAJAMOS CON USB CLOCK divido en 1
#pragma config VREGEN = OFF                //Trabajamos sin regulador interno 3.3v para usb
//-----------------------------------------------------------------
#pragma config FCMEN  = OFF, IESO    = OFF 
#pragma config PWRT   = ON, BOR     = OFF,BORV   = 0
#pragma config WDT    = OFF,WDTPS   = 32768 
#pragma config MCLRE  = ON, LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON 
#pragma config STVREN = OFF,LVP     = OFF,XINST  = OFF,DEBUG  = OFF 
#pragma config CP0    = OFF,CP1     = OFF,CP2    = OFF
#pragma config CPB    = ON, CPD     = ON 
#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


////////////////////////////////////////////////
///Variables globales                    ////////
////////////////////////////////////////////////
unsigned char kk;
unsigned char PWM[2];
unsigned int DUTY=0;
unsigned char flag=0;
/*------------------------------------------*/

//Prototipos de funciones        ///////
/*------------------------------------------*/
void ISRRX(void);            //Funcion de Interrupcion
void config(void);                //Funcion de Configuraciones de puertos, Timer,pwm,usart,adc
///////////////////////////////////
////Funcion de configuracion /////
///////////////////////////////////
void config(void){
    TRISC=0x80;
    OpenUSART(    USART_TX_INT_OFF    &    //Disable Interrupts
                USART_RX_INT_ON        &    //enable Interrupts
                USART_ASYNCH_MODE    &    //Modo asincronico
                USART_EIGHT_BIT        &    //8 bit
                USART_CONT_RX        &    //resepcion continua
                USART_BRGH_HIGH,
                207);                //FOSC / (16 * (spbrg + 1))
                                    //spbrg={(FOSC/BAUD)/16}-1
    //Configuramos PWM        
    OpenTimer2(TIMER_INT_OFF     &//Interrupcion timer2 OFF
               T2_PS_1_16        &//preescalar = 16
               T2_POST_1_1);     //POst escalar=1
                                //
    OpenPWM1(124);
                    //PWM period =   [(period  ) + 1] x 4 x Tosc x TMR2 prescaler
                    //PWM period =   [(255)+1]x(4/8Mhz)x16
                    // [.001s/((4/8Mhz)*16)]-1=period 
                    // [1/(f*(4/Tosc)*preescalar)]-1=period
    SetDCPWM1(DUTY);
    //Habilitamos interrupciones
    RCONbits.IPEN=0;            //Deshabilitamos prioridades
    INTCONbits.PEIE=1;
    INTCONbits.GIE=1;            //Interrupciones global Activadas
}
/*------------------------------------------*/
//Inicio de la interrupcion por Recepcion//////
//                                       //////
//0x08 es la posicion de alta prioridad//////
//0x18 es posicion de baja prioridad   //////
#pragma code Interrupcion = 0X0008
void VectorInterrupcion(void){
    _asm goto ISRRX _endasm
}
#pragma code
//Funcion de Interrupcion/////////////
#pragma interrupt ISRRX
void ISRRX(void){
    if(PIR1bits.RCIF){
        getsUSART(PWM,2);
        PIR1bits.RCIF=0;
        flag=1;
    }
}
//Fin de la interrupcion            //////////
/*------------------------------------------*/


void main(void){
    /*Calibramos el oscilador Interno del PIC*/
    OSCCON=0x70;
    Nop(); Nop();    //Para establecer frecuencia
    /*Llamamos la funcion de configuracion*/
    config();

    
    while(1){
        if(flag==1){
            //////////////////////////////////////
            //DUTY=0xPWM[1]PWM[0]=16bit
            DUTY=(unsigned int)PWM[1]<<8;
            DUTY|=((unsigned int)PWM[0]&0x00FF);
            //////////////////////////////////////
            SetDCPWM1(DUTY);    //Cambia el valor del PWM que corresponde a un valor analogo
                                //Con la formula podemos saber que salida se obtendra.
                                //DAC=(5*time in high)/time of period;
            flag=0;
        }
    }
}
```


----------



## muessli (Jul 14, 2010)

Hola george.manson.69, una pregunta, averiguando esto del c18 al parecer el compilador que ofrece en la pagina microchip es de pago,  tambien hay una version lite para estudiantes, la pregunta es estos programas los hiciste con la lite o conseguiste una completa? Sabes que limitaciones tiene la lite? 
Gracias y saludos.


----------



## george.manson.69 (Jul 15, 2010)

muessli dijo:


> Hola george.manson.69, una pregunta, averiguando esto del c18 al parecer el compilador que ofrece en la pagina microchip es de pago, tambien hay una version lite para estudiantes, la pregunta es estos programas los hiciste con la lite o conseguiste una completa? Sabes que limitaciones tiene la lite?
> Gracias y saludos.


 
Pues la version lite tiene baja optimizacion, es lo que tiene mas que nada...por ejemplo, un programa de LCD ¨hola mundo¨

Consume en modo lite consume mas de 30% mas recursos en lugar de tene el completo o alomejor mas depende del programa.

saludos

Yo tengo lite mode, tanto de HI TECH y C18, son buenos compiladores.


----------



## george.manson.69 (Jul 17, 2010)

Esta practica es muy sencilla, trata hacer una comunicacion serial, entre el pic16f886 y el software que he realizado en C# que captara el voltaje del potenciometro (10-bit)


```
///////////////////////////////////////////////////////////
//TITULO: USO ADC y usart                                ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>        //Incluimos libreria del micro a usar
#include<stdio.h>    //libreria para trabajar con conversiones

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
//DEBUGDIS    = Desactiva Debug
//BOR        = Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ
///////////////////////////////////////////////////
//Librerias de trabajo
////////////////////////////////////////////////////
#include"libUSART/usartdr.h" //Libreria creada para uso del usart
#include"libADC/adcdr.h"     //Libreria creada para uso del ADC
////////////////////////////////////////////////
///Variables globales                    ////////
////////////////////////////////////////////////
unsigned int ADC;
unsigned char send[2];

/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
    TRISA=0x01;                //RA0=entrada
    TRISC=0x80;                //RC8=RX,RC7=TX
    //Configuracion del USART
    OpenUSART(207,OFF,OFF);    //value=(FOSC/(baud*16))-1
                            //No interrupciones
                            //a 2400 baudios
    //Configuramos ADC
    OpenADC(FOSC_FRC,AN0,OFF);//Canal AN0 como analogo

    GIE=0;                    //INTERRUPCIONES GLOBALES DesACTIVADAS
    PEIE=0;                    //DesACTIVA INTERURPCIONES POR PERIFERICOS
    while(1){
        __delay_ms(1);        //Tiempo antes de pedir otro dato
        startADC();            //Empieza conversion
        while(GODONE!=0);    //ha terminad?
        ADC=readADC();        //SI, lee dato
        send[0]=ADC&0xFF;    //toma el low byte
        send[1]=(ADC>>8)&0x03;//Toma el high byte
        putch(send[0]);        //envia low byte primero
        putch(send[1]);        //envia high byte segundo
    }
}
```


----------



## george.manson.69 (Sep 4, 2010)

He subido algunos proyecto a la pagina:

http://ucursos.webs.com

Espero que sea de su agrado.


----------



## zoomg80 (Oct 3, 2010)

Hola 

He estado siguiendo los Post de C18, excelente informacion. 
Intento hacer lectura del USART de una cadena que me envia un Modem GSM, con esto:

while (1){
 comandXLCD(0x01);
 putrsXLCD("Presionar boton");
 while (Kbhit==0){                //Mientras no reciba dato USART
    if (BOTON == 1)
  {
 putrsUSART("AT+CMSS=2\r\n");
 gotoxyXLCD(1,1);
 putrsXLCD("Mensaje a Uva");
 Espera();
 comandXLCD(0x01);
  }else{
 LED = 0;
       }
                    }
 getsUSART(char *buffer, Unsigned char len);   //Intento de lectura.... Error de sintaxis
 Delay10KTCYx(100);
 Delay10KTCYx(100);
 printf("Me enviaste: %u", len);
 putrsUSART("\r\n");
 Kbhit=0;
 }
}

Alguna recomendacion me sera de mucha utilidad.

Saludos cordiales de Mexico


----------



## Pablet (Oct 11, 2010)

porque no lo haces con una interrupcion? tu codigo sera bastante mas eficiente ya que no has de esperarte a recibir algo ahi parado. . puedes ir haciendo otras cosas y cuando llegue algo irte a procesarlo. .  de todas formas. . ese codigo funciona¿?

Un saludo


----------



## george.manson.69 (Nov 15, 2010)

Esta practica es bastante buena ya que usa una tarjeta MMC donde se guarda las imagenes a mostrar en un GLCD y asi ahorramos memoria del microcontrolador.


```
////////////////////////////////////////////////////////
//    PROYECTO CON GLCD     ////
//Autor: george.manson.69       ////
//Lugar: Mexico          ////
//Compilador: HI TECH PIC18 (LITE MODE)    ////
////////////////////////////////////////////////////////
#include<htc.h>
/////////////////////////////////////////////////////////////
//Configuracion para trabajar Con oscilador interno de 8Mhz
__CONFIG(1,INTIO & FCMDIS & IESODIS & PLLDIV5 & PLLPOSTDIV2 & CPUDIV1 & USBOSC);
/////////////////////////////////////////////////////////////
__CONFIG(2,VREGDIS & PWRTEN & BORDIS & WDTDIS & BORV45 & WDTPS32K);
__CONFIG(3,PBDIGITAL & LPT1DIS & MCLREN);
__CONFIG(4,STVRDIS & LVPDIS & ICPORTDIS & DEBUGDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,UNPROTECT);
__CONFIG(7,UNPROTECT);
//////////////////////////////
//Frecuencia FOSC 8Mhz
//////////////////////////////
#define _XTAL_FREQ 8000000
#include"libMMC/libMMC.h"//Libreria del MMC modo Primitivo
#include"libGLCD/glcd.h" //Libreria para trabajar con GLCD
//////////////////////////////
//Variable Globales   //
//////////////////////////////
unsigned char sector[512];
//////////////////////////////
//FUNCION DE 1 SEG   //
//////////////////////////////
void DELAY1S(void){
 unsigned char time;
 for(time=0;time<100;time++){
  __delay_ms(10);
 }
}
unsigned char GLCD_MMC_image(unsigned char dir,unsigned char color){
   unsigned char i,j,*ptr,error,sum=32;
   signed char k;
 for(char s=(dir-1);s<dir+1;s++){
  if(MMC_Read(s,&sector)){
   RB7=1;//error
   return 1;
  }
  ptr=&sector;
    for(i=sum-32;i<sum;i++){  
       for(j=0;j<16;j++){   
          for(k=7;k>-1;--k){
    if((*ptr&(unsigned char)(1<<(7-k)))!=0){ 
               GLCD_point((j*8)+k,i,color);
     error=0;
        }
          }
    *ptr++; 
       }
    }
  sum+=32;
 }
 return error;
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////
//FUNCION PRINCIPAL
//////////////////////////////
void main(void){
 OSCCON=0x70;//Oscilador a 8Mhz
 NOP();NOP();NOP();NOP();
//////////////////////////////////////////////////////////////////////
//      Configuracion de Puertos       ///
//////////////////////////////////////////////////////////////////////
 TRISB=0x01;//SDI,CLK
 TRISC=0; //SD0,CS
 TRISD=0; //DB0~DB7
 TRISE=0; //
 RB5=0;
 ADCON0=0;
 ADCON1=0x0F;
 CMCON=0x07;
 
/*---------------------Fin de Conf. Puertos-------------------------*/
//iNICIALIZA GLCD
 GLCD_init(1);
 GLCD_clear(1);
//INICIALIZA MMC
 if(MMC_init()==0){
  GLCD_text(0,0,(unsigned char*) "MMC ERROR",1,0);
  while(1);
 }else
  GLCD_text(0,0,(unsigned char*)"MMC SUCCESSFUL",1,0);
 
 for(char ms=1;ms<8;ms+=2){
  DELAY1S();
  GLCD_clear(0);
  if(GLCD_MMC_image(ms,1)){
   GLCD_clear(0);
   GLCD_text(0,0,(unsigned char*)"ERROR AL CARGAR",1,1);
   while(1);
  }
 }
 while(1);
}
```
 
Contiene todo lo necesario para llevar acabo la simulñacion y si alguien lo desea tambien funciona fisicamente.

Nota para simular debe de tener Proteus 7.7 sp2


----------



## COSMICO (Nov 21, 2010)

Hola amigo george.manson.69
Estoy empezando con pic 18f4550 en ccs c pic compiler y necesito saber cómo configurar 
los fuses oscilador interno y como escojer la frecuencia de reloj
te agradesco la ayuda..


----------



## COSMICO (Nov 23, 2010)

Hola amigo george.manson.69
mira,tengo este programa para contar pulsos por el tmr0, cada vez que interrumpe el tmr1
a 100ms.La cosa es que cuando tomo el valor del registro que uso para leer el tmro
haciendo la conversion siempre pierdo las unidades, el valor lo represento en 4 display 7segmentos
Te agradesco la ayuda.Un saludo.
Mira la rutina para tomar y pasar los datos.


m=((val)/1000);
      c=((val-m*1000)/100);
      d=((val-c*100-m*1000)/10);
      u=val-d*10-c*100-m*1000;

 output_high(PIN_A3);//millares
      output_b(disp[m]);
      delay_ms(3);//(15);
      output_low(PIN_A3);
      delay_us(3);


      output_high(PIN_A2);//centena
      output_b(disp[c]);
      delay_ms(3);//(15);
      output_low(PIN_A2);
      delay_us(3);

      output_high(PIN_A1);//decena
      output_b(disp[d]);
      delay_ms(3);//(15);
      output_low(PIN_A1);
      delay_us(3);

      output_high(PIN_A0);//unidad
      output_b(disp);
      delay_ms(3);//(15);
      output_low(PIN_A0);
      delay_us(3);

      } while (TRUE);
}


----------



## ByAxel (Nov 23, 2010)

el tema correcto seria este: Ccs c programas hechos en mplab(Proyecto completo).

sobre el oscilador, guíate de esto: Consiguiendo 4 Mhz para los 48 Mhz necesarios en los PIC's con USB 2.0 que lo mismo digo "Absolutamente todo está en el datasheet".



> La cosa es que cuando tomo el valor del registro que uso para leer el tmro
> haciendo la conversion siempre pierdo las unidades


en el CCS trata de que el tipo de las variables sean las correctas (el CCS tiene bugs al respecto), sugiero que hagas las operaciones por separado en varias líneas para que veas donde va la falla o hacerlo en el proteus con el archivo *.cof, en modo debug y la simulación paso a paso para que revises el resultado...

igual, esperemos al experto... claro que este tema se trata del C18; el CCS lo tratan en otro sitio.

saludos


----------



## george.manson.69 (Dic 13, 2010)

Esta practica es muy sencilla trata de enviar el dato de la temperatura LM35 a la pc donde se vizualizaara en un software llamado " Termmometro".

Pragrama del PIC:


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL ADC y USART                                 ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>        //Incluimos libreria del micro a usar
#include<stdio.h>    //libreria para trabajar con conversiones
#include"libUSART/usartdr.h" //Libreria creada para uso del usart
#include"libADC/adcdr.h"//Inluimos libreria de trabajo con ADC

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
//DEBUGDIS    = Desactiva Debug
//BOR        = Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

unsigned char adc[2];
unsigned int dato;
///////////////////////////////
//Funcion de 1 segundo
////////////////////////////////
void Delay1S(void){
    unsigned char x;
    for(x=0;x<100;x++){
        __delay_ms(10);
    }
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
///////////////////////////////////
//Registro para trabajar a 8MHZ
///////////////////////////////////
    OSCCON=0x70;
    while(HTS==0); //Es estable la frecuencia ?
    TRISA=0x07;
    TRISC=0x80;                //RB1=RX,RB2=TX
    //Configuracion del USART
    OpenUSART(25,OFF,OFF);    //value=(FOSC/(baud*16))-1
                            //SIN INTERRUPCIONES
                            //a 9600 baudios
    //Configuracion del ADC
    OpenADC(FOSC_FRC,AN0,OFF);
                            //Oscilador interno
                            //AN0 como entrada analogo
                            //PORTB sin analoga

    GIE=0;                    //INTERRUPCIONES GLOBALES DesACTIVADAS
    PEIE=0;                    //DesACTIVA INTERURPCIONES POR PERIFERICOS

    while(1){
        __delay_ms(100);
        startADC();
        while(GODONE);
        dato=readADC();
        adc[0]=(unsigned char)dato;
        adc[1]=((dato&0x0300)>>8);
        putch(adc[0]);
        putch(adc[1]);
    }
    
}
```

Nota parea abror el software se debe de tener instalado el framework 4 en su PC


----------



## george.manson.69 (Ene 17, 2011)

HE realizado un programa hecho en Hi tech COMPILER.
para Manejo de un LCD 16x2 con un 74HC164.


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL LCD 3-WIRES                            ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>            //Incluimos libreria del micro a usar
#include<stdio.h>
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
//DEBUGDIS    = Desactiva Debug
//BOR        = Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ
#include"libLCD3PIN/lcd3pin.h"
////////////////////////////////////////////
//VARIABLES GLOBALES
///////////////////////////////////////////
unsigned char buffer[25];
//////////////////////////////////////////////////
//Funcion de segundo
//////////////////////////////////////////////////
void DELAY1S(void){
    unsigned char seg;
    for(seg=0;seg<100;seg++){
        __delay_ms(10);
    }
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
/////////////////////////////////////////////////
//Funcion Principal
/////////////////////////////////////////////////
void main(void){
///////////////////////////////////
//Registro para trabajar a 8MHZ
///////////////////////////////////
    OSCCON=0x70;
    while(HTS==0); //Es estable la frecuencia ?
    //Inicializa Puertos
    TRISB=0x00;
    PORTB=0x00;
    ADCON0=0;
    ANSELH=0;
    //Inicializa LCD
    lcd_init(CURSOR_OFF);
    lcd_rom_string("LCD 3-WIRES");
    lcd_gotoxy(1,2);
    lcd_rom_string("george.manson.69");
    DELAY1S();    //Esperamos 1 Segundo
    lcd_gotoxy(1,1);
    lcd_rom_string("ucursos.webs.com");
    lcd_gotoxy(1,2);
    lcd_rom_string("                ");
    for(unsigned char cont=0;cont<100;cont++){
        sprintf(buffer," value = %u  ",cont);
        lcd_gotoxy(1,2);
        lcd_ram_string(buffer);
        __delay_ms(100);
    }
    while(1);
}
```


----------



## Vegetal Digital (Ene 17, 2011)

Hola george, llego tarde al tema pero no para felicitarte, desde tu otro post para ccs veo que sos un gran programador que se desempeña sin mayores problemas en uno u otro lenguaje. Veo que es muy similar al CCS, asi que seguramente pronto estaré haciendo algunas pruebas guiandome por tus trabajos.
Sin más molestar, un cordial saludo para todos.


----------



## george.manson.69 (Ene 18, 2011)

Vegetal Digital dijo:


> Hola george, llego tarde al tema pero no para felicitarte, desde tu otro post para ccs veo que sos un gran programador que se desempeña sin mayores problemas en uno u otro lenguaje. Veo que es muy similar al CCS, asi que seguramente pronto estaré haciendo algunas pruebas guiandome por tus trabajos.
> Sin más molestar, un cordial saludo para todos.



Veo que los compiladores C18 y HI tech...son muy buenos y aparte estan en modo lite, y es para toda la familia 16 y 18(C18).

Espero que empecemos a hacer mas programas en C18 y Hi tech compiler.


----------



## @f2504 (Ene 18, 2011)

Buenas!
Primero que todo felicidades por el post! Apenas comienzo con C18 y ya presento problemas de los mas simples:
Tengo un 18F2550 con un pulsador en RA0, un LED en RB4, y este programa:

```
while(1){
  if(PORTAbits.RA0 == 1){
    LATB = 0x10;
    Delay10KTCYx(100);
    LATB = 0x00;
    Delay10KTCYx(100);
  }else{
    LATB = 0x00;
  }
}
```

En teoría el LED deberia prender y apagar cuando presiono el pulsador, pero solo se queda encendido.
Alguna idea?

Gracias de antemano

edit: Estoy utilizando el oscilador interno. Creo que por el ruido el LED no se veia titilar, sin embargo ya lo hace (si me alejo lo suficiente).


----------



## @f2504 (Ene 19, 2011)

Buenas a todos,

Logré solucionar mi problema, con un cristal de 20MHz, los condensadores de 15pF y colocando el bit FOSC = HS...

Ahora pasemos a cosas mas grandes!


----------



## george.manson.69 (Ene 22, 2011)

Simple uso de un LCD20x4, a 4 bits 






```
///////////////////////////////////////////////////////////
//TITULO: USO DEL LCD 4-bits							///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>			//Incluimos libreria del micro a usar
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT	= Codigo no Potegido
//WDTDIS	= Watch Dog Timer Desactivado
//PWRTEN	= Power Activado
//INTIO		= Osiclador interno
//MCLREN	= Activamos Master Clear
//LVPDIS	= Low Voltage Porgramming Desactivado
//DEBUGDIS	= Desactiva Debug
//BOR		= Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ
#include"lcd4bits/lcd.h"
////////////////////////////////////////////
//VARIABLES GLOBALES
///////////////////////////////////////////
unsigned char buffer[25];
//////////////////////////////////////////////////
//Funcion de segundo
//////////////////////////////////////////////////
void DELAY1S(void){
	unsigned char seg;
	for(seg=0;seg<100;seg++){
		__delay_ms(10);
	}
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
/////////////////////////////////////////////////
//Funcion Principal
/////////////////////////////////////////////////
void main(void){
///////////////////////////////////
//Registro para trabajar a 8MHZ
///////////////////////////////////
	OSCCON=0x70;
	while(HTS==0); //Es estable la frecuencia ?
	//Inicializa Puertos
	ADCON0=0;
	ANSELH=0;
	TRISC=0;
	//Inicializa LCD
	lcd_init(CURSOR_OFF);

	lcd_rom_string("  ucursos.webs.com  ");
	lcd_gotoxy(1,2);
	lcd_rom_string("  LCD20x4 - 4 bits  ");
	DELAY1S();
	lcd_gotoxy(1,3);
	lcd_rom_string("      Hi tech       ");
	lcd_gotoxy(1,4);
	lcd_rom_string("     for PIC16      ");
	while(1);
}
```

----------------------------------------------------------------------
Practica simple de uso de pwm dual con LCD 20 x4


```
///////////////////////////////////////////////////////////
//TITULO: Control de PWM DUAL							///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>			//Incluimos libreria del micro a usar
#include<stdio.h>
__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT	= Codigo no Potegido
//WDTDIS	= Watch Dog Timer Desactivado
//PWRTEN	= Power Activado
//INTIO		= Osiclador interno
//MCLREN	= Activamos Master Clear
//LVPDIS	= Low Voltage Porgramming Desactivado
//DEBUGDIS	= Desactiva Debug
//BOR		= Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ
#include"timer2/timer2.h"//LLama la libreria de usar Timer2
#include"pwmdr/pwm.h"	 //LLama libreria para usar PWM
#include"lcd4bits/lcd.h" //Libreria para LCD
#include"libADC/adcdr.h"//Inluimos libreria de trabajo con ADC
////////////////////////////////////////////
//VARIABLES GLOBALES
///////////////////////////////////////////
unsigned char buffer[25];
unsigned int adc[2];
//////////////////////////////////////////////////
//Funcion de segundo
//////////////////////////////////////////////////
void DELAY1S(void){
	unsigned char seg;
	for(seg=0;seg<100;seg++){
		__delay_ms(10);
	}
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
/////////////////////////////////////////////////
//Funcion Principal
/////////////////////////////////////////////////
void main(void){
///////////////////////////////////
//Registro para trabajar a 8MHZ
///////////////////////////////////
	OSCCON=0x70;
	while(HTS==0); //Es estable la frecuencia ?
	//Inicializa Puertos
	TRISC=0;
	TRISA=0x03;
	//Configuramos TIMER 2 para PWM
	OpenTimer2(PRESCALE_16);
	//Usamos libreria PWM
	OpenPwm(61);
	//PWM period =   [(period  ) + 1] x 4 x Tosc x TMR2 prescaler
	//PWM period =   [(255)+1]x(4/4Mhz)x16
	// [.001s/((4/4Mhz)*16)]-1=period 
	// [1/(f*(4/Tosc)*preescalar)]-1=period
	//Configuracion del ADC
	OpenADC(FOSC_FRC,AN0_AN1,OFF);
							//Oscilador interno
							//AN0 como entrada analogo
							//PORTB sin analoga
	//Inicializa LCD
	lcd_init(CURSOR_OFF);
	GIE=0;					//INTERRUPCIONES GLOBALES DesACTIVADAS
	PEIE=0;					//DesACTIVA INTERURPCIONES POR PERIFERICOS
////////////////////////////////////////////////////////////
	PwmDuty(0); //1023=100% 512=50% de duty
	PwmDuty2(0);//1023=100% 512=50% de duty

	lcd_rom_string("Control de PWM-dual ");
	DELAY1S();
	while(1){
		for(unsigned char ch=0;ch<2;ch++){
			channelADC(ch);
			__delay_ms(1);
			startADC();
			while(GODONE!=0);
			adc[ch]=readADC();
			if(adc[ch]<10) adc[ch]=0;
		}
		PwmDuty(adc[0]); //1023=100% 512=50% de duty
		PwmDuty2(adc[1]);//1023=100% 512=50% de duty
		sprintf(buffer,"PWM1= %u %% ",(unsigned int)(((unsigned long)adc[0]*100)/1023));
		lcd_gotoxy(1,2);
		lcd_ram_string(buffer);
		sprintf(buffer,"PWM2= %u %% ",(unsigned int)(((unsigned long)adc[1]*100)/1023));
		lcd_gotoxy(1,3);
		lcd_ram_string(buffer);
		__delay_ms(10);	
	}
			
	while(1);
}
```


----------



## george.manson.69 (Ene 24, 2011)

Simple controlador de lampara de 12 volts DC con PWM
usando la libreria de LCD3 wires para Usar menor pines del Micro





[ame="http://www.youtube.com/watch?v=iVr-nIzE6C8"][/ame]


----------



## george.manson.69 (Feb 7, 2011)

Manual Completo para programar un PIC18 para un sistema Difuso.
Espero sus Comentarios.

Video!


----------



## Moyano Jonathan (Feb 7, 2011)

Muy completo he interesante tu proyecto !


----------



## george.manson.69 (Mar 26, 2011)

En esta vez les traigo un gran manual de uso de Hi tech compiler:
De los cuales los temas son los siguientes.:


```
Índice
1 Introducción a la programación en C
1.1 Estructura de un programa____________________________________________1
1.2 Tipos de datos_______________________________________________________2
1.3 Constantes__________________________________________________________2
1.4 Tipos de Variables____________________________________________________2
1.5 Operadores_________________________________________________________3
1.5.1 Asignaciones_____________________________________________________3
1.5.2 Aritmética_______________________________________________________4
1.5.3 Relaciones_______________________________________________________4
1.6 Funciones___________________________________________________________5
2 Declaraciones de Control
2.1 IF-ELSE________________________________________________________________6
2.2 SWITCH-CASE___________________________________________________________7
2.3 FOR___________________________________________________________________8
2.4 WHILE/DO/WHILE________________________________________________________9
2.5 COMENTARIOS___________________________________________________________11
PRIMER PROGRAMA___________________________________________________________11
3 TIMERS
3.1 Timer0_______________________________________________________________17
3.2 Interrupción por desbordamiento_________________________________________22
3.3 Práctica: Corrimiento___________________________________________________25
4 USART
4.1 Modo Asincrónico________________________________________________________28
4.2 Modo Sincrónico_________________________________________________________28
4.3 Velocidad de Comunicación_________________________________________________29
4.4 Norma R232_____________________________________________________________29
4.5 Conexión de un Microcontrolador____________________________________________29
4.6 El conector DB9___________________________________________________________29
4.7 MAX232_________________________________________________________________30
4.8 Función en Hi tech_________________________________________________________30
4.9 Practica: Uso del USART_____________________________________________________31
5 ADC ---------------------------------------------------------------------------------------------------------------37
6 CCP
6.1 Modo Captura ___________________________________________________________42
6.2 Modo PWM _____________________________________________________________48
6.3 Modo Comparador________________________________________________________54
7 GLCD -------------------------------------------------------------------------------------------------------------60
7.7 Voltímetro con GLCD_______________________________________________________67
8 MMC
8.1 Conexión y señales en las tarjetas MMC________________________________________72
8.2 Tarjeta SD________________________________________________________________72
8.3 Conexión y señales en las Tarjetas SD _________________________________________73
8.4 Funcionamiento general del Protocolo_________________________________________74
8.5 Comandos Modo SPI_______________________________________________________74
8.6 Típicas Conexiones ________________________________________________________78
8.7 Utilidades para la práctica __________________________________________________79
8.8 Librería para Manejo de Tarjetas MMC________________________________________80
8.9 Usando Librería ___________________________________________________________81
9 Usando WinHEX_____________________________________________________________84
10 Practicas
10.1 Visualizador de ADC con Display’s de 7 seg ______________________________________85
10.2 Contador de Eventos con Display de 7 seg _______________________________________96
10.3 Reloj _____________________________________________________________________101
10.4 Matriz de led 8x8 ___________________________________________________________108
10.5 Cambio de Matrix via USART __________________________________________________116
10.6 Matriz de corrimiento ________________________________________________________122
10.7 Cambio de Texto por USART ___________________________________________________127
10.8 Proyectos con LCD y Teclado 4x4 _______________________________________________132
10.9 GLCD & MMC: Proyector de Imágenes ___________________________________________153
```

Pueden bajarlo gratis.

en http://ucursos.webs.com

deja tus comentarios. SALU2


----------



## george.manson.69 (Abr 29, 2011)

Simple enlace entre labview y pic16 usando serial.


```
///////////////////////////////////////////////////////////
//TITULO: USO DEL ADC y USART                                 ///
//AUTOR: george.manson.69
//COMPILADOR: HI TECH (LITE MODE)
//PAGE: http://ucursos.blogspot.com
//PAGE2:http://ucursos.webs.com
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

#include<htc.h>        //Incluimos libreria del micro a usar
#include<stdio.h>    //libreria para trabajar con conversiones
#include"libUSART/usartdr.h" //Libreria creada para uso del usart
#include"libADC/adcdr.h"//Inluimos libreria de trabajo con ADC

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);
__CONFIG(DEBUGDIS & BORDIS);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//UNPROTECT    = Codigo no Potegido
//WDTDIS    = Watch Dog Timer Desactivado
//PWRTEN    = Power Activado
//INTIO        = Osiclador interno
//MCLREN    = Activamos Master Clear
//LVPDIS    = Low Voltage Porgramming Desactivado
//DEBUGDIS    = Desactiva Debug
//BOR        = Desactivado
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

unsigned int adc;
unsigned char y;

///////////////////////////////
//Funcion de 1 segundo
////////////////////////////////
void Delay1S(void){
    unsigned char x;
    for(x=0;x<100;x++){
        __delay_ms(10);
    }
}
/////////////////////////////////////////////////
//Funcion de interrupcion
//Si no se usa simplemente no hacemos nada...
//Esto sirve para direccionar lo los datos
//en un lugar muy cercano al Inicio de la memoria
//de datos
////////////////////////////////////////////////
static void interrupt
isr(void){}
//////////////////////////////////////////////
//Funcion Principal
//////////////////////////////////////////////
void main(void){
///////////////////////////////////
//Registro para trabajar a 8MHZ
///////////////////////////////////
    OSCCON=0x70;
    while(HTS==0); //Es estable la frecuencia ?
    TRISA=0x01;
    TRISC=0x80;                //RB1=RX,RB2=TX
    //Configuracion del USART
    OpenUSART(25,OFF,OFF);    //value=(FOSC/(baud*16))-1
                            //SIN INTERRUPCIONES
                            //a 2400 baudios
    //Configuracion del ADC
    OpenADC(FOSC_FRC,AN0,OFF);
                            //Oscilador interno
                            //AN0 como entrada analogo
                            //PORTB sin analoga
//Desactivo Interrupciones GENERALES
    GIE=0;                    //INTERRUPCIONES GLOBALES DesACTIVADAS
    PEIE=0;                    //DesACTIVA INTERURPCIONES POR PERIFERICOS

    while(1){
        channelADC(0);        //Elige canal analogo
        Delay1S();            //Retardo de 1S para leer correctamente
        startADC();            //Empieza Ciclo de Conversion
        while(GODONE!=0);    //Ha terminado de convertir
        adc=readADC();        //Lee dato analogo
        printf("\fCanal Analogo 0 = %u",adc);//Imprime Dato analogo.
    }
    
}
```


----------



## george.manson.69 (Abr 30, 2011)

Esta idea surge por la necesidad de adquirir mas entradas hacia el  microcontrolador en este caso usar 6  pines del micro para obtener 16  entradas usando cirucitos 75HC151.


----------



## zoomg80 (May 1, 2011)

@f2504 dijo:


> Buenas!
> Primero que todo felicidades por el post! Apenas comienzo con C18 y ya presento problemas de los mas simples:
> Tengo un 18F2550 con un pulsador en RA0, un LED en RB4, y este programa:
> 
> ...


 
Hola

Tengo una rutina muy similar que use para enviar caracteres por el puerto serie al presionar un boton, al mismo tiempo enciendo el led para iluminarme.

Te dejo el fragmento espero te sirva, yo tampoco logro ver diferencia con tu codigo.


 while (1){
 while (Kbhit==0){              //Mientras no reciba dato USART
 putrsXLCD("Hor:min:seg");
 gotoxyXLCD(1,2);
 putrsXLCD("dia y fecha");                
    if (BOTON == 1)
  {
 putrsUSART("AT+CMSS=2\r\n");
 LED = 1;
 comandXLCD(0x01);
 putrsXLCD("Enviando mensaje");
 Espera();      //Loop espera si se queda presionado boton
 Delay10KTCYx(100);
 Delay10KTCYx(100);
 comandXLCD(0x01);
  }else{
 LED = 0;
       }
                    }
 Delay10KTCYx(100);
 Delay10KTCYx(100);
 Delay10KTCYx(100);
 Delay10KTCYx(100);
 Kbhit=0;
 }
}


----------



## george.manson.69 (May 16, 2011)

Esta practica ofrece solo la ventaja de usar mas entradas digitales, donde usaremos un software que fie realizado en Visual c#. 

Como podriamos ver en el video usamos pa la simulacion serial el programa Virtual Serial Port.


----------



## mecatrodatos (Oct 17, 2011)

Que tal george mirando tu post me dio la curiosidad por aprender, pude relizar esto con tu diseño y parte del programa donde manejas el nokia 3310 anexo la simulacion en proteus 7.7  y el programa en hi tech


```
#include <pic.h>  
#include <htc.h>
__CONFIG(FOSC_HS &   
  WDTE_OFF &   
  PWRTE_ON  &  
  BOREN_OFF &  
  MCLRE_ON &   
  LVP_OFF);  
#define GLCD_CS  RD0
#define GLCD_RST RD1
#define GLCD_DC  RD2
#define GLCD_SDA RD3
#define GLCD_SCLK RD4
#define _XTAL_FREQ 20000000
void pic_init(void);
void glcd8544_init(void);
void glcd8544_write(unsigned char c);
void glcd8544_goto(char x,char y);
void glcd8544_char(char c);
void glcd8544_string(const char *s);
static const char FontLookup[][5]={
{0x00,0x00,0x00,0x00,0x00},   // sp
{0x00,0x00,0x2f,0x00,0x00},   // !
{0x00,0x07,0x00,0x07,0x00},   // "
{0x14,0x7f,0x14,0x7f,0x14},   // #
{0x24,0x2a,0x7f,0x2a,0x12},   // $
{0xc4,0xc8,0x10,0x26,0x46},   // % 
{0x36,0x49,0x55,0x22,0x50},   // &
{0x00,0x05,0x03,0x00,0x00},   // '
{0x00,0x1c,0x22,0x41,0x00},   // (
{0x00,0x41,0x22,0x1c,0x00},   // )
{0x14,0x08,0x3E,0x08,0x14},   // *
{0x08,0x08,0x3E,0x08,0x08},   // +
{0x00,0x00,0x50,0x30,0x00},   // ,
{0x10,0x10,0x10,0x10,0x10},   // -
{0x00,0x60,0x60,0x00,0x00},   // .
{0x20,0x10,0x08,0x04,0x02},   // /
{0x3E,0x51,0x49,0x45,0x3E},   // 0
{0x00,0x42,0x7F,0x40,0x00},   // 1
{0x42,0x61,0x51,0x49,0x46},   // 2
{0x21,0x41,0x45,0x4B,0x31},   // 3
{0x18,0x14,0x12,0x7F,0x10},   // 4
{0x27,0x45,0x45,0x45,0x39},   // 5
{0x3C,0x4A,0x49,0x49,0x30},   // 6
{0x01,0x71,0x09,0x05,0x03},   // 7
{0x36,0x49,0x49,0x49,0x36},   // 8
{0x06,0x49,0x49,0x29,0x1E},   // 9
{0x00,0x36,0x36,0x00,0x00},   // :
{0x00,0x56,0x36,0x00,0x00},   // ;
{0x08,0x14,0x22,0x41,0x00},   // <
{0x14,0x14,0x14,0x14,0x14},   // =
{0x00,0x41,0x22,0x14,0x08},   // >
{0x02,0x01,0x51,0x09,0x06},   // ?
{0x32,0x49,0x59,0x51,0x3E},   // @
{0x7E,0x11,0x11,0x11,0x7E},   // A
{0x7F,0x49,0x49,0x49,0x36},   // B
{0x3E,0x41,0x41,0x41,0x22},   // C
{0x7F,0x41,0x41,0x22,0x1C},   // D
{0x7F,0x49,0x49,0x49,0x41},   // E
{0x7F,0x09,0x09,0x09,0x01},   // F
{0x3E,0x41,0x49,0x49,0x7A},   // G
{0x7F,0x08,0x08,0x08,0x7F},   // H
{0x00,0x41,0x7F,0x41,0x00},   // I
{0x20,0x40,0x41,0x3F,0x01},   // J
{0x7F,0x08,0x14,0x22,0x41},   // K
{0x7F,0x40,0x40,0x40,0x40},   // L
{0x7F,0x02,0x0C,0x02,0x7F},   // M
{0x7F,0x04,0x08,0x10,0x7F},   // N
{0x3E,0x41,0x41,0x41,0x3E},   // O
{0x7F,0x09,0x09,0x09,0x06},   // P
{0x3E,0x41,0x51,0x21,0x5E},   // Q
{0x7F,0x09,0x19,0x29,0x46},   // R
{0x46,0x49,0x49,0x49,0x31},   // S
{0x01,0x01,0x7F,0x01,0x01},   // T
{0x3F,0x40,0x40,0x40,0x3F},   // U
{0x1F,0x20,0x40,0x20,0x1F},   // V
{0x3F,0x40,0x38,0x40,0x3F},   // W
{0x63,0x14,0x08,0x14,0x63},   // X
{0x07,0x08,0x70,0x08,0x07},   // Y
{0x61,0x51,0x49,0x45,0x43},   // Z
{0x00,0x7F,0x41,0x41,0x00},   // [
{0x55,0x2A,0x55,0x2A,0x55},   // 55
{0x00,0x41,0x41,0x7F,0x00},   // ]
{0x04,0x02,0x01,0x02,0x04},   // ^
{0x40,0x40,0x40,0x40,0x40},   // _
{0x00,0x01,0x02,0x04,0x00},   // '
{0x20,0x54,0x54,0x54,0x78},   // a
{0x7F,0x48,0x44,0x44,0x38},   // b
{0x38,0x44,0x44,0x44,0x20},   // c
{0x38,0x44,0x44,0x48,0x7F},   // d
{0x38,0x54,0x54,0x54,0x18},   // e
{0x08,0x7E,0x09,0x01,0x02},   // f
{0x0C,0x52,0x52,0x52,0x3E},   // g
{0x7F,0x08,0x04,0x04,0x78},   // h
{0x00,0x44,0x7D,0x40,0x00},   // i
{0x20,0x40,0x44,0x3D,0x00},   // j
{0x7F,0x10,0x28,0x44,0x00},   // k
{0x00,0x41,0x7F,0x40,0x00},   // l
{0x7C,0x04,0x18,0x04,0x78},   // m
{0x7C,0x08,0x04,0x04,0x78},   // n
{0x38,0x44,0x44,0x44,0x38},   // o
{0x7C,0x14,0x14,0x14,0x08},   // p
{0x08,0x14,0x14,0x18,0x7C},   // q
{0x7C,0x08,0x04,0x04,0x08},   // r
{0x48,0x54,0x54,0x54,0x20},   // s
{0x04,0x3F,0x44,0x40,0x20},   // t
{0x3C,0x40,0x40,0x20,0x7C},   // u
{0x1C,0x20,0x40,0x20,0x1C},   // v
{0x3C,0x40,0x30,0x40,0x3C},   // w
{0x44,0x28,0x10,0x28,0x44},   // x
{0x0C,0x50,0x50,0x50,0x3C},   // y
{0x44,0x64,0x54,0x4C,0x44}    // z
};
main(void)
{
pic_init();      
glcd8544_init();     
__delay_ms(250);
for(;;){
 glcd8544_goto(0,0);
 glcd8544_string("PRUEBA HI-TECH");
 glcd8544_string("  84X48 GLCD  ");
 glcd8544_string("NOKIA 3310 LCD");
 glcd8544_string("              ");
 glcd8544_string("              ");
 glcd8544_string("              ");
 __delay_ms(1000);
 glcd8544_goto(0,0);
 glcd8544_string("              ");
 glcd8544_string("              ");
 glcd8544_string("              ");
 glcd8544_string(" PIC 16F887 ");
 glcd8544_string("    GRACIAS    ");
 glcd8544_string("  GEORGE MANSON ");
 __delay_ms(1000);
}}
void pic_init(void)
{
TRISA=0b00010000;
TRISB=0b00000000;
TRISC=0b00000000;
TRISD=0b00000000;
TRISE=0b00000000;
ANSEL=0b00000000;
ANSELH=0b00000000;   
PORTA=0b00000000;
PORTB=0b00000000;
PORTC=0b00000000;
PORTD=0b00000000;
PORTE=0b00000000;
}
 
void glcd8544_init(void)
{
GLCD_RST=1;
__delay_ms(15);  
glcd8544_write(0x21);  
glcd8544_write(0xC0);  
glcd8544_write(0x13);   
glcd8544_write(0x20);   
glcd8544_write(0x0C);   
}
 
void glcd8544_write(unsigned char c)   
{int i;
GLCD_CS=0;
for(i=7;i>=0;i--){
 if(((c>>i)&1)==1) GLCD_SDA=1;
 else GLCD_SDA=0;
 GLCD_SCLK=0;
 GLCD_SCLK=1;}
GLCD_CS=1;
}
 
void glcd8544_goto(char x, char y)
{
GLCD_DC=0;
glcd8544_write(0x40+y);
glcd8544_write(0x80+x);
GLCD_DC=1;
}
 
void glcd8544_char(char c)    
{int i;
for(i=0;i<5;i++) glcd8544_write(FontLookup[c-32][i]);
glcd8544_write(0x00);  
}
 
void glcd8544_string(const char *s) 
{
GLCD_DC=1;
while(*s)      
glcd8544_char(*s++);  
}
```
 
Pero me sale un mensaje en la compilacion que el programa se puede potencializar en un 40%


----------



## miguelfgp (Mar 3, 2013)

que tal saludos, alguien tiene algun link o info para usar el modulo USB de un pic18f4550 en el compilador C18?


----------



## miguelfgp (Abr 20, 2013)

Que tal foreros tengo una duda con el protocolo I2C no se como utilizar las funciones del compilador C18 para hacerlo funcionar, intente seguir un tutorial de c18 donde venia un ejemplo para escribir y leer en una eeprom pero no me simulo bien y tambien el ejemplo de este tema y no me simula bien y ya no eh encontrado otro ejemplo, de casualidad alguien x favor tiene algun ejemplo sencillo de I2C en C18, o un tutorial lo necesito la comunicacion para obtener datos de un sensor hmc5883l  pero no eh ni podido siquiera simular con una eeprom para leer y escribir datos, es para un pic18f458 gracias, mientras seguire intentando con el ejemplo de este tema


----------



## lusvin (Abr 21, 2013)

Buenas tardes

Quiero coectar un teclado de 4x4 por el potrD de mi pic18f4550 en Mpab C18..Que puedo hacer.. quien me puede orientar


----------



## miguelfgp (Abr 22, 2013)

en este tutorial dan un ejemplo para controlar un teclado matricial en c18


----------



## Marquitos RR (Jun 28, 2013)

Hola Gente !!! Alguien tiene idea de como hacer que en un pic 18Fxxxx que en un puerto x tenga un pulsador y en otro puerto x tenga por ejemplo un led y al apretar el pulsador este led prenda por 1 o mas minutos? Yo aprendi a hacer funcionar este mini proyecto usando "delays" pero la idea es usar los TIMER.
Tambien me gustaria usar el C18 Compiler, si alguien tiene una idea por fabor que me la diga estare eternamente agradecido ya que es un proyecto que quiero hacer para presentar en el instituto en el que empece a estudiar C18 hace unos meses.
Desde ya muy agradecido a todos y todas.
Saludos


----------



## D@rkbytes (Jun 28, 2013)

Te muestro una opción, quizás este programa te sirva Timer1 1 segundo Base

En ese programa se usa un cristal para el TMR1, pero también se puede hacer el conteo internamente.

Saludos.


----------



## Marquitos RR (Jun 28, 2013)

Gracias por tu rapida respuesta pero como soy nuevo en esto de la programacion C te hago una consulta sobre el codigo que me pasaste, dicho codigo esta formulado en CCS ahora tengo entendido que no es tan simple pasarlo a C18 en el que pretendo usar un pic 18Fxxx.
Si estoy equivocado te pido disculpas de antemano.
En la ciudad donde vivo no encontre otro curso mas que el de C18 Compiler y por lo que veo en la web no hay mucha data como asi para CCS, pero es lo unico que encontre para poder estudiar algo.
Muchas gracias por tu atencion y espero tu ayuda si no es mucha molestia.
Un abrazo.


----------



## D@rkbytes (Jun 28, 2013)

Marquitos RR dijo:


> Gracias por tu rapida respuesta pero como soy nuevo en esto de la programacion C te hago una consulta sobre el codigo que me pasaste, dicho codigo esta formulado en CCS ahora tengo entendido que no es tan simple pasarlo a C18 en el que pretendo usar un pic 18Fxxx.
> Si estoy equivocado te pido disculpas de antemano.
> En la ciudad donde vivo no encontre otro curso mas que el de C18 Compiler y por lo que veo en la web no hay mucha data como asi para CCS, pero es lo unico que encontre para poder estudiar algo.
> Muchas gracias por tu atencion y espero tu ayuda si no es mucha molestia.
> Un abrazo.


He ahí el detalle, me imagine que tenías algo de conocimientos ya.
Cómo quiera si te fijas bien en el código, se puede hacer uso de los registros unicamente.

Ese programa lo he realizado en Ensamblador, en PICC de CCS, en PICBasic Pro, y en PICBasic de Proton.
Así que, si le echas un poco de cabeza lo podrás migrar a C18 fácilmente.

Suerte.


----------



## george.manson.69 (Ago 11, 2013)

Este codigo es simple, solo trata de realizar comparaciones entre lo que escribes y lo que debe de ser, usando el compilador HiTech.

Saludos!


```
/* 
 * File:   MAIN.c
 * Author: george
 *
 * Created on 4 de agosto de 2013, 07:06 PM
 */
#include<htc.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<plib/usart.h>
/////////////////////////////////////////////////////////////
//Configuracion para trabajar Con oscilador interno de 8Mhz
#pragma config OSCS  = OFF, OSC  = HSPLL
#pragma config BOR   = OFF, BORV = 42,  PWRT = ON
#pragma config WDTPS = 128, WDT  = ON
#pragma config DEBUG = OFF, LVP  = OFF, STVR = OFF
#pragma config CP0   = OFF, CP1  = OFF, CP2  = OFF, CP3   = OFF
#pragma config CPD   = OFF, CPB  = OFF
#pragma config WRT0  = OFF, WRT1 = OFF, WRT2 = OFF, WRT3  = OFF
#pragma config WRTB  = OFF, WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1= OFF, EBTR2= OFF, EBTR3 = OFF
#pragma config EBTRB = OFF
//////////////////////////////
//Frecuencia FOSC 4Mhz x 4 PLL = 16 Mhz/4 = 4Mhz
//////////////////////////////
#define _XTAL_FREQ 4000000

struct{
    unsigned flag_rx:1;
    unsigned dumy:7;
}flags={0};

char data[25],i;
const char strings[6][20]={"COMANDO1\r",
                          "COMANDO2\r",
                          "COMANDO3\r",
                          "COMANDO4\r",
                          "COMANDO5\r",
                          "COMANDO6\r"};

void clear_string(){
    for(char index=0;index<=sizeof(data);index++){
        data[index]=0;
    }
}

void get_string_rx(char *s){
    do{
        while(!DataRdyUSART());
        *s=getcUSART();
    }while(*s++!='\r');
}

void interrupts_enables(void){
    INTCONbits.GIE=1;
    INTCONbits.PEIE=1;
}

static void interrupt isr(void){
    if(DataRdyUSART()){
       flags.flag_rx=1;
       get_string_rx(&data);
    }
}

void periphericals_configuration(void){
    TRISC=0X80;
//------------------------------------------------------------------
//		Configuracion del USART
//------------------------------------------------------------------
	OpenUSART(USART_TX_INT_OFF      &//Interrupcion por Transmision apagado
                  USART_RX_INT_ON	&//Interrupcion por Recepcion Apagado
		  USART_ASYNCH_MODE	&//Modo Asincronico
		  USART_EIGHT_BIT	&//8-bit de transmision
		  USART_CONT_RX		&//Recepcion Continua
		  USART_BRGH_HIGH,	 //Alta velocidad de baudios
		  51);                   //para alta Velocidad:
					 //FOSC (16 x (spbrg + 1))
					 //spbrg=(FOS/baud*16)-1
					 //Para baja Velocidad:
					 //FOSC (64 x (spbrg + 1))
/*---------------------Fin de Conf. USART----------------------------*/

        INTCONbits.GIE=1;
        INTCONbits.PEIE=1;
}

void putch(char c){
    /*Empty buffer?
     */
    while(!TXSTAbits.TRMT) continue;
    //load data into register to send
    TXREG=c;
}

void main(void){

    periphericals_configuration();
    interrupts_enables();

    while(1){
        if(flags.flag_rx){
            flags.flag_rx=0;
            printf("%s",data);
            for(unsigned char i=0;i<6;i++){
                if(strcmp(data,&strings[i])==0){
                    printf("%s es igual que %s\n",data,&strings[i]);
                    break;
                }
            }
            clear_string();
        }
        CLRWDT();
    }
    
    
}
```


----------



## BKAR (Sep 15, 2013)

Consulta!:
jugando con arreglos grandes, 
solo declararlos..

compila sin errores...

```
#pragma udata gpr1
char Cos[180];
#pragma udata
#pragma udata gpr2
char Sen[180];
#pragma udata
```

pero seria mejor...,

```
#pragma udata MISECCION
char Cos[180];
char Sen[180];
#pragma udata
```
lo cual me tira error...

hay algo que pase por alto  , con respecto a las secciones??


----------



## alberto0265 (Nov 11, 2013)

hago una consulta alguien tiene un ejemplo simple escribir y leer una eeprom 24lc256 por spi con pic 18f4550 o similar ya que uso el usb en C18.
Desde ya muy agradecido.


----------



## D@rkbytes (Nov 12, 2013)

alberto0265 dijo:


> hago una consulta alguien tiene un ejemplo simple escribir y leer una eeprom 24lc256 por spi con pic 18f4550 o similar ya que uso el usb en C18.
> Desde ya muy agradecido.


¿Y por que no lo haces por I2C? Es más fácil.
En el Foro de Microchip existen algunos ejemplos para C18.
También puedes buscar las notas de aplicación y los ejemplos en Microchip Application Notes Home

Suerte.


----------



## alberto0265 (Nov 12, 2013)

Gracias por contestar D@rkbytes .
Buscare por donde dices.


----------



## alberto0265 (Nov 19, 2013)

hola nuevamente por aqui para hacer una nueva consulta,ya consegui unas librerias para leer y escribir una eeprom 24lc256.
si yo uso una configuracion de fuses para trabajar con cristal de 20 mhz y usando comunicacion usb el micro 18f4550 corre a 48 mhz declarando lo siguiente como esta en este post (//Fuses para trabajar con 8Mhz/////////
#pragma config FOSC   = INTOSCIO_EC  //usamos 8Mhz internos)
el micro correria a 8 mhz para tener el sspadd=4 y poder hacer la comunicacion i2c sin problemas.
un abrazo para todos.


----------



## alberto0265 (Nov 28, 2013)

Ya esta solucionado mi probleman aclaro que no es necesario configurar #pragma config FOSC=INTOSCIO_EC.Simplemente en el main se coloca                                                 OSCCON=0x72;      //EMPIEZA A CORRER A FOSC=8Mhz 
Por que el micro esta trabajando con dos clock el modulo USB a 48MHZ a patir del cristal (20mhz en mi caso) y la CPU a 8MHZ.   Saludos


----------



## alberto0265 (Ene 6, 2014)

vuelvo a consultar sobre una comunicacion serie usart entre pc y un pic18f4550.
lo tengo funcionando tanto con interrupcion y sin ella tambien pero con el oscilador interno a 8mhz.
SPBRG=51
con SPBRG=311 calculado para 48mhz no funciona,como se puede lograr si alguien lo hiso.

```
#ifndef MAIN_C
#define MAIN_C

#include <p18F4550.h>
#include <delays.h>
#include <usart.h>
#include <stdio.h>
#include <stdlib.h>
#include "xlcd1.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            //INTOSC_HS                     //INTOSCIO_EC             //
        #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     = OFF       // 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

#pragma udata
void ISRRecepcion(void);
volatile char  Kbhit;
volatile  char Data;
   
#define REMAPPED_RESET_VECTOR_ADDRESS         0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS   0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS   0x1018

//void YourHighPriorityISRCode();
void YourLowPriorityISRCode();
   
extern void _startup (void);        // See c018i.c in your C18 compiler dir
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void){
    _asm goto _startup _endasm
}
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void Remapped_High_ISR (void)   {
     _asm goto ISRRecepcion _endasm                                        //_asm goto YourHighPriorityISRCode _endasm                                                                               
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
void Remapped_Low_ISR (void){
     _asm goto YourLowPriorityISRCode _endasm
}
   
#pragma code HIGH_INTERRUPT_VECTOR = 0x08
 void High_ISR (void)   {
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
}
#pragma code LOW_INTERRUPT_VECTOR = 0x18
void Low_ISR (void){
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
}
 #pragma code  
//#pragma interrupt YourHighPriorityISRCode
//void YourHighPriorityISRCode()   {
//}   //This return will be a "retfie fast", since this is in a #pragma interrupt section 
// Rutina de Interrupcion.-
#pragma interrupt ISRRecepcion
void ISRRecepcion(void){
   if(PIR1bits.RCIF==1){
      Data=getcUSART();   // Leemos Dato recibido
      Kbhit=1;          // Indicamos que se ha recibido un dato.-
      PIR1bits.RCIF=0;   // Borramos bandera.-
   }
   
} 


#pragma interruptlow YourLowPriorityISRCode
void YourLowPriorityISRCode()   {

}   //This return will be a "retfie", since this is in a #pragma interruptlow section 
#pragma code

   void DelayFor18TCY(void){
   Delay10TCYx(8);//8
   }
   void DelayPORXLCD(void){
   Delay1KTCYx(49);//49
   }

   void DelayXLCD(void){
   Delay1KTCYx(20);//20
   } 
/** DECLARATIONS ***************************************************/


   

   /* UART Global variables */

char message;//men2;                       //  Used for receiving commands from the computer
//unsigned char men[],i,len; 
unsigned char Rxdata[11];
unsigned char Txdata[] = "  PROBANDO_USART\n\r";

 
void main(void)
{
     ADCON1 |= 0x0F;
     //OSCCON=0x72;      //EMPIEZA A CORRER A FOSC=8Mhz
    //  Set all of PORTC as outputs. TX and RX must be set as outputs first
    TRISCbits.TRISC6=0; TRISCbits.TRISC7=1;            //
    //TRISC=0x00;
    TRISD=0x00;
     LATD=0; 
    //  Configure UART                                                                                                       //51 a 8mhz
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE &USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH,311 ); //311 baud = 48000000/(16 x 312) = 9615
        Kbhit=0;                                                                                                               // 129 baud= 20mhz/(16x130) =9615
   RCONbits.IPEN=0;   // Deshabilitamos Prioridades
   INTCONbits.PEIE=1;   // Habilitamos interrupcion de perifericos.-
   INTCONbits.GIE=1;      // Habilitamos interrupcion Global.
    PIE1bits.RCIE=1;
   
    putrsUSART("Prueba Comunicacion Serial \n\r");
        Delay1KTCYx(4);
        while(1)
        {
          // while(Kbhit==0){}; // esperamos a recibir dato.-
         // Kbhit=0;
          
           LATDbits.LATD3=~PORTDbits.RD3;  
         
               
               //------USART Transmission ----
             while(BusyUSART());             //Check if Usart is busy or not
              putsUSART((char *)Txdata);                //transmit the string
             
               //---USART Reception ---
            // while(!DataRdyUSART()); //sin interrupciones
              while(Kbhit==0){}; // esperamos a recibir dato.-
              Kbhit=0;
              // getsUSART((char *)Rxdata,10);             //Recieve data upto 24 bytes
               message=getcUSART();                         
               Delay10KTCYx(250);
              // Delay10KTCYx(250); 
              // Delay10KTCYx(250);
              // putsUSART((char *)Rxdata );                //transmit the string
               putcUSART(message);
            }


}
#endif
```
saludos

---------- Actualizado después de 3 horas ----------

Ya lo solucioné, pido disculpas pero hace días que estoy investigando después que publiqué el pedido seguí buscando y se solucionó en la búsqueda.
Aprovecho para desasnar; hay que calcular  BGRH_LOW(  USART_BRGH_LOW,77 );
Dicho 77 es para transmitir a 9600 baud.
Nuevamente  saludos


----------



## BKAR (Jun 15, 2014)

george.manson.69 dijo:


> ...
> He invito a otras personas a colaborar en la programacion de este compilador tanto de uso de librerias hechas para este lenguaje ASCII, para que fuera una gran ayuda para llegar a programar  correctamente estos  pic18 y  entender mas  porque de  las cosas....
> Ya que tengo unas cuantas dudas en la programacion...como son
> 
> ...



Yupi!!
la verdad no comprendi del todo como define los tipos de dato el C18, en especial los tipo 
--> (const rom char *)
dentro de las funciones...

entonces justamente en la funcion putrsXLCD() comparandola con la funcion putsXLCD(),
las definicion de la funcion practicamente identicas para ambas funciones 


```
while(*buffer)                  // Write data to LCD up to null
        {
                while(BusyXLCD());      // Wait while LCD is busy
                WriteDataXLCD(*buffer); // Write character to LCD
                buffer++;               // Increment buffer
        }
        return;
```

copy paste del archivo .c
solo cambiaban las deficiones de entrada..
void putrsXLCD(const rom char *buffer)
void putsXLCD(char *buffer)

los misma declaracion en los prototipos de funciones en el archivo xlcd.h
nada del otro mundo.. todo entendible.. porque no aparece nada en proteus con la funcion putrs??

mi curiosidad me llevo a investigar otros putrsXXX... como en putrsUSART()
pero encontre una variante en el archivo USART.h
el prototipo estaba declarado como:
void putrsUSART ( const MEM_MODEL rom char *data);
mientras que en xlcd.h:
void putrsXLCD(const rom char *) ;

que hace la diferencia MEM_MODEL? ni idea...

tan solo cambie el archivo xlcd.h... 
en el prototipo
void putrsXLCD(const MEM_MODEL rom char *) ;
y eso es todo.. funciona como deberia.

sera que las versiones del C18 modificaron algo y se olvidaron de corregir las librerias?
la fecha de mi arhcivo original usart.h es del 2013, pero xlcd.h es del 2009.

uso la version C18 3.47  que habra pasado jeje, no importa con ese cambio de soluciona.
*modificar xlcd.h
void putrsXLCD(const rom char *) ; ---> void putrsXLCD(const MEM_MODEL rom char *) ;*


----------

