Está en la página 1de 31

En esta aplicación utilicé los módulos básicos del PIC:

1- Display LCD a 4 bit

2- Conversión AD a 10 bit

3- Timer1, con interrupción

4- Transmisión serial RS-232 a 4800 bps, con interrupción en recepción RX

5- Cominicación I2C, con RTC DS1307

6- Teclado matricial de 4x4

7- Memoria EEPROM interna

Descripción:

1- El PIC realiza un conversión AD tomando la señal por RA0

2- Se toma el valor entero de 0-1023 y se calcula además en porcentaje, ambos valores son convertidos
en cadena y llevados al LCD

3- Esta cadena, resultado AD, es enviada al PC via RS-232

4- El dato recibido del PC, 1 caracter ASCII, es presentado en el LCD y alamacenado en la EEPROM en la
dirección 0.

5- Se lee las variables de tiempo real del DS-1307, se convierten en cadena y se presentan en el lcd,
ejemplo:"12:00:00 01/01/2000"

5- Por medio del teclado, presionando primero la tecla reloj, se habilita la programación de la hora y
fecha, haciendo oscilar el cursor del LCD en la variable correspondiente le llevamos el número deseado
desde el teclado, luego el dato es grabado en el DS-1307.

Siempre he programado en assembler y es obvio que tengo muchos vicios de este lenguaje, pero de
todos modos trataré de resolver cualquier inquietud que este ejercicio les suscite, además recibo
cualquier sugerencia, si se dé el caso, de alguna forma para mejorar un procedimiento.

Lástimosamente el puerto USB, que es mi siguiente paso, no lo domino en absoluto, pero cuando tenga
algo se los compartiré.
Un abrazo a todos los miembros del FORO.

<18F4550.h>

#device adc = 10

#use delay(clock=4000000)

#use i2c(master, sda=PIN_B0, scl=PIN_B1,force_hw)

#use rs232(baud=4800, xmit=PIN_C6,rcv=PIN_C7)

#fuses XT, MCLR, NOWDT

#include <stdlib.h>

//resgistros especiales del PIC

#byte porta = 0xf80

#byte portb = 0xf81

#byte portc = 0xf82

#byte portd = 0xf83

#byte porte = 0xf84

#byte t1con = 0xfcd

#byte latd = 0xf8c

#byte adcon0 = 0xfc2

#byte adcon1 = 0xfc1

#byte adcon2 = 0xfc0

#byte adresl = 0xfc3

#byte adresh = 0xfc4


//etiquetas

#define e porte,0

#define rs porte,1

#define puerto_tec latd

#define tec_c1 portd,4

#define tec_c2 portd,5

#define tec_c3 portd,6

#define tec_c4 portd,7

#define tec_f1 portd,0

#define tec_f2 portd,1

#define tec_f3 portd,2

#define tec_f4 portd,3

//definicion de funciones

void ini_lcd_4b();

void display_4b(short valor , int respaldo);

void msj1();

void teclado();

void msj_analogo();

void msj_ra0();

void conversion_ad();

void msj_analogo1();

void msj_rx();

void msj_datos_rec();
void msj_ds1307();

void leer_ds1307();

void conf_ds1307();

void confi_reloj(int valor);

//variables

char registro_tec;

char datos_rec;

short int ban_tmr1;

short int ban_tec1;

short int ban_tec2;

short int ban_tec3;

short int ban_tec4;

short int ban_tec5;

short int ban_tec6;

short int ban_tec7;

short int ban_tec8;

short int ban_tec9;

short int ban_tec10;

short int ban_tec11;

short int ban_tec12;

short int ban_tec13;

short int ban_tec14;

short int ban_tec15;


short int ban_tec16;

short int ban_reloj;

int dec_hora,uni_hora,dec_minu,uni_minu,dec_seg,uni_seg; //Definicion de


variables

int dia_sem, dec_dia, uni_dia, dec_mes, uni_mes, dec_amo, uni_amo;

int cont_prg_reloj;

char analogo[5];

char ds1307[18]; //= "12:00:00 22/09/75";

int16 resultado_ad;

//definicion de constantes

byte const tabla1[] = {"! Bienvenidos !"}; //Tabla que contiene el texto a mostrar

byte const tabla2[] = {"RA0 = "}; //Tabla que contiene el texto a mostrar

