You are on page 1of 14

#include <16F877a.

h>
///
libreria para el manejo del pic16f877a
#use delay(clock=4000000)
///
declara la frecuencia del
cristal
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#byte
#byte
#byte
#byte
#byte
#byte
#byte
#byte
#byte

porta = 5 // declaramos los puertos a usar


portb = 6
portc = 7
portd = 8
porte = 9
tmr0 = 1
status = 3
option_reg = 81
intcon = 0x000B

char Dec2Bcd (char decimalByte)


{
return (((decimalByte / 10) << 4) | (decimalByte % 10));
}

char minutos=0,horas=1,am=1,pm=0, minutosBCD, unidades, decenas=1,


horasBCD, aux1=0;
//Funcin para transformar de binario(decimal) a 7 segmentos:
char Bin2_7seg(char digit){
switch (digit){
case 0: return 0x3F; //0x3F es el cdigo 7-segmentos del 0.
case 1: return 0x06; //0x06 es el cdigo 7-segmentos del 1.
case 2: return 0x5B;
case 3: return 0x4F;
case 4: return 0x66;
case 5: return 0x6D;
case 6: return 0x7D;
case 7: return 0x07;
case 8: return 0x7F;
case 9: return 0x67;
}
}

void SUMAR(){

if(minutos<59){
minutos++;}
if(minutos>59)
{minutos==0;
horas++;
}
if(horas>12)
{horas==0;
if(am=1){
am==0;
pm==1;
if(pm=1)
{am==1;
pm==0;}
}
}
}

void t5ms()
{
tmr0==(236);
while(tmr0<254)
{tmr0++;
}
}

void MinutosU()
{
//Transformar los minutos para su presentacin: Unidad
minutosBCD=Dec2Bcd(minutos);
//Transforma de binario a BCD.
unidades=0b1111&minutosBCD;
//Sacar las unidades.
decenas=0b11110000&minutosBCD;
//Sacar las decenas.
decenas=decenas>>4;
//Desplazar 4 bits a la
derecha.
PORTD=Bin2_7seg(unidades);
//Unidades al puerto D.
}
void MinutosD()\
{
//Transformar los minutos para su presentacin:
minutosBCD=Dec2Bcd(minutos);
//Transforma de binario a BCD.

unidades=0b1111&minutosBCD;
decenas=0b11110000&minutosBCD;
decenas=decenas>>4;
derecha.
PORTD=Bin2_7seg(decenas);
}

//Sacar las unidades.


//Sacar las decenas.
//Desplazar 4 bits a la
//Decenas al puerto D.

void HoraU()
{
//Transformar las horas para su presentacin:
horasBCD=Dec2Bcd(horas);
//Transforma de binario a BCD.
unidades=0b1111&horasBCD;
//Sacar las unidades.
decenas=0b11110000&horasBCD;
//Sacar las decenas.
decenas=decenas>>4;
//Desplazar 4 bits a la
derecha.
PORTD=Bin2_7seg(unidades);
//Unidades al puerto D.
}
Void HoraD()
{
//Transformar las horas para su presentacin:
horasBCD=Dec2Bcd(horas);
//Transforma de binario a BCD.
unidades=0b1111&horasBCD;
//Sacar las unidades.
decenas=0b11110000&horasBCD;
//Sacar las decenas.
decenas=decenas>>4;
//Desplazar 4 bits a la
derecha.
if (decenas==1)
PORTD=Bin2_7seg(decenas);
//Decenas al puerto D.
if (decenas==2)
PORTD=0x3B;
//Formar el nmero "2".
if (decenas==0) PORTA=0;
//Apagar las decenas cuando
valgan cero.
}

