Você está na página 1de 61

Ing.

Oscar Concha Rdz

Programación de micro-controladores PIC


con el "MPLAB XC8"

Ing. Oscar Concha Rdz

Noviembre 7, 2016
Ing. Oscar Concha Rdz

Abstracto:
En este documento se presenta un tutorial del compilador XC8 que pretende proporcionar los
conocimientos básicos para comenzar a desarrollar diferentes proyectos con el PIC18F4455 de la
empresa “Microchip” y el software de simulación llamado “Proteus”
Por otro lado, como en este escrito solo se pueden observar los códigos de programación que se
llevan a cabo en el microcontrolador, se han tomado como referencias distintas páginas de
internet para instalar y configurar el compilador que se usa en el documento al final de éste
Introducción:
Un micro-controlador es un circuito integrado que en su interior contiene una unidad central de
procesamiento (CPU), unidades de memoria (RAM y ROM) además de puertos de entrada y
salida. Básicamente, un micro-controlador ejecuta el programa que ha sido descargado en su
memoria para realizar las diferentes tareas que se le a asignado llevar a cabo
Actualmente existe una gran diversidad de micro-controladores ubicados en diferentes sectores,
tales como: industria automovilística, aplicaciones militares y en el mercado de la comunicación.
Algunos ejemplos de ellos los podemos encontrar en teléfonos celulares, computadoras,
impresoras, entre otras
Los principales recursos específicos que incorporan los micro-controladores son: temporizadores
(timers), conversores análogos-digitales (ADC) y digitales-análogos (DAC), comparadores,
modulador de anchura de impulsos (PWM) y puertos de comunicación (USART, SPI, I2C)
Ing. Oscar Concha Rdz

PRAGMA PIC18F4455
// CONFIG1L
#pragma config PLLDIV = 1
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 1

// CONFIG1H
#pragma config FOSC = HS (Proteus) ó INTOSC_XT (Microcontrolador)
#pragma config FCMEN = OFF
#pragma config IESO = OFF

// CONFIG2L
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 3
#pragma config VREGEN = OFF

// CONFIG2H
#pragma config WDT = OFF
#pragma config WDTPS = 32768

// CONFIG3H
#pragma config CCP2MX = ON
#pragma config PBADEN = ON
#pragma config LPT1OSC = OFF
#pragma config MCLRE = ON

// CONFIG4L
#pragma config STVREN = ON
#pragma config LVP = ON
#pragma config ICPRT = OFF
#pragma config XINST = OFF
Ing. Oscar Concha Rdz

// CONFIG5L
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF

// CONFIG5H
#pragma config CPB = OFF
#pragma config CPD = OFF

// CONFIG6L
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF

// CONFIG6H
#pragma config WRTC = OFF
#pragma config WRTB = OFF
#pragma config WRTD = OFF

// CONFIG7L
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF

// CONFIG7H
#pragma config EBTRB = OFF
Ing. Oscar Concha Rdz

Configuración PORTB Interrupción


#include <xc.h>

void interrupt high_priority HIGH ()


{
if (INTCONbits.INT0IF == 1) //INT0 external interrupt occurred
{
PORTDbits.RD0 = ~PORTDbits.RD0;
}
INTCONbits.INT0IF = 0; //INT0 cleared in software

if (INTCON3bits.INT1IF == 1) //INT1 external interrupt occurred


{
PORTDbits.RD1 = ~PORTDbits.RD1;
}
INTCON3bits.INT1IF = 0; //INT1 cleared in software
}

void interrupt low_priority LOW ()


{
if (INTCON3bits.INT2IF == 1) //INT2 external interrupt occurred
{
PORTDbits.RD2 = ~PORTDbits.RD2;
}
INTCON3bits.INT2IF = 0; //INT2 cleared in software
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency select bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
Ing. Oscar Concha Rdz

TRISD = 0x00;
PORTD = 0x00;

ADCON1bits.PCFG3 = 1; //AD port configuration control bits (AN12 to AN0) digital


ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 1;

RCONbits.IPEN = 1; //Interrupt priority enable bit (priority levels on interrupts)

INTCONbits.GIEH = 1; //Enables all high priority interrupts


INTCONbits.GIEL = 1; //Enables all low priority interrupts

INTCON2bits.INTEDG0 = 1; //External interrupt 0 on rising edge


INTCON2bits.INTEDG1 = 1; //External interrupt 1 on rising edge
INTCON2bits.INTEDG2 = 1; //External interrupt 2 on rising edge

INTCONbits.INT0IE = 1; //INT0 external interrupt enable bit


INTCONbits.INT0IF = 0; //INT0 external interrupt flag bit (did not occur)

INTCON3bits.INT1IE = 1; //INT1 external interrupt enable bit


INTCON3bits.INT1IP = 1; //INT1 exernal interrupt priority bit (high priority)
INTCON3bits.INT1IF = 0; //INT1 external interrupt flag bit (did not occur)

INTCON3bits.INT2IE = 1; //INT2 external interrupt enable bit


INTCON3bits.INT2IP = 0; //INT2 exernal interrupt priority bit (low priority)
INTCON3bits.INT2IF = 0; //INT2 external interrupt flag bit (did not occur)

while (1)
{

}
return;
Ing. Oscar Concha Rdz

}
Ing. Oscar Concha Rdz

Configuración TMR0 Interrupción


#include <xc.h>

int msegundo;
int segundo;

void interrupt high_priority ISR ()


{
if (INTCONbits.TMR0IF == 1) //TMR0 register has overflowed
{
msegundo++;
if (msegundo > 999) //Overflow time = 0.001 seconds
{
msegundo = 0;
segundo++;
if (segundo > 1)
{
segundo = 0;
}
if (segundo == 0)
{
PORTDbits.RD0 = 0;
}
if (segundo == 1)
{
PORTDbits.RD0 = 1;
}
}
}
TMR0 = 6;
INTCONbits.TMR0IF = 0; //TMR0 cleared in software
}
Ing. Oscar Concha Rdz

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

TRISD = 0x00;
PORTD = 0x00;