byte const tabla_rx[] = {"RX="}; //Tabla que contiene el texto a mostrar

///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////

#INT_timer1 //Vector de interrupcion por desbordamiento del

//timer 1

void interrupcion_tmr1()

{
set_timer1(3042); //62.500 * 8 (prescaler) = 0,5 seg

ban_tmr1 = 1;

///////////////////////////////////////////////////////////////////////////////

#int_rda //Vector de interrupcion de la recepcion de datos

void interrupcion_rx() //por el usart

datos_rec = getc(); //Se lee el dato recibido

write_eeprom(0,datos_rec);

///////////////////////////////////////////////////////////////////////////////

#zero_ram //Borrado de la memoria ram

#rom 0xf00000 = {"Hola"} //Datos precargados en la rom

//Rutina principal

void main()

//configuracion de puertos y registros especiales

set_tris_b(0b11111111);

set_tris_d(0x0f);

set_tris_e(0);

t1con=(0b00110101); //Configuracion del tmr1

enable_interrupts(global); //Habilitación de todas las interrupciones


enable_interrupts(INT_timer1); //Habilitación de la interrupción del Tmr1

enable_interrupts(int_rda); //Habilitación, recepcion de datos del PC

adcon0 = (0b00000001);

adcon1 = (0b00001110);

adcon2 = (0b10000000);

//configurar el display

delay_ms(2);

ini_lcd_4b();

msj1();

delay_ms(2000);

display_4b(0 , 1); //Limpia el display

delay_ms(2);

portd = 0;

bit_set(porte,7); //habilita pull-up del puerto d ???

registro_tec = '?';

datos_rec = read_eeprom(0); //se lee los datos de la eeprom

memset(analogo,'0',sizeof(analogo)); //se carga la matriz analogo con valores "0"

msj_ra0();

msj_rx();
///////////////////////////////////////

while(true)

delay_ms(10);

teclado();

if(ban_tmr1 == 1)

if(ban_reloj == 1) //si esta programando el reloj salta estas rutinas

{goto no_display;}

ban_tmr1 = 0;

conversion_ad();

msj_analogo1();

msj_datos_rec();

leer_ds1307();

msj_ds1307();

no_display:

delay_cycles(1);

///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

//rutina que envia el primer mensaje al lcd

///////////////////////////////////////////////////////////////////////////////

void msj_ds1307()

int i;

sprintf(ds1307,"%u%u:%u%u:%u%u %u%u/%u%u/%u%u",dec_hora, uni_hora, dec_minu,


uni_minu, dec_seg, uni_seg, dec_dia, uni_dia, dec_mes, uni_mes, dec_amo, uni_amo);

display_4b(0 , 0x94); //Dirección donde se escribirá el mensaje

for(i=0;i<sizeof(ds1307)-1;i++) //Ciclo que envía el texto al LCD

display_4b(1 , ds1307[i]);

///////////////////////////////////////////////////////////////////////////////

void msj_rx()

int i;

display_4b(0 , 0x90); //Dirección donde se escribirá el mensaje

for(i=0;i<sizeof(tabla_rx)-1;i++) //Ciclo que envía el texto al LCD

{
display_4b(1 , tabla_rx[i]);

///////////////////////////////////////////////////////////////////////////////

void msj_datos_rec()

display_4b(0 , 0x93); //Dirección donde se escribirá el mensaje

display_4b(1 , datos_rec);

///////////////////////////////////////////////////////////////////////////////

void msj1()

int i;

display_4b(0 , 0x82); //Dirección donde se escribirá el mensaje

for(i=0;i<sizeof(tabla1)-1;i++) //Ciclo que envía el texto al LCD

display_4b(1 , tabla1[i]);

///////////////////////////////////////////////////////////////////////////////

void msj_ra0()

int i;
display_4b(0 , 0x80); //Dirección donde se escribirá el mensaje

for(i=0;i<sizeof(tabla2)-1;i++) //Ciclo que envía el texto al LCD

display_4b(1 , tabla2[i]);

///////////////////////////////////////////////////////////////////////////////

void msj_analogo1() //"RA0 = 0000 000%"

int i;

sprintf(analogo,"%04lu",resultado_ad);

printf("RA0 = %s - ",analogo); //datos ap PC, no envia retorno de carro

display_4b(0 , 0x86); //Dirección donde se escribirá el mensaje

for(i=0;i<sizeof(analogo)-1;i++) //Ciclo que envía el texto al LCD

display_4b(1 , analogo[i]);

///////////////////////////////////

i = ((int32)resultado_ad * 100) / 1024; //se calcula porcentaje

sprintf(analogo,"%03u%%",i);

puts(analogo); //datos al PC, se envia retorno de carro


display_4b(0 , 0x8b); //Dirección donde se escribirá el mensaje

for(i=0;i<sizeof(analogo)-1;i++) //Ciclo que envía el texto al LCD

display_4b(1 , analogo[i]);

///////////////////////////////////////////////////////////////////////////////

//rutina de inicializacion del lcd

void ini_lcd_4b()

display_4b(0 , 0b00111000); //Codigo para display a 4 bits

display_4b(0 , 0b00001100); //Codigo que activa el display

display_4b(0 , 0b00000110); //Que se desplace hacia la derecha

//display_4b(0 , 0b00000111)//Codigo que define el cursor para

//que desplace hacia la izquierda

//todo el mensaje

display_4b(0 , 1); //Limpia el display

delay_ms(2);

///////////////////////////////////////////////////////////////////////////////

void display_4b(short valor , int respaldo) //Rutina que envia al LCD una palabra de control o
dirección

int respaldo2;
if(valor == 0)

{bit_clear(rs);}

else

{bit_set(rs);}

portd &= 0x0f;

respaldo2 = respaldo & 0xf0 ;

portd |= respaldo2;

bit_set(e);

delay_cycles(10);

bit_clear(e);

portd &= 0x0f;

respaldo2 = swap(respaldo) & 0xf0 ;

portd |= respaldo2;

bit_set(e);

delay_cycles(10);

bit_clear(e);

delay_ms(1);

///////////////////////////////////////////////////////////////////////////////

void conversion_ad() //rutina de conversión AD


{

set_adc_channel(0);

delay_us(10);

resultado_ad = read_adc();

///////////////////////////////////////////////////////////////////////////////

void teclado() //Rutina general de teclado

puerto_tec=(0xf0);

bit_clear(tec_c1);

delay_us(100);

if((bit_test(tec_f1)==0)&&(ban_tec1==0)) //tecla que programa el reloj

int respaldo;

ban_tec1 = 1;

registro_tec = 'A';

cont_prg_reloj++;

respaldo = portd;

switch(cont_prg_reloj)

case 1:

ban_reloj = 1;
display_4b(0, 0x94);

display_4b(0 , 0b00001101); //Codigo que hace oscilar el


cursor

break;

case 2:

display_4b(0, 0x95);

break;

case 3:

display_4b(0, 0x97);

break;

case 4:

display_4b(0, 0x98);

break;

case 5:

display_4b(0, 0x9a);

break;

case 6:

display_4b(0, 0x9b);

break;

case 7:
display_4b(0, 0x9d);

break;

case 8:

display_4b(0, 0x9e);

break;

case 9:

display_4b(0, 0xa0);

break;

case 10:

display_4b(0, 0xa1);

break;

case 11:

display_4b(0, 0xa3);

break;

case 12:

display_4b(0, 0xa4);

break;

case 13:

ban_reloj = 0;
cont_prg_reloj = 0;

display_4b(0 , 0b00001100); //Codigo para que no oscile el


cursor

conf_ds1307();

default:

portd = respaldo;

if((bit_test(tec_f1)==1)&&(ban_tec1==1)) //tecla soltada

ban_tec1 = 0;

if((bit_test(tec_f2)==0)&&(ban_tec2==0)) //tecla presionada

ban_tec2 = 1;

registro_tec = '3';

confi_reloj(3);

if((bit_test(tec_f2)==1)&&(ban_tec2==1)) //tecla soltada

ban_tec2 = 0;

}
if((bit_test(tec_f3)==0)&&(ban_tec3==0)) //tecla presionada

ban_tec3 = 1;

registro_tec = '2';

confi_reloj(2);

if((bit_test(tec_f3)==1)&&(ban_tec3==1)) //tecla soltada

ban_tec3 = 0;

if((bit_test(tec_f4)==0)&&(ban_tec4==0)) //tecla presionada

ban_tec4 = 1;

registro_tec = '1';

confi_reloj(1);

if((bit_test(tec_f4)==1)&&(ban_tec4==1)) //tecla soltada

ban_tec4 = 0;

bit_set(tec_c1);
///////////////////////////////////

bit_clear(tec_c2);

delay_us(100);

if((bit_test(tec_f1)==0)&&(ban_tec5==0)) //tecla presionada

ban_tec5 = 1;

registro_tec = 'D';

if((bit_test(tec_f1)==1)&&(ban_tec5==1)) //tecla soltada

ban_tec5 = 0;

if((bit_test(tec_f2)==0)&&(ban_tec6==0)) //tecla presionada

ban_tec6 = 1;

registro_tec = '6';

confi_reloj(6);

if((bit_test(tec_f2)==1)&&(ban_tec6==1)) //tecla soltada

ban_tec6 = 0;

}
if((bit_test(tec_f3)==0)&&(ban_tec7==0)) //tecla presionada

ban_tec7 = 1;

registro_tec = '5';

confi_reloj(5);

if((bit_test(tec_f3)==1)&&(ban_tec7==1)) //tecla soltada

ban_tec7 = 0;

if((bit_test(tec_f4)==0)&&(ban_tec8==0)) //tecla presionada

ban_tec8 = 1;

registro_tec = '4';

confi_reloj(4);

if((bit_test(tec_f4)==1)&&(ban_tec8==1)) //tecla soltada

ban_tec8 = 0;

}
bit_set(tec_c2);

