Sunteți pe pagina 1din 105

INDICE:

1. Parpadeo de un led cada 0,5s


2. Parpadeo de un led cada 0,5s 16F628A
3. Parpadeo de tres led"s cada 0,5s
4. Parpadeo de cuatro led"s cada 0,5s
5. Coche Fantastico v.I
6. Coche Fantastico v.II funcion rotar
7. Coche Fantastico v.III bucle while
8. Coche Fantastico vIV bucle for
8. Juego de luces
10. Luces. Como realizar una libreria
11. Contador ascendente 0a9 (7seg)
12. Contador descendente 9a0 (7seg)
13. Contador reversible 0a9 con switch (7seg)
14. Contador 00a99. (7seg) uso del TMR0
15. Contador 00a99 automatico (7seg)
16. Contador 0a9 BCD&Boton
17. Contador 0a9 BCD 2pulsadores(1.Inc 2.Decr)
18. Super contador 0000a9999 (7seg)
19. BETI parpadeo (7seg)
20. AUPA DEPO (7seg)
21. HOLA rotar hacia izquierda (7seg)
22. Animacion limites (7seg)
23. Dado digital (7seg)
24. Hola mundo (LCD)
25. Hola mundo ahorrando 1 pin (LCD)
26. Abecedario (LCD)
27. Mover palabra por pantalla LCD
28. Limites LCD
29. Escribir&Leer eeprom interna del pic (LCD)
30. Contador 0a9 buzzer&boton (LCD)
31. Escribir&Leer eeprom 24LC256 (LCD)
32. Dado digital (LCD)
33. Reloj-Calendario DS1302 (LCD)
34. RS232: PIC->PC
35. Reloj-Calendario RS232
36. RS232 & teclado 3x4
37. LCD & Teclado 3x4
38. Clave (LCD&Teclado 4x4)
39. RS232: PC->PIC
40. Manejo INT/RB0 interrupcion externa
41. Manejo ccp1 mod.comparacion flanco asc/des genera int
42. Animacion bateria lcd2x16
43. Animacion come-cocos RS232->lcd 2x16
44. Temperatura con ds1620 BETA
45. Manejo del periferico CCP1 modo PWM
46. CCP1 modo PWM al 50% y 75% utilizacion y creacion .h
47. C & ASM
48. Interrupcion de los pines <4:7> portb
49. Abecedario(1 Matriz de led"s 5x7)
50. Reloj digital(display"s 7seg)
51. Interrupcion RS-232. Lectura/Escritura eeprom interna
52. Interrupcion RS-232. Lectura/Escritura eeprom 24LC256
53. SAA1064 modo DINAMICO

54.
55.
56.
57.
58.

SAA1064 modo ESTATICO


PCF8591 modo D/A
PCF8591 modo A/D
Manejo 16 display's 7seg con dos pines del micro (4 SAA1064 en bus i2c)
Termometro digital con ds1620

HERRAMIENTAS:
MPlab IDE -> Entorno de trabajo
CCS Plug-in MPlab -> Integrar nuestro compilador CCS al entrono MPlab
CCS Demo -> Una version demo de nuestro compilador
Como integrar CCS en Proteus -> CCS en PROTEUS
Como simular CCS en Proteus -> Debug con codigo .c
CCS manual -> Manual CCS en ingles(ultima version)
Manual CCS -> Manual de nuestro compilador en espaol
7Seg -> Programa que genera el codigo de display"s 7segmentos(ac & cc)
LCD 5x7 -> Programa que genera codigo para caracteres cgram LCD 5x7
ASCII & RCC -> Programas para obtener codigo ASCII y RCC para colores resistor

El primer ejemplo como no!!! la iluminacion de un led!!!jeje alguien alguna vez a visto programa similar???
jeje bueno fuera de bromas por alguno hay que empezar y este es el nivel inferior jeje. El programa consiste
en el encendido y apagado d eun led cada 0.5s por el pin RB0 del pueto B:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
//
6/Agosto/05
//
//Programa: Parpadeo de un led cada 0.5s
//Version: 0.0
//
//Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
//Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
//Notas: Parpadeo de un led cada 0.5s por el pin RB0 del puerto B
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use fast_io(b)
///PROGRAMA
void main(void)
{
set_tris_b(0xFE); //portb como salida(RB0,las demas desactivadas)
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas
do{
output_low(PIN_B0);

//led off

delay_ms(500);
output_high(PIN_B0);
//led on
delay_ms(500);
}while(TRUE);
//bucle infinito
}

2
Hola lordlafebre!!!por supuesto que puedes ir haciendo preguntas, asi entre todos podremos aprender juntos
jeje(que bien suena), bueno con respecto hacia el pic 16F628 decirte que microchip sugiere que utilicemos la
version 16F628A y claro que se puede utilizar este ejemplito para el pic que mencionaste, solamente
tendremos que adecuarlo a sus necesidades, y esta vez adecuarlo es bastante facil, solamente tendremos
que cambiar el include a nustro pic seleccionado(para asi poder utilizar las variables y funciones definidas
para este dispositivo) y nada mas!!!!(nada mas por ser el ejmeplito muy facil jeje en otros dsipositivos
tendriamos que ver si tienen los mismos perifericos etc), y aqui esta el programa modificado para el PIC
16F628A:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
14/Agosto/05
//
//Programa: Parpadeo de un led cada 0.5s
//Version: 0.0 revision del 16F628a
//
//Dispositivo: PIC 16F628A
Compilador: CCS vs3.227
//Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
//Notas: Parpadeo de un led cada 0.5s por el pin RB0 del puerto B
//////////////////////////////////////////////////////////////////////////////////
#include <16f628a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use fast_io(b)
///PROGRAMA
void main(void)
{
set_tris_b(0xFE); //portb como salida(RB0,las demas desactivadas)
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas
do{
output_low(PIN_B0); //led off
delay_ms(500);
output_high(PIN_B0); //led on
delay_ms(500);
}while(TRUE);
//bucle infinito
}

3
Aqui otro ejemplito mas de led"s, esta vez como encender tres led"s por el port b de tres formas
distintas...asi podreis elegir la que os guste mas jeje:
////////////////////////////////////////////////////////////////////////////////////

//
VsZeNeR"05
//
6/Agosto/05
//
//Programa: Parpadeo de tres leds cada 0.5s
//Version: 0.1
//
//Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
//Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
//Notas: Parpadeo de tres leds cada 0.5s de tres formas diferentes:
// RB0 -> con la funcion output_high()/output_low()
// RB1 -> definiendo el pin RB1
// RB2 -> con la funcion output_bit()
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h> //pic a utilizar
#fuses XT,NOCPD,NOWDT,NOPUT,NOLVP,NOBROWNOUT //ordenes programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fast_io(b)
#bit RB1=0x106.1 //definicion pin potrb B1
///PROGRAMA
void main(void)
{
set_tris_b(0xF8); //puerto b como salida
disable_interrupts(GLOBAL); //todas interrupciones desactivadas
RB1=0; //valor inicial B1 para que los led"s se iluminen igual
do{
output_high(PIN_B0);
//led"s on
RB1=!RB1;
output_bit(PIN_B2,1);
delay_ms(500);
output_low(PIN_B0);
//led"s off
RB1=!RB1;
output_bit(PIN_B2,0);
delay_ms(500);
}while(TRUE);
//bucle infinito
}

4
Ke pasa lordlafebre!!!jeje haber lo del set_tris_b....se puede utilizar el formato que quieras eso si, siempre
que uses la directiva adecuada:
Para HEXADECIMAL: 0xNUMERO_HEXADECIMAL -> 0x00
Para DECIMAL: EL_NUMERO_DECIMAL -> 0
Para BINARIO: 0bNUMERO_BINARIO -> 0b000000
Aunque aconsejo que uses la hexadecimal que es la mas usada, pero la forma binaria es util para solamente
elegir ciertos pines!!!!.
Bien sobre lo del comando RB1=!RB1 decirte que realiza la negacion logica, es decir si RB1=0 entonces
cuando llega a realizarse la instruccion RB1=!RB1 sera RB1=1, el simbolito ! cumple la funcion de
complemento igual que la funcion comf f,d en el esamblador.
Bien revisando el codigo del parpadeo de los tres led"s de tres formas distintas, decir que se me olvido una
cuarta formaa diistinta de encenderlos!!!!jeje aqui va el programa completo de como encender 4 led"s de 4
formas distintas:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
//
14/Agosto/05
//
// Programa: Parpadeo de cuatro leds cada 0.5s
// Version: 0.2
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Parpadeo de cuatro leds cada 0.5s de cuatro formas diferentes:
//
RB0 -> con la funcion output_high()/output_low()
//
RB1 -> definiendo el pin RB1
//
RB2 -> con la funcion output_bit()
//
RB3 -> con la funcion bit_set()/bit_clear()
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOCPD,NOWDT,NOPUT,NOLVP,NOBROWNOUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3) //pin de salida portb
#bit RB1=0x106.1
//definicion pin potrb B1
#byte portb=06
///PROGRAMA
void main(void)
{
set_tris_b(0x00);
//puerto b como salida
disable_interrupts(GLOBAL);
//todas interrupciones desactivadas
RB1=0;
//valor inicial B1 para que los led"s se iluminen igual
do{
output_high(PIN_B0);
//led"s on
RB1=!RB1;
output_bit(PIN_B2,1);
bit_set(portb,3);
delay_ms(500);
output_low(PIN_B0);
//led"s off
RB1=!RB1;
output_bit(PIN_B2,0);
bit_clear(portb,3);
delay_ms(500);
}while(TRUE);
//bucle infinito
}

5
Una mas de led"s jeje!!!quien no vio la serie de tv del coche fantastico??quien no soo algun dia con tener
uno?quien no hablo alguna que otra vez al volante del coche haber si le respondia Kit?? jeje (yo le hababa
en su momento al coche de mi papi un opel corsa de los antiguos jeje peor nunca me respondio ), pues el
siguiente ejemplito va dedicado a las luces del coche fantastico, ese movimiento de un lateral a otro y
viceversa:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"04
//
7/Agosto/05

//
// Programa: Coche Fantastico
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Barrido de led"s simulando la iluminacion del coche fantastico por el
//
puerto A
//
//
RA0 -> 1 Led
//
RA1 -> 2 Led
//
RA2 -> 3 Led
//
RA3 -> 4 Led
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(A)
//puerto A como salida
///DECLARACIONES DE FUNCIONES
void derecha(void);
//ilumina led"s derecha a izquierda
void izquierda(void);
//ilumina led"s izquierda a derecha
///PROGRAMA
void main(void)
{
set_tris_a(0xF0);
//porta como salida menos RA4(desactivado)
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{
derecha();
izquierda();
}while(TRUE);

//bucle...

}
void derecha(void)
{
output_high(PIN_A0);
delay_ms(300);
output_low(PIN_A0);
output_high(PIN_A1);
delay_ms(300);
output_low(PIN_A1);
output_high(PIN_A2);
delay_ms(300);
output_low(PIN_A2);
output_high(PIN_A3);
delay_ms(300);
}
void izquierda(void)
{
output_low(PIN_A3);
output_high(PIN_A2);
delay_ms(300);
output_low(PIN_A2);

//...infinito

output_high(PIN_A1);
delay_ms(300);
output_low(PIN_A1);

6
Bien lo prometido es deuda!!!jeje aqui pongo otra forma d hacer el colorido del coche fantastico con
led"s......las cosas con estos cacharros no s elimitan a una sola manera sino a las maneras x-proporcionales
de los que se paran a pensarlo jeje pos aqui esta:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
12/Agosto/05
//
// Programa: Coche Fantastico
// Version: 1.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Barrido de led"s simulando la iluminacion del coche fantastico por el
//
puerto B por medio de la instruccion de rotar.
//
//
RB0 -> 1 Led
//
RB1 -> 2 Led
//
RB2 -> 3 Led
//
RB3 -> 4 Led
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
//puerto B como salida
#byte portb= 0x6
//direccion port b
///PROGRAMA
void main(void)
{
int led_on=0b0001;
//led a iluminar
set_tris_b(0xf0);
//portb como salida (algunas desactivadas)
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{

//bucle...

do{
//iluminacion hacia izquierda
portb=led_on;
rotate_left(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,3)==0);
do{
//iluminacion hacia derecha
portb=led_on;
rotate_right(&led_on,1);
delay_ms(300);

}while(bit_test(led_on,0)==0);
}while(TRUE);

//...infinito

7
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
14/Agosto/05
//
// Programa: Coche Fantastico
// Version: 2.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Barrido de led"s simulando la iluminacion del coche fantastico por el
//
puerto B. Adaptacion del codigo en basic de lordlafebre
//
//
RB0 -> 1 Led
//
RB1 -> 2 Led
//
RB2 -> 3 Led
//
RB3 -> 4 Led
//
RB4 -> 5 Led
//
RB5 -> 6 Led
//
RB6 -> 7 Led
//
RB7 -> 8 Led
//
En la variable cont se va almacenando los valores 1-2-4-8-16-32-64-128
//
que en binario corresponden a la secuencia 00000001-00000010-00000100...
//
son los led"s a iluminar, coincidiendo con la secuencia de iluminacion
//
del coche fantastico(version Ecuatoriana: auto fantastico)
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
//puerto B como salida
///PROGRAMA
void main(void)
{
int i,cont;
//variables definidas
set_tris_b(0x00);
//portb como salida
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{
cont=1;
i=1;

//bucle...
//inicializar...
//...variables

do{
//led"s on derecha
output_b(cont);
//ilumino led correspondiente
delay_ms(100);
cont=cont*2;
i++;
//incremento i
}while(i<

i=1;

//reset valor i

do{
//led"s on izquierda
output_b(cont);
//ilumino led correspondiente
delay_ms(100);
cont=cont/2;
i++;
//incremento i
}while(i<

}while(TRUE);

//...infinito

}
He cambiado los dos bucles for que en basic estan escritos por dos while....el cambio la verdad lo he
realizado porque con los bucles for me da un problema y no se de ke es!!!!jeje puede ser un bug del
compilador al tratar la segunda asignacion del for o puede ser un bug en mi cabeza jeje(todo es posible).
Con respecto a tu pregunta de porque algunas veces pongo #use standard_io(B) y otras veces pongo #use
fast_io(b) es simplemente segun la asignacion que le quiero dar al puerto en cuestion a tratar(en este caso
el B), la #use standar_io() declara el puerto seleccionado como entrada y salida mientras que la otra debes
configurar la accion especifica de cada pin del puerto(si tienen comparadores,interrupciones,etc), una cosita
mas respecto a esta pregunta es que la asignacion #use fast_io() da problemas muchas veces y cuando vas
a simular el programa ves que los puertos no responden como quisiera, por lo tanto recomendarte que uses
la primera #use standard_io() aunque mirate el manual que lo explica mejor que yo jeje si tienes alguna
duda ya sabes!!!

8
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
14/Agosto/05
//
// Programa: Coche Fantastico
// Version: 2.1
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Barrido de led"s simulando la iluminacion del coche fantastico por el
//
puerto B. Adaptacion del codigo en basic de lordlafebre
//
//
RB0 -> 1 Led
//
RB1 -> 2 Led
//
RB2 -> 3 Led
//
RB3 -> 4 Led
//
RB4 -> 5 Led
//
RB5 -> 6 Led
//
RB6 -> 7 Led
//
RB7 -> 8 Led
//
En la variable cont se va almacenando los valores 1-2-4-8-16-32-64-128
//
que en binario corresponden a la secuencia 00000001-00000010-00000100...
//
son los led"s a iluminar, coincidiendo con la secuencia de iluminacion
//
del coche fantastico(version Ecuatoriana: auto fantastico)
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
//puerto B como salida

///PROGRAMA
void main(void)
{
int i,cont;
//variables definidas
set_tris_b(0x00);
//portb como salida
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{
cont=1;
for(i=1;i<8;i++){
output_b(cont);
delay_ms(100);
cont=cont*2;
}
for(i=1;i<8;i++){
output_b(cont);
delay_ms(100);
cont=cont/2;
}
}while(TRUE);

//bucle...
//inicializar...
//led"s on derecha
//ilumino led correspondiente

//ilumino led correspondiente

//...infinito

9
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
15/Agosto/05
//
// Programa: Juego de luces
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Iluminacion de juego de luces fuera-dentro y viceversa por el puerto B.
//
Adaptacion a c por vszener del codigo en basic de lordlafebre.
//
//
RB0 -> 1 Led
//
RB1 -> 2 Led
//
RB2 -> 3 Led
//
RB3 -> 4 Led
//
RB4 -> 5 Led
//
RB5 -> 6 Led
//
RB6 -> 7 Led
//
RB7 -> 8 Led
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
//puerto B
///PROGRAMA

void main(void)
{
signed char i;
//variable indice
int leds[4]={0b10000001,0b01000010,0b00100100,0b00011000}; //led"s
set_tris_b(0x00);
//portb como salida
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{

//bucle...

for(i=0;i<4;i++){
output_b(leds[ i ]);
delay_ms(100);
}
for(i=3;i>-1;i--){
output_b(leds[ i ]);
delay_ms(100);
}
}while(TRUE);

//led"s on fuera-dentro
//ilumino led"s correspondientes

//led"s on dentro-fuera
//ilumino led"s correspondientes

//...infinito

10
VsZeNeR"04
//
14/Agosto/05
//
// Programa: Coche Fantastico
// Version: 2.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Barrido de led"s simulando la iluminacion del coche fantastico por el
//
puerto B. Adaptacion del codigo en basic de lordlafebre
//
//
RB0 -> 1 Led
//
RB1 -> 2 Led
//
RB2 -> 3 Led
//
RB3 -> 4 Led
//
RB4 -> 5 Led
//
RB5 -> 6 Led
//
RB6 -> 7 Led
//
RB7 -> 8 Led
//
En la variable cont se va almacenando los valores 1-2-4-8-16-32-64-128
//
que en binario corresponden a la secuencia 00000001-00000010-00000100...
//
son los led"s a iluminar, coincidiendo con la secuencia de iluminacion
//
del coche fantastico(version Ecuatoriana: auto fantastico)
//////////////////////////////////////////////////////////////////////////////////
#use delay (clock=4000000)
//Fosc=4Mhz,define funcion delay
///FUNCION COCHE FANTASTICO
void kit(void)
{
int i,cont;
//variables definidas
cont=1;
for(i=1;i<8;i++){

//inicializar...
//led"s on derecha

output_b(cont);
delay_ms(100);
cont=cont*2;
}
for(i=1;i<8;i++){
output_b(cont);
delay_ms(100);
cont=cont/2;
}

//ilumino led correspondiente

//ilumino led correspondiente

}
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
15/Agosto/05
//
// Programa: Juego de luces
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Iluminacion de juego de luces fuera dentro por el puerto B.
//
Adaptacion a c por vszener del codigo en basic de lordlafebre.
//
//
RB0 -> 1 Led
//
RB1 -> 2 Led
//
RB2 -> 3 Led
//
RB3 -> 4 Led
//
RB4 -> 5 Led
//
RB5 -> 6 Led
//
RB6 -> 7 Led
//
RB7 -> 8 Led
//////////////////////////////////////////////////////////////////////////////////
///FUNCION JUEGO_LUCES
void juego_luces(void)
{
signed char i;
//variable indice
int leds[4]={0b10000001,0b01000010,0b00100100,0b00011000}; //led"s
for(i=0;i<4;i++){
output_b(leds[ i ]);
delay_ms(100);
}
for(i=3;i>-1;i--){
output_b(leds[ i ]);
delay_ms(100);
}

//led"s on fuera-dentro
//ilumino led"s correspondientes

//led"s on dentro-fuera
//ilumino led"s correspondientes

}
la guardamos con el nombre de vs_lib_luces.h
Y aqui el programa principal:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
15/Agosto/05
//
// Programa: Luces
// Version: 0.0

//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Programa que consiste en que si por el pin A0 del porta lee un "0" logico
//
es decir, esta en low, se ejecuta la iluminacion del coche fantastico
//
por el portb, en cambio si por el pin A0 del porta se recibe un estado alto
//
un "1" logico(high), se ejecuta por el portb la iluminacion de encender les"s
//
de fuera-dentro y viceversa. Tener en cuenta que hay que poner la
//
directiva NOLVP para que el pin B4 sea de salida
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#include <vs_lib_luces.h>
//nuestra libreria para las funciones kit(),juego_luces()
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use standard_io(B)
#use standard_io(A)
///PROGRAMA
void main(void)
{
set_tris_a(0xFF);
//porta como entrada
set_tris_b(0x00);
//portb como salida
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{
//bucle...
if(!input(PIN_A0))
//switch cerrado?
kit();
//SI ->ejecuta coche fantastico(kit)
else
juego_luces();
//NO ->ejecuta juego luces
}while(TRUE);
//...infinito
}
11
l ejemplito de hoy se basa en hacer un contador ascendente del 0 al 9 y volver a empezar, para ello
trabajaremos con el periferico 7segmentos de catodo comun, aqui el codigo:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"04
//
14/Agosto/05
//
// Programa: Contador ascendente 0-9
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador del 0 al 9 cada 0,5s y vuelta a empezar. Tener en cuenta
//
que hay que poner la directiva NOLVP para que el pin B4 sea de salida
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
///PROGRAMA

void main(void)
{
char i=0; //contador para tabla 7 seg
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};

//7seg hex 0-9

set_tris_b(0x00);
//portb como salida
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{
//bucle...
output_b(tab7seg[ i ]);
//muestra por portb digito 7 segmentos
delay_ms(500);
i++;
//incremento contador para visualizar siguiente digito
if(i>9)
//ya se ha mostrado el digito 9?
{
i=0;
//SI -> vuelve a empezar(digito 0)
}
}while(TRUE);
//...infinito
}
12
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"04
//
14/Agosto/05
//
// Programa: Contador descendente 9-0
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador del 9 al 0 cada 0,5s y vuelta a empezar. Tener en cuenta
//
que hay que poner la directiva NOLVP para que el pin B4 sea de salida
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
///PROGRAMA
void main(void)
{
char i=9; //contador para tabla 7 seg(apunta al digito 9 de tab7seg)
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};
set_tris_b(0x00);
//portb como salida
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{
//bucle...
output_b(tab7seg[ i ]);
//muestra por portb digito 7 segmentos
delay_ms(500);
i--;
//decremento contador para visualizar siguiente digito
if(i==-1)
//ya se ha mostrado el digito 0?
{
i=9;
//SI -> vuelve a empezar(digito 9)
}

//7seg hex 0-9

}while(TRUE);

//...infinito

}
13

Ya que sabemos contar del 0 al 9 y del 9 al 0 mediante el periferico 7 segmentos.....esta vez el ejemplito
propuesto es incorporarle un switch por el porta(pin A0) y si dicho switch esta abierto el contador sera
ascendente(del 0 al 9) y si esta cerrado el switch el contador sera descendente(del 9 al 0)....aqui el codigo:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"04
//
14/Agosto/05
//
// Programa: Contador reversible 0-9
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador reversible 0 al 9 viceversa cada 0,5s y vuelta a empezar. Tener
//
en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
//
salida. Cuando el switch esta cerrado se lee por el pin A0 del porta un
//
"0" logico(pin A0 low)y el contador se configura como descendente encambio
//
si el switch esta abierto se lee por el pin A0 del porta un "1"
//
logico(pin A0 high) por lo tanto el contador se configura como ascendente
//
// Conexiones:
A0 -> switch
a
//
B0 -> a 7seg
____
//
B1 -> b 7seg
f | |b
//
B2 -> c 7seg
|g |
//
B3 -> d 7seg
---//
B4 -> e 7seg
e | |c
//
B5 -> f 7seg
|____|
//
B6 -> g 7seg
d
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3,PIN_B4,PIN_B5,PIN_B6)
#use standard_io(A)
///DECLARACION DE FUNCIONES
void up(void);
//funcion cuenta ascendente
void down(void); //funcion cuenta descendente
///DECLARACION VARIABLES GLOBALES
signed char i; //contador para tabla 7 seg (se tiene en cuenta el signo)
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};
///PROGRAMA
void main(void)
{
set_tris_a(0xFF);
//porta como entrada
set_tris_b(0x00);
//portb como salida
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas

//7seg hex 0-9

///inicializamos el contador
if(!input(PIN_A0))
//para ello leemos el estado del pin A0 del porta
i=10;
//contador descendente
else
i=-1;
//contador ascendente
do{
//bucle...
if(input(PIN_A0))
//switch abierto?
up();
//SI -> contador ascendente
else
down();
//NO -> contador descendente
output_b(tab7seg[ i ]);
//muestra por portb digito 7 segmentos
delay_ms(500);
}while(TRUE);
//...infinito
}
void up(void)
{
i++;
if(i>9)
i=0;
}
void down(void)
{
i--;
if(i==-1)
i=9;
}

//funcion cuenta ascendente


//incremento contador para visualizar siguiente digito
//ya se ha mostrado el digito 9?
//SI -> vuelve a empezar(digito 0)

//funcion cuenta descendente


//decremento contador para visualizar siguiente digito
//ya se ha mostrado el digito 0?
//SI -> vuelve a empezar(digito 9)

14
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
18/Agosto/05
//
// Programa: Contador del 00 al 99
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador del 00 al 99 cada 1s y vuelta a empezar. Tener en cuenta
//
que hay que poner la directiva NOLVP para que el pin B4 sea de salida.
//
Se utiliza variables locales:
//
* i -> indice tabla 7seg para mostrar digito por 1 7seg
//
* j -> indice tabla 7seg para mostrar digito por 2 7seg
//
* flag -> variable que cuenta 1s
//
* var -> ajuste fino para que desborde cada segundo
//
Utilizamos la funcion de interrupcion para actualizar indices de la
//
tabla de 7seg para mostrar el digito correspondiente en el respectivo
//
7seg, para ello el TMR0 se desborda cada 1s, para ello debe ser cargado
//
con 61(equivale a un desbordamiento cada 50ms mas o menos), para obtener
//
un desbordamiento de 1s utilizamos una variable(flag) que no entra en
//
la actualizacion de indices hasta transcurrido 1s.
// Conexiones:
//
RA0 -> Display 1 7seg

//
RA1 -> Display 2 7seg
//
RB0 -> a 7seg
//
RB1 -> b 7seg
//
RB2 -> c 7seg
//
RB3 -> d 7seg
//
RB4 -> e 7seg
//
RB5 -> f 7seg
//
RB6 -> g 7seg
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
#use fixed_io(a_outputs=PIN_A0,PIN_A1) //A0,A1 como salidas en porta
char i=0,j=0,flag=0,var=20;

//variables globales

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){
//ya es 1 segundo?
var--;
//SI -> decremento var...
if(var<18)
var=20;
//...ajuste fino de 1s
flag=0;
//reset flag para contar 1s
if(i> {
//se ha mostrado por 1 7seg digito 9?
i=0;
//SI -> i=0 (muestra digito 0) (*)
j++;
//incremento indice j
if(j>9){ //se ha mostrado por 2 7seg digito 9?
j=0;} //SI -> j=0 (muestra digito 0)
}
else{
//(*) NO -> incrementa i
i++;}
}
set_timer0(61);
//reset TMR0
flag++;
//incremento variable flag
}
///PROGRAMA
void main(void)
{
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};

//7seg hex 0-9

set_tris_b(0x00);
//portb como salida
enable_interrupts(INT_TIMER0);
//interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0
set_timer0(61);
//carga TMR0
enable_interrupts(GLOBAL);
//activadas interrupciones
do{
//bucle...
output_high(PIN_A1);
//2 7seg off
output_low(PIN_A0);
//1 7seg on
delay_ms(15);
output_b(tab7seg[ i ]);
//muestra por portb digito 7 segmentos
output_low(PIN_A1);
//2 7seg on

output_high(PIN_A0);
//1 7seg off
delay_ms(15);
output_b(tab7seg[ j ]);
//muestra por portb digito 7 segmentos
}while(TRUE);
//...infinito
}
15
///////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
22/Agosto/05
//
// Programa: Contador del 00 al 99 y viceversa automaticamente
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador del 00 al 99 cada 1s y vuelta a empezar. Tener en cuenta
//
que hay que poner la directiva NOLVP para que el pin B4 sea de salida.
//
Se utiliza variables locales:
//
* i -> indice tabla 7seg para mostrar digito por 1 7seg
//
* j -> indice tabla 7seg para mostrar digito por 2 7seg
//
* flag -> variable que cuenta 1s
//
* var -> ajuste fino para que desborde cada segundo
//
* cuenta -> cuenta=0 -> Contador ascendente ; cuenta=1 -> Contador descendente
//
Utilizamos la funcion de interrupcion para actualizar indices de la
//
tabla de 7seg para mostrar el digito correspondiente en el respectivo
//
7seg, para ello el TMR0 se desborda cada 1s, para ello debe ser cargado
//
con 61(equivale a un desbordamiento cada 50ms mas o menos), para obtener
//
un desbordamiento de 1s utilizamos una variable(flag) que no entra en
//
la actualizacion de indices hasta transcurrido 1s. Configuramos una
//
variable tipo short,bit, llamada "cuenta" que si vale 1 significa que
//
el contador es descendente y si vale 0 significa que el contador es ascendente.
// Conexiones:
//
RA0 -> Display 1 7seg
//
RA1 -> Display 2 7seg
//
RB0 -> a 7seg
//
RB1 -> b 7seg
//
RB2 -> c 7seg
//
RB3 -> d 7seg
//
RB4 -> e 7seg
//
RB5 -> f 7seg
//
RB6 -> g 7seg
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
#use fixed_io(a_outputs=PIN_A0,PIN_A1) //A0,A1 como salidas en porta
//VARIABLES GLOBALES
signed char i=0,j=0; //indices(se tiene en cuenta signo para comprobaciones de fin tab7seg)
char flag=0,var=20;
short cuenta=0;
//cuenta=0 -> Contador ascendente ; cuenta=1 -> Contador descendente
///LLAMADA FUNCION INTERRUPCION

#INT_TIMER0
void interrupcion()
{
if(flag>var){
//ya es 1 segundo?rutina:actualizar indices y contador ascendente/descendente
var--;
//SI -> decremento var...
if(var<18)
var=20;
//...ajuste fino de 1s
flag=0;
//reset flag para contar 1s
if(cuenta==0){ //Contador ascendente?
if(i> {
//SI -> se ha mostrado por 1 7seg digito 9?
i=0;
//SI -> i=0 (muestra digito 0) (*)
j++;
//incremento indice j
if(j>9){
//se ha mostrado digito 99?
cuenta=1; //SI -> contador descendente...
j=9;
//restauro...
i=8;
//...indices
}
}
else{
//(*) NO -> incrementa i
i++;}
}
else{
//Contador descendente
i--;
//decremento indice i
if(i<0){
//fin tab7seg en indice i?
i=9;
//SI -> restauro i
j--;
//decremento indice j
if(j<0){
//fin tab7seg en indice j 00?
cuenta=0; //SI -> Contador descendente
i=1;
//restauro...
j=0;
//...indices
}
}
}
} //fin actualizar indices y contador ascendente/descendente
set_timer0(61);
//reset TMR0
flag++;
//incremento variable flag
}
///PROGRAMA
void main(void)
{
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};

//7seg hex 0-9

set_tris_b(0x00);
//portb como salida
enable_interrupts(INT_TIMER0);
//interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0
set_timer0(61);
//carga TMR0
enable_interrupts(GLOBAL);
//activadas interrupciones
do{
//bucle...
output_high(PIN_A1);
//2 7seg off
output_low(PIN_A0);
//1 7seg on
delay_ms(15);
output_b(tab7seg[ i ]);
//muestra por portb digito 7 segmentos
output_low(PIN_A1);
//2 7seg on
output_high(PIN_A0);
//1 7seg off
delay_ms(15);

output_b(tab7seg[ j ]);
//muestra por portb digito 7 segmentos
}while(TRUE);
//...infinito
}
16

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

VsZeNeR"05

//

22/Agosto/05

//
//

Programa:

//

Version:

Contador 0-9 display BDC & Boton para cuenta ascendente o descendente

0.0

//
//

Dispositivo: PIC 16F648A

Compilador:

//

Entorno IDE: MPLAB IDE v7.20

CCS vs3.227

Simulador:

Proteus 6.7sp3

//
//

Notas: Contador 0 al 9 cada vez que pulsemos el boton y vuelta a empezar. Tener

//

en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida. Cuando agregamos un boton a nuestro circuito hay que tener en cuenta

//

que este dispositivo genera "rebotes" que hay que ser eliminados para

//

una correcta visualizacion en el display del digito seleccionado. Esta vez

//

la eliminacion de "los rebotes" se ha realizado mediante software.

//

Cuando por el pin A0 del porta se introduce un "0" logico(low), se

//

incrementa un digito en el display BCD, encambio si por el pin A1 se introduce

//

un "0" logico(low) se decrementa en una unidad el digito a mostrar.

//
//

Conexiones:

A0 -> boton

up(cuenta ascendente)

//

A1 -> boton down(cuenta descendente)

//

B0 -> a

//

B1 -> b

//

B2 -> c

//

B3 -> d

//

BCD:

//

dcba

NUM

//

0000

//

0001

//

0010

//

0011

//

0100

//

0101

//

0110

//

0111

//

1000

//

1001

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
#use delay (clock=4000000)

//ordenes para el programador

//Fosc=4Mhz

#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3)
#use standard_io(A)

///PROGRAMA
void main(void)
{
signed char i=0;

//contador para tabla BCD

int
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1001};

//BCD

0-9

set_tris_a(0xFF);

//porta como entrada

disable_interrupts(GLOBAL);

output_b(tabBCD[ i ]);

for( ; ; ){

//todas las interrupciones desactivadas

//inicializa displayBCD digito 0

//bucle...

if(!input(PIN_A0))

//se ha pulsado el boton up?

{
delay_ms(151);
i++;

//incremento contador indice tabBCD

if(i>9)
i=0;

//SI -> retardo para evitar los rebotes

//se ha mostrado digito 9?


//SI -> restaura valor indice(para mostrar digito 0)

}
if(!input(PIN_A1))

//se ha pulsado el boton down?

{
delay_ms(151);
i--;
if(i<0)
i=9;

//SI -> retardo para evitar los rebotes

//decremento contador indice tabBCD


//se ha mostrado digito 0?
//SI -> restaura valor indice(para mostrar digito 9)

}
output_b(tabBCD[ i ]);
}

//muestra por portb digito BCD

//...infinito

}
Recordad que los botones generan los llamados "rebotes" que deben ser eliminados bien hardware o bien