RCONbits.IPEN = 1; //Interrupt priority enable bit (priority levels on interrupts)

INTCONbits.GIEH = 1; //Enables all high priority interrupts


INTCONbits.GIEL = 1; //Enables all low priority interrupts

T0CONbits.T08BIT = 1; //TMR0 8-16 bit control bit (8 bit timer/counter)

T0CONbits.PSA = 0; //TMR0 prescaler assignment bit (TMR0 prescaler is assigned)

T0CONbits.T0PS2 = 0; //TMR0 prescaler select bits (1:8 prescale value)


T0CONbits.T0PS1 = 1;
T0CONbits.T0PS0 = 0;

T0CONbits.T0CS = 0; //TMR0 clock source select bit

INTCONbits.TMR0IE = 1; //TMR0 overflow intterrupt enable bit (enables overflow interrupt)


INTCON2bits.TMR0IP = 1; //TMR0 overflow interrupt priority bit (high priority)
INTCONbits.TMR0IF = 0; //TMR0 overflow interrupt flag bit (did not overflow)

TMR0 = 6; //TMR0 = 256 - (overflow time) / (4*Tosc*Prescaler)

T0CONbits.TMR0ON = 1; //Timer0 on control bit


while(1)
{
Ing. Oscar Concha Rdz

}
return;
}
Ing. Oscar Concha Rdz

Configuración TMR1 y TMR3 Interrupción


#include <xc.h>

int msegundo;
int segundo;

void interrupt high_priority ISR ()


{
if (PIR1bits.TMR1IF == 1) //TMR1 register has overflowed
{
msegundo++;
if (msegundo > 999) //Overflow time = 0.001 seconds
{
msegundo = 0;
segundo++;
if (segundo > 8)
{
segundo = 0;
}
if (segundo == 0)
{
PORTD = 0x00;
}
if (segundo == 1)
{
PORTD = 0x01;
}
if (segundo == 2)
{
PORTD = 0x02;
}
if (segundo == 3)
{
Ing. Oscar Concha Rdz

PORTD = 0x04;
}
if (segundo == 4)
{
PORTD = 0x08;
}
if (segundo == 5)
{
PORTD = 0x10;
}
if (segundo == 6)
{
PORTD = 0x20;
}
if (segundo == 7)
{
PORTD = 0x40;
}
if (segundo == 8)
{
PORTD = 0x80;
}
}
}
TMR1H = 255;
TMR1L = 6;
PIR1bits.TMR1IF = 0; //TMR1 cleared in software
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency select bits (8MHz)
OSCCONbits.IRCF1 = 1;
Ing. Oscar Concha Rdz

OSCCONbits.IRCF0 = 1;

TRISD = 0x00;
PORTD = 0x00;

RCONbits.IPEN = 1; //Interrupt priority enable bit (priority levels on interrupts)

INTCONbits.GIEH = 1; //Enables all high priority interrupts


INTCONbits.GIEL = 1; //Enables all low priority interrupts

T1CONbits.RD16 = 0; //Mode enable bit (two 8 bit operation)

T1CONbits.T1OSCEN = 1; //TMR1 oscillator enable bit

T1CONbits.T1CKPS1 = 1; //TMR1 prescaler select bits (1:8 prescale value)


T1CONbits.T1CKPS0 = 1;

T1CONbits.TMR1CS = 0; //Internal clock (Fosc/4)

T1CONbits.TMR1ON = 1; //TMR1 on bit

PIE1bits.TMR1IE = 1; //TMR1 overflow interrupt enable bit


IPR1bits.TMR1IP = 1; //TMR1 overflow interrupt priority bit (high priority)
PIR1bits.TMR1IF = 0; //TMR1 overflow interrupt flag bit (did not occur)

//TMR1 = 65536 - (overflow time) / (4*Tosc*Prescaler)


// overflow time = 65286 = 11111111 00000110
TMR1H = 255;
TMR1L = 6;

while (1)
{
Ing. Oscar Concha Rdz

}
return;
}
Ing. Oscar Concha Rdz

Configuración ADC Interrupción


#include <xc.h>

int ADC = 0;

void interrupt high_priority ISR ()


{
if (PIR1bits.ADIF == 1) //A/D conversion completed
{
ADC = (ADRESH << 8) + ADRESL; //10bits result
PORTC = ADC; //LSB
PORTD = ADC >> 8; //MSB
}
PIR1bits.ADIF = 0; //A/D conversion cleared in software
ADCON0bits.GO = 1; //AD conversion status bit (conversion in progress)
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

TRISC = 0x00;
PORTC = 0x00;
TRISD = 0x00;
PORTD = 0x00;

RCONbits.IPEN = 1; //Interrupt priority enable bit (priority levels on interrupts)


INTCONbits.GIEH = 1; //Enables all high priority interrupts
INTCONbits.GIEL = 1; //Enables all low priority interrupts

PIE1bits.ADIE = 1; //A/D converter interrupt enable bit


Ing. Oscar Concha Rdz

IPR1bits.ADIP = 1; //A/D converter interrupt priority bit (high priority)


PIR1bits.ADIF = 0; //A/D converter interrupt flag bit

ADCON2bits.ACQT2 = 1; //Table 2-11


ADCON2bits.ACQT1 = 1;
ADCON2bits.ACQT0 = 0;

ADCON2bits.ADCS2 = 1; //Table 2-11


ADCON2bits.ADCS1 = 0;
ADCON2bits.ADCS0 = 1;

ADCON2bits.ADFM = 1; //AD result format select bit (right justified)

ADCON1bits.PCFG3 = 1; //AD port configuration control bits (AN0 analog)


ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 0;

ADCON0bits.CHS3 = 0;//Analog channel select bits (AN0)


ADCON0bits.CHS2 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS0 = 0;

ADCON1bits.VCFG1 = 0; //Voltage reference (Vss)


ADCON1bits.VCFG0 = 0; //Voltage reference (Vdd)

ADCON0bits.ADON = 1; //AD on bit

ADCON0bits.GO = 1; //AD conversion status bit (conversion in progress)

while (1)
{
Ing. Oscar Concha Rdz

}
return;
}
Ing. Oscar Concha Rdz