///////////////////////////////////

bit_clear(tec_c3);

delay_us(100);

if((bit_test(tec_f1)==0)&&(ban_tec9==0)) //tecla presionada

ban_tec9 = 1;

registro_tec = 'I';

if((bit_test(tec_f1)==1)&&(ban_tec9==1)) //tecla soltada

ban_tec9 = 0;

if((bit_test(tec_f2)==0)&&(ban_tec10==0)) //tecla presionada

ban_tec10 = 1;

registro_tec = '9';

confi_reloj(9);

if((bit_test(tec_f2)==1)&&(ban_tec10==1)) //tecla soltada

ban_tec10 = 0;
}

if((bit_test(tec_f3)==0)&&(ban_tec11==0)) //tecla presionada

ban_tec11 = 1;

registro_tec = '8';

confi_reloj(8);

if((bit_test(tec_f3)==1)&&(ban_tec11==1)) //tecla soltada

ban_tec11 = 0;

if((bit_test(tec_f4)==0)&&(ban_tec12==0)) //tecla presionada

ban_tec12 = 1;

registro_tec = '7';

confi_reloj(7);

if((bit_test(tec_f4)==1)&&(ban_tec12==1)) //tecla soltada

ban_tec12 = 0;

}
bit_set(tec_c3);

///////////////////////////////////

