Académique Documents
Professionnel Documents
Culture Documents
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
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;
while (1)
{
}
return;
Ing. Oscar Concha Rdz
}
Ing. Oscar Concha Rdz
int msegundo;
int segundo;
void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
TRISD = 0x00;
PORTD = 0x00;
}
return;
}
Ing. Oscar Concha Rdz
int msegundo;
int segundo;
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;
while (1)
{
Ing. Oscar Concha Rdz
}
return;
}
Ing. Oscar Concha Rdz
int ADC = 0;
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;
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;
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
{
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;
while (1)
{
ADCON0bits.CHS3 = 0; //Analog channel select bits (AN0)
ADCON0bits.CHS2 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS0 = 0;
PORTDbits.RD0 = 0;
}
}
return;
}
Ing. Oscar Concha Rdz
void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency select bits (1MHz)
OSCCONbits.IRCF1 = 0;
OSCCONbits.IRCF0 = 0;
CCP1CONbits.DC1B1 = 0;
CCP1CONbits.DC1B0 = 0;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
while (1)
{
CCPR1L = 0x7D;
}
return;
}
Ing. Oscar Concha Rdz
int ADC = 0;
int i = 0;
void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
//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
//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
void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
//TCY = 4 / Fosc
//CCPR1 = valor deseado / TCY (valor máximo = 65536)
//CCPR1 = 4E20 = 10ms/0.5us = 20000 cumple
CCPR1H = 78;
CCPR1L = 32;
while (1)
{
}
return;
}
Ing. Oscar Concha Rdz
Ing. Oscar Concha Rdz
void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency select bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
Ing. Oscar Concha Rdz
//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;
while (1)
{
Ing. Oscar Concha Rdz
}
return;
}
Ing. Oscar Concha Rdz
int captura = 0;
unsigned int valor1 = 0;
unsigned int valor2 = 0;
unsigned int valor3 = 0;
if (captura == 1)
{
valor1 = CCPR1L + (CCPR1H * 256);
}
if (captura == 2)
{
valor2 = CCPR1L + (CCPR1H * 256);
valor3 = (valor2 - valor1);
PORTD = valor3;
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;
TRISD = 0x00;
PORTD = 0x00;
//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
while (1)
{
}
return;
}
Ing. Oscar Concha Rdz
char dato;
void main(void)
{
OSCCONbits.IRCF2 = 1; //Internal oscillator frequency selecct bits (8MHz)
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
while (1)
{
}
return;
}
Ing. Oscar Concha Rdz
#include <xc.h>
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;
}
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;
PORTD = 0x00;
while (1)
{
}
return;
}
Ing. Oscar Concha Rdz
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;
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
Configuración LCD
HEADER FILE
#ifndef FLEX_LCD_H
#define FLEX_LCD_H
//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
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;*/
void main(void)
{
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
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;
#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
{
uT = max;
}
else
{
if (uT <= min)
{
uT = min;
}
}
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/