Configuración ADC
#include <xc.h>

int ADC;

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency select bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

TRISD = 0x00;
PORTD = 0x00;

ADCON2bits.ACQT2 = 1; //Table 2-11


ADCON2bits.ACQT1 = 1;
ADCON2bits.ACQT0 = 0;

ADCON2bits.ADCS2 = 1; //Table 2-11


ADCON2bits.ADCS1 = 0;
ADCON2bits.ADCS0 = 1;

ADCON2bits.ADFM = 1; //AD result format select bit (right justified)

ADCON1bits.PCFG3 = 1; //AD port configuration control bits (AN0 analog)


ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 0;

ADCON0bits.CHS3 = 0; //Analog channel select bits (AN0)


ADCON0bits.CHS2 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS0 = 0;
Ing. Oscar Concha Rdz

ADCON1bits.VCFG1 = 0; //Voltage reference (Vss)


ADCON1bits.VCFG0 = 0; //Voltage reference (Vdd)

ADCON0bits.ADON = 1; //AD on bit

while (1)
{
ADCON0bits.GO = 1; //AD conversion status bit (conversion in progress)
while (ADCON0bits.nDONE == 1) continue; //Wait until conversion is over
ADC = (ADRESH << 8) + ADRESL; //10bits result

if (ADC >= 0 && ADC <= 128)


{
PORTD = 0x01;
}
if (ADC >= 129 && ADC <= 256)
{
PORTD = 0x02;
}
if (ADC >= 257 && ADC <= 384)
{
PORTD = 0x04;
}
if (ADC >= 385 && ADC <= 512)
{
PORTD = 0x08;
}
if (ADC >= 513 && ADC <= 640)
{
PORTD = 0x10;
}
if (ADC >= 641 && ADC <= 768)
Ing. Oscar Concha Rdz

{
PORTD = 0x20;
}
if (ADC >= 769 && ADC <= 896)
{
PORTD = 0x40;
}
if (ADC >= 897 && ADC <= 1023)
{
PORTD = 0x80;
}
}
return;
}
Ing. Oscar Concha Rdz

Configuración TOUCH
#include <xc.h>

int voltage = 0;
int touch = 0;
int rango = 0;

void main(void)
{
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

TRISD = 0x00;
PORTD = 0x00;

ADCON2bits.ACQT2 = 1; //Table 2-11


ADCON2bits.ACQT1 = 1;
ADCON2bits.ACQT0 = 0;

ADCON2bits.ADCS2 = 1; //Table 2-11


ADCON2bits.ADCS1 = 0;
ADCON2bits.ADCS0 = 1;

ADCON2bits.ADFM = 0; //AD result format select bit (left justified)

ADCON1bits.PCFG3 = 1; //AD port configuration control bits (AN0 analog)


ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 0;
ADCON1bits.PCFG0 = 1;

ADCON1bits.VCFG1 = 0; //Voltage reference (Vss)


ADCON1bits.VCFG0 = 0; //Voltage reference (Vdd)
Ing. Oscar Concha Rdz

ADCON0bits.ADON = 1; //AD on bit

while (1)
{
ADCON0bits.CHS3 = 0; //Analog channel select bits (AN0)
ADCON0bits.CHS2 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS0 = 0;

ADCON0bits.GO = 1; //AD conversion status bit (conversion in progress)


while (ADCON0bits.nDONE == 1) continue; //Wait until conversion is over
voltage = ADRESH; //8bit result
//PORTD = voltage;

ADCON0bits.CHS3 = 0; //Analog channel select bits (AN1)


ADCON0bits.CHS2 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS0 = 1;

ADCON0bits.GO = 1; //AD conversion status bit (conversion in progress)


while (ADCON0bits.nDONE == 1) continue; //Wait until conversion is over
touch = ADRESH; //8bit result
//PORTD = touch;

rango = (voltage * touch) / (voltage + touch);

if (rango >= 7 && rango <= 15)


{
PORTDbits.RD0 = 1;
}
else
{
Ing. Oscar Concha Rdz

PORTDbits.RD0 = 0;
}
}
return;
}
Ing. Oscar Concha Rdz

Configuración PWM FIJO


#include <xc.h>

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency select bits (1MHz)
OSCCONbits.IRCF1 = 0;
OSCCONbits.IRCF0 = 0;

//16ms (periodo) 8ms (duty cycle)


//PR2 = (PWM period / (TMR2prescale *4 * Tosc)) - 1
//CCPR1L:CCP1CON = (PWM duty-cycle/(TMR2prescale * Tosc))
//NOTA: Convertir resultado obtenido entero a valor binario de 10 bits
//CCPR1L:CCP1CON = 500 = 01111101 00
//Últimos dos bits al registro CCP1CON (bit 4 y 5)
//Primeros ocho bits al registro CCPR1L

TRISCbits.RC2 = 0; //Pin RC2/CCP1 as an output


PORTCbits.RC2 = 0;

T2CONbits.T2CKPS1 = 1; //TMR2 clock prescale select bits (prescaler is 16)


T2CONbits.T2CKPS0 = 0;
T2CONbits.TMR2ON = 1; //TMR2 On bit (TMR2 is on)

PR2 = 0xF9; //Maximo 8 bits

CCPR1L = 0x7D; //10 bits

CCP1CONbits.DC1B1 = 0;
CCP1CONbits.DC1B0 = 0;

CCP1CONbits.CCP1M3 = 1; //PWM mode


CCP1CONbits.CCP1M2 = 1;
Ing. Oscar Concha Rdz

CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;

while (1)
{
CCPR1L = 0x7D;
}
return;
}
Ing. Oscar Concha Rdz

Configuración PWM Variable


#include <xc.h>

int ADC = 0;
int i = 0;

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

TRISCbits.RC2 = 0; //Pin RC2/CCP1 as an output


PORTCbits.RC2 = 0;