por software(el cual es este ejemplo mediante una pausa de 151ms)....corto y cambio!!!
17

//

Programa:

//

Version:

Contador 0-9 display BDC & Boton para cuenta ascendente o descendente

0.0

//
//

Dispositivo: PIC 16F648A

Compilador:

//

Entorno IDE: MPLAB IDE v7.20

CCS vs3.227

Simulador:

Proteus 6.7sp3

//
//

Notas: Contador 0 al 9 cada vez que pulsemos el boton y vuelta a empezar. Tener

//

en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida. Cuando agregamos un boton a nuestro circuito hay que tener en cuenta

//

que este dispositivo genera "rebotes" que hay que ser eliminados para

//

una correcta visualizacion en el display del digito seleccionado. Esta vez

//

la eliminacion de "los rebotes" se ha realizado mediante software.

//

Cuando por el pin A0 del porta se introduce un "0" logico(low), se

//

incrementa un digito en el display BCD, encambio si por el pin A1 se introduce

//

un "0" logico(low) se decrementa en una unidad el digito a mostrar.

//
//

Conexiones:

A0 -> boton

up(cuenta ascendente)

//

A1 -> boton down(cuenta descendente)

//

B0 -> a

//

B1 -> b

//

B2 -> c

//

B3 -> d

//

BCD:

//

dcba

NUM

//

0000

//

0001

//

0010

//

0011

//

0100

//

0101

//

0110

//

0111

//

1000

//

1001

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
#use delay (clock=4000000)

//ordenes para el programador

//Fosc=4Mhz

#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3)
#use standard_io(A)

///PROGRAMA
void main(void)
{
signed char i=0;

//contador para tabla BCD

int
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1001};
0-9

set_tris_a(0xFF);

//porta como entrada

disable_interrupts(GLOBAL);

output_b(tabBCD[ i ]);

for( ; ; ){

//todas las interrupciones desactivadas

//inicializa displayBCD digito 0

//bucle...

if(!input(PIN_A0))

//se ha pulsado el boton up?

{
delay_ms(151);
i++;
if(i>9)
i=0;

//SI -> retardo para evitar los rebotes

//incremento contador indice tabBCD


//se ha mostrado digito 9?
//SI -> restaura valor indice(para mostrar digito 0)

}
if(!input(PIN_A1))

//se ha pulsado el boton down?

{
delay_ms(151);
i--;
if(i<0)
i=9;

//SI -> retardo para evitar los rebotes

//decremento contador indice tabBCD


//se ha mostrado digito 0?
//SI -> restaura valor indice(para mostrar digito 9)

}
output_b(tabBCD[ i ]);
}

//muestra por portb digito BCD

//...infinito

}
18
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

23/Agosto/05

//

//BCD

//

Programa:

//

Version:

Contador del 0000 al 9999

0.0

//
//

Dispositivo: PIC 16F648A

Compilador:

//

Entorno IDE: MPLAB IDE v7.20

Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Contador del 0000 al 9999 cada 1s y vuelta a empezar. Tener en cuenta

//

que hay que poner la directiva NOLVP para que el pin B4 sea de salida.

//

Se utiliza variables locales:

//

* i -> indice tabla 7seg para mostrar digito por 1 7seg

//

* j -> indice tabla 7seg para mostrar digito por 2 7seg

//

* w -> indice tabla 7seg para mostrar digito por 3 7seg

//

* z -> indice tabla 7seg para mostrar digito por 4 7seg

//

* flag -> variable que cuenta 1s

//

* var -> ajuste fino para que desborde cada segundo

//

Utilizamos la funcion de interrupcion para actualizar indices de la

//

tabla de 7seg para mostrar el digito correspondiente en el respectivo

//

7seg, para ello el TMR0 se desborda cada 1s, para ello debe ser cargado

//

con 61(equivale a un desbordamiento cada 50ms mas o menos), para obtener

//

un desbordamiento de 1s utilizamos una variable(flag) que no entra en

//

la actualizacion de indices hasta transcurrido 1s.

//

Conexiones:

//

RA0 -> Display 1 7seg

//

RA1 -> Display 2 7seg

//

RA2 -> Display 3 7seg

//

RA3 -> Display 4 7seg

//

RB0 -> a 7seg

//

RB1 -> b 7seg

//

RB2 -> c 7seg

//

RB3 -> d 7seg

//

RB4 -> e 7seg

//

RB5 -> f 7seg

//

RB6 -> g 7seg

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
#use delay (clock=4000000)

//ordenes para el programador

//Fosc=4Mhz

#use standard_io(B)
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)

//A0,A1,A2,A3 como salidas en porta

char i=0,j=0,w=0,z=0,flag=0,var=20;

//variables globales

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){

//ya es 1 segundo?

var--;

//SI -> decremento var...

if(var<18)
var=20;

//...ajuste fino de 1s

flag=0;
if(i>

//reset flag para contar 1s

//se ha mostrado por 1 7seg digito 9?

i=0;

//SI -> i=0 (muestra digito 0) (*)

j++;

//incremento indice j

if(j>9){

//se ha mostrado por 2 7seg digito 9?

j=0;

//SI -> j=0 (muestra digito 0)

w++;

//incremento indice w

if(w>9){

//se ha mostrado por 3 7seg digito 9?

w=0;

//SI -> w=0 (muestra digito 0)

z++;

//incremento indice z

if(z>9)
z=0;

//se ha mostrado por 4 7seg digito 9?


//SI -> z=0 (muestra digito 0)

}
}
}
else{

//(*) NO -> incrementa i

i++;}
}
set_timer0(61);
flag++;

//reset TMR0
//incremento variable flag

///PROGRAMA
void main(void)
{
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};

set_tris_b(0x00);

//portb como salida

enable_interrupts(INT_TIMER0);

//interrupcion TIMER0 activada

setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
set_timer0(61);

//7seg hex 0-9

//carga TMR0

//configuracion interrupcion TMR0

enable_interrupts(GLOBAL);

do{

//activadas interrupciones

//bucle...

output_high(PIN_A0);
output_high(PIN_A1);
output_high(PIN_A2);
output_low(PIN_A3);

//activado...

output_b(tab7seg[ i ]);

//...1 7seg

delay_ms(10);
output_high(PIN_A0);
output_high(PIN_A1);
output_low(PIN_A2);

//activado...

output_high(PIN_A3);
output_b(tab7seg[ j ]);

//...2 7seg

delay_ms(10);
output_high(PIN_A0);
output_low(PIN_A1);

//activado...

output_high(PIN_A2);
output_high(PIN_A3);
output_b(tab7seg[ w ]);

//...3 7seg

delay_ms(10);
output_low(PIN_A0);

//activado...

output_high(PIN_A1);
output_high(PIN_A2);
output_high(PIN_A3);
output_b(tab7seg[ z ]);

//...4 7seg

delay_ms(10);
}while(TRUE);

//...infinito

}
19
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

24/Agosto/05

//
//

Programa:

//

Version:

BETI parpadeo

0.0

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.20

Compilador:
Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Muestra el mensaje de BETI por cuatro display"s de 7 segmentos

//

multiplexados. El mensaje aparece cada 0,5s parpadeando

//

Tener en cuenta que hay que poner la directiva NOLVP

//

para que el pin B4 sea de salida.

//

Se utiliza variables locales:

//
//

* i -> contador para visualizar BETI


Conexiones:

//

RA0 -> Display 1 7seg

//

RA1 -> Display 2 7seg

//

RA2 -> Display 3 7seg

//

RA3 -> Display 4 7seg

//

RB0 -> a 7seg

//

RB1 -> b 7seg

//

RB2 -> c 7seg

//

RB3 -> d 7seg

//

RB4 -> e 7seg

//

RB5 -> f 7seg

//

RB6 -> g 7seg

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
#use delay (clock=4000000)

//ordenes para el programador

//Fosc=4Mhz

#use standard_io(B)
#use standard_io(A)

///PROGRAMA
void main(void)
{
char i;

//contador de visualizacion BETI

set_tris_b(0x00);

//portb como salida

set_tris_a(0x00);

//porta como salida

disable_interrupts(GLOBAL);

do{

//activadas interrupciones

//bucle...

for(i=0;i<15;i++){

//bucle visualizacion beti

output_a(0b1110);
output_b(0x7C);

//1 7seg on B

delay_ms(10);
output_a(0b1101);
output_b(0x79);

//2 7seg on E

delay_ms(10);
output_a(0b1011);
output_b(0x78);

//3 7seg on T

delay_ms(10);
output_a(0b0111);
output_b(0x30);

//4 7seg on I

delay_ms(10);
}

output_b(0x00);

//todo...

output_a(0b0000);
delay_ms(500);
}while(TRUE);

//...apagado durante 0,5s


//...infinito

}
20
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