bit_clear(tec_c4);

delay_us(100);

if((bit_test(tec_f1)==0)&&(ban_tec13==0)) //tecla presionada

ban_tec13 = 1;

registro_tec = 'B';

if((bit_test(tec_f1)==1)&&(ban_tec13==1)) //tecla soltada

ban_tec13 = 0;

if((bit_test(tec_f2)==0)&&(ban_tec14==0)) //tecla presionada

ban_tec14 = 1;

registro_tec = 'E';

if((bit_test(tec_f2)==1)&&(ban_tec14==1)) //tecla soltada

ban_tec14 = 0;
}

if((bit_test(tec_f3)==0)&&(ban_tec15==0)) //tecla presionada

ban_tec15 = 1;

registro_tec = '0';

confi_reloj(0);

if((bit_test(tec_f3)==1)&&(ban_tec15==1)) //tecla soltada

ban_tec15 = 0;

if((bit_test(tec_f4)==0)&&(ban_tec16==0)) //tecla presionada

int respaldo;

respaldo = portd;

ban_tec16 = 1;

registro_tec = 'S';

ban_reloj = 0;

cont_prg_reloj = 0;
display_4b(0 , 0b00001100); //Codigo para que no oscile el cursor

portd = respaldo;

if((bit_test(tec_f4)==1)&&(ban_tec16==1)) //tecla soltada

ban_tec16 = 0;

bit_set(tec_c4);

///////////////////////////////////////////////////////////////////////////////

void confi_reloj(int valor) //rutina que carga en las variables de reloj el numero presionado