//ADC
ADCON2bits.ACQT2 = 1; //Table 2-11
ADCON2bits.ACQT1 = 1;
ADCON2bits.ACQT0 = 0;
ADCON2bits.ADCS2 = 1; //Table 2-11
ADCON2bits.ADCS1 = 0;
ADCON2bits.ADCS0 = 1;
ADCON2bits.ADFM = 0; //AD result format select bit (left justified)
ADCON1bits.PCFG3 = 1; //AD port configuration control bits (AN0 analog)
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 0;
ADCON0bits.CHS3 = 0;//Analog channel select bits (AN0)
ADCON0bits.CHS2 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS0 = 0;
ADCON1bits.VCFG1 = 0; //Voltage reference (Vss)
ADCON1bits.VCFG0 = 0; //Voltage reference (Vdd)
Ing. Oscar Concha Rdz

ADCON0bits.ADON = 1; //AD on bit

//PWM
CCP1CONbits.CCP1M3 = 1; //PWM mode
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
PR2 = 0xF9; //500Hz
T2CONbits.T2CKPS1 = 1; //TMR2 clock prescale select bits (prescaler is 16)
T2CONbits.T2CKPS0 = 0;
T2CONbits.TMR2ON = 1; //TMR2 On bit (TMR2 is on)

while (1)
{
ADCON0bits.GO = 1; //AD conversion status bit (conversion in progress)
while (ADCON0bits.nDONE == 1) continue; //Wait until conversion is over
ADC = ADRESH; //8bit result

for (i == 0; i < 51; i++)


{
CCPR1L = ADC;
}
i = 0;
}
return;
}
Ing. Oscar Concha Rdz
Ing. Oscar Concha Rdz

Configuración Compare (50% Duty Cycle) Interrupción


#include <xc.h>

void interrupt high_priority ISR ()


{
if (PIR1bits.CCP1IF == 1) //A TMR1 register compare match ocurred
{
PORTCbits.CCP1 = ~PORTCbits.CCP1; // T = 20ms con 50% duty cycle
}
CCPR1H = 78;
CCPR1L = 32;
PIR1bits.CCP1IF = 0; //TMR1 cleared in software
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

TRISCbits.RC2 = 0; //Pin RC2/CCP1 as an output


PORTCbits.RC2 = 0;

RCONbits.IPEN = 1; //Interrupt priority enable bit (priority levels on interrupts)


INTCONbits.GIEH = 1; //Enables all high priority interrupts
INTCONbits.GIEL = 1; //Enables all low priority interrupts

CCP1CONbits.CCP1M3 = 1; //Compare mode, trigger special event


CCP1CONbits.CCP1M2 = 0;
CCP1CONbits.CCP1M1 = 1;
CCP1CONbits.CCP1M0 = 1;

PIE1bits.CCP1IE = 1; //CCP1 interrupt enable bit


Ing. Oscar Concha Rdz

IPR1bits.CCP1IP = 1; //CCP1 interrupt priority bit (high priority)


PIR1bits.CCP1IF = 0; //CCP1 interrupt flag bit (No TMR1 register compare match ocurred)

//TCY = 4 / Fosc
//CCPR1 = valor deseado / TCY (valor máximo = 65536)
//CCPR1 = 4E20 = 10ms/0.5us = 20000 cumple
CCPR1H = 78;
CCPR1L = 32;

T1CONbits.RD16 = 0; //Mode enable bit (two 8 bit operation)


T1CONbits.T1OSCEN = 1; //TMR1 oscillator enable bit
T1CONbits.T1CKPS1 = 0; //TMR1 prescaler select bits (1:1 prescale value)
T1CONbits.T1CKPS0 = 0;
T1CONbits.TMR1CS = 0; //Internal clock (Fosc/4)
T1CONbits.TMR1ON = 1; //TMR1 on bit

while (1)
{

}
return;
}
Ing. Oscar Concha Rdz
Ing. Oscar Concha Rdz

Configuración Compare (Variable Duty Cycle) Interrupción


#include <xc.h>

void interrupt high_priority ISR ()


{
if (PIR1bits.CCP1IF == 1) //A TMR1 register compare match ocurred
{
if (CCP1CON == 8)
{
CCP1CON = 9; //CCP1 pin high
//CCPR1 = 0x2710 = 5ms
CCPR1H = 0x27;
CCPR1L = 0x10;
}
else
{
CCP1CON = 8; //CCP1 pin low
//CCPR1 = 0x7530 = 15ms
CCPR1H = 0x75;
CCPR1L = 0x30;
}
}
TMR1H = 0;
TMR1L = 0;
PIR1bits.CCP1IF = 0; //TMR1 cleared in software
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency select bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
Ing. Oscar Concha Rdz

TRISCbits.RC2 = 0; //Pin RC2/CCP1 as an output


PORTCbits.RC2 = 0;

RCONbits.IPEN = 1; //Interrupt priority enable bit (priority levels on interrupts)


INTCONbits.GIEH = 1; //Enables all high priority interrupts
INTCONbits.GIEL = 1; //Enables all low priority interrupts

CCP1CONbits.CCP1M3 = 1; //Initializate CCP1 pin high


CCP1CONbits.CCP1M2 = 0;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 1;

PIE1bits.CCP1IE = 1; //CCP1 interrupt enable bit


IPR1bits.CCP1IP = 1; //CCP1 interrupt priority bit (high priority)
PIR1bits.CCP1IF = 0; //CCP1 interrupt flag bit (No TMR1 register compare match ocurred)

//TCY = 4 / Fosc
//CCPR1 = valor deseado / TCY (valor máximo = 65536)
//CCPR1 = 15ms/0.5us = 30000 = 0x7530 cumple
//CCPR1 = 5ms/0.5us = 10000 = 0x2710 cumple
CCPR1H = 0x27;
CCPR1L = 0x10;

T1CONbits.RD16 = 0; //Mode enable bit (two 8 bit operation)


T1CONbits.T1OSCEN = 1; //TMR1 oscillator enable bit
T1CONbits.T1CKPS1 = 0; //TMR1 prescaler select bits (1:1 prescale value)
T1CONbits.T1CKPS0 = 0;
T1CONbits.TMR1CS = 0; //Internal clock (Fosc/4)
T1CONbits.TMR1ON = 1; //TMR1 on bit

while (1)
{
Ing. Oscar Concha Rdz

}
return;
}
Ing. Oscar Concha Rdz

