Programas hechos en C18 compiler

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...
Código:
#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

Código:
#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

Código:
/////////////////////////////////////////////////////////////
//                        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

Código:
/////////////////////////////////////////////////////////////
//                        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

Código:
#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

Código:
#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
Código:
/////////////////////////////////////////////////////////////
//                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
Código:
/////////////////////////////////////////////////////////////
//                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...:unsure:.
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)
....
 

Adjuntos

  • adc.jpg
    adc.jpg
    215.9 KB · Visitas: 207
  • Control del led.jpg
    Control del led.jpg
    164.2 KB · Visitas: 143
  • eeprom.jpg
    eeprom.jpg
    197.7 KB · Visitas: 126
  • pwmrs2.jpg
    pwmrs2.jpg
    129.6 KB · Visitas: 129
  • pwmrs23.jpg
    pwmrs23.jpg
    240.2 KB · Visitas: 122
  • P1.zip
    15.9 KB · Visitas: 374
  • P2.zip
    60.7 KB · Visitas: 252
  • P3.zip
    92.4 KB · Visitas: 247
  • P4.zip
    111.3 KB · Visitas: 248
  • P5.zip
    46.5 KB · Visitas: 242
  • P6.zip
    69.2 KB · Visitas: 240
  • P7.zip
    67.9 KB · Visitas: 267
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
 
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

Código:
/////////////////////////////////////////////////////////////
//    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
}
 

Adjuntos

  • P8.zip
    155.9 KB · Visitas: 325
  • imagen.jpg
    imagen.jpg
    140.3 KB · Visitas: 153
  • Creando librerias C18.pdf
    181.9 KB · Visitas: 346
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.

Código:
/////////////////////////////////////////////////////////////
//    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
 }
}
 

Adjuntos

  • display.jpg
    display.jpg
    205.6 KB · Visitas: 101
  • Display.zip
    40.5 KB · Visitas: 203
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

Código:
///////////////////////////////////////////////////////////
//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

Código:
///////////////////////////////////////////////////////////
//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

Código:
///////////////////////////////////////////////////////////
//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

Código:
///////////////////////////////////////////////////////////
//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
 

Adjuntos

  • serial.jpg
    serial.jpg
    162.7 KB · Visitas: 53
  • pwm.jpg
    pwm.jpg
    194.6 KB · Visitas: 50
  • TIMER0.jpg
    TIMER0.jpg
    185.1 KB · Visitas: 44
  • Serial.zip
    149.7 KB · Visitas: 176
  • PWM.zip
    87 KB · Visitas: 219
  • Timer0.zip
    74.3 KB · Visitas: 191
  • Timer0_2.zip
    107.1 KB · Visitas: 154
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.
 
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!
 
usando el compilador hi tech he programado mi pic16f648a para hacer una matriz de de 8x24 que contara de 000 a 999.

Código:
//////////////////////////////////////////////////////////////
//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;
        }   
       } 
      }
     }
    }
   }
  }
}
 

Adjuntos

  • matrix2.jpg
    matrix2.jpg
    154.9 KB · Visitas: 115
  • Matrix cont.zip
    354.3 KB · Visitas: 251
He desarrollado una libreria para trbajar con LCD en el entorno de HI TECH
Espero que sea de ayuda

Código:
///////////////////////////////////////////////////////////
//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
 }
 
}
 

Adjuntos

  • lcd.jpg
    lcd.jpg
    200.9 KB · Visitas: 61
  • LCD.zip
    657.5 KB · Visitas: 164
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.

Código:
///////////////////////////////////////////////////////////
//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;
        }
    }
}
 

Adjuntos

  • LCD_KEY.jpg
    LCD_KEY.jpg
    272.9 KB · Visitas: 88
  • P8.zip
    560.5 KB · Visitas: 169
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.

Código:
/////////////////////////////////////////////////////////////
//                        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;
        }
    }
}
 

Adjuntos

  • analogo.jpg
    analogo.jpg
    214.6 KB · Visitas: 81
  • PWM_analogo.zip
    389.2 KB · Visitas: 172
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.
 
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.
 
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)

Código:
///////////////////////////////////////////////////////////
//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
    }
}
 

Adjuntos

  • IMAGEN.jpg
    IMAGEN.jpg
    262.1 KB · Visitas: 73
  • p11.zip
    894.5 KB · Visitas: 167
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
 
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
 
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.

Código:
////////////////////////////////////////////////////////
//    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
 

Adjuntos

  • image.jpg
    image.jpg
    160.4 KB · Visitas: 71
  • P5.2.zip
    584.3 KB · Visitas: 164
Última edición:
Hola amigo george.manson.69:apreton:
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..(y)
 
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);
}
 
Última edición:
Atrás
Arriba