int respaldo;

respaldo = portd;

switch(cont_prg_reloj)

case 1:

dec_hora = valor;

display_4b(1, dec_hora + 0x30);

display_4b(0, 0x94);

break;

case 2:

uni_hora = valor;

display_4b(1, uni_hora + 0x30);


display_4b(0, 0x95);

break;

case 3:

dec_minu = valor;

display_4b(1, dec_minu + 0x30);

display_4b(0, 0x97);

break;

case 4:

uni_minu = valor;

display_4b(1, uni_minu + 0x30);

display_4b(0, 0x98);

break;

case 5:

dec_seg = valor;

display_4b(1, dec_seg + 0x30);

display_4b(0, 0x9a);

break;

case 6:

uni_seg = valor;

display_4b(1, uni_seg + 0x30);

display_4b(0, 0x9b);

break;

case 7:

dec_dia = valor;

display_4b(1, dec_dia + 0x30);


display_4b(0, 0x9d);

break;

case 8:

uni_dia = valor;

display_4b(1, uni_dia + 0x30);

display_4b(0, 0x9e);

break;

case 9:

dec_mes = valor;

display_4b(1, dec_mes + 0x30);

display_4b(0, 0xa0);

break;

case 10:

uni_mes = valor;

display_4b(1, uni_mes + 0x30);

display_4b(0, 0xa1);

break;

case 11:

dec_amo = valor;

display_4b(1, dec_amo + 0x30);

display_4b(0, 0xa3);

break;

case 12:

uni_amo = valor;

display_4b(1, uni_amo + 0x30);


display_4b(0, 0xa4);

break;

default:

portd = respaldo;

///////////////////////////////////////////////////////////////////////////////

void leer_ds1307()

int respaldo;

i2c_start(); //Start

i2c_write(0b11010000); //Control

i2c_write(0b00000000); //Direccion

i2c_stop(); //Stop

i2c_start(); //Start

i2c_write(0b11010001); //Control para lectura

respaldo = i2c_read(); //Se lee los segundos

uni_seg = respaldo;

dec_seg = swap(respaldo);

uni_seg &= 0x0f;

dec_seg &= 0x0f;


respaldo = i2c_read(); //Se lee los minutos

uni_minu = respaldo;

dec_minu = swap(respaldo);

uni_minu &= 0x0f;

dec_minu &= 0x0f;

respaldo = i2c_read(); //Se lee las horas

uni_hora = respaldo;

dec_hora = swap(respaldo);

uni_hora &= 0x0f;

dec_hora &= 0x0f;

respaldo = i2c_read(); //Se lee el dia de la semana

dia_sem = respaldo;

respaldo = i2c_read(); //Se lee el dia del mes

uni_dia = respaldo;

dec_dia = swap(respaldo);

uni_dia &= 0x0f;

dec_dia &= 0x0f;

respaldo = i2c_read(); //Se lee el mes

uni_mes = respaldo;

dec_mes = swap(respaldo);

uni_mes &= 0x0f;


dec_mes &= 0x0f;

respaldo = i2c_read(); //Se lee los años

uni_amo = respaldo;

dec_amo = swap(respaldo);

uni_amo &= 0x0f;

dec_amo &= 0x0f;

respaldo = i2c_read();

i2c_stop(); //Stop

///////////////////////////////////////////////////////////////////////////////

void conf_ds1307()

int respaldo;

i2c_start(); //Start

i2c_write(0b11010000); //Control

i2c_write(0b00000000); //Direccion

respaldo = (uni_seg | (swap(dec_seg))); //Se escriben los segundos

i2c_write(respaldo);

respaldo = (uni_minu | (swap(dec_minu))); //Se escriben los minutos


i2c_write(respaldo);

respaldo = (uni_hora | (swap(dec_hora))); //Se escriben las horas

i2c_write(respaldo);

i2c_write(dia_sem);

respaldo = (uni_dia | (swap(dec_dia))); //Se escriben los dias del mes

i2c_write(respaldo);

respaldo = (uni_mes | (swap(dec_mes))); //Se escribe el mes

i2c_write(respaldo);

respaldo = (uni_amo | (swap(dec_amo))); //Se escribe el año

i2c_write(respaldo);

i2c_write(0); //Control de pulsos

i2c_stop(); //Stop

También podría gustarte