/* ---------------------------------------------------------------------------
* File: main.c
* Author: Lagruya
* Pic usado 16F88
* Created on 22 de enero de 2013, 11:12
* --------------------------------------------------------------------------*/
#include <xc.h>
#include <stdio.h>
/*-----configuracion de bits de configuracion para el pic 16f88 (fuses)----- */
#pragma config BOREN = OFF, CPD = OFF, CCPMX = RB0, DEBUG = OFF, WRT = OFF, \
FOSC = INTOSCIO, MCLRE = OFF, WDTE = OFF, CP = OFF, LVP = OFF, \
PWRTE = OFF, IESO = ON, FCMEN = ON
/*---------------------------------------------------------------------------*/
/*---definicion para el correcto funcionamiento de la funcion delayms y us---*/
#define _XTAL_FREQ 8000000UL
#pragma intrinsic(_delay)
extern void _delay(unsigned long);
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
/*---------------------------------------------------------------------------*/
/*-----Etiquetas para los puertos del pic segun su coneccion con el LCD------*/
#define LCDBus PORTA
#define LCDenable RA6
#define LCDregisterselect RA7
#define LCDdata4 RA0
#define LCDdata5 RA1
#define LCDdata6 RA2
#define LCDdata7 RA3
#define mascara 0b11110000 // comentar si se usa nibble alto para LCD
//#define mascara 0b00001111 // descomentar si se usa nibble bajo
/*#define mascaraH /* descomentar si se usa el nibble alto del
* puerto para comunicarce con el LCD */
#define mascaraH >> 4 /* comentar si se usa el nibble alto del puerto para
* comunicarce con el LCD */
/*#define mascaraL << 4 /* idem mascaraH */
#define mascaraL /* idem mascaraH */
/*---------------------------------------------------------------------------*/
/*------------------------Etiquetas comandos LCD-----------------------------*/
#define borrapantalla (0b00000001)
#define cursor_home (0b00000010)
#define cursor_der_LCDquieto (0b00000110)
#define LCD_off (0b00001000)
#define LCD_on (0b00001111)
#define cursor_off (0b00001100)
#define cursor_on (0b00001110)
#define cursor_parpadeo_off (0b00001110)
#define cursor_parpadeo_on (0b00001111)
#define _2lineas4bits5x7 (0b00101000)
#define direccionDDRAM_0x08 (0b10001000)
/*---------------------------------------------------------------------------*/
/*------------------------Declaracion de funciones---------------------------*/
void inicializaLCD(void); // funcion para inicializa LCD
void enviacomando(unsigned char); // funcion para enviar comando al LCD
void enviadato(unsigned char); // funcion que enviara los datos al LCD
void imprime_cadena_literal(const unsigned char *); /* funcion para imprimir
* en el LCD una cadena
* literal de caracteres */
void imprime_cadena(unsigned char *); /* funcion para imprimir un dato
* numerico convertido a cadena de
* caracteres */
void conf_oscilador (void); // Configuracion del oscilador
void conf_puertos (void); // Configuracion de puertos I/O
/*---------------------CUERPO PRINCIPAL DEL PROGRAMA-------------------------*/
int main(void) {
conf_oscilador ();
conf_puertos ();
RA4 = 1;
__delay_ms(1000);
RA4 = 0;
inicializaLCD();
LCDregisterselect = 1;
enviadato(0b01000001);
RA4 = 1;
while (1)
{
continue; // bucle infinito, se queda esperando por interrupciones
}
}
/*------------------------------FUNCIONES------------------------------------*/
/* Funcion para la configuracion del oscilador del pic16f88 */
void conf_oscilador (void) {
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1; // IRCF <2:0> = 111 setea Fosc 8MHz
OSCCONbits.SCS1 = 0;
OSCCONbits.SCS0 = 0; /* SCS <1:0> = 00 Modo del oscilador definido por
* FOSC <2:0> en #pragma config FOSC = INTOSCIO */
}
/* Funcion para la configuracion de los puertos entrada salida del pic 16f88 */
void conf_puertos (void) {
ANSEL = 0; // registro ANSEL = 0 no se usan puertos analogicos
TRISA = 0b00100000; /* RA0-4 y RA6-7 como salidas */
TRISB = 0b11111111; // todo el puerto B como entradas
PORTA = 0;
}
void inicializaLCD(void){ // inicializacion de LCD seteo para bus de 4 bits
LCDenable = 0;
LCDregisterselect = 0;
LCDBus &= mascara; // pone a 0 los 4 bits de datos
LCDBus |= (0b00100000 mascaraH); // inicio secuencia de seteo 4bits
LCDenable = 1; // habilita transmision
__delay_us(5);
LCDenable = 0;
enviadato(0b00101000);//envio en 2 partes la confirmacion de comando 4 bits
enviadato(0b00000110); //comando display quieto incrementa cursor
enviadato(0b00001110); //comando LCD on Cursor on
}
void enviacomando(unsigned char comando){
LCDregisterselect = 0;
enviadato(comando);
}
void enviadato(unsigned char datoLCD){
unsigned char nibbleH;
unsigned char nibbleL;
nibbleH = (datoLCD & 0b11110000) mascaraH;
/* se obtiene el nibble alto de datoLCD si se usa el nibble bajo del puerto
* mascaraH "corre" los 4 bits mas significativos al lugar de los menos
* significativos */
nibbleL = (datoLCD & 0b00001111) mascaraL;
/* se obtiene el nibble bajo de datoLCD ...*/
LCDBus &= mascara;
LCDBus |= nibbleH; // se transmite al LCD el nibble alto de datoLCD
LCDenable = 1; // se habilita el LCD para que procese LCDBus
__delay_us(5); // retardo para garantizar pasaje de datos al LCD
LCDenable = 0; // se deshabilita el LCD
LCDBus &= mascara;
LCDBus |= nibbleL; // se transmite al LCD el nibble bajo de datoLCD
LCDenable = 1; // se habilita el LCD para que procese LCDBus
__delay_us(5); // retardo para garantizar pasaje de datos al LCD
LCDenable = 0; // se deshabilita el LCD
if (LCDregisterselect) // retardo segun tarea del LCD
__delay_us(50); // escritura RAM del LCD
else
__delay_ms(2); // comando
}
void imprime_cadena(unsigned char *buffer){ /* *buffer es un puntero que apunta
* a la posicion de memoria donde
* comienza la matriz de caracteres
* o lo que es lo mismo: es el
* nombre de la matriz */
LCDregisterselect = 1; /* se prepara el LCD para escribir en la
* DDRAM */
while(*buffer) /* siempre que *bufer sea un valor verdadero hasta que
* sea NULL (el final de la matriz de caracteres) */
{
enviadato(*buffer); /* se le pasa el char alojado en la
* direccion *bufer a la funcion
* enviadato*/
buffer++; /* se incrementa en 1 la direccion para enviar el
* siguiente caracter de la cadena */
}
}
void imprime_cadena_literal(const unsigned char *buffer){
/* *buffer es un puntero que apunta a la posicion de memoria donde comienza la
* matriz de caracteres o lo que es lo mismo: es el nombre de la matriz, que en
* este caso se pasa como un argumento literal a la funcion */
LCDregisterselect = 1; /* se prepara el LCD para escribir en la
* DDRAM */
while(*buffer) /* siempre que *bufer sea un valor verdadero hasta que
* sea NULL (el final de la matriz de caracteres) */
{
enviadato(*buffer); /* se le pasa el char alojado en la
* direccion *bufer a la funcion
* enviadato*/
buffer++; /* se incrementa en 1 la direccion para enviar el
* siguiente caracter de la cadena */
}
}
/*---------------------------------------------------------------------------*/