Configuración Capture Interrupción


#include <xc.h>

int captura = 0;
unsigned int valor1 = 0;
unsigned int valor2 = 0;
unsigned int valor3 = 0;

void interrupt high_priority ISR ()


{
if (PIR1bits.CCP1IF == 1) //TMR1 register capture ocurred
{
captura++;

if (captura == 1)
{
valor1 = CCPR1L + (CCPR1H * 256);
}

if (captura == 2)
{
valor2 = CCPR1L + (CCPR1H * 256);
valor3 = (valor2 - valor1);

PORTD = valor3;

//Tosc = (Fosc/4)^-1 = 0.5us


//periodo = (valor3 * Tosc * prescaler)/#rising edge;
//frecuencia = 1/periodo

captura = 0;
}
}
Ing. Oscar Concha Rdz

CCPR1H = 0;
CCPR1L = 0;
PIR1bits.CCP1IF = 0;
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

TRISCbits.RC2 = 1; //CCP1 input bit

TRISD = 0x00;
PORTD = 0x00;

RCONbits.IPEN = 1; //Interrupt priority enable bit (priority levels on interrupts)


INTCONbits.GIEH = 1; //Enables all high priority interrupts
INTCONbits.GIEL = 1; //Enables all low priority interrupts

PIE1bits.CCP1IE = 1; //Enables the CCP1 interrupt


IPR1bits.CCP1IP = 1; //CCP1 interrupt priority bit (high priority)
PIR1bits.CCP1IF = 0; //A TMR1 register captured didn't ocurr

//TMR1
T1CONbits.RD16 = 1; //Mode enable bit (one 16 bit operation)
T1CONbits.T1OSCEN = 0; //TMR1 oscillator enable bit
T1CONbits.T1CKPS1 = 0; //TMR1 prescaler select bits (1:2 prescale value)
T1CONbits.T1CKPS0 = 1;
T1CONbits.TMR1CS = 0; //Internal clock (Fosc/4)

TMR1H = 0;
TMR1L = 0;
Ing. Oscar Concha Rdz

CCP1CONbits.CCP1M3 = 0; //Capture mode, every 4th rising edge


CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 1;
CCP1CONbits.CCP1M0 = 0;

T3CONbits.T3CCP2 = 0; //TMR1 is the capture clock source for CCP1


T3CONbits.T3CCP1 = 1;

T1CONbits.TMR1ON = 1; //TMR1 on bit

while (1)
{

}
return;
}
Ing. Oscar Concha Rdz

Configuración EUSART Interrupción


#include <xc.h>

char dato;

void interrupt high_priority ISR ()


{
if (PIR1bits.RCIF == 1) //RCREG is full
{
dato = RCREG; //The received data is sent to character
while (!TXSTAbits.TRMT) continue; //Waiting for a whole data frame to be ready for a transmission
TXREG = dato + 1; //Write charater to TXREG and start transmission
}
PIR1bits.RCIF = 0; //USART receive buffer cleared in software
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

TRISCbits.TRISC6 = 1; //TX pin is input


TRISCbits.TRISC7 = 1; //RX pin is input

TXSTAbits.TXEN = 1; //Transmit enable bit


RCSTAbits.CREN = 1; //Continous receive enable bit
TXSTAbits.SYNC = 0; //EUSART mode select bit (asynchronoous mode)
BAUDCONbits.BRG16 = 0; //16-bit baud rate register enable bit
TXSTAbits.BRGH = 1; //High baud rate select bit (high speed)
RCSTAbits.SPEN = 1; //Serial port enable bit

SPBRG = 8; //SPBRG = Fosc/[16(n+1)] ((Table 20.3)


Ing. Oscar Concha Rdz

PIE1bits.RCIE = 1; //EUSART receive interrrupt enable bit


IPR1bits.RCIP = 1; //EUSART receive interrupt priority bit (high priority)
PIR1bits.RCIF = 0; //EUSART receive interrupt flag bit (buffer is empty)

RCONbits.IPEN = 1; //Interrupt priority enable bit (priority levels on interrupts)


INTCONbits.GIEH = 1; //Enables all high priority interrupts
INTCONbits.GIEL = 1; //Enables all low priority interrupts

while (1)
{

}
return;
}
Ing. Oscar Concha Rdz

Configuración SPI MAESTRO

#include <xc.h>

int datout; // Master prepares to send data/character/number


int dato; // Master sends information to slave
int recibidos; //Master recives information from slave
int dat; //Master shows information on display

void interrupt high_priority ISR ()