25/Agosto/05

//
//

Programa:

//

Version:

AUPA DEPO parpadeo

0.0

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.20

Compilador:

CCS vs3.227

Simulador:

Proteus 6.7sp3

//
//

Notas: Muestra el mensaje de AUPA DEPO por cuatro display"s de 7 segmentos

//

multiplexados. El mensaje aparece cada 0,5s parpadeando primero la

//

frase AUPA y luego la frase DEPO y suena un pitido al cambio de frase.

//

Tener en cuenta que hay que poner la directiva NOLVP

//

para que el pin B4 sea de salida.

//

Se utiliza variables locales:

//

* i -> indice 1 7seg

//

* j -> indice 2 7seg

//

* w -> indice 3 7seg

//

* z -> indice 4 7seg

//

* cont -> contador: cont=0 -> AUPA

//

cont=1 -> DEPO

//

* rep -> variable para visualizar mensaje

//

* tab7seg[] -> vector donde se almacenan letras mensajes

//
//

Conexiones:
RA0 -> Display 1 7seg

//

RA1 -> Display 2 7seg

//

RA2 -> Display 3 7seg

//

RA3 -> Display 4 7seg

//

RB0 -> a 7seg

//

RB1 -> b 7seg

//

RB2 -> c 7seg

//

RB3 -> d 7seg

//

RB4 -> e 7seg

//

RB5 -> f 7seg

//

RB6 -> g 7seg

//

RB7 -> Buzzer

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
#use delay (clock=4000000)

//ordenes para el programador

//Fosc=4Mhz

#use standard_io(B)
#use standard_io(A)

///PROGRAMA
void main(void)
{
char rep,cont=0,i=0,j=1,w=2,z=0;

//variables

int tab7seg[6]={0x77,0x3E,0x73,0x5E,0x79,0x3F};

set_tris_b(0x00);

//portb como salida

set_tris_a(0x00);

//porta como salida

disable_interrupts(GLOBAL);

do{

//A U P D E O

//desactivadas interrupciones

//bucle...

for(rep=0;rep<15;rep++){

//bucle visualizacion aupa/depo

output_a(0b1110);
output_b(tab7seg[ i ]);

//1 7seg on

delay_ms(10);
output_a(0b1101);
output_b(tab7seg[ j ]);

//2 7seg on

delay_ms(10);
output_a(0b1011);
output_b(tab7seg[ w ]);
delay_ms(10);
output_a(0b0111);

//3 7seg on

output_b(tab7seg[ z ]);

//4 7seg on

delay_ms(10);
}

cont=!cont;

//cont=~cont

if(cont==1){

//muestra:

i=3;

//D

j=4;

//E P

z=5;}

//O

else{

//muestra:

i=0;

//A

j=1;

//U P

z=0;}

//A

output_b(0b10000000);

//Buzzer on...todo...

output_a(0b0000);
delay_ms(500);
}while(TRUE);

//...apagado durante 0,5s


//...infinito

}
21
RE: Ejemplitos en C para 16F648A

Respuesta #52 : 26 de Agosto de 2005, 09:12:00

Espaa
Mensajes:
2387

Un ejemplito mas!!!!y seguimos machacando los display"s de 7 segmentos de catodo


comun...esta vez el ejemplo consiste en 4 display"s de 7seg mostrar la palabra "hola" e
ir rotandola hacia la izquierda:

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

VsZeNeR

//

VsZeNeR"05

//

21/Agosto/05

//
//

Programa:

//

Version:

HOLA

0.0

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.20

Compilador:
Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Muestra el mensaje de HOLA por cuatro display"s de 7 segmentos

//

multiplexados. El mensaje se va rotando por los display"s hacia la

//

izquierda. Tener en cuenta que hay que poner la directiva NOLVP

//

para que el pin B4 sea de salida.

//

Se utiliza variables locales:

//

* i -> indice tabla 7seg para mostrar 1 7seg

//

* j -> indice tabla 7seg para mostrar 2 7seg

//

* z -> indice tabla 7seg para mostrar 3 7seg

//

* w -> indice tabla 7seg para mostrar 4 7seg

//

* flag -> variable que cuenta 0.5s

//

* var -> ajuste fino para que desborde cada medio segundo.

//

Utilizamos la funcion de interrupcion para actualizar indices de la

//

tabla de 7seg para mostrar la palabra correspondiente en el respectivo

//

7seg, para ello el TMR0 se desborda cada 0.5s, para ello debe ser cargado

//

con 61(equivale a un desbordamiento cada 50ms mas o menos), para obtener

//

un desbordamiento de 0.5s utilizamos una variable(flag) que no entra en

//

la actualizacion de indices hasta transcurrido 0.5s.

//

Conexiones:

//

RA0 -> Display 1 7seg

//

RA1 -> Display 2 7seg

//

RA2 -> Display 3 7seg

//

RA3 -> Display 4 7seg

//

RB0 -> a 7seg

//

RB1 -> b 7seg

//

RB2 -> c 7seg

//

RB3 -> d 7seg

//

RB4 -> e 7seg

//

RB5 -> f 7seg

//

RB6 -> g 7seg

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
#use delay (clock=4000000)

//ordenes para el programador

//Fosc=4Mhz

#use standard_io(B)
#use standard_io(A)