void TIME1()
{
while(aux1<49)
{
aux1++;
}
aux1==0;

void PRE(){

void BARRIDO()
{
PIN_E0==(1); // Seleccionamos el
PIN_E1==(0); // Minutos > Decena
PIN_E2==(0); // Hora > Unidad
PIN_A3==(0); // Hora > Decena
MinutosU();
t5ms();
PIN_E0==(0); // Seleccionamos el
PIN_E1==(1); // Minutos > Decena
PIN_E2==(0); // Hora > Unidad
PIN_A3==(0); // Hora > Decena
MinutosD();
t5ms();
PIN_E0==(0); // Seleccionamos el
PIN_E1==(0); // Minutos > Decena
PIN_E2==(1); // Hora > Unidad
PIN_A3==(0); // Hora > Decena
HoraU();
t5ms();
PIN_E0==(0); // Seleccionamos el
PIN_E1==(0); // Minutos > Decena
PIN_E2==(1); // Hora > Unidad
PIN_A3==(0); // Hora > Decena
HoraD();
t5ms();
}

display // Minutos > Unidad

display // Minutos > Unidad

display // Minutos > Unidad

display // Minutos > Unidad

void main ()
{
// Los transistores estan en el puerto E y el que falta en RA3
setup_adc_ports(NO_ANALOGS);
set_tris_a(0b00100011); // RA0: Inicio o parado del reloj. RA1:
Reseteo. Alarma. RA5: 2 Puntos a 1Hz
set_tris_b(0b00000001); // RB0 boton para configurar y activar alarma
set_tris_c(0b11111111); // teclado matricial
set_tris_d(0b00000000); // horas/minutos
set_tris_e(0b000);
OPTION_REG=0b01010111;
//Pull ups habilitados.Timer0 como
temporizador. //Prescaler asignado al Timer0. Prescaler 1:256.
INTCON=0b10010000;

while(true){
PIN_A5==(1);
TIME1();
PIN_A5==(0);
if(bit_test(porta,0))
{
SUMAR();
}
if(bit_test(porta,1))
{
minutos==0;
horas==1;
unidades==0;
decenas==1;
}
}
}

(1/2) > >>


micro_carp:
Hola a todos!!!
Hace unos meses que retom el tema de los Pics. Desde hace muchos aos
que no haca nada respecto a esto, pero ahora estoy volviendo por los viejos
caminos, porque esto es fascinante y adems creo que tiene mucho
potencial!!! Antes el C no era tan difundido como ahora para aplicaciones
con Microcontroladores es mucho ms potente que el asembler. Soy nuevo
en el foro, as que espero el apoyo de todo visitante a este post, tampoco soy
un experto en programacin, pero all vamos...
Estaba pensando hacer una aplicacin prctica simple con el fin de poder
poner en marcha lo poco que puedo aprender durante mi tiempo libre, as que
es una buena prctica (para m) publicar mis avances, as puedo recibir crticas
que mejoren mi tcnica!!!
Vamos con lo principal:
Mi proyectito lo he llamado: Aplicacin prctica de un Temporizador
programable
Quera hacer una pequea aplicacin para una maquina, yo pensaba en usarlo
para una insoladora aunque podra ser usado para cualquier cosa donde uno
desee ingresar un tiempo por medio de unas teclas y luego presionado
arranque debe empezar a funcionar, pero en realidad esto tiene varias
funciones y tambin varias teclas que detallar mas adelante.
Por ahora les doy a conocer algunas de mis planteamientos. He pensado en
que mi aplicacin debe tener las siguientes funciones:
o Ingreso del tiempo de insolacin
o Medidor del valor instantneo de temperatura.
o Proteccin por sobre temperatura del motor y de la maquina insoladora
o Reloj en tiempo real
o Horas de funcionamiento de las lmparas UV.
o Apagado de la luz UV al aperturar la puerta de la insoladora
Quiz pueda parecer complicado para alguien que apenas empieza a manejar
el C Pero es un reto hacerlo posible, y aqu podrn seguir mis avances quiz
en cmara lenta por que este desarrollo lo har en mi tiempo libre, pero esto

me pone en el reto de hacerlo lo mejor posible y en el menor tiempo que


pueda.
Por mi trabajo quiz pace algn tiempo antes de poder responder los mensaje
que puedan haber, pero har lo posible por tenerles algn avance cuando este
cerca a una conexin a internet.
En el prximo post les doy ms detalles de mi proyectito, por ahora les
adelanto que quiero trabajar con el PIC16F877 compilo con MikroC.
Hasta el prximo post!!!
micro_carp:
Un esquema inicial con el cual quiero empezar es el que inserto a
continuacin. Como vern, quiero que mi aplicacin lleve 4 display de 7
segmentos. Como les deca mi aplicacin no es algo de expertos y solo quiero
poner en prctica lo que aprendo da a da, y lo ms bsico y econmico es
trabajar con display de segmentos y pulsadores.
- El PUERTO A manejar los 4 displays,
- El PUERTO D enva los datos a los displays
- El PUERTO B maneja los pulsadores
- El resto de pines disponibles sern utilizados mas adelante.
No se como hacer para que la imagen pueda ser colocada aqui mismo, asi que
mejor lo adjunto, si alguien sabe com pegar la imagen en el mensaje me indica
como hacerlo, por que no encuentro la manera de hacerlo.
Hasta la proxima...
micro_carp:
Una de las cosas en las que he estado haciendo pruebas es como mostrar los
datos en los displays de 7 segmentos. El programa que controlara todo
debera ser definido desde un inicio, por lo menos debera tener una secuencia
ya definida, seguro que un programador experto hara un diagrama de flujo
antes de empezar.
En realidad yo no tengo diagrama de flujo, pero tengo una idea de la
secuencia que quiero que el programa realice. Eso lo publicar en su
momento.
Por ahora a mi me preocupa crear la parte del programa que deba mostrar en
pantalla los datos. As que me centrar en este punto Mostrar en pantalla

los datos que yo deseo.


Para que esto sea ordenado, en mi prximo post, vemos eso
micro_carp:
Como comentaba anteriormente, una parte del programa que debo realizar y
en la que me ocupar ahora es en mostrar los datos en los display. Tenemos 3
tipos de informacin que deben aparecer en la pantalla y son:
- Los minutos y segundos.
- La hora actual.
- Valores de configuracin.
Como sabemos, tenemos 4 displays de 7 segmentos, el formato sera as:
88.88
Es decir MM.SS, estos mismos displays nos deben servir para mostrar otros
datos por ejemplo, si yo quiero mostrar un cdigo de error o alarma, estos
mismos displays deben usarse. Digamos por ejemplo que el usuario apertura
la tapa del equipo y entonces quiero mostrar un cdigo de error, entonces debo
mostrar cdigos como er.01
Entonces, esta parte del programa debe mostrar los valores que se guardan en
los registros tanto para la hora y minutos como para otros parmetros
diversos.
Yo pienso que los dos primeros digititos deben mostrar los valores de algn
registro y los otros dos deben mostrar los valores de otro registro. As por
ejemplo, mi temporizador tendr un registro para contar los segundos y otro
registro para contar los minutos, debo hacer que el programa decodifique el
valor de estos registros y los muestre en la pantalla. El mismo trato tiene el
registro de alarmas y errores incluso los registros donde actualizar los datos
para el reloj.
Olvid decirles que pienso usar un reloj en tiempo real, pero como no se como
hacer esa parte, lo estoy dejando para ms adelante. Me ocupar mas delante
de este punto, por ahora la prioridad es el uso de los displays.
En el prximo post publico el programa que hace el barrido delos 4 displays y
toma el dato de un registro y lo decodifica de tal manera que lo separa en dos
registros y agrega el punto decimal. No se lo pierdan que esta interesante y

necesito sus apreciaciones.


Por ahora paro la mano y me voy a hacer un poco de ejercicio fsico para
despejar la mente y concentrarme en mi proyectito!!!
micro_carp:
Como les deca, lo primero que quiero hacer es la parte del programa que
permita mostrar en pantalla el valor de los registros, aqui esta el codigo inicial
que hace esto.
Explico luego:
-----------------------------------------------------------------------------------------------------------------------------------------//*****DECLARACION DE LAS FUNCIONES
void BIN_7SEG(int f_data1bin,int f_data2bin);//Usado en la conversion de
datos a
//valor de 7segmentos. Ingresas dos registros por ejemplo el de los segundos y
//minutos y entrega los datos en los registros (displa_1 ... display_4)
int BCD_7SEG(int f_digit);//Usado en la conversion de los datos a 7
segmentos
//Convierte valor BCD a 7 segmentos, cada registro es convertido a BCD y
guardado
//en dos registros.
void DISPLAY(int f_data,int f_port);//Usado cuando se hace el barrido en
cada
//interrupcion. Permite activar el bit del puerto que habilita el display asi
//mismo saca el dato por el puerto del display de 7segmentos
(display_1...display_4)

//*****DECLARACION DE LAS VARIABLES


//*****DECLARACION DE VARIABLES USADAS PARA MOSTRAR
VALOR EN DISPLAYS
unsigned count_1 =0; //Contador 1. Usado para mostrar los datos en displays
unsigned display_data=0; //Usado en "DISPLAY". Contiene valor a mostrar
unsigned display_port=0; //Usado en "DISPLAY". Indica que display mostrar

//*****DECLARACION DE VARIABLES USADAS PARA


CONTABILIZAR SEGUNDOS Y MINUTOS
unsigned count_1sec=0; //Ayuda a temporizar 250 veces 4ms para obtener 1
segundo
unsigned seconds_bin=0;//Cuenta los segundos en binario, de 0 a 59 segundos
unsigned minutes_bin=0;//Cuenta los minutos en binario, de 0 a 59 minutos

//*****DECLARACION DE VARIABLES USADAS PARA LA


CONVERSION DE DATOS A VALORES DE
//7 SEGMENTOS. POR EJEMPLO EL REGISTRO SEGUNDOS ES
CONVERTIDO PRIMERO A DOS
//REGISTROS EN BCD Y LUEGO PASADO A DOS REGISTROS
CODIFICADO PARA 7 SEGMENTOS.
unsigned valor1_bcd=0;//Contiene el valor en BCD de f_data1bin
unsigned data1_7seg=0;//Contiene el primer digito en 7segmentos de
Valor1_bcd
unsigned data2_7seg=0;//Contiene el segundo digito en 7segmentos de
Valor2_bcd
unsigned valor2_bcd=0;//Contiene el valor en BCD de f_data2bin
unsigned data3_7seg=0;//Contiene el primer digito en 7segmentos de
Valor2_bcd
unsigned data4_7seg=0;//Contiene el segundo digito en 7segmentos de
Valor2_bcd
unsigned display_1=0; //Valor a mostrar en primer display (lado derecho)
unsigned display_2=0; //Valor a mostrar en segundo display
unsigned display_3=0; //Valor a mostrar en tercer display
unsigned display_4=0; //Valor a mostrar en cuarto display(lado izquierdo)

//--------------- RUTINA DE ATENCION A INTERRUPCIONES


-------------------------void interrupt() {
//------------- RUTINA DE ATENCION A INTERRUPCIONES POR TMRO
------------------if (INTCON.TMR0IF==1){//Verificar si la interrupcion es por TMR0
//PRESENTACION DE VALOR EN LOS DISPLAYS EN CADA

INTERRUPCION
count_1++; //Contador usado para mostrar los datos en los displays. Cada
incre//mento se hace en 4ms.
if (count_1==150) count_1=30; //Solo se muestran 4 displays y el punto
switch (count_1){ // Permite seleccionar display que activara y valor que
//mostrara el display seleccionado.
case 30: // Activaremos primer display y mostramos valor de
"display_1"
display_port=0b00000001;
display_data=display_1;
DISPLAY(display_data,display_port);//Llamada a funcion
break;
case 60: // Activamos segundo display y mostramos valor de "display_2"
display_port=0b00000010;
display_data=display_2;
DISPLAY(display_data,display_port);//Llamada a funcion
break;
case 90: // Activamos tercer display y mostramos valor de "display_3"
display_port=0b00000100;
display_data=display_3;
DISPLAY(display_data,display_port);//Llamada a funcion
break;
case 120: // Activamos cuarto display y mostramos valor de "display_4"
display_port=0b00001000;
display_data=display_4;//Llamada a funcion
DISPLAY(display_data,display_port);
break;
}

//REINICIO DE INTERRUPCION POR TMRO


TMR0=6; //Cargamos TMRO con el valor inicial
INTCON=0b10100000; // TMROIF=0(Bit_2), Reset Overflow Flag
// TMROIE=1(Bit_5), Enable TMRO interrupt
//GIE=1(Bit_7), Enable all interrupts

}
}
//-------------------------RUTINA PRINCIPAL------------------------------------void main(){
OPTION_REG = 0b10000100; //PS=100 (Bit_0,1,2) Prescaler select 1:32
//PSA=0 (Bit_3) Prescaler asigned to TMRO module
//TOCS=0 (Bit_5) Internal Clock (CLKO)
ADCON1=0X06;
//Configurar IOs como digitales
TRISA=0X00;
//Puerto_C como salida. Habilitacion de los displays
TRISD=0X00;
TRISB=0X00;
//Puerto_D como salida. Bus de datos para los displays
PORTA=PORTB=PORTD=0X00; //Inicializar con los puertos apagados
TMR0=6;
// Temporizador T0 cuenta de 6 a 255
INTCON=0b10100000;
// Habilitar interrupcin por TMR0
// TMROIE=1 (Bit_5), Enable TMRO interrupt
// GIE=1 (Bit_7), Enable Global interrupts
while(1) {
minutes_bin=3;
seconds_bin=5;
BIN_7SEG(minutes_bin,seconds_bin);
}
}

//++++++++++++++++++++DESARROLLO DE LAS FUNCIONES++++++


+++++++++++++++++++++++++

//*****DESARROLLO DE FUNCION PARA CONVERTIR LOS DATOS


BINARIOS A 4 VALORES GUAR
//DADOS EN DISPLAY_1 AL 4. F_DATA1BIN CONTIENE EL PRIMER
VALOR BINARIO QUE SE
//CONVERTIRA EN BCD Y LUEGO A 7SEGMENTOS. F_DATA2BIN ES

EL SEGUNDO VALOR BINARIO


//f_data1bin es convertido y luego guardado en displays 1 y 2
//f_data2bin sobre los displays 3 y 4
void BIN_7SEG(int f_data2bin,int f_data1bin){
valor1_bcd=Dec2Bcd(f_data1bin);//Funcion para convertir binario a BCD
data1_7seg=valor1_bcd & 0b00001111;//Separar el primer digito BCD
data2_7seg=(valor1_bcd & 0b11110000)>>4;//Separar el segundo digito
BCD
display_1=BCD_7SEG(data1_7seg);
display_2=BCD_7SEG(data2_7seg);
valor2_bcd=Dec2Bcd(f_data2bin);//Funcion para convertir binario a BCD
data3_7seg=valor2_bcd & 0b00001111;//Separar el primer digito BCD
data4_7seg=(valor2_bcd & 0b11110000)>>4;//Separar el segundo digito
BCD
display_3=(BCD_7SEG(data3_7seg)|0b10000000);//Colocamos el punto
decimal
display_4=BCD_7SEG(data4_7seg);//Funcion convierte el valor BCD a 7
Seg
}

//*****DESARROLLO DE FUNCION PARA MOSTRAR LOS DATOS EN


LOS DISPLAYS
void DISPLAY(int f_data,int f_port){
PORTD=f_data; //Actualiza el valor a mostrar en display
PORTA=f_port; //Activa el display donde mostraremos el dato
return;
}
//*****DESARROLLO DE FUNCION PARA PASAR BCD A 7
SEGMENTOS
int BCD_7SEG(int f_digit){
switch (f_digit){
case 0: return 0x3F; //0x3F es el cdigo 7-segmentos del 0.
case 1: return 0x06; //0x06 es el cdigo 7-segmentos del 1.
case 2: return 0x5B;
case 3: return 0x4F;
case 4: return 0x66;
case 5: return 0x6D;

case 6: return 0x7D;


case 7: return 0x07;
case 8: return 0x7F;
case 9: return 0x6F;
}
}
Navegacin
[0] ndice de Mensajes