{
if (INTCONbits.RBIF == 1) //At least of the RB7:RB4 pins changed state
{
if (PORTBbits.RB4 == 1)
{
datout = datout + 1;

if(datout <= 8)
{
dato = datout; // datout = 0, 1, 2, 3, 4, 5, 6, 7, 8
PORTAbits.RA5 = 0; // Pull SS low to select slave
SSPBUF = dato; // Write charater to SSPBUF and start transmission
while (!SSPSTATbits.BF); // Waiting for a whole data frame to be ready for a transmission
PORTAbits.RA5 = 1; // Pull SS hgh to terminate transfer
recibidos = SSPBUF; //The received data from slave is sent to SSPBUF
dat = recibidos; //Master recives information from slave
}

if (datout >= 9)
{
datout = 0; // datout = 0;
dato = datout;
PORTAbits.RA5 = 0;
Ing. Oscar Concha Rdz

SSPBUF = dato;
while (!SSPSTATbits.BF);
PORTAbits.RA5 = 1;
recibidos = SSPBUF;
dat = recibidos;
}

switch (dat) //Master shows information on PORTD


{
case 0:
PORTD = 0;
break;
case 1:
PORTD = 1;
break;
case 2:
PORTD = 2;
break;
case 3:
PORTD = 3;
break;
case 4:
PORTD = 4;
break;
case 5:
PORTD = 5;
break;
case 6:
PORTD = 6;
break;
case 7:
PORTD = 7;
break;
Ing. Oscar Concha Rdz

case 8:
PORTD = 8;
break;
}
}
}
INTCONbits.RBIF = 0; //RBIF register cleared in software
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

ADCON1 = 0x0F; //Digital I/O (AN12 to AN0)

TRISBbits.RB4 = 1; //Push botom in pin RB4 (input)


PORTBbits.RB4 = 0;

INTCONbits.GIEH = 1; //Enables all high priority interrupts


INTCONbits.GIEL = 1; //Enables all low priority interrupts

INTCONbits.RBIE = 1; //Enables the RB port change interrupt


INTCON2bits.RBIP = 1; //RB port change interrupt high priority bit
INTCONbits.RBIF = 0; //None of the RB7:RB4 pins have changed state

TRISBbits.RB0 = 1; //SDI serial data in


TRISBbits.RB1 = 0; //SCK serial clock
TRISCbits.RC7 = 0; //SDO serial data out
TRISAbits.RA5 = 0; //SS slave select

TRISD = 0x00; //Port D as output


Ing. Oscar Concha Rdz

PORTD = 0x00;

SSPSTATbits.SMP = 0; //Input data sampled at middle of data output time


SSPSTATbits.CKE = 0; //Transmit occurs on transition from idle to active clock state

SSPCON1 = 0x00; //SPI master mode, clk = Fosc/4


SSPCON1bits.CKP = 1; //Idle state for clock is a high level
SSPCON1bits.SSPEN = 1; //Enables serial port SDI, SDO, SCK, SS

while (1)
{

}
return;
}
Ing. Oscar Concha Rdz

Configuración SPI ESCLAVO


#include <xc.h>

int recibidos;
int datout;
int dat;
int dato;

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

ADCON1 = 0x0F; //Digital I/O (AN12 to AN0)

TRISBbits.RB0 = 1; //SDI serial data in


TRISBbits.RB1 = 1; //SCK serial clock
TRISCbits.RC7 = 0; //SDO serial data out
TRISAbits.RA5 = 1; //SS select slave

TRISD = 0x00; //Port D as output


PORTD = 0x00;

SSPSTATbits.SMP = 0; //Input data sampled at middle of data output time


SSPSTATbits.CKE = 0; //Transmit occurs on transition from idle to active clock state

SSPCON1 = 0x04; //SPI slave mode, clk = SCK pin, SS pin control enabled
SSPCON1bits.CKP = 1; //Idle state for clock is a high level
SSPCON1bits.SSPEN = 1; //Enables serial port SDI, SDO, SCK, SS

while (1)
{
Ing. Oscar Concha Rdz

recibidos = SSPBUF; //The received data from master is sent to SSPBUF

switch (recibidos) //Slave sends information to master


{
case 0: //If slave recives '0'
datout = 1; //The slave sends '1'
break;
case 1:
datout = 2;
break;
case 2:
datout = 3;
break;
case 3:
datout = 4;
break;
case 4:
datout = 5;
break;
case 5:
datout = 6;
break;
case 6:
datout = 7;
break;
case 7:
datout = 8;
break;
case 8:
datout = 0;
break;
}
Ing. Oscar Concha Rdz

dat = recibidos; //Slave recives information from master

switch (dat) //Master shows information on PORTD


{
case 0:
PORTD = 1;
break;
case 1:
PORTD = 2;
break;
case 2:
PORTD = 3;
break;
case 3:
PORTD = 4;
break;
case 4:
PORTD = 5;
break;
case 5:
PORTD = 6;
break;
case 6:
PORTD = 7;
break;
case 7:
PORTD = 8;
break;
case 8:
PORTD = 0;
break;
}
Ing. Oscar Concha Rdz

dato = datout; //datout 1, 2, 3, 4, 5, 6, 7, 8, 0


SSPBUF = dato; // Write charater to SSPBUF and start transmission
while (!SSPSTATbits.BF); // Waiting for a whole data frame to be ready for a transmission
SSPCON1bits.SSPOV = 0; //Recive overflow indicator bit (no overflow)
}
return;
}
Ing. Oscar Concha Rdz

Configuración LCD
HEADER FILE
#ifndef FLEX_LCD_H
#define FLEX_LCD_H

#define LCD_RD7 PORTDbits.RD7 // D7


#define TRISRD7 TRISDbits.TRISD7

#define LCD_RD6 PORTDbits.RD6 // D6


#define TRISRD6 TRISDbits.TRISD6

#define LCD_RD5 PORTDbits.RD5 // D5


#define TRISRD5 TRISDbits.TRISD5

#define LCD_RD4 PORTDbits.RD4 // D4


#define TRISRD4 TRISDbits.TRISD4

#define LCD_EN PORTEbits.RE2 // EN


#define TRISEN TRISEbits.TRISE2

#define LCD_RS PORTEbits.RE1 // RS


#define TRISRS TRISEbits.TRISE1

//comandos disponibles
#define LCD_FIRST_ROW 128
#define LCD_SECOND_ROW 192
#define LCD_THIRD_ROW 148
#define LCD_FOURTH_ROW 212
#define LCD_CLEAR 1
#define LCD_RETURN_HOME 2
#define LCD_CURSOR_OFF 12
#define LCD_UNDERLINE_ON 14
#define LCD_BLINK_CURSOR_ON 15
Ing. Oscar Concha Rdz

#define LCD_MOVE_CURSOR_LEFT 16
#define LCD_MOVE_CURSOR_RIGHT 20
#define LCD_TURN_OFF 0
#define LCD_TURN_ON 8
#define LCD_SHIFT_LEFT 24
#define LCD_SHIFT_RIGHT 28

void Lcd_Init(void);
void Lcd_Out(unsigned char y, unsigned char x, const char *buffer);
void Lcd_Out2(unsigned char y, unsigned char x, char *buffer);
void Lcd_Chr_CP(char data);
void Lcd_Cmd(unsigned char data);