char i=0,j=1,z=2,w=3,var=10,flag=0;

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){

//ya es 1 segundo?

//indices para tabla 7 seg

var--;

//SI -> decremento var...

if(var<18)
var=10;

//...ajuste fino de 1s

flag=0;
i++;

//reset flag para contar 1s


//incrementos...

j++;
z++;
w++;

//...indices para mostrar en 7seg

if(i>3)
i=0;

//Ha llegado fin tab7seg?


//SI -> restaura indice i

if(j>3)
j=0;

//Ha llegado fin tab7seg?


//SI -> restaura indice j

if(z>3)
z=0;

//Ha llegado fin tab7seg?


//SI -> restaura indice z

if(w>3)
w=0;

//Ha llegado fin tab7seg?


//SI -> restaura indice w

set_timer0(61);
flag++;

//reset TMR0
//incremento variable flag

///PROGRAMA
void main(void)
{
int tab7seg[4]={0x76,0x3F,0x38,0x77};

//7seg H O L A

set_tris_b(0x00);

//portb como salida

set_tris_a(0x00);

//porta como salida

enable_interrupts(INT_TIMER0);

//interrupcion TIMER0 activada

setup_counters(RTCC_INTERNAL,RTCC_DIV_256);

//configuracion interrupcion

TMR0
set_timer0(61);

//carga TMR0

enable_interrupts(GLOBAL);

do{

//activadas interrupciones

//bucle...

output_low(PIN_A0);
output_high(PIN_A1);

//activado...

output_high(PIN_A2);
output_high(PIN_A3);
output_b(tab7seg[ i ]);

//...1 7seg

delay_ms(10);
output_high(PIN_A0);
output_low(PIN_A1);

//activado...

output_high(PIN_A2);
output_high(PIN_A3);
output_b(tab7seg[ j ]);

//...2 7seg

delay_ms(10);
output_high(PIN_A0);
output_high(PIN_A1);
output_low(PIN_A2);

//activado...

output_high(PIN_A3);
output_b(tab7seg[ z ]);

//...3 7seg

delay_ms(10);
output_high(PIN_A0);
output_high(PIN_A1);
output_high(PIN_A2);
output_low(PIN_A3);

//activado...

output_b(tab7seg[ w ]);

//...4 7seg

delay_ms(10);
}while(TRUE);

//...infinito

22
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

26/Agosto/05

//
//

Programa:

//

Version:

Cuadrado que recorre 4 display"s de 7seg de izuiqerda a derechas

0.0

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.20

Compilador:
Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Simbolo recorre cuatro display"s de 7 segmentos de izquierda

//

a derechas y viceversa.

//

Tener en cuenta que hay que poner la directiva NOLVP

//

para que el pin B4 sea de salida.

//

Se utiliza variables locales:

//

* i -> contador de display on

//

* display_on[] -> vector con el display on

//

Conexiones:

//

RA0 -> Display 1 7seg

//

RA1 -> Display 2 7seg

//

RA2 -> Display 3 7seg

//

RA3 -> Display 4 7seg

//

RB0 -> a 7seg

//

RB1 -> b 7seg

//

RB2 -> c 7seg

//

RB3 -> d 7seg

//

RB4 -> e 7seg

//

RB5 -> f 7seg

//

RB6 -> g 7seg

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
#use delay (clock=4000000)

//ordenes para el programador

//Fosc=4Mhz

#use standard_io(B)
#use standard_io(A)

///PROGRAMA
void main(void)
{
char i=0;

//contador de display on

int display_on[4]={0b1110,0b1101,0b1011,0b0111}; //tabla display on

set_tris_b(0x00);

//portb como salida

set_tris_a(0x00);

//porta como salida

disable_interrupts(GLOBAL);

output_b(0x63);

//muestra por pantalla simbolo

output_a(display_on[ i ]);

do{

//inicializo display

//bucle...

for(i=0;i<3;i++){

//hacia la izquierda

delay_ms(100);
output_a(display_on[ i ]);
}

//desactivadas interrupciones

for(i=3;i>0;i--){

//hacia la derecha

delay_ms(100);
output_a(display_on[ i ]);
}
}while(TRUE);

//...infinito

}
23
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

25/Agosto/05

//
//

Programa:

//

Version:

Dado digital

0.0

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.20

Compilador:
Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Dado digital, que al presionar el boton conectado al pin A0 del porta

//

genera un numero pseudo-aleatorio mediante la funcion rand() que se

//

encuentra en la libreria STDLIB.H. El numero pseudo-aleatorio es elegido

//

mediante la funcion rand() y segun los "rebotes" producidos por el boton.Tener

//

en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida. Cuando agregamos un boton a nuestro circuito hay que tener en cuenta

//

que este dispositivo genera "rebotes" que hay que ser eliminados para

//

una correcta visualizacion en el display del digito seleccionado. Esta vez

//

la eliminacion de "los rebotes" se ha realizado mediante software.

//
//

Conexiones:

A0 -> boton

//

B0 -> a

//

B1 -> b

//

B2 -> c

//

B3 -> d

//

BCD:

//

dcba

NUM

//

0000

//

0001

//

0010

//

0011

//

0100

//

0101

//

0110

//

0111

//

1000

//

1001

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

#include <16f648a.h>

//pic a utilizar

#include <STDLIB.H>

//libreria donde esta la funcion rand();

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
#use delay (clock=4000000)

//ordenes para el programador

//Fosc=4Mhz

#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3)
#use standard_io(A)

///PROGRAMA
void main(void)
{
char num=0;

//variable almacena numero aleatorio

set_tris_a(0xFF);

//porta como entrada

disable_interrupts(GLOBAL);

srand(10);

//todas las interrupciones desactivadas

//maximo hasta 9

for( ; ; ){

//bucle...

if(!input(PIN_A0))

//se ha pulsado el boton?

{
do{

//elimina...

num=rand();

//genera numero pseudo-aleatorio

}while(!input(PIN_A0));

//...rebotes

}
output_b(num);
}

//muestra por portb digito 7 segmentos

//...infinito

}
24
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

26/Agosto/05

//
//

Programa:

//

Version:

Hola mundo

0.0

//
//

Dispositivo: PIC 16F648A

Compilador:

CCS vs3.227

//

Entorno IDE: MPLAB IDE v7.21

Simulador:

Proteus 6.7sp3

//
//

Notas: Se muestra por pantalla de lcd(LM016L) en la primera linea la

//

frase "hola mundo

" y en la segunda linea "VsZeNeR"05". Tener

//

en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida.

//
//

Conexiones:

B0 -> E

//

B1 -> RS

//

B2 -> RW

//

B4 -> D4

//

B5 -> D5

//

B6 -> D6

//

B7 -> D7

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP

//ordenes para el programador

#use delay (clock=4000000)

//Fosc=4Mhz

#define use_portb_lcd TRUE

//definir portb lcd

#include<lcd.c>

//libreria manejo lcd

///PROGRAMA
void main(void)
{
lcd_init();

//inicializa lcd

printf(lcd_putc,"hola mundo ; )
VsZeNeR"05" );

//muestra por pantalla el mensaje

}
25
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

26/Agosto/05

//
//

Programa:

//

Version:

Hola mundo VsZeNeR"05 ahorrando 1 pin

0.1

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.20

Compilador:
Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Se muestra por pantalla de lcd(LM016L) en la primera linea la

//

frase "hola mundo ; )" y en la segunda linea "VsZeNeR"05". Para ahorrar un

//

pin conectamos RW a tierra(GND) y en nuestro programa generamos un retraso de

//

2ms para poder apreciarse todos los caracteres. La ventaja es que nos ahorramos

//

1 pin pero la desventaja es menor rapidez ya que empaquetamos en bloques de 4 bit.

//

Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida.

//
//

Conexiones:

B0 -> E

//

B1 -> RS

//

B4 -> D4

//

B5 -> D5

//

B6 -> D6

//

B7 -> D7

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP

//ordenes para el programador

#use delay (clock=4000000)

//Fosc=4Mhz

#define use_portb_lcd TRUE

//definir portb lcd

#include<lcd.c>

//libreria manejo lcd

///PROGRAMA
void main(void)
{
lcd_init();

//inicializa lcd

delay_ms(2);

//retardo para apreciarse todos los caracteres

printf(lcd_putc,"hola mundo ; )
VsZeNeR"05" ) ;

//muestra por pantalla el mensaje

}
26
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

29/Agosto/05

//
//

Programa:

//

Version:

VsZeNeR"05 mov pantalla

0.0

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.21

Compilador:
Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Se muestra por pantalla de lcd(LM016L) como la palabra VsZeNeR"05

//

se va moviendo por pantalla, empieza en la 1fila y termina en la 2fila.

//

Se utiliza variables locales:

//

x -> indice filas, es de tipo char signed porque necesitamos n negativos

//

para que en la 2fila del lcd aparezca primero el final del mensaje.

//

y -> indice de columnas: y=1 -> 1columna

//

y=2 -> 2columna

//

La "x" se comprende en pantalla desde 1 hasta 16 y la "y" desde 1 hasta 2.

//

Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida.

//
//

Conexiones:

B0 -> E

//

B1 -> RS

//

B2 -> RW

//

B4 -> D4

//

B5 -> D5

//

B6 -> D6

//

B7 -> D7

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP

//ordenes para el programador

#use delay (clock=4000000)

//Fosc=4Mhz

#define use_portb_lcd TRUE

//definir portb lcd

#include<lcd.c>

//libreria manejo lcd

///PROGRAMA
void main(void)
{
char y=1;

//indice columnas

signed char x=1;

//indice filas

lcd_init();

while(TRUE){

//inicializa lcd

//bucle...

lcd_gotoxy(x,y) ;

//cursor para escribir mensaje

lcd_putc("VsZeNeR"05" ) ;

//muestra por pantalla el mensaje

delay_ms(150);
x++;
if(x>16){

//incremento indice de filas


//ya se ha mostrado mensaje entero por 1fila?

x=-8;

//SI -> indice fila x=-8

y++;

//incremento indice columnas

if(y>2)

//ya se ha mostrado mensaje por 2 columna?

y=1;

//SI -> restauro indice columna

}
lcd_putc("f" ) ;
}

//borra pantalla

//...infinito

}
27
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

26/Agosto/05

//
//

Programa:

//

Version:

Abecedario

0.0

//
//

Dispositivo: PIC 16F648A

Compilador:

//

Entorno IDE: MPLAB IDE v7.21

CCS vs3.227

Simulador:

Proteus 6.7sp3

//
//

Notas: Se muestra por pantalla de lcd(LM016L) el abecedario y vuelta a empezar

//

Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida.

//

abecedario[] -> vector donde se almacena abecedario

//

x -> indice para vector abecedario e indice para columna lcd

//

y -> indice para fila lcd: y=1 -> Fila 1

//
//

y=2 -> Fila 2


Conexiones:

B0 -> E

//

B1 -> RS

//

B2 -> RW

//

B4 -> D4

//

B5 -> D5

//

B6 -> D6

//

B7 -> D7

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP

//ordenes para el programador

#use delay (clock=4000000)

//Fosc=4Mhz

#define use_portb_lcd TRUE

//definir portb lcd

#include<lcd.c>

///PROGRAMA
void main(void)

//libreria manejo lcd

{
char abecedario[27]={"
","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"},x,y=1;
//tabla y variables definidas

lcd_init();

//inicializa lcd

do{

//bucle...

for(x=1;x<27;x++){
if(y==1)

//bucle para mostrar digito

//1 fila del lcd

lcd_gotoxy(x,y);
else

//2 fila del lcd

lcd_gotoxy((x-16),y);

if(x>15)

//ya esta completa la 1 fila del lcd?

y=2;

//SI -> escribe en 2 fila

printf(lcd_putc,"%c",abecedario[ x ]);

//muestra por pantalla el caracter

delay_ms(300);
}
printf(lcd_putc,"f " ) ;
y=1;

//borra pantalla del lcd

//restablece indice

}while(TRUE);

//...infinito

}
28
Programa:
//

Version:

VsZeNeR"05 mov limites


0.0

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.21

Compilador:
Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Se muestra por pantalla de lcd(LM016L) como la palabra VsZeNeR"05

//

se va moviendo por pantalla, empieza en la 1fila y termina en la 2fila y

//

empieza a moverse en sentido contrario,2fila hasta la 1fila.

//

Se utiliza variables globales:

//

x -> indice filas, es de tipo char signed porque necesitamos n negativos

//

para que en la 2fila del lcd aparezca primero el final del mensaje.

//
//

y -> indice de columnas: y=1 -> 1columna


y=2 -> 2columna

//

derecha() -> funcion que muestra mensaje de izquierda a derecha

//

izquierda() -> funcion que muestra mensaje de derecha a izquierda

//

La "x" se comprende en pantalla desde 1 hasta 16 y la "y" desde 1 hasta 2.

//

Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida.

//
//

Conexiones:

B0 -> E

//

B1 -> RS

//

B2 -> RW

//

B4 -> D4

//

B5 -> D5

//

B6 -> D6

//

B7 -> D7

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP

//ordenes para el programador

#use delay (clock=4000000)

//Fosc=4Mhz

#define use_portb_lcd TRUE

//definir portb lcd

#include<lcd.c>

//libreria manejo lcd

///DEFINICION VARIABLES GLOBALES


char y=1;

//indice columnas

signed char x=1;

//indice filas

///DECLARACION DE FUNCIONES
void derecha(void);

//mensaje hacia la derecha

void izquierda(void);

//mensaje hacia la izquierda

///PROGRAMA
void main(void)
{
lcd_init();

//inicializa lcd

while(TRUE){

//bucle...

derecha() ;
izquierda() ;
}

//...infinito

///FUNCION MUESTRA MENSAJE DE IZQUIERDA -> DERECHA


void derecha(void)
{

do{
lcd_gotoxy(x,y);

//cursor para escribir mensaje

lcd_putc("VsZeNeR"05" );

//muestra por pantalla el mensaje

delay_ms(150);
x++;

//incremento indice de filas

if(x>17){

//ya se ha mostrado mensaje entero por 1fila?

x=-8;

//SI -> indice fila x=-8

y++;

//incremento indice columnas

if(y>2){

//ya se ha mostrado mensaje entero por 2fila?

x=16;

//SI -> actualiza indice filas

y=2;

//actualiza indice columnas

return;}

//sal de la funcion derecha()

}
lcd_putc("f" );

//borra pantalla

}while(TRUE);
}
///FUNCION MUESTRA MENSAJE DE DERECHA -> IZQUIERDA
void izquierda(void)
{
do{
x--;

//decremento indice de filas

if(x<-9){

//ya se ha mostrado mensaje entero por 2fila?

x=16;

//SI -> indice fila x=16

y--;

//decremento indice columnas

if(y<1){

//ya se ha mostrado mensaje por 1 fila?

x=-8;

//SI -> restauro indice filas

y=1;

//restauro indice columnas

return;}

//sal de la funcion izquierda()

}
lcd_gotoxy(x,y) ;

//cursor para escribir mensaje

lcd_putc("VsZeNeR"05" ) ;

//muestra por pantalla el mensaje

delay_ms(150) ;
lcd_putc("f" ) ;

//borra pantalla

}while(TRUE) ;
}
29
////////////////////////////////////////////////////////////////////////////////////
//

VsZeNeR"05

//

30/Agosto/05

//
//

Programa:

Escribir & leer eeprom interna del PIC y mostrarla por lcd

//

Version:

0.0

//
//

Dispositivo: PIC 16F648A

Compilador:

//

Entorno IDE: MPLAB IDE v7.21

CCS vs3.227

Simulador:

Proteus 6.7sp3

//
//

Notas: Se muestra por pantalla de lcd(LM016L) la informacion grabada en la memoria

//

interna del PIC(eeprom) y luego se muestra por la lcd

//

Se utiliza variables locales:

//

LAST_VOLUME -> posicion a grabar en la eeprom del pic

//

mensaje1[] -> contiene 1 mensaje a escribir en eeprom y mostrar en lcd

//

mensaje2[] -> contiene 2 mensaje a escribir en eeprom y mostrar en lcd

//

mensaje3[] -> contiene 3 mensaje a escribir en eeprom y mostrar en lcd

//

mensaje4[] -> contiene 4 mensaje a escribir en eeprom y mostrar en lcd

//

volume -> contiene mensaje leido por la eeprom interna del pic

//

Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de

//

salida.

//

Conexiones:

B0 -> E

//

B1 -> RS

//

B2 -> RW

//

B4 -> D4

//

B5 -> D5

//

B6 -> D6

//

B7 -> D7

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP

//ordenes para el programador

#use delay (clock=4000000)

//Fosc=4Mhz

#define use_portb_lcd TRUE

//definir portb lcd

#include<lcd.c>

//libreria manejo lcd

///PROGRAMA
void main(void)
{
char LAST_VOLUME=0,volume;

//variables de direccion escritura eeprom y mensaje

char mensaje1[]="VsZeNeR"05";

//mensajes...

char mensaje2[]="HOLA";
char mensaje3[]="FORO";
char mensaje4[]="TODOPIC!";

//a escribir en eeprom interna y mostrar en lcd

lcd_init();

//inicializa lcd

write_eeprom(LAST_VOLUME,mensaje1);

//escritura de los mensajes...

LAST_VOLUME++;
write_eeprom(LAST_VOLUME,mensaje2);
LAST_VOLUME++;
write_eeprom(LAST_VOLUME,mensaje3);
LAST_VOLUME++;
write_eeprom(LAST_VOLUME,mensaje4);

for( ; ; ){

//...en la eeprom interna(0 hasta la 3)

//bucle...

for(LAST_VOLUME=0;LAST_VOLUME<4;LAST_VOLUME++){

//bucle que recorre las posiciones de

eeprom
volume = read_EEPROM (LAST_VOLUME);
printf(lcd_putc,"%s",volume) ;

//almacena mensaje de la direccion eeprom

//muestra mensaje por pantalla lcd

delay_ms(500);
lcd_putc("f" );
}

//borra pantalla lcd

//...infinito

}
}
30
RE: Ejemplitos en C para 16F648A

Respuesta #78 : 05 de Septiembre de 2005, 06:01:00

Espaa
Mensajes:
2387

Vamos con un ejemplito mas de manejo de lcd!!!esta vez haremos un contador de 0 a 9


y vuelta a empezar pero con un pulsador, es decir cada vez que presionemos el
pulsador se mostrara el siguiente digito de nuestro contador hasta llegar a 9 que
entonces si volvemos a pulsar el boton volvera a cero y se escuchara un beep del
zumbador conectado al pic:

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

VsZeNeR

//

VsZeNeR"05

//

27/Agosto/05

//
//

Programa:

//

Version:

Contador 0a9 por LCD con pulsador y buzzer

0.0

//
//

Dispositivo: PIC 16F648A

//

Entorno IDE: MPLAB IDE v7.21

Compilador:
Simulador:

CCS vs3.227
Proteus 6.7sp3

//
//

Notas: Se muestra por pantalla de lcd(LM016L) un mensaje de inicio del programa

//

y se espera hasta que pulsemos el boton, entonces se borra pantalla y cada vez

//

que presionemos el boton se ira incrementando en un valor el digito mostrado

en
//

la mitad de la fila 1 del lcd hasta llegar a 9 que entonces volvera a 0 y se

//

emitira un beep.

//

Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea

de
//

salida.

//

tabNum[] -> vector donde se almacenan numeros del contador 0a9

//

i -> indice para vector tabNum

//

Conexiones:

B0 -> E

//

B1 -> RS

//

B2 -> RW

//

B4 -> D4

//

B5 -> D5

//

B6 -> D6

//

B7 -> D7

//

B3 -> Buzzer(beep)

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

#include <16f648a.h>

//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP

//ordenes para el programador

#use delay (clock=4000000)

//Fosc=4Mhz

#define use_portb_lcd TRUE

//definir portb lcd

#include<lcd.c>

//libreria manejo lcd

///PROGRAMA
void main(void)
{
char tabNum[10]={"0","1","2","3","4","5","6","7","8","9"},i=0;

//tabla y variable

definida

lcd_init();

//inicializa lcd

printf(lcd_putc,"Presione boton
para contador0a9" );

do{

//muestra mensaje inicio

//espera hasta que se pulse boton...

}while(input(PIN_A0)==1);
printf(lcd_putc,"f" );

//...para borrar pantalla e iniciar contador

printf(lcd_putc,"
VsZeNeR"05" );

//auto publicidad en la 2fila lcd

lcd_gotoxy(8,1);

//vuelve 1fila lcd y apunta la mitad de la columna

for( ; ; ){

//bucle...

if(!input(PIN_A0)){
do{

//se ha pulsado el boton?


//SI -> eliminar...

}while(!input(PIN_A0));
if(i>9){

//...rebotes del boton

//se ha mostrado digito 9?

i=0;

//SI -> restaura valor indice(para mostrar digito 0)

output_high(PIN_B3);
delay_ms(50);

//activa buzzer(beep)
//tiempo de escucha del beep

output_low(PIN_B3);

//desactiva buzzer(beep)

}
printf(lcd_putc,"%c",tabNum[ i ]);
printf(lcd_putc,"" );
i++;

//muestra por pantalla el numero

//retrasa el cursor una posicion(escribe encima)


//incremento contador indice tabNum

}
}

//...infinito

31

////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
30/Agosto/05
//
// Programa: Escribir & leer eeprom externa 24LC256 y mostrarla por lcd
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) la informacion grabada en la memoria
//
externa 24LC256(eeprom) y luego se muestra por la lcd
//
Se utiliza variables locales:
//
dir-> posicion a grabar en la eeprom 24LC256
//
men1[] -> contiene 1 mensaje a escribir en eeprom y mostrar en lcd
//
men2[] -> contiene 2 mensaje a escribir en eeprom y mostrar en lcd
//
men3[] -> contiene 3 mensaje a escribir en eeprom y mostrar en lcd
//
men4[] -> contiene 4 mensaje a escribir en eeprom y mostrar en lcd
//
En la pantalla lcd se muestra la direccion de memoria donde esta grabado el
//
mensaje a mostrar y el correspondiente mensaje.
//
Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
//
salida.
// Conexiones:
A0 -> SCK eeprom externa

//
A1 -> SDA eeprom externa
//
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#use delay(CLOCK=4000000)
//Fosc=4Mhz
#fuses HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT //comandos para el programador
#define use_portb_lcd TRUE
//utilizar el port b para lcd
#define EEPROM_SDA PIN_A1
//definimos los pines donde...
#define EEPROM_SCL PIN_A0
//la eeprom ira conectada
#include <24256.c>
//libreria de eeprom externa 24LC256
#include <lcd.c>
//libreria de lcd
///PROGRAMA
void main(void){
int dir=0;
//direccion de eeprom a escribir y leer mensajes
char men1[]="VsZeNeR"05"; //declaracion de...
char men2[]="Hola";
char men3[]="Foro";
char men4[]="TODOPIC!";
//...mensajes a escribir y leer por 25LC256
lcd_init();
//inicializa lcd
init_ext_eeprom();
//inicializa eeprom
lcd_putc("~ Escribiendo en...
24LC256
");
delay_ms(500);
write_ext_eeprom(dir,men1 ) ;
dir++;
write_ext_eeprom(dir,men2 ) ;
dir++;
write_ext_eeprom(dir,men3 ) ;
dir++;
write_ext_eeprom(dir,men4) ;
lcd_putc("fFin de escritura en
24LC25" ) ;
delay_ms(1500) ;

//proceso de escribir...

//...los mensajes en la eeprom externa

lcd_putc("f>>>Leyendo...
");
for(dir=0;dir<4;dir++){
//bucle para leer mensajes en eeprom externa y muestra por lcd
printf(lcd_putc,"
%d ~ %s",dir,read_ext_eeprom(dir) ) ;
delay_ms(1500);
//retraso para que se vea en pantalla los mensajes
lcd_putc("
" );
//borrado 2linea de lcd
}
output_a(0b00);
//apago port a
lcd_putc("fFin de lectura!" ) ;
for( ; ; ){

//animacion...

for(dir=1;dir<8;dir++){
lcd_gotoxy(dir,2);
lcd_putc("VsZeNeR"05" ) ;
delay_ms(200);
lcd_putc("
" );
}
for(dir=6;dir>1;dir--){
lcd_gotoxy(dir,2);
lcd_putc("VsZeNeR"05" ) ;
delay_ms(200);
lcd_putc("
");
}
}
//...final
}
32
//
VsZeNeR"05
//
08/Septiembre/05
//
// Programa: Dado digital con lcd y buzzer
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Dado digital, que al presionar el boton conectado al pin A0 del porta
//
genera un numero pseudo-aleatorio mediante la funcion rand() que se
//
encuentra en la libreria STDLIB.H. El numero pseudo-aleatorio es elegido
//
mediante la funcion rand() y segun los "rebotes" producidos por el boton.Tener
//
en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
//
salida. Cuando agregamos un boton a nuestro circuito hay que tener en cuenta
//
que este dispositivo genera "rebotes" que hay que ser eliminados para
//
una correcta visualizacion en la lcd del digito seleccionado. Esta vez
//
la eliminacion de "los rebotes" se ha realizado mediante software.
//
// Conexiones:
A0 -> boton
//
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//
B3 -> Buzzer(beep)
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#define RAND_MAX 7
//dado solamente 6 numeros
#include <STDLIB.H>
//libreria donde esta la funcion rand();
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(B)
#use fast_io(A)
#define use_portb_lcd TRUE
//definir portb lcd
#include<lcd.c>
//libreria manejo lcd

///PROGRAMA
void main(void)
{
char num=0;

//variable almacena numero aleatorio

set_tris_a(0xFF);
//porta como entrada
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
lcd_init();

//inicializa lcd

srand(10);
//maximo hasta 9
lcd_putc("Dado Electronico
Pulse boton..." );
while(input(PIN_A0)){}
lcd_putc("fDado:
VsZeNeR"05" );
lcd_gotoxy(7,1);

//Se mantiene cabecera hasta que se pulse el boton

//Coordenadas dond se muestra el numero

for( ; ; ){
//bucle...
if(!input(PIN_A0))
//se ha pulsado el boton?
{
do{
//SI -> elimina...
num=rand();
//genera numero pseudo-aleatorio
}while(!input(PIN_A0)); //...rebotes
printf(lcd_putc,"%d",num); //muestra por lcd numero
lcd_putc("" );
//retrocede un espacio
output_high(PIN_B3);
//activa buzzer(beep)
delay_ms(50);
//tiempo de escucha del beep
output_low(PIN_B3);
//desactiva buzzer(beep)
}
}

//...infinito

}
33
///////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
09/Septiembre/05
//
// Programa: Reloj-Calendario DS1302
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) la fecha y hora obtenida mediante la
//
lectura del DS1302. Pudiendose modificar mediante los botones Conf/Ok y up.
//
Se utiliza variables globales:
//
day-> dia ds1302
//
mth -> mes ds1302
//
year -> ao ds1302
//
hour -> hora ds1302
//
min -> minutos ds1302
//
sec-> segundos ds1302

//
menu -> variable que muestra opcion del menu configurar
//
flag -> variable que cuenta hasta 130ms aprox.
//
var -> ajuste fino para que desborde cada 130ms aprox.
//
Se carga el TMR0 con 0 por lo tanto se desborda en 65ms aprox, queremos
//
visualizar y restaurar valores cogidos del ds1302 cada 130ms aprox por lo tanto
//
utilizamos una variable llamada flag que sera la encargada de dicha tarea.
//
Al inicio del programa debe ser configurado el reloj, siendo el boton "up" el
//
encargado de ir moviendose mediante las opciones del menu:hora,minutos,....
//
y el boton "Conf/Ok" el encargado de configurar el reloj(cuando estemos en modo ver
//
hora y fecha) o el encargado de salir de la configuracion de las opciones(cuando
//
estemos en formato de configurar fecha y hora).
//
Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
//
salida.
// Conexiones:
A0 -> RST DS1302
//
A1 -> SCLK DS1302
//
A2 -> I/O DS1302
//
A3 -> Boton "up"
//
A5 -> Boton "Conf/Ok"
//
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//
B3 -> Zumbador(beep)
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#use delay(CLOCK=4000000)
//Fosc=4Mhz
#fuses HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT,NOMCLR
#use standard_io(a)
#use standard_io(b)
#define use_portb_lcd TRUE
//utilizar el port b para lcd
#define RTC_SCLK PIN_A1
//definimos pin"s...
#define RTC_IO PIN_A2
#define RTC_RST PIN_A0
//...de conexion de la rtc ds1302
#include <ds1302.c>
//libreria de rtc ds1302
#include <lcd.c>
//libreria de lcd
///VARIABLES GLOBALES
byte day,mth,year,dow,hour,min,sec; //variabes para ds1302
byte menu=0,flag=0,var=2;
//variables para menu configurar
///DEFINICION DE FUNCIONES
void configurar(void);
void horas(void);
void minutos(void);
void dia(void);
void mes(void);
void anio(void);
void beep(void);
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER0
void interrupcion()
{
if(flag>var){
//ya es 130ms aprox?

//comandos para el programador

var--;
//SI -> decremento var...
if(var==0)
var=2;
//...ajuste fino de 130ms aprox
flag=0;
//reset flag para contar 130ms aprox
rtc_get_date(day,mth,year,dow);
//coge dia,mes,ao
rtc_get_time(hour,min,sec );
//coge hora,minuto,segundo
printf(lcd_putc,"fFecha: %2X/%2X/%2X
Hora: %2X:%2X:%2X",day,mth,year,hour,min,sec);
//lcd
}
set_timer0(0);
//reset TMR0
flag++;
//incremento variable flag
}
///PROGRAMA
void main(void){
enable_interrupts(INT_TIMER0);
//interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0
set_timer0(0);
//carga TMR0
lcd_init();
rtc_init();

//inicializa lcd
//inicializa rtc

lcd_putc("Reloj Calendario
VsZeNeR"05" ); //presentacion...
delay_ms(800);
//...inicial
configurar();
//ve a menu configurar
enable_interrupts(GLOBAL);
//activadas interrupciones
for( ; ; ){
//bucle...
if(input(PIN_A5)==0){
//Si se pulsa Conf....
while(!input(PIN_A5)){}
//elimina rebotes
beep();
configurar();
}
//ve a menu
configurar
}
}

//...infinito

///FUNCION CONFIGURAR
void configurar(void){
disable_interrupts(GLOBAL);
do{
switch(menu){
case 0: lcd_putc("fConfigurar
horas?" );
//horas
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
horas();
menu=1;

//desactivadas interrupciones

//apunta siguiente opcion


}
break;
case 1: lcd_putc("fConfigurar
minutos?" );
//minutos
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
minutos();
menu=2;
//apunta siguiente opcion
}
break;
case 2: lcd_putc("fConfigurar
dia?" );
//dias
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
dia();
menu=3;
//apunta siguiente opcion
}
break;
case 3: lcd_putc("fConfigurar
mes?" );
//mes
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
mes();
menu=4;
//apunta siguiente opcion
}
break;
case 4: lcd_putc("fConfigurar
anio?" );
//aos
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
anio();
menu=5;
//apunta siguiente opcion
}
break;
case 5: lcd_putc("fSalir
configurar?" );
//salir configuracion
if(!input(PIN_A5)){
menu=6;
beep();
}
}
if(!input(PIN_A3)){
//controla el boton up...
while(!input(PIN_A3)){}
menu++;

if(menu>5)
menu=0;
}

//...para mostrar menu

por lcd
delay_ms(130);
}while(menu<6);

//retardo para ver lcd

menu=0;
//actualiza indices menu
rtc_set_datetime(day,mth,year,dow,hour,min); //nueva hora,minuto,...
enable_interrupts(GLOBAL);
//activadas
interrupciones
set_timer0(0);
//carga TMR0
}
///FUNCION CONFIGURA HORAS
void horas(void){
printf(lcd_putc,"fConf.Horas:
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por lcd
do{
if(!input(PIN_A3)){
//se ha pulsado up?
while(!input(PIN_A3)){}
//elimina rebotes
hour++;
//SI ->
incremento hour
switch(hour){
//limites...
case 0x0A: hour=0x10;break;
case 0x1A: hour=0x20;break;
case 0x24: hour=0x00;
}
//...hour
printf(lcd_putc,"
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por lcd hour
}
}while(input(PIN_A5));
while(!input(PIN_A5)){}
//elimina rebotes
}
///FUNCION CONFIGURA MINUTOS
void minutos(void){
printf(lcd_putc,"fConf.Minutos:
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por lcd
do{
if(!input(PIN_A3)){
//se ha pulsado up?
while(!input(PIN_A3)){}
//elimina rebotes
min++;
//SI -> incremento min
switch(min){
//limites...
case 0x0A: min=0x10;break;
case 0x1A: min=0x20;break;
case 0x2A: min=0x30;break;
case 0x3A: min=0x40;break;
case 0x4A: min=0x50;break;
case 0x5A: min=0x00;

}
//...min
printf(lcd_putc,"
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por lcd min
}
}while(input(PIN_A5));
while(!input(PIN_A5)){}
//elimina rebotes
}
///FUNCION CONFIGURA DIAS
void dia(void){
printf(lcd_putc,"fConf.Dias:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por lcd
do{
if(!input(PIN_A3)){
//se ha pulsado up?
while(!input(PIN_A3)){}
//elimina rebotes
day++;
//SI -> incremento day
switch(day){
//limites...
case 0x0A: day=0x10;break;
case 0x1A: day=0x20;break;
case 0x2A: day=0x30;break;
case 0x32: day=0x01;
}
//...day
printf(lcd_putc,"fConf.Dias:
Fecha: %2X/%2X/%2X",day,mth,year);
//muestra por lcd day
}
}while(input(PIN_A5));
while(!input(PIN_A5)){}
//elimina rebotes
}
///FUNCION CONFIGURA MES
void mes(void){
printf(lcd_putc,"fConf.Mes:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por lcd
do{
if(!input(PIN_A3)){
//se ha pulsado up?
while(!input(PIN_A3)){}
//elimina rebotes
mth++;
//SI -> incremento mth
switch(mth){
//limites...
case 0x0A: mth=0x10;break;
case 0x13: mth=0x01;
}
//...mth
printf(lcd_putc,"fConf.Mes:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por
lcd
}
}while(input(PIN_A5));
while(!input(PIN_A5)){}

//elimina rebotes
}
///FUNCION CONFIGURA AOS
void anio(void){
printf(lcd_putc,"fConf.Anio:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por lcd
do{
if(!input(PIN_A3)){
//se ha pulsado up?
while(!input(PIN_A3)){}
//elimina rebotes
year++;
//SI -> incremento mth
switch(year){
//limites...

case 0x0A: year=0x10;break;


case 0x1A: year=0x20;break;
case 0x2A: year=0x30;break;
case 0x3A: year=0x40;break;
case 0x4A: year=0x50;break;
case 0x5A: year=0x60;break;
case 0x6A: year=0x70;break;
case 0x7A: year=0x80;break;
case 0x8A: year=0x90;break;
case 0x9A: year=0x00;
}
//...year
printf(lcd_putc,"fConf.Anio:
Fecha: %2X/%2X/%2X",day,mth,year);

//muestra por

lcd
}
}while(input(PIN_A5));
while(!input(PIN_A5)){}
}
///FUNCION BEEP
void beep(void){
output_high(PIN_B3);
delay_ms(50);
output_low(PIN_B3);
}

//elimina rebotes

//activa zumbador
//desactiva zumbador

Decir, que el programita aparte de manejar dispositivos externos(lcd,buzzer,ds1302), maneja tb la


interrupcion del TMR0 para la visualizacion en formato visualizar fecha-hora en la lcd, aparte tb he quitado la
funcion de reset externo mediante el MRCL y he utilizado ese pin para el boton "Conf/Ok" esto no es
aconsejable ya que siempre es bueno tener un reset externo pero bueno era simplemente para poner un
ejemplo de eliminar el reset externo y utilizar dicho pin como un puerto mas
34
//
//
//
//
//
//
//
//
//

VsZeNeR"05
11/Septiembre/05
Programa: Comunicacion PC via RS232
Version: 0.0
Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
Notas: Se muestra por pantalla de lcd(LM016L) en la primera linea la

//
frase "hola mundo
" y en la segunda linea "VsZeNeR"05". Se muestra el
//
mismo mensaje por el PC. Tener en cuenta que hay que poner la directiva
//
NOLVP para que el pin B4 sea de salida.
//
// Conexiones:
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//
A0 -> T1IN MAX232
//
A1 -> R1OUT MAX232
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) //manejo del RS232
#define use_portb_lcd TRUE
//definir portb lcd
#include<lcd.c>
//libreria manejo lcd
///PROGRAMA
void main(void)
{
lcd_init();

//inicializa lcd

printf(lcd_putc,"hola mundo ; )
VsZeNeR"05" ); //mensaje por lcd
printf("hola mundo VsZeNeR"05" );
}

//mensaje por PC

35
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
17/Septiembre/05
//
// Programa: RS232 y teclado 3x4
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por virtual terminal(PC) la tecla pulsada conectado un
//
keypad 4x3 al pic. Tener en cuenta que hay que poner la directiva
//
NOLVP para que el pin B4 sea de salida.
//
// Conexiones:
B1 -> Fila A keypad
//
B2 -> Fila B keypad
//
B3 -> Fila C keypad
//
B4 -> Fila D keypad
//
B5 -> Columna 1 keypad
//
B6 -> Columna 2 keypad
//
B7 -> Columna 3 keypad
//
A0 -> Rx
//
A1 -> Tx
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) //manejo del RS232
#define use_portb_kbd TRUE
//definir portb keypad
#include<kbd.c>
//libreria manejo keypad
///PROGRAMA
void main(void)
{
char c;
kbd_init();

//variable almacenamos tecla


//inicializa teclado

port_b_pullups(TRUE);

//necesario para teclado

puts("Manejo del teclado 3x4


VsZeNeR"05" );
puts("====================" );
puts("
Pulse una tecla: " );
//...presentacion

//inicio...

for( ; ; ) { //bucle...
do{
//hacer hasta...
c=kbd_getc(); //recogemos tecla pulsada
}while(c==""); //...que no se pulse tecla
printf("" );
//retrocede una posicion(borra ultima tecla)
printf("%c",c);
//mensaje por v.terminal
}
//...infinito
}
37

////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
17/Septiembre/05
//
// Programa: RS232 y teclado 3x4
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por virtual terminal(PC) la tecla pulsada conectado un
//
keypad 4x3 al pic. Tener en cuenta que hay que poner la directiva
//
NOLVP para que el pin B4 sea de salida.
//
// Conexiones:
B1 -> Fila A keypad
//
B2 -> Fila B keypad
//
B3 -> Fila C keypad
//
B4 -> Fila D keypad
//
B5 -> Columna 1 keypad
//
B6 -> Columna 2 keypad
//
B7 -> Columna 3 keypad
//
A0 -> Rx
//
A1 -> Tx
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) //manejo del RS232
#define use_portb_kbd TRUE
//definir portb keypad
#include<kbd.c>
//libreria manejo keypad
///PROGRAMA
void main(void)
{
char c;
kbd_init();

//variable almacenamos tecla


//inicializa teclado

port_b_pullups(TRUE);

//necesario para teclado

puts("Manejo del teclado 3x4


VsZeNeR"05" );
puts("====================" );
puts("
Pulse una tecla: " );
//...presentacion

//inicio...

for( ; ; ) { //bucle...
do{
//hacer hasta...
c=kbd_getc(); //recogemos tecla pulsada
}while(c==""); //...que no se pulse tecla
printf("" );
//retrocede una posicion(borra ultima tecla)
printf("%c",c);
//mensaje por v.terminal
}
//...infinito
}
///////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
27/Septiembre/05
//
// Programa: Contador BCD y binario del 0 al 9
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador 0 al 9 usando interrupcion externa por el pin B0. Tener
//
en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
//
salida.
//
// Conexiones:
A0 -> A 74247/Led D1
//
A1 -> B 74247/Led D2
//
A2 -> C 74247/Led D3
//
A3 -> D 74247/Led D4
//
B0 -> Interrupcion externa
// BCD:
//
d c b a NUM
//
0000 0
//
0001 1
//
0010 2
//
0011 3
//
0100 4
//
0101 5
//
0110 6
//
0111 7
//
1000 8
//
1001 9
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(b)
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)
///VARIABLES GLOBALES
char i=0; //contador para tabla BCD
char

tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1001};//BCD 0-9
///LLAMADA FUNCION INTERRUPCION
#INT_EXT
void IntRB0()
{
i++;
//incremento contador indice tabBCD
if(i>9)
//se ha mostrado digito 9?
i=0;
//SI -> restaura valor indice(para mostrar digito 0)
output_a(tabBCD[ i ]); //muestra por porta digito 7 segmentos
}
///PROGRAMA
void main(void)
{
enable_interrupts(int_ext);
//activar interrupcion externa
ext_int_edge(L_TO_H);
//configuracion:interrupcion cuando seal esta en alta
enable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
for( ; ; ){}

//bucle infinito esperando interrupcion

}
38
Buenas!!!el programa de hoy consiste en manejar un pokitin mas el lcd y el keypad de forma dinamica...esta
vez vamos a usar un keypad de 4x4 pero nos va hacer falta modificar en algo la libreria que os puse en
algun mensaje anterior ya que necesitamos adaptarla al teclado que aparece en PROTEUS, decir que vamos
a usar un teclado el cual no viene instalado en PROTEUS sino que os lo debeis bajar de los enlaces que os
puse en un anterior post...ahi si vienen ya que yo lo he sacado de esos enlaces(es necesario ya que sino lo
haceis PROTEUS dara un error de librerias....), bien el programita consiste en hacer una llave electronica, es
decir nosotros introducimos un password/clave la cual se almacenara en una variable y despues tendremos
un menu donde podremos cambiar la clave o comprobarla con una introducida por teclado....decir que la
programacion se ha realizado caracter por caracter al introducir y comprobar la clave por lo que el codigo es
mas extenso, peor creo que asi es mas ilustrativo.....ya en la revision de este ejemplito intentaremos
modificarlo para hacerlo mas optimo!aqui el programita ke me enrollo jeje!!!:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
21/Septiembre/05
//
// Programa: Clave
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Se pide por lcd una clave a introducir, despues hay un menu de opciones:
//
0->Introducir password
//
1->Cambiar clave
//
Los caracteres * o # son fin de instruccion/accion, si estamos en cambiar clave
//
o en comprobar clave, cada vez que se pulsen dichos caracteres se terminara
//
la accion. Para introducir clave, tecleamos caracteres hasta pulsar * o # y la clave
//
ya estara almacenada. Para comprobar clave, tecleamos caracteres hasta pulsar * o #
//
y se comprobara la clave introducida con la nuestra almacenada.
//
Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de salida.
//
Se utiliza variables globales:
//
c-> almacena letra pulsada del keypad
//
limit -> longitud de clave

//
i -> contador
//
var -> 1->Clave incorrecta
//
clave[16] -> almacena clave(maximo 16 caracteres)
//
// Conexiones:
B0 -> D0 LCD/Columna 1 keypad
//
B1 -> D1 LCD/Columna 2 keypad
//
B2 -> D2 LCD/Columna 3 keypad
//
B3 -> D3 LCD/Columna 4 keypad
//
B4 -> D4 LCD/Fila A keypad
//
B5 -> D5 LCD/Fila B keypad
//
B6 -> D6 LCD/Fila C keypad
//
B7 -> D7 LCD/Fila D keypad
//
A0 -> RS LCD
//
A1 -> RW LCD
//
A2 -> E LCD
//
A3 -> Led red
//
A5 -> Led green
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT,NOMCLR
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#include<kbd4x4ABCD_PROTEUS.c>
//libreria manejo keypad
#include<lcd2.c>
//libreria manejo lcd 8bits
#use fixed_io(a_outputs=PIN_A3,PIN_A5)
#use fast_io(B)
///DEFINICION DE FUNCIONES
void nueva_clave(void);
//funcion que cambia clave
void comprueba_clave(void);
//funcion que comprueba clave
///VARIABLES GLOBALES
char clave[16],c,limit;
signed char i;
boolean var=0;
///PROGRAMA
void main(void)
{
lcd_init();

//inicializa lcd

delay_ms(50);
//presentacion...
output_low(PIN_A5);
delay_ms(50);
output_high(PIN_A3);
delay_ms(50);
output_low(PIN_A3);
lcd_putc(" VsZeNeR"05
Clave" );
delay_ms(1000);
//...inicial
nueva_clave();

//introducimos clave

for( ; ; ){ //bucle...
lcd_putc("f0->Password
1->Cambia Clave" );
do{
//espera hasta...
c=kbd_getc();
}while(c==0); //...pulsar una tecla

if(c=="1")
//ve a introducir nueva clave
nueva_clave();
if(c=="0")
//ve a comprobar clave
comprueba_clave();
}
//...infinito
}
///FUNCION CAMBIAR CLAVE
void nueva_clave(void){
lcd_putc("fNueva clave:
" ); //presentacion
for(i=0;i<16;i++){
do{
//espera hasta...
c=kbd_getc();
}while(c==0); //...pulsar una tecla
if(c=="*" || c=="#"){
//si se pulsa * o # se sale de la funcion
if(i==0){
//no se sale...
lcd_putc("
Escribe una!!!" );
delay_ms(500);
lcd_putc("
" );
lcd_gotoxy(1,2);
i=-1;
continue;
//...hasta poner una clave valida
}
break;
//salir de funcion nueva_clave
}
lcd_putc("*" );
limit=i+1;
//longitud de la clave
clave[ i ]=c;
//almacena clave(maximo 16 caracteres)
}
}
///FUNCION COMPROBAR CLAVE
void comprueba_clave(void){
lcd_putc("fIntroduce clave:
" ); //presentacion
for(i=0; ;i++){ //bucle no sale...
do{
//espera hasta...
c=kbd_getc();
}while(c==0); //...pulsar una tecla
lcd_putc("*" );
if(c=="#" || c=="*"){
//si se pulsa * o # se sale de la funcion
if(i==0){
//no se sale...
lcd_putc("
Escribe una!!!" );
delay_ms(500);
lcd_putc("
" );
lcd_gotoxy(1,2);
i=-1;
continue;
}
//...poner una clave valida
if(i!=limit) //para ser correcto debe tener tb longitud correcta

var=1;
break;
}

//salimos si se pulsa tecla * o #

if(c!=clave[ i ])
//comprobacion de caracteres correctos
var=1;
//No es correcto->clave incorrecta
}
//...hasta pulsar * o #
if(var>0){
//Clave incorrecta
lcd_putc("fClave
Incorrecta!" );
output_high(PIN_A3);
delay_ms(500);
output_low(PIN_A3);
}
else{
//Clave correcta
lcd_putc("fClave
Correcta!" );
output_high(PIN_A5);
delay_ms(500);
output_low(PIN_A5);
}
var=0;
//reset var
}
39

//////////////////////////////////////////////////////////
//////////////////////////
// VsZeNeR'05
// 24/Septiembre/05
// vszener@gmail.com
// Programa: RS232 Y PIC
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
// Notas: Se interacciona el PC con el PIC mediante RS232,
se pide por v.terminal
//
un numero comprendido entre 1 al 4, segun numero
marcado por v.terminal
//
se encendera un led 0,5s. Tener en cuenta que hay que
poner la directiva
//
NOLVP para que el pin B4 sea de salida.
//
// Conexiones: A0 -> led azul
// A1 -> led verde
// A2 -> led rojo
// A4 -> led amarillo

// B2 -> TxD
// B1 -> RxD
//////////////////////////////////////////////////////////
////////////////////////
#include <16f648a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //ordenes
para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)
#use rs232(baud=9600, xmit=PIN_B1, rcv=PIN_B2,
FORCE_SW) //manejo del RS232

///PROGRAMA
void main(void)
{
puts("Interaccion PC->PIC
VsZeNeR'05");
//presentacion...
puts("=================");
puts("Seleccione tecla:");
puts("");
puts("
1->Led on Azul");
puts("
2->Led on Verde");
puts("
3->Led on Rojo");
puts("
4->Led on Amarillo"); //...inicial
for(;;){ //bucle...
switch(getc()){ //coge tecla
case '1': output_high(PIN_A0); //led on azul
delay_ms(500);
output_low(PIN_A0);
break;
case '2': output_high(PIN_A1); //led on verde
delay_ms(500);
output_low(PIN_A1);
break;
case '3': output_high(PIN_A2); //led on rojo
delay_ms(500);
output_low(PIN_A2);
break;
case '4': output_high(PIN_A3); //led on amarillo
delay_ms(500);
output_low(PIN_A3);
}
} //...infinito
}


Programa: Contador BCD y binario del 0 al 9
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador 0 al 9 usando interrupcion externa por el pin B0. Tener
//
en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
//
salida.
//
// Conexiones:
A0 -> A 74247/Led D1
//
A1 -> B 74247/Led D2
//
A2 -> C 74247/Led D3
//
A3 -> D 74247/Led D4
//
B0 -> Interrupcion externa
// BCD:
//
d c b a NUM
//
0000 0
//
0001 1
//
0010 2
//
0011 3
//
0100 4
//
0101 5
//
0110 6
//
0111 7
//
1000 8
//
1001 9
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(b)
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)
///VARIABLES GLOBALES
char i=0; //contador para tabla BCD
char
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1001};//BCD 0-9
///LLAMADA FUNCION INTERRUPCION
#INT_EXT
void IntRB0()
{
i++;
//incremento contador indice tabBCD
if(i>9)
//se ha mostrado digito 9?
i=0;
//SI -> restaura valor indice(para mostrar digito 0)
output_a(tabBCD[ i ]); //muestra por porta digito 7 segmentos
}
///PROGRAMA
void main(void)
{
enable_interrupts(int_ext);

//activar interrupcion externa

ext_int_edge(L_TO_H);
//configuracion:interrupcion cuando seal esta en alta
enable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
for( ; ; ){}

//bucle infinito esperando interrupcion

}
40
Buenas!!!jeje despues de las minis-vacaciones que me he dado(isla magica....por cierto muy bonito las
actuaciones en la calle y los teatros, hacer un examen pufff jeje aunque aprovado seguro!jeje...)he vuelto
con mas programas!jeje, bien el siguiente programa vamos a trabajar con un periferico interno del PIC, en
este caso con la interrupcion externa de la patita RB0, por dicha patita se recibira una seal cuadrada de
1Hz,eso significa que cada 1s habra un nivel logico alto(se puede programar para que atendamos a la
interrupcion en nivel logico bajo) el cual producira una interrupcion, en dicha llamada de la interrupcion se
mostrara por el porta en codigo BCD numeros del 0 al 9 y su correspondiente conversion a binario. Aqui el
codigo:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
27/Septiembre/05
//
// Programa: Contador BCD y binario del 0 al 9
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador 0 al 9 usando interrupcion externa por el pin B0. Tener
//
en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
//
salida.
//
// Conexiones:
A0 -> A 74247/Led D1
//
A1 -> B 74247/Led D2
//
A2 -> C 74247/Led D3
//
A3 -> D 74247/Led D4
//
B0 -> Interrupcion externa
// BCD:
//
d c b a NUM
//
0000 0
//
0001 1
//
0010 2
//
0011 3
//
0100 4
//
0101 5
//
0110 6
//
0111 7
//
1000 8
//
1001 9
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(b)
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)
///VARIABLES GLOBALES
char i=0; //contador para tabla BCD

char
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1001};//BCD 0-9
///LLAMADA FUNCION INTERRUPCION
#INT_EXT
void IntRB0()
{
i++;
//incremento contador indice tabBCD
if(i>9)
//se ha mostrado digito 9?
i=0;
//SI -> restaura valor indice(para mostrar digito 0)
output_a(tabBCD[ i ]); //muestra por porta digito 7 segmentos
}
///PROGRAMA
void main(void)
{
enable_interrupts(int_ext);
//activar interrupcion externa
ext_int_edge(L_TO_H);
//configuracion:interrupcion cuando seal esta en alta
enable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
for( ; ; ){}

//bucle infinito esperando interrupcion

}
41
Buenas!!!!el ejemplo de hoy se trata de manejar el periferico interno ccp(modulos de captura: comparacion
y modulacion de anchuras de pulsos), el cual puede actuar de las siguientes maneras: Como captura, como
comparacion o como modulacion de anchura de pulsos(PWM). En este ejemplo lo vamos a configurar como
comparacion. Es decir por la patita RB3/ccp1 conectaremos una seal de pulsos la cual generara una
interrupcion cada flanco de subida(un 1 logico por dicho pin) pero si pulsamos el boton conectado a la patita
RB0/int generara una interrupcion externa(ya programada e el ejemplo anterior...)la cual cambiara el modo
de comparacion, pasando este a capturar y generar una interrupcion por el pin RB3/ccp1 cada flanco
descendente es decir de bajada(un 0 logico por dicho pin)...bueno y la interrupcion lo que hace es
simplemente aumentar indice de contador para mostrar numeros del 0 al 9 en bcd....lo importante es saber
programar los perifericos! aqui el programa:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
29/Septiembre/05
//
// Programa: Uso del CCP1 como comparador ascendente/descendente
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20
Simulador: Proteus 6.7sp3
//
// Notas: Contador 0 al 9 usando interrupcion ccp1 por el pin B3/ccp1. Si no pulsamos
//
el boton, la cuenta del contador sera cada flanco ascendente que entre por
//
la patita RB3/ccp1, en cambio si pulsamos el boton, la cuenta del contador sera
//
cada flanco descendente que reciba el pin RB3/ccp1. Tener en cuenta que hay que
//
poner la directiva NOLVP para que el pin B4 sea de salida. Aparte se a programado
//
mediante la instruccion INTRC el oscilador interno de 4MHz asi tendremos las
//
patitas RA7 Y RA6 libres.
//
// Conexiones:
A0 -> A
//
A1 -> B
//
A2 -> C
//
A3 -> D

//
B0 -> Interrupcion externa
//
B3 -> Interrupcion ccp1
// BCD:
//
d c b a NUM
//
0000 0
//
0001 1
//
0010 2
//
0011 3
//
0100 4
//
0101 5
//
0110 6
//
0111 7
//
1000 8
//
1001 9
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(b)
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)
///VARIABLES GLOBALES
char i=0; //contador para tabla BCD
char
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1001};//BCD 0-9
boolean var=0; //variable para captura en alto(var=0) o en bajo(var=1)
///LLAMADA FUNCION INTERRUPCION
#INT_CCP1
void ccp1()
{
if(i>9)
//se ha mostrado digito 9?
i=0;
//SI -> restaura valor indice(para mostrar digito 0)
output_a(tabBCD[ i ]); //muestra por porta digito 7 segmentos
i++;
//incremento contador indice tabBCD
}
#INT_EXT
void IntRB0()
{
var=!var;
//complementa valor de modo
if(!var)
//var!=0?
setup_ccp1(CCP_CAPTURE_RE);
//SI -> ccp1 modo captura configurado flanco ascendente
else
setup_ccp1(CCP_CAPTURE_FE);
//NO -> ccp1 modo captura configurado flanco descendente
}
///PROGRAMA
void main(void)
{
setup_ccp1(CCP_CAPTURE_RE);
//ccp1 modo captura configurado flanco ascendent
enable_interrupts(int_ext);
//activar interrupcion externa
ext_int_edge(H_TO_L);
//configuracion:interrupcion cuando seal esta en baja
enable_interrupts(INT_CCP1); //activar interrupcion en ccp1
enable_interrupts(GLOBAL);
//todas las interrupciones desactivadas

for( ; ; ){}

//bucle infinito esperando interrupcion

}
42
Buenas!!! al final me he puesto manos a la obra y he realizado la animacion de carga de una bateria....jeje,
para ello se disea los caracteres de la bateria(al 0%, al 20%, al 40%, al 60%, al 80% y al 100%), decir que
solamente he utilizado una posicion de memoria de la GCRAM(aunque cada animacion ocupa 8 posiciones),
he ido machacando valores.......aqui el codigo:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
30/Septiembre/05
//
// Programa: Bateria
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) la animacion de carga de
//
una bateria, para ello se han diseado nuevos caracteres y almacenados
//
en la memoria GCRAM de la lcd, solo se ha usado una posicion de memoria
//
de dicha GCRAM. Tener en cuenta que hay que poner la directiva NOLVP para
//
que el pin B4 sea de salida.
//
// Conexiones:
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#define use_portb_lcd TRUE
#include <lcd.c>
//libreria manejo de la lcd
///DECLARACION DE FUNCIONES
void recarga(void);
//funcion que crea el nuevo caracter
///DECLARACION DE VARIABLES GLOBALES
char cont=0;
//contador que apunta al nuevo caracter diseado
int8
bat0[]={0b00001110,0b00001010,0b00010001,0b00010001,0b00010001,0b000010001,0b00010001,0b0
0011111},
bat20[]={0b00001110,0b00001010,0b00010001,0b00010001,0b00010001,0b00010001,0b00011111,0b00
011111},
bat40[]={0b00001110,0b00001010,0b00010001,0b00010001,0b00010001,0b00011111,0b00011111,0b00
011111},
bat60[]={0b00001110,0b00001010,0b00010001,0b00010001,0b00011111,0b00011111,0b00011111,0b00
011111},
bat80[]={0b00001110,0b00001010,0b00010001,0b00011111,0b00011111,0b00011111,0b00011111,0b00
011111},
bat100[]={0b00001110,0b00001010,0b00011111,0b00011111,0b00011111,0b00011111,0b00011111,0b0

0011111};
///PROGRAMA
void main(void)
{
lcd_init();
//inicializa lcd
recarga();

//crea 1 animacion

lcd_gotoxy(5,1); //presentacion...
lcd_putc("Cargando
VsZeNeR"05" ); //...inicial
for( ; ; ){ //bucle...
lcd_gotoxy(2,1);
//donde se va a mostrar la animacion de la bateria
lcd_send_byte(1,0); //muestra animacion
delay_ms(250);
cont++;
//apunta a siguiente animacion
recarga();
//crea animacion
} //...infinito
}
///FUNCION ENCARGADA DE CREAR ANIMACION
void recarga(void){
char i;
//indice para for
lcd_send_byte(0,0x40); // se escribe en la GCRAM posicion 0x40
switch(cont){ //selecciona animacion
case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,bat0[ i ]);
break;
case 1: for(i=0;i<8;i++) //bateria al 20%
lcd_send_byte(1,bat20[ i ]);
break;
case 2: for(i=0;i<8;i++) //bateria al 40%
lcd_send_byte(1,bat40[ i ]);
break;
case 3: for(i=0;i<8;i++) //bateria al 60%
lcd_send_byte(1,bat60[ i ]);
break;
case 4: for(i=0;i<8;i++) //bateria al 80%
lcd_send_byte(1,bat80[ i ]);
break;
case 5: for(i=0;i<8;i++) //bateria al 100%
lcd_send_byte(1,bat100[ i ]);
cont=0;
//restaura indice de crear animacion
}
}

Bueno ya sabemos como dibujar en una lcd no grafica 2x16!!!


43
Ke tal!!!bien siguiendo con lcd y escribir e su CGRAM aqui pongo la animacion del mueco come-cocos
controlado por PC via v.terminal,No es el juego! simplemente pulsamos la tecla 4 para desplazar el mueco
come-cocos hacia la izquierda y la tecla 6 para desplazarlo hacia la derecha de la 1 fila de lcd:

////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
30/Septiembre/05
//
// Programa: Animacion dibujo ComeCocos controlado por RS232
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) en la primera linea la
//
animacion del dibujo ComeCocos controlado por el v.terminal, si se pulsa
//
numero 4 por PC la animacion se desplaza hacia la izquierda, si se pulsa
//
numero 6 por PC la animacion se desplaza hacia la derecha. Las figuras
//
son simetricas por lo tanto no se han declarado enteras. Tener en cuenta que
//
hay que poner la directiva NOLVP para que el pin B4 sea de salida.
//
// Conexiones:
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//
A0 -> T1IN MAX232
//
A1 -> R1OUT MAX232
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
//ordenes para el programador
#use delay (clock=4000000)
//Fosc=4Mhz
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) //manejo del RS232
#define use_portb_lcd TRUE
//definir portb lcd
#include<lcd.c>
//libreria manejo lcd

///DECLARACION DE FUNCIONES
void recarga(void);
//funcion que crea el nuevo caracter
///DECLARACION DE VARIABLES GLOBALES
char cont=0,lim=1;
//contador que apunta al nuevo caracter diseado
int8 cocod1[]={0b00001111,0b00011110,0b00011100,0b00011000},
cocod2[]={0b00000000,0b01111111,0b11111111,0b11111100},
cocoi1[]={0b00011110,0b00001111,0b00000111,0b00000011},
cocoi2[]={0b00000000,0b01111111,0b11111111,0b00000011};
///PROGRAMA
void main(void)
{
lcd_init();

//inicializa lcd

puts("Animacion Come Cocos" ); //animacion...


puts("====================" );
puts(" Teclas:" );
puts(" " );
puts("
<---> " );
puts("
4
6 " );
puts("VsZeNeR"05" );
//...por v.terminal
printf(lcd_putc,"ComeCocos

VsZeNeR"05" );

//mensaje por lcd

for( ; ; ){ //bucle...
recarga();
//funcion para el movimiento del comecocos
if(lim>16)
//limites...
lim=16;
if(lim<1)
lim=1;
//...de lcd
lcd_putc("f
VsZeNeR"05" );
lcd_gotoxy(lim,1);
//movimiento de la animacion
lcd_send_byte(1,0); //muestra animacion
} //...infinito
}
///FUNCION ENCARGADA DE CREAR ANIMACION
void recarga(void){
signed char i;
//indice para for
lcd_send_byte(0,0x40); // se escribe en la GCRAM posicion 0x40
switch(getc() ){ //selecciona animacion
case "4": if(!cont){ //movimiento hacia izquierda
for(i=0;i<4;i++) //boca abierta
lcd_send_byte(1,cocoi1[ i ]);
for(i=3;i>-1;i--)
lcd_send_byte(1,cocoi1[ i ]);
cont++;
}
else{
//boca cerrada
for(i=0;i<4;i++)
lcd_send_byte(1,cocoi2[ i ]);
for(i=3;i>-1;i--)
lcd_send_byte(1,cocoi2[ i ]);
cont=0;
}
lim--; //apunta siguiente posicion a mostrar animacion en lcd
break;
case "6": if(!cont){ //movimiento hacia derecha
for(i=0;i<4;i++) //boca abierta
lcd_send_byte(1,cocod1[ i ]);
for(i=3;i>-1;i--)
lcd_send_byte(1,cocod1[ i ]);
cont++;
}
else{
//boca cerrada
for(i=0;i<4;i++)
lcd_send_byte(1,cocod2[ i ]);
for(i=3;i>-1;i--)
lcd_send_byte(1,cocod2[ i ]);
cont=0;
}
lim++; //apunta siguiente posicion a mostrar animacion en lcd
}
}
44

ke tal!!! bien hoy voy a usar la liberia ds1620.c BETA que realice, asi que el ejemplo de hoy es como hacer
un medidor de temperatura usando este dispositivo, aqui el programa:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
19/Octubre/05
//
// Programa: Termometro digital DS1620
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.235
// Entorno IDE: MPLAB IDE v7.21
Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) la temperatura del ds1620
// Conexiones:
A0 -> DQ DS1620
//
A1 -> CLK DS1620
//
A2 -> RST DS1620
//
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#use delay(CLOCK=4000000)
//Fosc=4Mhz
#fuses HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT //comandos para el programador
#fuses INTRC //oscilador interno
#use standard_io(a)
#use standard_io(b)
#define use_portb_lcd TRUE
//utilizar el port b para lcd
#define DS1620_DQ
PIN_A0
//declaracion de pins...
#define DS1620_CLK
PIN_A1
#define DS1620_RST
PIN_A2
//...para el ds1620
#include <ds1620.c>
//libreria del termometro ds1620
#include <lcd.c>
//libreria de lcd
///PROGRAMA
void main(void){
char i;
int8 grado[]={0b00000110,0b00001001,0b00000110};
lcd_init();

//inicializa lcd

lcd_putc(" Termometro
VsZeNeR"05" ); //presentacion...
delay_ms(800);
lcd_putc("f" );
//...inicial
lcd_putc(" VsZeNeR"05
Temperatura:" ); //pantalla temp
lcd_send_byte(0,0x40); // se escribe en la GCRAM posicion 0x40
for(i=0;i<3;i++)
//dibujo del simbolo grado
lcd_send_byte(1,grado[ i ]);
lcd_gotoxy(16,2);
//donde se va a mostrar

lcd_send_byte(1,0);
ds1620_init();

//muestra animacion

//inicializa ds1620

for(; ; ){
//bucle...
lcd_gotoxy(14,2);
printf(lcd_putc,"%d",read_ds1620(0xAA));
delay_ms(500);
lcd_putc("" );
}
//...infinito

//muestra temperatura por pantalla

}
Aqui la primera prueba con la libreria ds1620.c!
45
Holaaaaa!!!!jeje bien, el programa de hoy consiste en manejar el periferico CCP1 configurado como PWM,
decir que el PWM consiste en obtener a frecuencias constantes(por lo tanto periodo constante) una anchura
de pulso variable(la cual nosotros programamos), en este caso, la anchura de pulsos para las frecuencias
constantes es siempre la misma, la mitad del periodo, y las frecuencias las obtenemos mediante el
preescaler del TMR2....aqui el ejemplito:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
2/Noviembre/05
//
// Programa: Uso del CCP1 como PWM
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.235
// Entorno IDE: MPLAB IDE v7.22
Simulador: Proteus 6.7sp3
//
// Notas: Usamos el modulo CCP1 como PWM, para ello configuramos el TMR2 de sus tres
//
formas distintas mediante el preescales(1,4,16) que nos dara distintas frecuencias.
//
El ciclo viene determinado por (1/clock)*4*t2div*(periodo+1), donde en este caso
//
clock=4MHz y periodo=127.
//
Frecuencias:
//
T2_DIV_BY_1 -> 128us -> 7,81KHz
//
T2_DIV_BY_4 -> 512us -> 1,95KHz
//
T2_DIV_BY_16 -> 2,05ms -> 487,8Hz
//
En este programa tendremos un nivel alto a la mitad de la frecuencia obtenida mediante
//
la relacion valor*(1/clock)*t2div donde valor=%nivel alto del pulso
//
Anchura del pulso(Duty):
//
128us -> 64us -> 64us/(1*(1/4000000)) = 256
//
512us -> 256us -> 256us/(4*(1/4000000)) = 256
//
2,05ms -> 1,02ms -> 1,02ms/(16*(1/4000000)) = 256
//
//
Conexiones:
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//
B3 -> Canal 1 osciloscopio
//
A0 -> Boton
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(b)
#define use_portb_lcd TRUE
//definir portb lcd
#include<lcd.c>
//libreria manejo lcd
///DECLARACION DE FUNCIONES
void cambia_frec(char);
//funcion encargada de cambiar la frecuencia
///PROGRAMA
void main(void)
{
char opcion=0;

//variable encargada de mostrar menu de frec

setup_ccp1(CCP_PWM);
lcd_init();

//ccp1 modo PWM

//inicializa lcd

cambia_frec(opcion);

//muestra primera frec

for( ; ; ){
//bucle...
if(!input(PIN_A0)){
//se ha pulsado el boton?
do{
//SI -> eliminar...
}while(!input(PIN_A0));
//...rebotes del boton
opcion++;
//apunta a siguiente frec
if(opcion>2)
//ya se han mostrado todas las frec?
opcion=0;
//SI -> resetea opcion
cambia_frec(opcion);
//cambia frecuencia
}
}
//...infinito
}
///FUNCION ENCARGADA DE CAMBIAR LA FRECUENCIA POR CCP1
void cambia_frec(char menu)
{
lcd_putc("f" );
switch(menu){ //menu para eleccion de frecuencias
case 0: setup_timer_2(T2_DIV_BY_1, 127, 1);
//128us -> 7,81kHz
set_pwm1_duty(256);
//64us/(1*(1/4000000)) = 256
lcd_putc(" VsZeNeR"05
Frec=7,81KHz" );
break;
case 1: setup_timer_2(T2_DIV_BY_4, 127, 1);
//512us -> 1,95kHz
set_pwm1_duty(256);
//256us/(4*(1/4000000)) = 256
lcd_putc(" VsZeNeR"05
Frec=1,95KHz" );
break;
case 2: setup_timer_2(T2_DIV_BY_16, 127, 1); //2,05ms -> 487,8Hz
set_pwm1_duty(256);
//1,02ms/(16*(1/4000000)) = 256
lcd_putc(" VsZeNeR"05
Frec=487,8Hz" );
}
}
Ejemplo como funciona pwm

PWM=Modo de modulacion de anchura de pulsos


Este modulo sirve para obtener impulsos logicos cuya anchura del nivel alto es variable(Anchura
variable=Duty Cycle)
El tiempo que dura el periodo de la onda viene determinado por el valor cargado en PR2(tener en cuenta que
PR2 es la parte alta del TMR2):

Codigo:
Periodo=[ (PR2)+1] 4 Tosc Valor Preescaler PR2
Cuando el valor del TMR2=PR2 ocurren tres acontecimientos:

Codigo:
1. Se borra TMR2
2. La patita del CCP1 se pone a 1
3. El valor CCPR1L(determina anchura del pulso) se carga en CCPR1H
Para obtener la anchura del pulso:

Codigo:
Anchura del pulso=(CCPR1L:CCP1CON<5:4> ) ToscValor Preescaler TMR2

Pasos para configurar PWM:

Codigo:
1.
2.
3.
4.
5.

Asignar el periodo cargando valor oportuno en PR2


Asignar la anchura del pulso(Duty Cycle)
Configurar CCP1 como salida
Asignar valor predivisor y activar TMR2
Configurar modulo CCP1 como PWM.

46
Buenas!!!bien el ejemplito de hoy consiste en manejar igualmente que el programa anterior el modulo CCP1
en modo PWM, pero en vez de ser constante como el anterior a 50% la anchura de pulso, se ha programado
para que sea variable a 50% y al 75%, tambien este programa pretende aparte de manejar dicho modulo, la
utilizacion y creacion de archivos .h, los cuales haran que el programa principal main este mas estructurado
en tema codigo:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
6/Noviembre/05
//
// Programa: Uso del CCP1 como PWM al 50% y 75%
// Version: 1.0
//

// Dispositivo: PIC 16F648A


Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22
Simulador: Proteus 6.7sp3
//
// Notas: Usamos el modulo CCP1 como PWM, para ello configuramos el TMR2 de sus tres
//
formas distintas mediante el preescales(1,4,16) que nos dara distintas frecuencias.
//
El ciclo viene determinado por (1/clock)*4*t2div*(periodo+1), donde en este caso
//
clock=4MHz y periodo=127.
//
Frecuencias:
//
T2_DIV_BY_1 -> 128us -> 7,81KHz
//
T2_DIV_BY_4 -> 512us -> 1,95KHz
//
T2_DIV_BY_16 -> 2,05ms -> 487,8Hz
//
La anchura de pulso en nivel alto depende de la relacion valor*(1/clock)*t2div donde
//
valor=%nivel alto del pulso.
//
Anchura del pulso(Duty):
//
*Para 50%:
//
128us -> 64us -> 64us/(1*(1/4000000)) = 256
//
512us -> 256us -> 256us/(4*(1/4000000)) = 256
//
2,05ms -> 1,02ms -> 1,02ms/(16*(1/4000000)) = 256
//
*Para 75%:
//
128us -> 96us -> 96us/(1*(1/4000000)) = 384
//
512us -> 384us -> 384us/(4*(1/4000000)) = 384
//
2,05ms -> 1,54ms -> 1,54ms/(16*(1/4000000)) = 384
//
Este programa tambien ha pretendido abarcar como crear archivos .h para
//
que dicho codigo sea mas estructurado.
//
Conexiones:
B0 -> E
//
B1 -> RS
//
B2 -> RW
//
B4 -> D4
//
B5 -> D5
//
B6 -> D6
//
B7 -> D7
//
B3 -> Canal 1 osciloscopio
//
A0 -> Boton
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#include<vs_fuses&demas.h>
//libreria manejo fuses
#define use_portb_lcd TRUE
//definir portb lcd
#include<lcd.c>
//libreria manejo lcd
#include<vs_variables_globales.h>
//libreria manejo de funciones
#include<vs_funciones.h>
//libreria manejo de variables
///PROGRAMA
void main(void)
{
setup_ccp1(CCP_PWM);
lcd_init();
cambia_frec( );
cambia_duty( );

//ccp1 modo PWM

//inicializa lcd
//muestra primera frec
//muestra primer ancho de pulso

for( ; ; ){
//bucle...
if(!input(PIN_A0)){
//se ha pulsado el boton?
do{
//SI -> eliminar...
}while(!input(PIN_A0));
//...rebotes del boton
opcion++;
//apunta a siguiente frec
if(opcion>2)
//ya se han mostrado todas las frec?

opcion=0;
cambia_frec( );
}

//SI -> resetea opcion


//cambia frecuencia

if(!input(PIN_A1)){
//se ha pulsado el boton?
do{
//SI -> eliminar...
}while(!input(PIN_A1));
//...rebotes del boton
duty++;
//apunta a siguiente frec
if(duty>1)
//ya se han mostrado todas las anchuras de pulso?
duty=0;
//SI -> resetea duty
cambia_duty();
//cambia anchura pulso
}
}
//...infinito
}
47
Buneasss!!!Bien el ejemplito de hoy trata de como insertar codigo ASM en nuestro programa en C.
Normalmente dicho codigo en ASM se hace para temporizaciones muy finas, en este caso lo usaremos para
gobernar el programa. Dicho programa realiza la iluminacion sucesiva de 4 led"s mediante un decodificador,
en ASM se ha programado como manejar la variable cont para dar la instruccion a que led encender, el
programa tambien realiza a la vez, la cuenta ascendente de un numero bcd 0a9 mediante un bcd-7seg, esta
vez el codigo ASM se encarga de todo tanto de la variable como de mostrarlo por pantalla....bueno no me
enrrollo mas!!!jeje aqui el programa:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
8/Noviembre/05
//
// Programa: Led"s & display 7seg andodo comun
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22
Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra como incorporar codigo ASM en nuestro programa en C.
//
Los modulos en asm manejan lso perifericos(uno es una barra de led"s, se
//
iluminan hasta 4 led"s de forma consecutiva y vuelta a empezar, y el otro
//
maneja un contador ascendente bcd de 0a9 y vuelta a empezar). Se usa los
//
perifericos decodificador 4555 y bcd-7seg 74247.
//
Conexiones:
A0 -> A 4555 DEC
//
A1 -> B 4555 DEC
//
B4 -> A 74247
//
B5 -> B 74247
//
B6 -> C 74247
//
B7 -> D 74247
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#use fast_io(a)
#use fast_io(b)
#byte PORTB=0x06
//definicion del PORTB
#byte STATUS=0x03
//definicion del STATUS
///PROGRAMA
void main(void)

{
char cont=0;
//definicion de...
signed char bcd=-1;
//...variables
set_tris_a (0x00);
set_tris_b (0x00);

//porta salida
//portb salida

for( ; ; ){ //bucle...
output_a(cont);
//enciende led correspondiente
#asm
//modulo asm para manejar bcd->7seg
movlw 1
;w <- 1
addwf bcd,1
;bcd <- w + bcd
movf bcd,0
;w <- bcd
sublw 10
;10- w
btfsc STATUS,2 ;se ha llegado a 9?
goto igual
;SI->ve a igual
swapf bcd,0
;NO: w <- parte alta bcd
goto muestra
;ve a muestra
igual:
movlw 0
;w <- 0
movwf bcd
;bcd <- w
muestra:
movwf PORTB
;PORTB <- w
#endasm
//fin modulo asm para manejar bcd->7seg
delay_ms(450);
#asm
//modulo asm para manejar led"s
movlw 1
;w <- 1
addwf cont,1
;cont <- w + cont
#endasm
//fin modulo asm para manejar led"s
if(cont>3)
//se ha mostrado el ultimo led?
cont=0;
//SI-> reset cont
}
//...infinito
}
48
Buenas!!!!bien, el programa de hoy se basa en las interrupciones producidas al cambio de estado por uno de
los pines del portb dedicados a dicha tarea, los pines que generan interrupcion son <4:7>. El programa en si
realiza la secuencia de luces del coche fantastico con 4 led"s hasta que uno de los pines <4:7> cambia de
estado del port b, entonces genera una interrupcion y realiza una secuencia de iluminacion de los led"s
distinta, aparte cada vez que estemos en una interrupcion se iluminara el led conectado al pin b0....bueno
aqui el codigo!:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
15/Noviembre/05
//
// Programa: Interrupcion debido a cambio de estado del portb <4:7>
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22
Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra como funciona la interrupcion de cambio de estado de

//
algunos de los pines <4:7> del portb. Mientras no se pulse ningun boton,
//
ilumina 4 led"s de forma consecutiva y viceversa, cuando se produce un
//
cambio de estado en algunos de los pines del port b <4:7> genera interrupcion.
//
Se ha programado de tal forma que sepa diferenciar que pin genera la interrupcion.
//
Interrupcion:
//
B4 -> Se produce la secuencia de iluminacion 1 vez
//
B5 -> Se produce la secuencia de iluminacion 2 veces
//
B6 -> Se produce la secuencia de iluminacion 3 veces
//
B7 -> Se produce la secuencia de iluminacion 4 veces
//
Conexiones:
A0 -> led
//
A1 -> led
//
A2 -> led
//
A3 -> led
//
B0 -> led
//
B4 -> boton
//
B5 -> boton
//
B6 -> boton
//
B7 -> boton
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#use standard_io(a)
#use fast_io(b)
#byte port_b=0x06
//declaracion del puerto b
///DECLARACION DE FUNCIONES GLOBALES
void led(void);
//funcion que ejecuta la iluminacion del porta dada la interrupcion
///DECLARACION DE VARIABLES GLOBALES
int last_b;
//variable de almacenar el estado del portb
///LLAMADA FUNCION INTERRUPCION
#INT_RB
void IntPortB4_7( )
{
char cont=0;
//contador para la iluminacion de la interrupcion
byte changes;
//variable que almacena que pin a realizado la interrupcion
output_high(PIN_B0);

//indicador interrupcion on

changes = last_b ^ port_b;


last_b = port_b;

//changes<-pin que genera la interrupcion

//last_b=como estaba el portb antes de interrupcion

if (bit_test(changes,4 )&& !bit_test(last_b,4))


//PIN_B4 genera interrupcion?
led( );
//SI -> ejecuta 1 vez funcion led()
if (bit_test(changes,5)&& !bit_test (last_b,5)){ //PIN_B5 genera interrupcion?
do{
//SI -> ejecuta 2 veces funcion led()
led( );
cont++;
}while(cont<2);
}
if (bit_test(changes,6)&& !bit_test (last_b,6)){ //PIN_B6 genera interrupcion?
do{
//SI -> ejecuta 3 veces funcion led()
led( );

cont++;
}while(cont<3);
}
if (bit_test(changes,7)&& !bit_test (last_b,7)){ //PIN_B7 genera interrupcion?
do{
//SI -> ejecuta 4 veces funcion led()
led( );
cont++;
}while(cont<4);
}
cont=0;
//reset variable cont
output_low(PIN_B0); //indicador interrupcion off
}
///PROGRAMA
void main(void)
{
char led_on=0b0001;

//led a iluminar

set_tris_b (0b11111110);

//portb entrada menos pin B0 es salida

enable_interrupts(int_rb);
enable_interrupts(GLOBAL);

//activar interrupcion rb4:7


//activar interrupciones

do{

//bucle...

do{
//iluminacion hacia izquierda
output_a(led_on);
rotate_left(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,3)==0);
do{
//iluminacion hacia derecha
output_a(led_on);
rotate_right(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,0)==0);
last_b = input_b( );
}while(TRUE);
//...infinito
}
///FUNCION QUE EJECUTA LA SECUENCIA DE ILUMINACION DEBIDO A INTERRUPCION POR EL PORTB4:7
void led(void)
{
signed char i;
//variable indice
int leds[2]={0b1001,0b0110}; //led"s
for(i=0;i<2;i++){
output_a(leds[ i ]);
delay_ms(150);
}
for(i=1;i>-1;i--){
output_a(leds[ i ]);
delay_ms(150);
}
}
49

//led"s on fuera-dentro
//ilumino led"s correspondientes

//led"s on dentro-fuera
//ilumino led"s correspondientes

Buenas!!!!bien, viendo el trabajo que estan haciendo mis compaeros de ensear a utilizar basic y proteus
para pic"s y para atmel(que la verdad esta muy bien aqui el link: EJEMPLITOS DE BASCOM AVR...
ATMEGA8.. ) he visto que tienen programas de manejos de matrices de led"s asi que me ha dado pequea
envidia(envidia buena claro esta jeje) y me he dicho: "porque en c no hay esos programas"? bueno pues
aqui uno muy simple, tratamos una matriz 5x7 y enseamos por ella el abecedario:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
19/Diciembre/05
//
// Programa: Abecedario en matrices de led"s 5x7
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.30
Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra por el abecedario en una matriz de led"s 5x7.
//
En las columnas se usa un decodificador 4028 para hacer su barrido
//
Conexiones:
A0 -> A 4028 DEC
//
A1 -> B 4028 DEC
//
A2 -> C 4028 DEC
//
A3 -> D 4028 DEC
//
B0 -> Fila 1 matriz 5x7
//
B1 -> Fila 2 matriz 5x7
//
B2 -> Fila 3 matriz 5x7
//
B3 -> Fila 4 matriz 5x7
//
B4 -> Fila 5 matriz 5x7
//
B5 -> Fila 6 matriz 5x7
//
B6 -> Fila 7 matriz 5x7
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#use fast_io(a)
#use fast_io(b)
///DEFINICION VARIABLES GLOBALES
int letra[5],opcion=0;
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER1
void interrupcion()
{
switch(opcion){ //selecciona letra
case 0: letra[0]=0b00000001; //A
letra[1]=0b01110110;
letra[2]=0b01110110;
letra[3]=0b01110110;
letra[4]=0b00000001;
opcion++;
break;
case 1: letra[0]=0b01001001; //B
letra[1]=0b00110110;
letra[2]=0b00110110;
letra[3]=0b00110110;
letra[4]=0b00000000;

opcion++;
break;
case 2: letra[0]=0b00111110;
letra[1]=0b00111110;
letra[2]=0b00111110;
letra[3]=0b00111110;
letra[4]=0b01000001;
opcion++;
break;
case 3: letra[0]=0b01000001;
letra[1]=0b00111110;
letra[2]=0b00111110;
letra[3]=0b00111110;
letra[4]=0b00000000;
opcion++;
break;
case 4: letra[0]=0b00111110;
letra[1]=0b00110110;
letra[2]=0b00110110;
letra[3]=0b00110110;
letra[4]=0b00000000;
opcion++;
break;
case 5: letra[0]=0b01111110;
letra[1]=0b01110110;
letra[2]=0b01110110;
letra[3]=0b01110110;
letra[4]=0b00000000;
opcion++;
break;
case 6: letra[0]=0b01001110;
letra[1]=0b00110110;
letra[2]=0b00110110;
letra[3]=0b00111110;
letra[4]=0b01000001;
opcion++;
break;
case 7: letra[0]=0b00000000;
letra[1]=0b01110111;
letra[2]=0b01110111;
letra[3]=0b01110111;
letra[4]=0b00000000;
opcion++;
break;
case 8: letra[0]=0b00111110;
letra[1]=0b00111110;
letra[2]=0b00000000;
letra[3]=0b00111110;
letra[4]=0b00111110;
opcion++;
break;
case 9: letra[0]=0b01111111;
letra[1]=0b00000000;
letra[2]=0b00111110;
letra[3]=0b00101110;
letra[4]=0b01001111;
opcion++;
break;

//C

//D

//E

//F

//G

//H

//I

//J

case 10: letra[0]=0b00111110;


letra[1]=0b01011101;
letra[2]=0b01101011;
letra[3]=0b01110111;
letra[4]=0b00000000;
opcion++;
break;
case 11: letra[0]=0b00111111;
letra[1]=0b00111111;
letra[2]=0b00111111;
letra[3]=0b00111111;
letra[4]=0b00000000;
opcion++;
break;
case 12: letra[0]=0b00000000;
letra[1]=0b01111101;
letra[2]=0b01111011;
letra[3]=0b01111101;
letra[4]=0b00000000;
opcion++;
break;
case 13: letra[0]=0b00000011;
letra[1]=0b01011111;
letra[2]=0b01101111;
letra[3]=0b01110111;
letra[4]=0b00000011;
opcion++;
break;
case 14: letra[0]=0b00000011;
letra[1]=0b01011101;
letra[2]=0b01101101;
letra[3]=0b01110101;
letra[4]=0b00000011;
opcion++;
break;
case 15: letra[0]=0b01000001;
letra[1]=0b00111110;
letra[2]=0b00111110;
letra[3]=0b00111110;
letra[4]=0b01000001;
opcion++;
break;
case 16: letra[0]=0b01111001;
letra[1]=0b01110110;
letra[2]=0b01110110;
letra[3]=0b01110110;
letra[4]=0b00000000;
opcion++;
break;
case 17: letra[0]=0b00000001;
letra[1]=0b00011110;
letra[2]=0b00101110;
letra[3]=0b00111110;
letra[4]=0b01000001;
opcion++;
break;
case 18: letra[0]=0b01111001;
letra[1]=0b00110110;

//K

//L

//M

//N

//

//O

//P

//Q

//R

case

case

case

case

case

case

case

case

letra[2]=0b01010110;
letra[3]=0b01100110;
letra[4]=0b00000000;
opcion++;
break;
19: letra[0]=0b01001110;
letra[1]=0b00110110;
letra[2]=0b00110110;
letra[3]=0b00110110;
letra[4]=0b00111001;
opcion++;
break;
20: letra[0]=0b01111110;
letra[1]=0b01111110;
letra[2]=0b00000000;
letra[3]=0b01111110;
letra[4]=0b01111110;
opcion++;
break;
21: letra[0]=0b01000000;
letra[1]=0b00111111;
letra[2]=0b00111111;
letra[3]=0b00111111;
letra[4]=0b01000000;
opcion++;
break;
22: letra[0]=0b01100000;
letra[1]=0b01011111;
letra[2]=0b00111111;
letra[3]=0b01011111;
letra[4]=0b01100000;
opcion++;
break;
23: letra[0]=0b01000000;
letra[1]=0b00111111;
letra[2]=0b01000111;
letra[3]=0b00111111;
letra[4]=0b01000000;
opcion++;
break;
24: letra[0]=0b00111011;
letra[1]=0b01010111;
letra[2]=0b01101111;
letra[3]=0b01010111;
letra[4]=0b00111011;
opcion++;
break;
25: letra[0]=0b01111110;
letra[1]=0b01111101;
letra[2]=0b00000011;
letra[3]=0b01111101;
letra[4]=0b01111110;
opcion++;
break;
26: letra[0]=0b00111100;
letra[1]=0b00111010;
letra[2]=0b00110110;
letra[3]=0b00101110;

//S

//T

//U

//V

//W

//X

//Y

//Z

letra[4]=0b00011110;
opcion=0;
}
set_timer1(3036);

//TMR1 se desborda cada 0,5s

}
void main(void)
{
int i; //variable contador
enable_interrupts(INT_TIMER1);
//interrupcion TIMER1 activada
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
//configuracion TMR1
set_timer1(65535);
//carga TMR1 para un desbordamiento inmediato
enable_interrupts(GLOBAL);
//activadas interrupciones
set_tris_b (0x00);
set_tris_a (0x00);

//portb salida
//porta salida

do{
//bucle...
for(i=0;i<5;i++){
output_a( i );
//columnas
output_b(letra[ i ]);
//filas
delay_ms(10);
//pausa para poder verse
}
}while(TRUE); //...infinito
}
50
Holaaa!!!bueno, aqui dejo un programa que se sale de la tematica de aprendizaje a programar perifericos
internos del pic, pero vamos creo que es ilustrativo a la programacion del mismo y hardware, hace tiempo
que pense en regalarle un reloj digital a mi nia, y bueno pue sme puse manos a la obra, el conteo y la
realizacion del reloj lo realiza todo el pic, aqui el programa:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"05
//
29/Noviembre/05
//
// Programa: Reloj digital 7seg
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22
Simulador: Proteus 6.7sp3
//
// Notas: Reloj digital en 7seg. Se utiliza un DEC 4555 para realizar el barrido
//
de los 7seg, se usa tambien, un BCD-7Seg 4543 para la visualizacion
//
de los numeros en el 7seg. El reloj esta compuesto de 4 botones.
//
Botones: Hora/Minutos->RB1:
Cuando estemos en modo Configuracion,
//
pasar de hora a minutos para incrementar.
//
+ ->RB2:
Para incrementar en una unidad el digito actual.
//
Configuracion/Ok->RB3: Si se pulsa pasamos al modo
//
configuracion para poder actualizar
//
la hora actual, una vez actualizada,
//
si se pulsa pasamos al modo de reloj
//
Conexiones:
A0 -> A 4555 DEC
//
A1 -> B 4555 DEC
//
A2 -> 2 led"s en serie(secundero)
//
A5 -> Boton reset(externo)

//
B1 -> Boton Hora/Minuto
//
B2 -> Boton +
//
B3 -> Boton Configuracion/Ok
//
B4 -> A 4543
//
B5 -> B 4543
//
B6 -> C 4543
//
B7 -> D 4543
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOCPD,NOWDT,NOPUT,NOLVP,NOBROWNOUT
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2)
#use fixed_io(b_outputs=PIN_B4,PIN_B5,PIN_B6,PIN_B7)
#bit RA2=05.2
//secundero
///DEFINICION DE FUNCIONES
void configurar(void);
///VARIABLES GLOBALES
char min1=0,min2=0,hor1=0,hor2=0;
char flag=0,var=119;
//variables de ajuste de 1 minuto
char tab[10]={0x00,0b00010000,0b00100000,0b00110000,
0b01000000,0b01010000,0b01100000,0b01110000,0b10000000,0b10010000};
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER1
void interrupcion()
{
if(flag>var){
//Ya es 1 minuto?
var--;
//SI -> decremento var...
if(var<118)
var=120;
//...ajuste fino de 1min
flag=0;
//reset flag para contar 1min
min1++;
if(min1>9){
//Se ha mostrado xx:x9?
min1=0;
//SI -> reset min1 xx:x0
min2++;
if(min2>5){
//Se ha mostrado xx:59?
min2=0;
//SI -> reset min2 xx:00
hor1++;
if(hor2==2){
//Estamos en modo noche 2x:xx?
if(hor1>3)
//SI -> Se ha mostrado 23:59?
goto noche;}//SI -> ve a noche
if(hor1>9){
//No estamos en modo noche-> se ha mostrado 19:59?
noche:
hor1=0;
//SI -> reset hor1 x0:00 || noche: reset hor1 x0:00
hor2++;
if(hor2>2)
//Se ha mostrado 23:59?
hor2=0;
//SI -> reset hor2 00:00
}
}
}
}
RA2=!RA2;
//parpadeo secundero cada 0,5s
set_timer1(3036);
//reset TMR1
flag++;
}

//bcd parte alta 0-9

///PROGRAMA
void main(void)
{
enable_interrupts(INT_TIMER1);
//interrupcion TIMER1 activada
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
//configuracion TMR1
set_timer1(3036);
//carga TMR1 para desvordar cada 0.5s
enable_interrupts(GLOBAL);
//activadas interrupciones
do{
//bucle...
output_low(PIN_A0);
//Primer 7seg...
output_low(PIN_A1);
//...on
output_b(tab[min1]);
delay_ms(10);
output_low(PIN_A1);
//Segundo 7seg...
output_high(PIN_A0);
//...on
output_b(tab[min2]);
delay_ms(10);
output_high(PIN_A1);
//Tercer 7seg...
output_low(PIN_A0);
//...on
output_b(tab[hor1]);
delay_ms(10);
output_high(PIN_A0);
//Cuarto 7seg...
output_high(PIN_A1);
//...on
output_b(tab[hor2]);
delay_ms(10);
if(!input(PIN_B3)){
//Se ha pulsado boton Configuracion?
while(!input(PIN_B3)){} //SI -> elimina rebotes pulsador...
configurar();
//...ve a configurar
}
}while(TRUE); //...infinito
}
///FUNCION QUE CONFIGURA LA HORA ACTUAL
void configurar(void){
boolean sal=0;
char menu=0;
//menu=0: incremento minutos || menu=1: incremento horas
disable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
do{
do{
output_a(0b00);
output_b(tab[min1]);
delay_ms(10);
output_a(0b01);
output_b(tab[min2]);
delay_ms(10);
output_a(0b10);
output_b(tab[hor1]);
delay_ms(10);
output_a(0b11);
output_b(tab[hor2]);
delay_ms(10);
if(!input(PIN_B1)){
//Se ha pulsado boton Horas/Minutos?
while(!input(PIN_B1)){}
menu=!menu;
//SI -> Cambia minutos/horas y viceversa
}
if(!input(PIN_B2)){
//Se ha pulsado boton +?
while(!input(PIN_B2)){}
sal=1;
//SI -> incrementa una unidad el digito(segun variable menu)

}
if(!input(PIN_B3)){
//Se ha pulsado boton Ok?
while(!input(PIN_B3)){}
sal=1;
//SI -> salir...
menu=2;
//...modo Configurar y mostrar hora actualizada
}
}while(sal==0);
sal=0;
//reset variable sal
if(menu==0){
//Incremento digito de minutos?
min1++;
//SI
if(min1>9){
//Se ha mostrado xx:x9?
min1=0;
//SI -> reset min1 xx:x0
min2++;
if(min2>5)
//Se ha mostrado xx:59?
min2=0;
//SI -> reset min2 xx:00
}
}
if(menu==1){
//Incremento digito horas?
hor1++;
//SI
if(hor2==2){
//Estamos en modo noche 2x:xx?
if(hor1>3)
//SI -> se ha mostrado 23:xx?
goto night;
//SI -> ve a night
}
if(hor1>9){
//No estamos en modo noche->se ha mostrado 19:xx?
night:
hor1=0;
//SI -> reset hor1 10:xx ||modo noche: reset hor1 20:xx
hor2++;
if(hor2>2)
//Se ha mostrado 23:xx?
hor2=0;
//SI -> reset hor2 00:xx
}
}
}while(menu<2);
enable_interrupts(GLOBAL);
//todas las interrupciones desactivadas
set_timer1(3036);
//carga TMR1
flag=0;
//reset variables...
var=119;
//...ajuste de 1min
}

51
Buenas!!!!aqui os dejo lo que os dije!el manejo d ela interrupcion serial!, este ejemplo sirve como revision
del programa 29, el cual se encarga de la escritura y lectura de la eeprom interna del pic, en este caso de
256k, aqui el programa:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"06
//
23/Enero/06
//
// Programa: RS232 Y PIC
// Version: 1.0 REVISION del programa 45
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.30
Simulador: Proteus 6.7sp3
//
// Notas: Se interacciona el PC con el PIC mediante RS232 para el tratamiento de la memoria
//
eeprom interna,se muestra por v.terminal un menu:
//
0 -> Muestra nuevamente el menu

//
1 -> LLena la eeprom a 0xFF
//
2 -> Lee la eeprom en modo hex
//
3 -> Escribe en la eeprom
//
4 -> Lee la eeprom en modo texto(ASCII)
//
Todas las acciones se realizan mediante la interrupcion del puerto serial.
//
Al comienzo del programa, realizar el paso 1. en caso de empezar a escribir
//
en la eeprom!. Decir que las funciones gethex1() y gethex() estan sacadas
//
de la libreria incluida en CCS, input.c, estan puestas en el programa
//
por la pequea modificacion en la funcion gethex1() que, en este caso, solo
//
permite el paso de digitos comprendidos entre 0-f o 0-F. Tener en cuenta
//
que los datos a introducir deben ser en hexadecimal, por ejmeplo, en el
//
caso de almacenar en la letra "a" minuscula en la posicion 00 de la eeprom
//
interna del pic, habra que realizar los siguientes pasos:
//
1. Pulsamos 3 para escribir en la eeprom interna
//
2. Ponemos la direccion 00 (esta en hexadecimal!)
//
3. Damos el valor en hex de la letra a=0x61
//
4. Leemos la memoria para ver que se almacenado correctamente(pulsando 2)
//
La eeprom interna del 16F648A es de 256k.
//
// Conexiones:
B2 -> TxD
//
B1 -> RxD
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //ordenes para el programador
#fuses RC_IO
//reloj interno
#use delay (clock=4000000)
//Fosc=4Mhz
#use rs232(baud=9600, xmit=PIN_b2, rcv=PIN_b1) //manejo del RS232
///DECLARACION DE VARIABLES GLOBALES
boolean menu=1,opcion=1;
//si menu=0 se muestra el menu de inicio...
//...si opcion=1 estamos en modo direccion
//
opcion=0 estamos en modo dato
///DECLARACION DE FUNCIONES
BYTE gethex1( );
//verifica que esta dentro del rango y muestra por pantalla
BYTE gethex( );
//devuelve el numero en hex
///LLAMADA FUNCION INTERRUPCION
#int_rda
void rs232()
{
BYTE i=0,j=0,address,value;
//definicion...
char digito;
//...variables
disable_interrupts(global);
digito=getc();

//apago interrupcion

//almaceno dato serial(rs232) en digito

puts("
****************************************************" );
switch(digito){
case "0":
menu=!menu;
//muestra menu
break;
case "1":
printf("LLenando buffer..." ) ; //llena memoria 0xff
for(i=0; i<16;i++){
for(j=0; j<16;j++)
write_eeprom(i*16+j,0xff);

}
puts(" Buffer completado!" );
break;
case "2":
puts("Realizando Lectura...
//opcion que realiza la lectura modo hex
puts("00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" );
puts("==============================================" );
for(i=0;i<16;i++) {
for(j=0;j<16;j++) {
printf("%2x ",read_eeprom(i*16 +j) );
}
printf("|| %3x0

" );

",i );
}
puts("
Lectura finalizada!" );
break;
case "3":
printf("
Direccion a cambiar: " ); //opcion que realiza la escritura
address = gethex( );
//le damos la direccion
printf("
Nuevo valor: " );
opcion=0;
//modo datos
value = gethex( );
//le damos el dato a escribir
opcion=1;
//modo direcciones
printf("
Realizando escritura..."
;
write_eeprom(address,value);
printf(" Escritura finalizada!
"

//escribe en la eeprom

" );

break;
case "4":
puts("Realizando Lectura...
//opcion que realiza la lectura modo texto
puts("00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" );
puts("==============================================" );
for(i=0;i<16;i++) {
for(j=0;j<16;j++) {
printf("%c ",read_eeprom(i*16 +j));
}
printf("|| %3x0

",i );
}
puts("
Lectura finalizada!" );
break;
default:
puts("Opcion incorrecta, para ver Menu pulse 0 VsZeNeR"06" );
}
puts("****************************************************
" );
enable_interrupts(global);
//activamos de nuevo la interrupcion serial rs-232
}
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ);
enable_interrupts(int_rda);

//reloj interno de 4MHz


//activo interrupcion serial rs-232

enable_interrupts(global);

//habilito la interrupcion

do{
//bucle...
puts("Lectura/Escritura de EEPROM interna VsZeNeR"06
" );
//menu...
puts("==============================================
" );
puts("Seleccione opcion:
" );
puts("" );
puts(" 0->Ver opciones" );
puts(" 1->LLenar buffer" );
puts(" 2->Lectura modo HEX" );
puts(" 3->Escritura EEPROM" );
puts(" 4->Lectura modo TEXTO" );
//...principal
menu=1;
//muestra menu solamente una vez
while(menu==1){}
//espera tecla pulsada por teclado(rs-232)
}while(TRUE); //...infinito
}
///FUNCION QUE SELECCIONA DIGITO CORRESPONDIENTE
BYTE gethex1() {
char digit;
do{
//espera hasta tener un dato correcto
digit = getc( );
if(opcion==0)
//si estamos introduciendo un dato no hace falta las restricciones
break;
}while((digit<"0" || digit>"9") && (digit<"A" || digit>"F") && (digit<"a" || digit>"f") );
putc(digit);

//muestra por pantalla el dato introducido

if(digit<="9")
//se ha introducido un numero
return(digit-"0");
else
//se ha introducido una letra
return((toupper(digit)-"A")+10);
}
///FUNCION QUE DEVUELVE EL NUMERO HEXADECIMAL
BYTE gethex() {
int lo,hi;
hi = gethex1( );
//parte alta
lo = gethex1( );
//parte baja
if(lo==0xdd)
return(hi);
else
return( hi*16+lo );
}
52
Buenass!!!lo prometido es deuda! aqui esta el programa que gestiona la lectura/escritura de una eeprom
externa, concretamente la 24LC256:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"06
//
23/Enero/06
//
// Programa: RS232 Y PIC

// Version: 1.0 REVISION del programa 48


//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.30
Simulador: Proteus 6.7sp3
//
// Notas: Se interacciona el PC con el PIC mediante RS232 para el tratamiento de la memoria
//
eeprom externa 24LC256,se muestra por v.terminal un menu:
//
0 -> Muestra nuevamente el menu
//
1 -> LLena la eeprom a 0xFF
//
2 -> Lee la eeprom en modo hex
//
3 -> Escribe en la eeprom
//
4 -> Lee la eeprom en modo texto(ASCII)
//
Todas las acciones se realizan mediante la interrupcion del puerto serial.
//
Al comienzo del programa, realizar el paso 1. en caso de empezar a escribir
//
en la eeprom!. Decir que las funciones gethex1() y gethex() estan sacadas
//
de la libreria incluida en CCS, input.c, estan puestas en el programa
//
por la pequea modificacion en la funcion gethex1() que, en este caso, solo
//
permite el paso de digitos comprendidos entre 0-f o 0-F. Tener en cuenta
//
que los datos a introducir deben ser en hexadecimal, por ejmeplo, en el
//
caso de almacenar en la letra "a" minuscula en la posicion 0x00 de la eeprom
//
24LC256, habra que realizar los siguientes pasos:
//
1. Pulsamos 3 para escribir en la eeprom interna
//
2. Ponemos la direccion 00 (esta en hexadecimal!)
//
3. Damos el valor en hex de la letra a=61
//
4. Leemos la memoria para ver que se almacenado correctamente(pulsando 2)
//
// Conexiones:
A0 -> SCK eeprom 24LC256
//
A1 -> SDA eeprom 24LC256
//
B2 -> TxD
//
B1 -> RxD
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //ordenes para el programador
#fuses RC_IO
//reloj interno
#use delay (clock=4000000)
//Fosc=4Mhz
#use rs232(baud=9600, xmit=PIN_b2, rcv=PIN_b1) //manejo del RS232
#define EEPROM_SDA PIN_A1
//pines para...
#define EEPROM_SCL PIN_A0
//...manejo de eeprom 24LC256
#include <24256.c>
//libreria eeprom 24LC256
///DECLARACION DE VARIABLES GLOBALES
boolean menu=1,opcion=1;
//si menu=0 se muestra el menu de inicio...
//...si opcion=1 estamos en modo direccion
//
opcion=0 estamos en modo dato
///DECLARACION DE FUNCIONES
BYTE gethex1( );
//verifica que esta dentro del rango y muestra por pantalla
BYTE gethex( );
//devuelve el numero en hex
///LLAMADA FUNCION INTERRUPCION
#int_rda
void rs232( )
{
BYTE i=0,j=0,value;
//definicion...
EEPROM_ADDRESS address;
char digito;
//...variables
disable_interrupts(global);

//apago interrupcion

digito=getc( );

//almaceno dato serial(rs232) en digito

puts("
****************************************************" );
switch(digito){
case "0":
menu=!menu;
//muestra menu
break;
case "1":
printf("LLenando buffer..." ); //llena memoria 0xff
for(i=0; i<16;i++){
for(j=0; j<16;j++)
write_ext_eeprom(i*16+j,0xff);
}
puts(" Buffer completado!" );
break;
case "2":
puts("Realizando Lectura...
" ); //opcion que realiza la lectura modo hex
puts("00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" );
puts("==============================================" );
for(i=0;i<16;i++) {
for(j=0;j<16;j++) {
printf("%2x ",read_ext_eeprom(i*16 +j) );
}
printf("|| %3x0
",i );
}
puts("
Lectura finalizada!"
;
break;
case "3":
printf("
Direccion a cambiar: " ); //opcion que realiza la escritura
address = gethex( );
//le damos la direccion
printf("
Nuevo valor: " );
opcion=0;
//modo datos
value = gethex( );
//le damos el dato a escribir
opcion=1;
//modo direcciones
printf("
Realizando escritura..." );
write_ext_eeprom(address,value);
//escribe en la eeprom
printf(" Escritura finalizada!
" );
break;
case "4":
puts("Realizando Lectura...
" ); //opcion que realiza la lectura modo texto
puts("00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" );
puts("==============================================" );
for(i=0;i<16;i++) {
for(j=0;j<16;j++) {
printf("%c ",read_ext_eeprom(i*16 +j) );
}
printf("|| %3x0
",i );
}
puts("
Lectura finalizada!" );
break;

default:
puts("Opcion incorrecta, para ver Menu pulse 0 VsZeNeR"06" );
}
puts("****************************************************
"

;
enable_interrupts(global);

//activamos de nuevo la interrupcion serial rs-232

}
void main(void)
{
setup_oscillator(OSC_4MHZ);
enable_interrupts(int_rda);
enable_interrupts(global);

//reloj interno de 4MHz


//activo interrupcion serial rs-232
//habilito la interrupcion

init_ext_eeprom( );
do{
//bucle...
puts("Lectura/Escritura de EEPROM 24LC256 VsZeNeR"06
" );
//menu...
puts("==============================================
" );
puts("Seleccione opcion:
" );
puts("" );
puts(" 0->Ver opciones" );
puts(" 1->LLenar buffer" );
puts(" 2->Lectura modo HEX" );
puts(" 3->Escritura EEPROM" );
puts(" 4->Lectura modo TEXTO" );
//...principal
menu=1;
//muestra menu solamente una vez
while(menu==1){ }
//espera tecla pulsada por teclado(rs-232)
}while(TRUE); //...infinito
}
///FUNCION QUE SELECCIONA DIGITO CORRESPONDIENTE
BYTE gethex1( ) {
char digit;
do{
//espera hasta tener un dato correcto
digit = getc();
if(opcion==0)
//si estamos introduciendo un dato no hace falta las restricciones
break;
}while((digit<"0" || digit>"9") && (digit<"A" || digit>"F") && (digit<"a" || digit>"f" ));
putc(digit);

//muestra por pantalla el dato introducido

if(digit<="9" )
//se ha introducido un numero
return(digit-"0" );
else
//se ha introducido una letra
return((toupper(digit)-"A" )+10);
}
///FUNCION QUE DEVUELVE EL NUMERO HEXADECIMAL
BYTE gethex() {
int lo,hi;
hi = gethex1();
lo = gethex1( );
if(lo==0xdd)
return(hi);

//parte alta
//parte baja

else
return( hi*16+lo );
}
53
Buenasss!!!bien, el sigiente programa es simplemente manejar el dispositivo SAA1064 de Philips, el cual
sirve para manejar display"s de 7segmentos mediante bus I2C, tanto para la libreria del dispositivo para CCS
como para PROTEUS lo podeis encontrar en el siguiente post:
Libreria: SAA1064 (CCS)
El SAA1064 es util para ahorrar pines del pic(ya que solamente usa 2 para manejo del I2C), dicho dispositivo
puede actuar tanto en modo dinamico(manejando un total de 4 display"s multiplexados), como en modo
estatico(solamente 2 display"s), puede controlar la iluminosidad, parpadeo,...mirar el enlace anterior donde
esta el data sheet!, bueno el ejemplo es manejar el SAA1064 en modo dinamico:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"06
//
29/Enero/06
//
// Programa: Manejo del dispositivo SAA1064 en modo DINAMICO
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.30
Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra pos cuatro display"s de 7seg mensajes de texto, para
//
ello usamos el dispositivo SAA1064 de bus I2C.
//
//
Conexiones:
A0 -> SDA saa1064
//
A1 -> SCL saa1064
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#define SAA1064_DINAMICO
//trabajar en modo dinamico el saa1064
#define SAA1064_SCL PIN_A1
//definicion de pines...
#define SAA1064_SDA PIN_A0
//...de manejo del saa1064
#include <vs_saa1064.c>
//libreria saa1064
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ);
saa1064_init();

//configuracion del oscilador interno a 4MHz

//inicializo saa1064

do{
//bucle...
///MANIPULAMOS SAA1064 CON DIVERSAS CONFIGURACIONES
saa1064_conf(0b00010001);
//3mA & NO parpadeo & Dinamico
saa1064_putc(0x76,0x3F,0x38,0x77); //HOLA
delay_ms(1500);
saa1064_conf(0b00100011);
//6mA & parpadeo 1&3 & Dinamico
saa1064_putc(0x71,0x5C,0x50,0x5C); //Foro
delay_ms(1500);
saa1064_conf(0b01000101);

//12mA & parpadeo 2&4 & Dinamico

saa1064_putc(0x78,0x5C,0x5E,0x5C);
delay_ms(1500);

//todo

saa1064_conf(0b00110111);
//9mA & parpadeo TODO & Dinamico
saa1064_putc(0x73,0x30,0x39,0x86); //PIC!
delay_ms(1500);
saa1064_conf(0b01110001);
//21mA & NO parpadeo & Dinamico
saa1064_putc(0x5B,0x3F,0x3F,0x7D); //2006
delay_ms(1500);
///MANIPULAMOS SAA1064 A CONFIGURACION FIJA -> CAMBIAMOS SOLAMENTE DIGITO DESEADO
saa1064_conf(0b01110001);
//21mA & NO parpadeo & Dinamico ->Configuracion fija!
saa1064_putc(0x76,0x3F,0x38,0x77); //HOLA -> texto donde trabajar!
delay_ms(1500);
saa1064_subaddress(1,0xFF);
//Pongo en el 1 digito el caracter 8.
delay_ms(1500);
saa1064_putc(0x76,0x3F,0x38,0x77); //reset -> HOLA
saa1064_subaddress(2,0xFF);
//Pongo en el 2 digito el caracter 8.
delay_ms(1500);
saa1064_putc(0x76,0x3F,0x38,0x77); //reset -> HOLA
saa1064_subaddress(3,0xFF);
//Pongo en el 3 digito el caracter 8.
delay_ms(1500);
saa1064_putc(0x76,0x3F,0x38,0x77); //reset -> HOLA
saa1064_subaddress(4,0xFF);
//Pongo en el 4 digito el caracter 8.
delay_ms(1500);
saa1064_putc(0x76,0x3F,0x38,0x77); //reset -> HOLA
}while(TRUE);
}

//...infinito

54
Holaaa!!!Bueno, trabajando un poco mas con la libreria del SAA1064, el siguiente ejemplo quiere mostrar
como trabajar con las funciones de dicha libreria para modo ESTATICO, es decir, simplemente manejaremos
dos display"s de 7 segmentos, aqui el programa:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"06
//
29/Enero/06
//
// Programa: Manejo del dispositivo SAA1064 en modo ESTATICO
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.30
Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra por dos display"s de 7seg numeros, para
//
ello usamos el dispositivo SAA1064 de bus I2C.
//
//
Conexiones:
A0 -> SDA saa1064
//
A1 -> SCL saa1064
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#define SAA1064_SCL PIN_A1
//definicion de pines...
#define SAA1064_SDA PIN_A0
//...de manejo del saa1064
#include <vs_saa1064.c>
//libreria saa1064
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ);
saa1064_init( );

//configuracion del oscilador interno a 4MHz

//inicializo saa1064

do{
//bucle...
///MANIPULAMOS SAA1064 CON DIVERSAS CONFIGURACIONES
saa1064_conf(0b00010000); //3mA & NO parpadeo & Estatico
saa1064_putc(0x66,0x3F); //40
delay_ms(1500);
saa1064_conf(0b00100010); //6mA & parpadeo & Estatico
saa1064_putc(0x4F,0x06); //31
delay_ms(1500);
saa1064_conf(0b01000100); //12mA & parpadeo & Estatico
saa1064_putc(0x5B,0x5B); //22
delay_ms(1500);
saa1064_conf(0b00110110); //9mA & parpadeo & Estatico
saa1064_putc(0x06,0x4F); //13
delay_ms(1500);
saa1064_conf(0b01110000); //21mA & NO parpadeo & Estatico
saa1064_putc(0x3F,0x66); //04
delay_ms(1500);
///MANIPULAMOS SAA1064 CON CONFIGURACION FIJA -> CAMBIAMOS SOLO UN DIGITO
saa1064_conf(0b00010000); //3mA & NO parpadeo & Estatico -> configuracion fija!
saa1064_putc(0x3F,0x3F); //00 -> texto donde trabajar!
delay_ms(1500);
saa1064_subaddress(1,0xff); //cambio el 1 digito por 8 ->08
delay_ms(1500);
saa1064_putc(0x3F,0x3F); //restauro -> 00
saa1064_subaddress(2,0xff);
delay_ms(1500);
}while(TRUE);

//cambio el 2 digito por 8 ->80

//...infinito

}
55
Holaaa!!!he aqui un programita que maneja la libreria y el dispositivo pcf8591!, en este caso como D/A, es
decir, mediante un pulsador vamos sumando un valor que sera mostrado por el pcf8591 en el pin AOUT,
dicho valor es de 8 bits y se vera el encendido paulatino de un led y su tension correspondiente por dicho
pin:

////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"06
//
13/Marzo/06
//
// Programa: Manejo del dispositivo PCF8591 en modo D/A
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.31
Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra el encendido paulatino de un diodo led
//
conectado al pcf8591 configurado para actuar como D/A.
//
La Vref es de 2,5v por lo tanto la resolucion del conversor es 10mV.
//
Al pulsar el boton se produce una interrupcion, en dicha interrupcion
//
se incrementa la variable "dato" en una unidad y se muestra por el pcf8591
//
por el pin AOUT, al ser de tipo entero dicha variable puede llegar hasta
//
255 siendo este el valor maximo que puede alcanzar la seal analogica del
//
pcf8591.
//
//
Conexiones:
B7 -> SDA pcf8591
//
B6 -> SCL pcf8591
//
B0 -> Boton
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#define PCF8591_SCL PIN_B6
//definicion de pines...
#define PCF8591_SDA PIN_B7
//...de manejo del pcf8591
#include <vs_pcf8591.c>
//libreria pcf8591
///DEFINICION VARIABLES GLOBALES
int dato;
//variable de salida por AOUT
///LLAMADA FUNCION INTERRUPCION
#INT_EXT
void IntRB0()
{
dato++;
//incremento variable dato
write_dac_value(dato);
//salida analogica AOUT
}

///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ);

//configuracion del oscilador interno a 4MHz

enable_interrupts(int_ext);
//activar interrupcion externa
ext_int_edge(H_TO_L);
//configuracion:interrupcion cuando seal esta en baja
enable_interrupts(GLOBAL);
//activar interrupciones
pcf8591_dac_init( );
write_dac_value(dato);

//inicializamos pcf8591 en modo D/A


//voltaje inicial de salida 0v

sleep( );

//modo reposo hasta la interrupcion

}
56
Holaaa!!!aqui el programita que usaremos con la "mini-libreria" pcf8591 pero esta vez configurada como
A/D, este programa es el tipico del voltimetro digital!:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"06
//
13/Marzo/06
//
[email]vszener@gmail.com[/email]
//
// Programa: Manejo del dispositivo PCF8591 en modo A/D
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.31
Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra el voltaje de entrada por el AIN0 en formato simple
//
de un potenciometro.
//
La Vref es de 2,5v por lo tanto la resolucion del conversor es 10mV.
//
Se configura el dispositivo con 4 entradas analogicas simples y no hay
//
auotincremento. La lectura se realiza mediante el desbordamiento del timer0
//
aproximadamente cada 65.5ms. Al ser la resolucion 2,5v, el voltaje maximo
//
puede medir es de 2,5v. Mediante software se intenta mejorar la aproximacion
//
de la seal obtenida, se multiplica por 0.009803 para mostrar el dato en su
//
forma decimal y mejorar su resolucion, tener en cuenta que el dato leido
//
por el pcf8591 es el voltaje de un potenciometro y su valor oscila entre
//
0-2.5v. Para su representacion en forma decimal debemos efectuar la operacion
//
anteriormente mencionada ya que si no lo hicieramos se mostraria por pantalla
//
un numero entero(para 2,5v se mostraria 255).
//
//
Conexiones:
A1 -> SDA pcf8591
//
A0 -> SCL pcf8591
//
B0 -> E LCD
//
B1 -> RS LCD
//
B2 -> RW LCD
//
B4 -> D4 LCD
//
B5 -> D5 LCD
//
B6 -> D6 LCD
//
B7 -> D7 LCD
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#define use_portb_lcd TRUE
#include <lcd.c>
//libreria para lcd
#define PCF8591_SCL PIN_A0
//definicion de pines...
#define PCF8591_SDA PIN_A1
//...de manejo del pcf8591
#include <vs_pcf8591.c>
//libreria pcf8591
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER0
void interrupcion( )
{
int dato;
//almacena lectura del pcf8591

float variable;

//tratamiento de la informacion a representar

dato=read_adc_value( );
//lee del pcf8591
variable=(float)dato*0.009803;
//se procesa la seal para su representacion
printf(lcd_putc,"fTension: %1.2f V",variable); //muestra por lcd
lcd_putc("
VsZeNeR"06" );
set_timer0(0 );

//carga TMR0

}
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ);

//configuracion del oscilador interno a 4MHz

enable_interrupts(INT_TIMER0);
//interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0
lcd_init( );
set_timer0(0 );
enable_interrupts(GLOBAL);

//inicializamos lcd
//carga TMR0 -> temporizacion maxima aprox 65.5ms
//activadas interrupciones

pcf8591_adc_init(0b00000000);
//inicializamos pcf8591 en modo D/A con entradas
//entradas analog. simples
while(TRUE){ }
//bucle infinito
}
57
Holaaa!!!aqui el programita que usaremos con la "mini-libreria" pcf8591 pero esta vez configurada como
A/D, este programa es el tipico del voltimetro digital!:
////////////////////////////////////////////////////////////////////////////////////
//
VsZeNeR"06
//
13/Marzo/06
//
[email]vszener@gmail.com[/email]
//
// Programa: Manejo del dispositivo PCF8591 en modo A/D
// Version: 0.0
//
// Dispositivo: PIC 16F648A
Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.31
Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra el voltaje de entrada por el AIN0 en formato simple
//
de un potenciometro.
//
La Vref es de 2,5v por lo tanto la resolucion del conversor es 10mV.
//
Se configura el dispositivo con 4 entradas analogicas simples y no hay
//
auotincremento. La lectura se realiza mediante el desbordamiento del timer0
//
aproximadamente cada 65.5ms. Al ser la resolucion 2,5v, el voltaje maximo
//
puede medir es de 2,5v. Mediante software se intenta mejorar la aproximacion
//
de la seal obtenida, se multiplica por 0.009803 para mostrar el dato en su
//
forma decimal y mejorar su resolucion, tener en cuenta que el dato leido
//
por el pcf8591 es el voltaje de un potenciometro y su valor oscila entre
//
0-2.5v. Para su representacion en forma decimal debemos efectuar la operacion
//
anteriormente mencionada ya que si no lo hicieramos se mostraria por pantalla
//
un numero entero(para 2,5v se mostraria 255).
//

//
Conexiones:
A1 -> SDA pcf8591
//
A0 -> SCL pcf8591
//
B0 -> E LCD
//
B1 -> RS LCD
//
B2 -> RW LCD
//
B4 -> D4 LCD
//
B5 -> D5 LCD
//
B6 -> D6 LCD
//
B7 -> D7 LCD
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>
//pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador
#fuses INTRC
//oscilador interno
#use delay (clock=4000000)
//Fosc=4Mhz
#define use_portb_lcd TRUE
#include <lcd.c>
//libreria para lcd
#define PCF8591_SCL PIN_A0
//definicion de pines...
#define PCF8591_SDA PIN_A1
//...de manejo del pcf8591
#include <vs_pcf8591.c>
//libreria pcf8591
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER0
void interrupcion( )
{
int dato;
//almacena lectura del pcf8591
float variable;
//tratamiento de la informacion a representar
dato=read_adc_value( );
//lee del pcf8591
variable=(float)dato*0.009803;
//se procesa la seal para su representacion
printf(lcd_putc,"fTension: %1.2f V",variable); //muestra por lcd
lcd_putc("
VsZeNeR"06" );
set_timer0(0 );

//carga TMR0

}
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ);

//configuracion del oscilador interno a 4MHz

enable_interrupts(INT_TIMER0);
//interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0
lcd_init( );
set_timer0(0 );
enable_interrupts(GLOBAL);

//inicializamos lcd
//carga TMR0 -> temporizacion maxima aprox 65.5ms
//activadas interrupciones

pcf8591_adc_init(0b00000000);
//inicializamos pcf8591 en modo D/A con entradas
//entradas analog. simples
while(TRUE){ }
//bucle infinito
}
58

1. VsZeNeR'06
2. //

23/Mayo/06

3. //

vszener@gmail.com

4. //
5. //

Programa: Termometro digital mediante el ds1620

6. //

Version:

1.0

7. //
8. //
Dispositivo: PIC 16F648A
CCS vs3.249

Compilador:

9. //
Entorno IDE: MPLAB IDE v7.31
Proteus 6.7sp3

Simulador:

10.

//

11.
//
Notas: Este programa muestra por el
hyperterminal la temperatura leida
12.

//

13.

//

14.

//

del dispositivo ds1620.

Conexiones:

A0 -> DQ ds1620

15.
//
ds1620

A1 -> CLK/CONV#

16.
//
ds1620

A2 -> RST#

17.
///////////////////////////////////////////////////
///////////////////////////////
18.
19.
#include <16f648a.h>
utilizar

//pic a

20.

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP
//ordenes para el programador

21.

#fuses INTRC
//oscilador interno

22.

#use delay (clock=4000000)


//Fosc=4Mhz

23.

#use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1)
//manejo del RS232

24.

#define DS1620_DQ
//declaracion...

PIN_A0

25.

#define DS1620_CLK

PIN_A1

26.
#define DS1620_RST
pines para el ds1620

PIN_A2

27.

//...de

#include <vs_ds1620.c>
//libreria ds1620

28.
29.

///LLAMADA FUNCION INTERRUPCION

30.

#INT_TIMER1

31.
void interrupcion() //leemos la temp y la enviamos
via serial rs232 al hyperterminal
32.

33.
printf("\fVsZeNeR'06 -> Termometro
Digital\n\r\n\rTemperatura: %3.1f C",read_ds1620());
34.

35.
36.

///PROGRAMA

37.

void main(void)

38.

39.

setup_oscillator(OSC_4MHZ);
//configuracion del oscilador interno a 4MHz

40.

enable_interrupts(INT_TIMER1);
//interrupcion TIMER1 activada

41.

SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_8);
//configuracion interrupcion TMR1

42.

set_timer1(10);
//carga TMR1

43.

enable_interrupts(GLOBAL);
//activadas interrupciones

44.

setup_uart(TRUE);
//activamos la uart

45.
46.
for(;;){}
interrupcion del TMR1
47.

//bucle infinito -> espera

S-ar putea să vă placă și