void Lcd_Init(void){
unsigned char data;
TRISRD7 = 0;
TRISRD6 = 0;
TRISRD5 = 0;
TRISRD4 = 0;
TRISEN = 0;
TRISRS = 0;
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 0;
LCD_RD4 = 0;
LCD_EN = 0;
LCD_RS = 0;
__delay_us(5500);
__delay_us(5500);
__delay_us(5500);
__delay_us(5500);
__delay_us(5500);
__delay_us(5500);
Ing. Oscar Concha Rdz

for(data = 1; data < 4; data ++)


{
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 1; LCD_EN = 0;
LCD_RS = 0; LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 1;
LCD_EN = 1; LCD_RS = 0;
__delay_us(5);
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 1; LCD_EN = 0;
LCD_RS = 0;
__delay_us(5500);
}
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 0; LCD_EN = 0; LCD_RS = 0;
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 0; LCD_EN = 1; LCD_RS = 0;
__delay_us(5);
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 0; LCD_EN = 0; LCD_RS = 0;
__delay_us(5500);
data = 40; Lcd_Cmd(data);
data = 16; Lcd_Cmd(data);
data = 1; Lcd_Cmd(data);
data = 15; Lcd_Cmd(data);
}

void Lcd_Out(unsigned char y, unsigned char x, const char *buffer)


{
unsigned char data;
switch (y)
{
case 1: data = 128 + x; break;
case 2: data = 192 + x; break;
case 3: data = 148 + x; break;
case 4: data = 212 + x; break;
default: break;
}
Lcd_Cmd(data);
Ing. Oscar Concha Rdz

while(*buffer) // Write data to LCD up to null


{
Lcd_Chr_CP(*buffer);
buffer++; // Increment buffer
}
return;
}

void Lcd_Out2(unsigned char y, unsigned char x, char *buffer)


{
unsigned char data;
switch (y)
{
case 1: data = 128 + x; break;
case 2: data = 192 + x; break;
case 3: data = 148 + x; break;
case 4: data = 212 + x; break;
default: break;
}
Lcd_Cmd(data);
while(*buffer) // Write data to LCD up to null
{
Lcd_Chr_CP(*buffer);
buffer++; // Increment buffer
}
return;
}

void Lcd_Chr_CP(char data){


LCD_EN = 0; LCD_RS = 1;
LCD_RD7 = (data & 0b10000000)>>7; LCD_RD6 = (data & 0b01000000)>>6;
LCD_RD5 = (data & 0b00100000)>>5; LCD_RD4 = (data & 0b00010000)>>4;
_delay(10);
Ing. Oscar Concha Rdz

LCD_EN = 1; __delay_us(5); LCD_EN = 0;


LCD_RD7 = (data & 0b00001000)>>3; LCD_RD6 = (data & 0b00000100)>>2;
LCD_RD5 = (data & 0b00000010)>>1; LCD_RD4 = (data & 0b00000001);
_delay(10);
LCD_EN = 1; __delay_us(5); LCD_EN = 0;
__delay_us(5); __delay_us(5500);
}

void Lcd_Cmd(unsigned char data){


LCD_EN = 0; LCD_RS = 0;
LCD_RD7 = (data & 0b10000000)>>7; LCD_RD6 = (data & 0b01000000)>>6;
LCD_RD5 = (data & 0b00100000)>>5; LCD_RD4 = (data & 0b00010000)>>4;
_delay(10);
LCD_EN = 1; __delay_us(5); LCD_EN = 0;
LCD_RD7 = (data & 0b00001000)>>3; LCD_RD6 = (data & 0b00000100)>>2;
LCD_RD5 = (data & 0b00000010)>>1; LCD_RD4 = (data & 0b00000001);
_delay(10);
LCD_EN = 1; __delay_us(5); LCD_EN = 0;
__delay_us(5500);//Delay_5us();
}
#endif
Ing. Oscar Concha Rdz

PROGRAMA
#define _XTAL_FREQ 8000000

#include <xc.h>
#include <stdio.h> //Uso de la función sprintf, float %f, int %d, char %s,
#include "flex_lcd.h"

/*Lcd_Init();
Nos permite inicializar la lcd siempre hay que ejecutar esta función antes de comenzar a usar la lcd

* Lcd_Out(y,x,constante);
Con esta escribimos sobre la pantalla en la posición inicial y,x y escribimos una constante.

* Lcd_Out2(y, x, variable);
Con esta función hacemos lo mismo que con la anterior solo que aquí podemos agragar una variable.

* Lcd_Cmd()
Nos permite ejecutar los siguientes comandos;*/

/*LCD_FIRST_ROW //Ubica el cursor en el primer renglón


LCD_SECOND_ROW //Ubica el cursor en el segundo renglón
LCD_THIRD_ROW //Ubica el cursor en el tercer renglón
LCD_FOURTH_ROW //Ubica el cursor en el cuarto renglón
LCD_CLEAR //Limpia la pantalla
LCD_RETURN_HOME //Regreso del cursor al inicio
LCD_CURSOR_OFF //Apaga el cursor
LCD_UNDERLINE_ON //Selección de subrayado
LCD_BLINK_CURSOR_ON //Parpadeo del cursor
LCD_MOVE_CURSOR_LEFT //Cursor se mueve a la izquierda
LCD_MOVE_CURSOR_RIGHT //Cursor se mueve a la derecha
LCD_TURN_OFF //Apaga el lcd
LCD_TURN_ON //Enciende el lcd
LCD_SHIFT_LEFT //Desplazamiento a la izquierda
Ing. Oscar Concha Rdz

LCD_SHIFT_RIGHT //Desplazamiento a la derecha*/

char buffer [16];


int i = 0;

void main(void)
{
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;

ADCON1bits.PCFG3 = 1; //AD port configuration control bits (all digital)


ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 1;

Lcd_Init(); //Inicializamos el lcd


Lcd_Cmd(LCD_CLEAR); //Limpiamos el lcd
Lcd_Cmd(LCD_CURSOR_OFF); //Apagamos el cursor

while (1)
{
for (i == 0; i <= 50; i++)
{
sprintf (buffer,"Cuenta %d",i); //Guardamos en el string Buffer1 la palabra Cuenta espacio y el valor de i
Lcd_Out2 (1, 1, buffer); //Escribimos en el renglon uno espaco 1 la que contiene buffer1
__delay_ms (98); //Esperamos y repetimos
}
i = 0;

Lcd_Out (1,1,"Yo soy: "); //Escribimos en la linea 1 espacio 1 la palabra


Lcd_Out (2,1,"Oscar Concha "); //Escribimos en la linea 2 espacio 1 la palabra
__delay_ms (98);
Ing. Oscar Concha Rdz

Lcd_Cmd (LCD_CLEAR); //Limpiamos el cursor


__delay_ms (98);
}
return;
}
Ing. Oscar Concha Rdz

Control PID Temperatura


#define _XTAL_FREQ 4000000

#include <xc.h>
#include <stdio.h> //Uso de la función sprintf, float %f, int %d, char %s,
#include "flex_lcd.h" //Librería LCD

//Variables PID
unsigned long valor, controlador; //Variables para lectura de ADC y señal de control al módulo CCP
float a,b,c; //Constantes para parámetros de controlador PID
float TEMPERATURA_LIMITE; //Referencia de Temperatura
float rT,eT,iT,dT,yT,uT,iT0,eT0; //Variables del controlador PID
float max,min; //Variables para anti-windup

//Variables LCD
char buffer1 [16];
char buffer2 [16];
float tempera = 0;

void PID ()
{
ADCON0bits.GO = 1; //AD conversion status bit (conversion in progress)
while (ADCON0bits.nDONE == 1) continue; //Wait until conversion is over
valor = (ADRESH << 8) + ADRESL; //Leer ADC de 10bits

yT = (5000.0 * valor) / (1024.0); //Señal de salida y(kT)


rT = TEMPERATURA_LIMITE; //Referencia
eT = rT - yT; //Calcular señal de error e(kT)
iT = b * eT + iT0; //Calcular termino integrativo i(kT)
dT = c * (eT - eT0); //Calcular termino derivativo d(kT)
uT = iT + a * eT + dT; //Calcular señal de control u(kT)

if (uT >= max)


Ing. Oscar Concha Rdz

{
uT = max;
}
else
{
if (uT <= min)
{
uT = min;
}
}

unsigned long uTEntero = (unsigned long) uT; //flotante a entero


controlador = uTEntero;

CCPR1L = controlador;
iT0 = iT;
eT0 = eT;
}

void LCD ()
{
sprintf (buffer1," Setpoint %f ",TEMPERATURA_LIMITE); //Guardamos en el string Buffer1 la palabra Setpoint
y su valor
Lcd_Out2 (1, 0, buffer1); //Escribimos en el renglón uno, columna cero lo que contiene buffer1
tempera = yT/10;
sprintf (buffer2,"Tempera %f",tempera); //Guardamos en el string Buffer2 la palabra Tempera y su valor
Lcd_Out2 (2, 0, buffer2); //Escribimos en el renglón dos, columna 0 lo que contiene buffer2
}

void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency select bits (4MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 0;
Ing. Oscar Concha Rdz

min = 0.0;
max = 1000.0;
iT0 = 0.0;
eT0 = 0.0;
a = 0.1243;
b = 0.0062;
c = 0.6215;
TEMPERATURA_LIMITE = 600.0; //Set-Point r(kT)= 60°C

//PWM
TRISCbits.RC2 = 0; //Pin RC2/CCP1 as an output
PORTCbits.RC2 = 0;
CCP1CONbits.CCP1M3 = 1; //PWM mode
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
PR2 = 0x7C; //1KHz
T2CONbits.T2CKPS1 = 1; //TMR2 clock prescaler select bits (prescaler is 16)
T2CONbits.T2CKPS0 = 0;
T2CONbits.TMR2ON = 1; //TMR2 On bit (TMR2 is on)

//ADC
ADCON2bits.ACQT2 = 1; //Table 2-11
ADCON2bits.ACQT1 = 1;
ADCON2bits.ACQT0 = 0;
ADCON2bits.ADCS2 = 1; //Table 2-11
ADCON2bits.ADCS1 = 0;
ADCON2bits.ADCS0 = 1;
ADCON2bits.ADFM = 1; //AD result format select bit (right justified)
ADCON1bits.PCFG3 = 1; //AD port configuration control bits (AN0 analog)
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
Ing. Oscar Concha Rdz

ADCON1bits.PCFG0 = 0;
ADCON0bits.CHS3 = 0; //Analog channel select bits (AN0)
ADCON0bits.CHS2 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS0 = 0;
ADCON1bits.VCFG1 = 0; //Voltage reference (Vss)
ADCON1bits.VCFG0 = 0; //Voltage reference (Vdd)
ADCON0bits.ADON = 1; //AD on bit

//LCD
Lcd_Init ( ); //Inicializamos el LCD
Lcd_Cmd (LCD_CLEAR); //Limpiamos el LCD
Lcd_Cmd (LCD_CURSOR_OFF); //Apagamos el cursor

while (1)
{
PID ( ); //Llamamos la rutina PID a ejecutar
LCD ( ); //Llamamos la rutina LCD a ejecutar
__delay_ms (100); //Periodo de muestreo T = 0.1 segundos
}
return;
}
Ing. Oscar Concha Rdz
Ing. Oscar Concha Rdz

Referencias:
gabrielcg3023 (2013). “Instalación XC8 y MPLAB X”. MKMEKATRONIKA.
Recuperado el 7 de noviembre de 2016 de https://mkmekatronika.wordpress.com/page/3/

"PIC18F4455 DATASHEET (PDF) - Microchip Technology” (n.f.). Microchip.


Recuperado el 7 de noviembre de 2016 de http://www.alldatasheet.es/datasheet-
pdf/pdf/93910/MICROCHIP/PIC18F4455.html

Você também pode gostar