Documente Academic
Documente Profesional
Documente Cultură
Mensajes: 75 ////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// Practica 1 : Parpadeo de LED´S con PIC16F84A ///
/// para el foro.elhacker.net by Marco ///
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//////////////////////////GLOBALES//////////////////////////////////////////////
/// Estos parámetros son visibles desde todo el
código ///
/// por eso se les llama globales ///
/// Al ser constantes,lo más práctico es declararlas aquí. ///
////////////////////////////////////////////////////////////////////////////////////
int contador;
void main()
{
/// bucle infinito para que las instrucciones que tiene siempre se
ejecuten
while (true)
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// Practica 2 /////////////////////////////////
// Esta practica pasa la informacion que hay en el puerto B y la pasa //
// al puerto A //
///////////////////////// By Marco_recargado ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
void main(void)
{
while(true) // Bucle infinito
{
set_tris_b(0xff); // se configura el puerto A como entrada
set_tris_c(0x00); // se configura el puerto B como salida
port_b_pullups(true); // activa las resistencias de pull-up
portc=portb;
}
} // fin de programa
////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////Practica 3 ///////////////////////////////////////////
////////Visualiza un conteo por el PORTB a travez de dos display de 8 seg////////
////////////////////////// By MARCO_RECARGADO///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
#include <16F877A.h> /// libreria para el manejo del pic16f877a
#use delay(clock=8000000) /// declara la frecuencia del cristal
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
int conteo=0;
#use fast_io(A)
#use fast_io(B)
#use fast_io(C) /// con esta instruccion evitamos que
#use fast_io(D) /// se este configurando cada vez que usamos
#use fast_io(E) /// alguna instruccion de entrada o salida
#byte porta = 5
#byte portb = 6
#byte portc = 7 /// se definen direcciones de memoria
#byte portd = 8
#byte porte = 9
////////////////////////////////////////////////////////////////////////////////////
//////////////////////inicio del programa principal/////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
void main(void)
{
set_tris_b(0x00);
while(true) //bucle infinito
{
conteo++;
////////////////////////////////////////////////////////////////////////////////
////////////// Practica 2 //////////////////////
////////////// practica que escribe en una LCD //////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////// By MARCO RECARGADO //////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
////////////////////////////////////////////////////////////////////////////////
int i;
void main(void)
{
lcd_init(); // Antes de usar el lcd,hay que inicializarlo
while (1){
lcd_gotoxy(5,1);
lcd_putc("Martin"); // Escribes en la lcd
delay_ms(50);
for(i=0;i<8;++i){
lcd_putc("\fM\n");
delay_ms(30);
lcd_putc("\f a\n");
delay_ms(30);
lcd_putc("\f t\n");
delay_ms(30);
lcd_putc("\f i\n");
delay_ms(30);
lcd_putc("\f n\n");
delay_ms(30);
}}
} // fin de programa
En línea
////////////////////////////////////////////////////////////////////////////////
////////////ESTE PROGRAMA UTILZA EL CIRCUITO DS1307 PARA
MOSTRAR LA ////////////
//////////HORA EN TIEMPO REAL A TRAVEZ DE UNOS DISPLAY´S
DE 7 SEGMENTOS/////////
//////////EL PROGRAMA PARA SIMULARLO EN PROTEUS SE LLAMA
RELOJ TIEMPO REAL//////
Mas recargado que nunca
////////////////////////BY MARCO RECARGADO//////////////////////////////////////
int32 tiempo_real=0;
long dato_1=0;
long dato_2=0;
long dato_3=0;
long dato_4=0;
long dato_5=0;
long dato_6=0;
#use fast_io(A)
#use fast_io(B)
//#use fast_io(C) /// con esta instruccion evitamos que
#use fast_io(D) /// se este configurando cada vez que usamos
#use fast_io(E) /// alguna instruccion de entrada o salida
byte sec;
byte min;
byte hrs;
byte day;
byte month;
byte yr;
byte dow;
////////////////////////////////////////////////////////////////////////////////
////////funcion que manda el a desplagar informacion en los displays////////////
/////Tomese en cuenta que las conexiones de los puertos son las
siguientes//////
// pc0=a //
// pc1=b //
// pc6=d //
// pc7=c //
// pd1=digito 6 //
// pd4=digito 5 //
// pd0=digito 4 //
// pd7=digito 3 //
// pd5=digito 2 //
// pd6=digito 1 //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void desplegar()
{
portd1=0;
portd4=0;
portd0=0; /// se inihiben los displays
portd7=0;
portd5=0;
portd6=0;
portc0=dato_6a;
portc7=dato_6b;
portc1=dato_6c;
portc6=dato_6d;
portd1=1;
portd1=0;
portc0=dato_5a;
portc7=dato_5b;
portc1=dato_5c;
portc6=dato_5d;
portd4=1;
portd4=0;
portc0=dato_4a;
portc7=dato_4b;
portc1=dato_4c;
portc6=dato_4d;
portd0=1;
portd0=0;
portc0=dato_3a;
portc7=dato_3b;
portc1=dato_3c;
portc6=dato_3d;
portd7=1;
portd7=0;
portc0=dato_2a;
portc7=dato_2b;
portc1=dato_2c;
portc6=dato_2d;
portd5=1;
portd5=0;
portc0=dato_1a;
portc7=dato_1b;
portc1=dato_1c;
portc6=dato_1d;
portd6=1;
portd6=0;
}
////////////////////////////////////////////////////////////////////////////////
//////////////////////Comienzo de la funcion principal//////////////////////////
////////////////////////////////////////////////////////////////////////////////
void main()
{
set_tris_a(0xff);
set_tris_d(0x00);
set_tris_b(0x00);
set_tris_c(0x04);
set_tris_e(0x01);
port_b_pullups(true);
dato_1=8;
dato_2=8;
dato_3=8;
dato_4=8;
dato_5=8;
dato_6=8;
desplegar();
while(1)
{
delay_ms(1000);
sec=bin2bcd(sec);
min=bin2bcd(min);
hrs=bin2bcd(hrs);
dato_1=0x0f&sec;
dato_2=swap(0xf0&sec);
dato_3=0x0f&min;
dato_4=swap(0xf0&min);
dato_5=0x0f&hrs;
dato_6=swap(0xf0&hrs);
desplegar();
}
}
///////////////////////////// fin de programa /////////////////////////////////////////////
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
//////////////////////////////////////////////////////////////////////////////////
///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
}
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()
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
set_tris_b(0xF8); //puerto b como salida
disable_interrupts(GLOBAL); //todas interrupciones desactivadas
////////////////////////////////////////////////////////////////////////////////////
// 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()
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
set_tris_b(0x00); //puerto b como salida
disable_interrupts(GLOBAL); //todas interrupciones desactivadas
///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{ //bucle...
derecha();
izquierda();
}while(TRUE); //...infinito
}
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);
output_high(PIN_A1);
delay_ms(300);
output_low(PIN_A1);
}
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///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...
}while(TRUE); //...infinito
}
// 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
signed char i; //variable indice
int leds[4]={0b10000001,0b01000010,0b00100100,0b00011000}; //led"s
do{ //bucle...
}while(TRUE); //...infinito
}
Bien aqui la nueva entrega de programitas en c jeje!!!, esta vez no voy a poner un programa
nuevo, sino la recopilacion de dos que ya hemos realizado, me explico la idea es que con el
programa del coche fantastico y el programa este ultimo del juego de luces....¿porque no
realizar el pic los dos?es decir, con un switch si esta cerrado que ejecute un programa y si
esta abierto realice el otro...para ello debemos hacernos nuestra libreria(nuestro include
fichero.h)y alli definir nuestras funciones(digo hacer librerias porque no vamos a programar
otra vez lo que ya hemos hecho!!!): aqui la libreria:
////////////////////////////////////////////////////////////////////////////////////
// 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; //inicializar...
for(i=1;i<8;i++){ //led"s on derecha
output_b(cont); //ilumino led correspondiente
delay_ms(100);
cont=cont*2;
}
for(i=1;i<8;i++){
output_b(cont); //ilumino led correspondiente
delay_ms(100);
cont=cont/2;
}
}
////////////////////////////////////////////////////////////////////////////////////
// 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
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///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
}
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///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
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
}
Bien el ejemplito de hoy es igual que el anterior, es decir un contador descendente 9-0 y
vuelta a empezar.....digo que es igual en tema de codigo, solamente cambia algun que otro
comando.......aqui esta:
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///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}; //7seg hex
0-9
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)
}
}while(TRUE); //...infinito
}
///DECLARACION DE FUNCIONES
void up(void); //funcion cuenta ascendente
void down(void); //funcion cuenta descendente
do{ //bucle...
if(input(PIN_A0)) //¿switch abierto?
up(); //SI -> contador ascendente
else
down(); //NO -> contador descendente
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; //7seg hex
0-9
Aqui estamos de nuevo!!!jeje ya que sabemos contar desde 0 al 99, ¿porque no contar
desde 99 a 00?ummmm pero de forma automatica, es decir, nuestro contador empezara a
contar de forma ascendente de 00 a 99 y cuando alcance el digito 99 que empiece a contar
de forma descendente de 99 a 00 y vuelta a empezar!!!! aqui va el codigo:
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
//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
///PROGRAMA
void main(void)
{
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; //7seg hex
0-9
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
}
Código
GeSHi (c):
1. ///////////////////////////////////////////////////////////////////
/////////////////
2. // VsZeNeR'05
3. // 22/Agosto/05
4. //
vszener@gmail.com
5. // Programa: Contador 0-9 display BDC & Boton
6. // Version: 0.0
7. //
8. // Dispositivo: PIC 16F648A Compilador: CCS vs3.227
9. // Entorno IDE: MPLAB IDE v7.20 Simulador:
Proteus 6.7sp3
10. //
11. // Notas: Contador 0 al 9 cada vez que pulsemos el boton y
vuelta a empezar. Tener
12. // en cuenta que hay que poner la directiva NOLVP
para que el pin B4 sea de
13. // salida. Cuando agregamos un boton a nuestro
circuito hay que tener en cuenta
14. // que este dispositivo genera 'rebotes' que hay
que ser eliminados para
15. // una correcta visualizacion en el display del
digito seleccionado. Esta vez
16. // la eliminacion de 'los rebotes' se ha realizado
mediante software.
17. // Cuando por el pin A0 del porta se introduce un
'0' logico(low), se
18. // incrementa un digito en el display BCD.
19. //
20. // Conexiones: A0 -> boton
21. // B0 -> a
22. // B1 -> b
23. // B2 -> c
24. // B3 -> d
25. // BCD:
26. // d c b a NUM
27. // 0 0 0 0 0
28. // 0 0 0 1 1
29. // 0 0 1 0 2
30. // 0 0 1 1 3
31. // 0 1 0 0 4
32. // 0 1 0 1 5
33. // 0 1 1 0 6
34. // 0 1 1 1 7
35. // 1 0 0 0 8
36. // 1 0 0 1 9
37. //////////////////////////////////////////////////////////////////
////////////////
38.
39. #include <16f648a.h> //pic a utilizar
40. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el
programador
41. #use delay (clock=4000000) //Fosc=4Mhz
42. #use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3)
43. #use standard_io(A)
44.
45. ///PROGRAMA
46. void main(void)
47. {
48. char i=0; //contador para tabla BCD
49. int
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111
,0b1000,0b1001}; //BCD 0-9
50.
51. set_tris_a(0xFF); //porta como
entrada
52. disable_interrupts(GLOBAL); //todas las
interrupciones desactivadas
53.
54. output_b(tabBCD[i]); //inicializa
displayBCD digito 0
55.
56. for(;;){
//bucle...
57. if(!input(PIN_A0)) //¿se ha
pulsado el boton?
58. {
59. delay_ms(151); //SI ->
retardo para evitar los rebotes
60. i++;
//incremento contador indice tabBCD
61. if(i>9)
//¿se ha mostrado digito 9?
62. i=0; //SI
-> restaura valor indice(para mostrar digito 0)
63. output_b(tabBCD[i]); //muestra por
portb digito 7 segmentos
64. }
65. } //...infinit
66. }
67.
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 22/Agosto/05
//
// Programa: Contador 0-9 display BDC & Boton para cuenta ascendente o 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 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:
// 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
signed char i=0; //contador para tabla BCD
int
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1
001}; //BCD 0-9
for( ; ; ){ //bucle...
if(!input(PIN_A0)) //¿se ha pulsado el boton up?
{
delay_ms(151); //SI -> retardo para evitar los rebotes
i++; //incremento contador indice tabBCD
if(i>9) //¿se ha mostrado digito 9?
i=0; //SI -> restaura valor indice(para mostrar digito 0)
}
if(!input(PIN_A1)) //¿se ha pulsado el boton down?
{
delay_ms(151); //SI -> retardo para evitar los rebotes
i--; //decremento contador indice tabBCD
if(i<0) //¿se ha mostrado digito 0?
i=9; //SI -> restaura valor indice(para mostrar digito 9)
}
output_b(tabBCD[ i ]); //muestra por portb digito BCD
} //...infinito
}
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 23/Agosto/05
//
// Programa: Contador del 0000 al 9999
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; //7seg hex
0-9
do{ //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
}
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 24/Agosto/05
//
// Programa: BETI parpadeo
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
char i; //contador de visualizacion BETI
do{ //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); //...apagado durante 0,5s
}while(TRUE); //...infinito
}
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 25/Agosto/05
//
// Programa: AUPA DEPO parpadeo
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 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
//////////////////////////////////////////////////////////////////////////////////
///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}; //A U P D E O
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
///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); //activadas interrupciones
do{ //bucle...
output_low(PIN_A0); //activado...
output_high(PIN_A1);
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
}
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 26/Agosto/05
//
// Programa: Cuadrado que recorre 4 display"s de 7seg de izuiqerda a derechas
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: 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
//////////////////////////////////////////////////////////////////////////////////
do{ //bucle...
for(i=0;i<3;i++){ //hacia la izquierda
delay_ms(100);
output_a(display_on[ i ]);
}
Bien aqui el ejemplito numero 22!!!!jeje esta vez consiste en hacer un dado electronico, se
utilizada un display de 7seg en formato BCD(que ya conocemos) y un pulsador(los cuales
producen los molestos "rebotes" que pueden ser eliminados mediante hardware o como este
caso emdiante software pero esta vez no realizamos una espera sino que lo eliminamos
mediante un bucle), el programa llama a una funcion definida en la libreria #include
<STDLIB.H> la cual tiene la funcion srand() y rand() , esta ultima para generar numeros
aleatorios, tener en cuenta que tenemos que definir esta variable como sigue: #define
RAND_MAX 10 para que solo contemos del 0 al 9:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 25/Agosto/05
//
// Programa: Dado digital
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 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 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:
// 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
char num=0; //variable almacena numero aleatorio
Y para empezar con estos "cacharros" que mejor que decir "hola mundo" jeje pues aqui
esta!!!!:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 26/Agosto/05
//
// Programa: Hola mundo
// 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". 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
lcd_init(); //inicializa lcd
printf(lcd_putc,"hola mundo ; )
VsZeNeR"05" ); //muestra por pantalla el mensaje
}
Buenas!!!!decir que el ejemplo que propongo es igual al anterior excepto una salvedad, esta
vez nos ahorraremos un pin, es decir, el programa dira la frase "hola mundo...." pero
utilizando un pin menos conectado al lcd, el pin que nos vamos ahorrar es el conectado a
RW de la lcd, esto tiene sus ventajas y sus inconvenientes, VENTAJAS: tenemos un pin
mas sobre el cual poder actuar de nuestro dispositivo, menos lineas de ruteo, etc...
INCONVENIENTES: en vez de mandar los datos al lcd empaquetados en 8bits lo
mandamos empaquetados en 4 por lo tanto la informacion se procesa de modo mas lenta lo
que nos obliga a realizar un retraso de unos 2ms antes de mostrar el mensaje para que
pueda ser apreciado todos los caracteres, no podemos leer datos de la lcd, etc.....Bueno
decir que segun sea nuestro programa utilizaremos la forma ahorro de un pin o utilizaremos
la forma normal...aqui el codigo:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 26/Agosto/05
//
// Programa: Hola mundo VsZeNeR"05 ahorrando 1 pin
// Version: 0.1
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 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". 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
//////////////////////////////////////////////////////////////////////////////////
///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
}
Hola!!!el programita de hoy consiste en mostrar por pantalla del lcd el abecedario carcater
por carcater(eso si teniendo en cuenta los caracteres imprimibles de la lcd-ver data sheet
que esta indicado en unos de los mensajes anteriores -)uno al lado del otro y borra
pantalla y vuelta a empezar:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 26/Agosto/05
//
// Programa: Abecedario
// 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) 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
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
do{ //bucle...
for(x=1;x<27;x++){ //bucle para mostrar digito
if(y==1) //1º fila del lcd
lcd_gotoxy(x,y);
else //2º fila del lcd
lcd_gotoxy((x-16),y);
Wenas!!!!jeje bien el programa ke ofrezco hoy es mostrar una frase por lcd e ir moviendola
primero por la 1ºfila de la lcd cuando se haya mostrado completo por la primera fila se
traslada a la 2ºfila hasta recorrer toda esta 2ºfila y mostrarse completo y vuelta a
empezar!!!:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 29/Agosto/05
//
// Programa: VsZeNeR"05 mov pantalla
// 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) como la palabra VsZeNeR"05
// se va moviendo por pantalla, empieza en la 1ºfila y termina en la 2ºfila.
// Se utiliza variables locales:
// ·x -> indice filas, es de tipo char signed porque necesitamos nº negativos
// para que en la 2ºfila del lcd aparezca primero el final del mensaje.
// ·y -> indice de columnas: y=1 -> 1ºcolumna
// y=2 -> 2ºcolumna
// 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
char y=1; //indice columnas
signed char x=1; //indice filas
lcd_init(); //inicializa lcd
while(TRUE){ //bucle...
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>16){ //¿ya se ha mostrado mensaje entero por 1ºfila?
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
}
Bueno el programa de hoy se basa ver los limites de la lcd a nivel de pantalla, vamos es
igual que el ejemplo anterior pero esta vez la frase en vez de volver al principio(1º fila) sale
por la 2ºfila y vuelve a la primera y vuelta a empezar, recorre 1ºfila->2ºfila->2ºfila->1ºfila y
asi sucesivamente:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 30/Agosto/05
//
// Programa: VsZeNeR"05 mov limites
// 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) como la palabra VsZeNeR"05
// se va moviendo por pantalla, empieza en la 1ºfila y termina en la 2ºfila y
// empieza a moverse en sentido contrario,2ºfila hasta la 1ºfila.
// Se utiliza variables globales:
// ·x -> indice filas, es de tipo char signed porque necesitamos nº negativos
// para que en la 2ºfila del lcd aparezca primero el final del mensaje.
// ·y -> indice de columnas: y=1 -> 1ºcolumna
// y=2 -> 2ºcolumna
// ·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
//////////////////////////////////////////////////////////////////////////////////
///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
}
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 30/Agosto/05
//
// Programa: Escribir & leer eeprom interna del PIC 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
// 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
//////////////////////////////////////////////////////////////////////////////////
for( ; ; ){ //bucle...
for(LAST_VOLUME=0;LAST_VOLUME<4;LAST_VOLUME++){ //bucle que
recorre las posiciones de eeprom
volume = read_EEPROM (LAST_VOLUME); //almacena mensaje de la
direccion eeprom
printf(lcd_putc,"%s",volume) ; //muestra mensaje por pantalla lcd
delay_ms(500);
lcd_putc("f" ); //borra pantalla lcd
} //...infinito
}
}
Este ejemplito esinteresante ya que utilizamos la eeprom interna de nuestro dispositivo para
almacenar 4 mensajes y despues sacralos por pantalla, recordar que la eeprom es una
porcion de memoria no volatil, es decir los tres mensajes grabados se quedaran
almacenados en el pic incluso quitandole la alimentacion al pic!
RE: Ejemplitos en C para 16F648A
« Respuesta #78 : 05 de Septiembre de 2005, 06:01:00 »
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 27/Agosto/05
//
// Programa: Contador 0a9 por LCD con pulsador y buzzer
// 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) 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)
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
char tabNum[10]={"0","1","2","3","4","5","6","7","8","9"},i=0; //tabla y variable
definida
printf(lcd_putc,"
VsZeNeR"05" ); //auto publicidad en la 2ºfila lcd
lcd_gotoxy(8,1); //vuelve 1ºfila lcd y apunta la mitad de la columna
for( ; ; ){ //bucle...
if(!input(PIN_A0)){ //¿se ha pulsado el boton?
do{ //SI -> eliminar...
}while(!input(PIN_A0)); //...rebotes del boton
if(i>9){ //¿se ha mostrado digito 9?
i=0; //SI -> restaura valor indice(para mostrar digito 0)
output_high(PIN_B3); //activa buzzer(beep)
delay_ms(50); //tiempo de escucha del beep
output_low(PIN_B3); //desactiva buzzer(beep)
}
printf(lcd_putc,"%c",tabNum[ i ]); //muestra por pantalla el numero
printf(lcd_putc,"" ); //retrasa el cursor una posicion(escribe encima)
i++; //incremento contador indice tabNum
}
} //...infinito
}
RE: Ejemplitos en C para 16F648A
« Respuesta #82 : 06 de Septiembre de 2005, 06:58:00 »
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///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_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 2ºlinea 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
}
////////////////////////////////////////////////////////////////////////////////////
// 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)
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
char num=0; //variable almacena numero aleatorio
lcd_putc("fDado:
VsZeNeR"05" );
lcd_gotoxy(7,1); //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
VsZeNeR En línea
///DEFINICION DE FUNCIONES
void configurar(void);
void horas(void);
void minutos(void);
void dia(void);
void mes(void);
void anio(void);
void beep(void);
//lcd
}
///PROGRAMA
void main(void){
lcd_putc("Reloj Calendario
VsZeNeR"05" ); //presentacion...
delay_ms(800); //...inicial
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); //desactivadas interrupciones
do{
switch(menu){
case 0: lcd_putc("fConfigurar
horas?" ); //horas
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
horas();
menu=1;
menu=0;
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);
lcd
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA AÑOS
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)){} //elimina rebotes
}
///FUNCION BEEP
void beep(void){
output_high(PIN_B3); //activa zumbador
delay_ms(50);
output_low(PIN_B3); //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...
Pues ya tenemos un reloj-calendario!!!!ya no hay excusa de no saber que
hora es ni en que dia vivimos!jeje
En línea
En línea
///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
}
En línea
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 09/Septiembre/05
//
// Programa: Reloj-Calendario DS1302 y RS232
// Version: 1.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por virtual terminal 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 -> año 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./ tb vale como control menu
// ·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"
// B1 -> Tx
// B2 -> Rx
// B3 -> Zumbador(beep)
//////////////////////////////////////////////////////////////////////////////////
///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);
///PROGRAMA
void main(void){
puts("Reloj Calendario" );
puts("VsZeNeR"05" );
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); //desactivadas interrupciones
do{
switch(menu){
case 0: printf("fConfigurar
horas?" ); //horas
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
horas();
menu=1; //apunta siguiente opcion
flag=1; //para el retorno funcion ver sig
}
break;
case 1: printf("fConfigurar
minutos?" ); //minutos
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
minutos();
menu=2; //apunta siguiente opcion
flag=1; //para el retorno funcion ver sig
}
break;
case 2: printf("fConfigurar
dia?" ); //dias
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
dia();
menu=3; //apunta siguiente opcion
flag=1; //para el retorno funcion ver sig
}
break;
case 3: printf("fConfigurar
mes?" ); //mes
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
mes();
menu=4; //apunta siguiente opcion
flag=1; //para el retorno funcion ver sig
}
break;
case 4: printf("fConfigurar
año?" ); //años
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
anio();
menu=5; //apunta siguiente opcion
flag=1; //para el retorno funcion ver sig
}
break;
case 5: printf("fSalir
configurar?" ); //salir configuracion
if(!input(PIN_A5)){
while(!input(PIN_A5)){} //elimina rebotes
menu=6;
flag=1;
beep();
}
}
flag=0;
}while(menu<6);
Y el ejemplito de hoy es seguir trabjando con el puerto serie RS232 peor esta vez
introduciremos un periferico externo nuevo, el teclado, en este caso vamos a usar un
teclado 3x4 donde cada tecla pulsada ira apareciendo en el v.terminal, aqui el programita:
////////////////////////////////////////////////////////////////////////////////////
// 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; //variable almacenamos tecla
for( ; ; ) { //bucle...
do{ //hacer hasta...
c=kbd_getc(); //recogemos tecla pulsada
}while(c==""); //...que no se pulse tecla
Decir que para el manejo del teclado he utilizado la libreria del CCS llamada KBD.C que es
compatible con teclados 3x4, aqui dejo el link al sitio donde CCS tiene puesta sus librerias
y sus data sheet patron de la realizacion de las mismas:
Y aqui esta un ejemplito mas!!!esta vez el ejemplo consiste en un teclado y una lcd
conectados....decir que para este ejemplo hacen falta las librerias lcd2.c y kbd3x4.c que las
podreis encontrar en el post anterior....lcd2.c maneja la lcd pero las lineas de control estan
en el porta y las de datos en el b, tambien decir que usamos 8bits de datos, y la kbd3x4.c es
para manejar teclados 3x4 y esta conectado al portb conjuntamente al lcd por lo tanto
debemos hacer una seleccion dinamica para manejar conjuntamente el lcd y el teclado(de
eso se encargan la slibrerias....jeje), bueno el programa consiste en mostrar por lcd la tecla
pulsada en el teclado:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 17/Septiembre/05
//
// Programa: LCD 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 lcd la tecla pulsada conectado un
// keypad 3x4 al pic. Tener en cuenta que hay que poner la directiva
// NOLVP para que el pin B4 sea de salida.
//
// Conexiones: B0 -> D0 LCD/Columna 1 keypad
// B1 -> D1 LCD/Columna 2 keypad
// B2 -> D2 LCD/Columna 3 keypad
// B3 -> D3 LCD
// 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
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //ordenes para el
programador
#use delay (clock=4000000) //Fosc=4Mhz
#include<kbd3x4.c> //libreria manejo keypad
#include<lcd2.c> //libreria manejo lcd 8bits
#use fast_io(A)
#use fast_io(B)
///PROGRAMA
void main(void)
{
char c; //variable donde se almacena tecla pulsada
lcd_putc(" VsZeNeR"05
Tecla pulsada:" ); //presentacion
lcd_gotoxy(15,2); //donde se va a mostrar tecla
for( ; ; ){ //bucle...
do{ //espera hasta...
c=kbd_getc();
}while(c==0); //...pulsar una tecla
///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
for( ; ; ){ //bucle...
lcd_putc("f0->Password
1->Cambia Clave" );
do{ //espera hasta...
c=kbd_getc();
}while(c==0); //...pulsar una tecla
lcd_putc("*" );
Aqui interaccionaremos entre el PC -> PIC (Este es otro post que no estaba...)
Código
GeSHi (c):
1. ///////////////////////////////////////////////////////////////////
/////////////////
2. // VsZeNeR'05
3. // 24/Septiembre/05
4. // vszener@gmail.com
5. // Programa: RS232 Y PIC
6. // Version: 0.0
7. //
8. // Dispositivo: PIC 16F648A Compilador: CCS vs3.227
9. // Entorno IDE: MPLAB IDE v7.21 Simulador:
Proteus 6.7sp3
10. //
11. // Notas: Se interacciona el PC con el PIC mediante RS232, se
pide por v.terminal
12. // un numero comprendido entre 1 al 4, segun
numero marcado por v.terminal
13. // se encendera un led 0,5s. Tener en cuenta que
hay que poner la directiva
14. // NOLVP para que el pin B4 sea de salida.
15. //
16. // Conexiones: A0 -> led azul
17. // A1 -> led verde
18. // A2 -> led rojo
19. // A4 -> led amarillo
20. // B2 -> TxD
21. // B1 -> RxD
22. //////////////////////////////////////////////////////////////////
////////////////
23. #include <16f648a.h> //pic a utilizar
24. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //or
25. #use delay (clock=4000000) //Fosc=4Mhz
26. #use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)
27. #use rs232(baud=9600, xmit=PIN_B1, rcv=PIN_B2, FORCE_SW)
//manejo del RS232
28.
29. ///PROGRAMA
30. void main(void)
31. {
32. puts("Interaccion PC->PIC VsZeNeR'05");
//presentacion...
33. puts("=================");
34. puts("Seleccione tecla:");
35. puts("¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨");
36. puts(" 1->Led on Azul");
37. puts(" 2->Led on Verde");
38. puts(" 3->Led on Rojo");
39. puts(" 4->Led on Amarillo");
40.
41. for(;;){ //bucle...
42. switch(getc()){ //coge tecla
43. case '1': output_high(PIN_A0);
//led on azul
44. delay_ms(500);
45. output_low(PIN_A0);
46. break;
47. case '2': output_high(PIN_A1);
//led on verde
48. delay_ms(500);
49. output_low(PIN_A1);
50. break;
51. case '3': output_high(PIN_A2);
//led on rojo
52. delay_ms(500);
53. output_low(PIN_A2);
54. break;
55. case '4': output_high(PIN_A3);
//led on amarillo
56. delay_ms(500);
57. output_low(PIN_A3);
58. }
59. } //...infinito
60. }
61.
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///VARIABLES GLOBALES
char i=0; //contador para tabla BCD
char
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1
001};//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 señal esta en alta
enable_interrupts(GLOBAL); //todas las interrupciones desactivadas
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///VARIABLES GLOBALES
char i=0; //contador para tabla BCD
char
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1
001};//BCD 0-9
boolean var=0; //variable para captura en alto(var=0) o en bajo(var=1)
#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 señal esta en baja
enable_interrupts(INT_CCP1); //activar interrupcion en ccp1
enable_interrupts(GLOBAL); //todas las interrupciones desactivadas
////////////////////////////////////////////////////////////////////////////////////
// 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 diseñado 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
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
}
Ke tal!!!bien siguiendo con lcd y escribir e su CGRAM aqui pongo la animacion del
muñeco come-cocos controlado por PC via v.terminal,No es el juego! simplemente
pulsamos la tecla 4 para desplazar el muñeco 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
///PROGRAMA
void main(void)
{
lcd_init(); //inicializa 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
}
Decir que la figura del come-cocos no se ha declarado entera ya que es simetrica la parte de
arriba con la de abajo, entonces nos basta con declarar la mitad d ela figura....bueno ya
tenemos una animacion moviendose por lcd controlada por RS232....ya seeee que el dibujo
no esta muy bien dibujadooooo!!!jeje pero nunca se me ha dado bien el dibujo y menos en
matrices 7x5 jeje!!!
RE: Ejemplitos en C para 16F648A
« Respuesta #141 : 02 de Octubre de 2005, 00:13:00 »
hola amigo vs.zener estuve mirando la bateria cargandose y la entendi a la perfeccion. hice
esto miralo en proteus como quedo, y una nueva pregunta la cgram solo tiene 8 pocisiones
como podria hacer para hacer una animacion para cada una de las 32 posiciones de la lcd
todavia tengo la idea metida en la cabeza poder manejar cada cuadricula de forma de
mostrar una imagen en toda la lcd no se si sirva multiplezar las memorias o algo asi, un dia
vi que en una cabina telefonica una lcd de 2x16 con el nombre de SISCO pero utilizaban
toda la lcd se veia super y desde ahi se me ocurrio .. ya sabes... gracias por responderme y
ademas esto le servira a todos en el foro nuevamente gracias :
////////////////////////////////////////////////////////////////////////////////////
// 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 diseñado 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
//////////////////////////////////////////////////////////////////////////////////
///DECLARACION DE FUNCIONES
void recarga(void); //funcion que crea el nuevo caracter
void cara(void);//carita creada por monopic
int8 feliz[]={0b11011,0b00000,0b11011,0b11011,0b00000,0b10001,0b01110};
int8 triste[]={0b11011,0b00000,0b11011,0b11011,0b00000,0b01110,0b10001};
//mios monopic
///PROGRAMA
void main(void)
{
lcd_init(); //inicializa lcd
for(; { //bucle...
lcd_gotoxy(2,1); //donde se va a mostrar la animacion de la bateria
lcd_send_byte(1,0); //muestra animacion
recarga(); //crea animacion
delay_ms(500);
lcd_gotoxy(3,1);
lcd_send_byte(1,1); // muestra animacion por monopic
cara();
cont++; //apunta a siguiente animacion
} //...infinito
}
void cara(void){
char i;
lcd_send_byte(0,0x48);
hola amigo vs.zener estuve mirando la bateria cargandose y la entendi a la perfeccion. hice
esto miralo en proteus como quedo, y una nueva pregunta la cgram solo tiene 8 pocisiones
como podria hacer para hacer una animacion para cada una de las 32 posiciones de la lcd
todavia tengo la idea metida en la cabeza poder manejar cada cuadricula de forma de
mostrar una imagen en toda la lcd no se si sirva multiplezar las memorias o algo asi, un dia
vi que en una cabina telefonica una lcd de 2x16 con el nombre de SISCO pero utilizaban
toda la lcd se veia super y desde ahi se me ocurrio .. ya sabes... gracias por responderme y
ademas esto le servira a todos en el foro nuevamente gracias :
////////////////////////////////////////////////////////////////////////////////////
// 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 diseñado 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
//////////////////////////////////////////////////////////////////////////////////
///DECLARACION DE FUNCIONES
void recarga(void); //funcion que crea el nuevo caracter
void cara(void);//carita creada por monopic
int8 feliz[]={0b11011,0b00000,0b11011,0b11011,0b00000,0b10001,0b01110};
int8 triste[]={0b11011,0b00000,0b11011,0b11011,0b00000,0b01110,0b10001};
//mios monopic
///PROGRAMA
void main(void)
{
lcd_init(); //inicializa lcd
for(; { //bucle...
lcd_gotoxy(2,1); //donde se va a mostrar la animacion de la bateria
lcd_send_byte(1,0); //muestra animacion
recarga(); //crea animacion
delay_ms(500);
lcd_gotoxy(3,1);
lcd_send_byte(1,1); // muestra animacion por monopic
cara();
cont++; //apunta a siguiente animacion
} //...infinito
}
void cara(void){
char i;
lcd_send_byte(0,0x48);
Bueno en esta direccion , en el tercer mensaje encontraras una rutina que elaboramos
entre todos para hacer una presentacion numerica en un lcd 2x16 y utilizando ambas
lineas:
http://miarroba.com/foros/ver.php?foroid=46840&temaid=1654587&marcar=ejemplos+p
rogramas
hola vszener mira lo que he creado son tres animaciones la primera una cara feliz-triste, la
segunda esta la bateria que inicialmente hiciste y en la tercera el famoso caminante el cual
lo hice basandome en tu ejemplo.,,
//////////////////////////////////////////////////////////////////////////////////
// 3 animaciones en una lcd de 2x16
// Conexiones: B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
//////////////////////////////////////////////////////////////////////////////////
///DECLARACION DE FUNCIONES
void recarga(void); //funcion que crea el nuevo caracter
void cara(void);//carita creada por monopic
void caminante(void);
///DECLARACION DE VARIABLES GLOBALES
char cont=0; //contador que apunta al nuevo caracter diseñado
int8 bat0[]={0b00001110,0b00001010,0b00010001,0b00010001,0b00010001,0b00001
0001,0b00010001,0b00011111},
bat20[]={0b00001110,0b00001010,0b00010001,0b00010001,0b00010001,0b00010001,0b
00011111,0b00011111},
bat40[]={0b00001110,0b00001010,0b00010001,0b00010001,0b00010001,0b00011111,0b
00011111,0b00011111},
bat60[]={0b00001110,0b00001010,0b00010001,0b00010001,0b00011111,0b00011111,0b
00011111,0b00011111},
bat80[]={0b00001110,0b00001010,0b00010001,0b00011111,0b00011111,0b00011111,0b
00011111,0b00011111},
bat100[]={0b00001110,0b00001010,0b00011111,0b00011111,0b00011111,0b00011111,0
b00011111,0b00011111};
int8 feliz[]={0b11011,0b00000,0b11011,0b11011,0b00000,0b10001,0b01110,0b00000};
int8 triste[]={0b11011,0b00000,0b11011,0b11011,0b00000,0b01110,0b10001,0b00000};
int8 cam0[]={0b01110,0b01110,0b00100,0b00100,0b00100,0b00100,0b01100,0b00000},
cam1[]={0b01110,0b01110,0b00100,0b00100,0b01100,0b00100,0b01100,0b00000},
cam2[]={0b01110,0b01110,0b00100,0b00100,0b01010,0b11010,0b00110,0b00000},
cam3[]={0b01110,0b01110,0b00100,0b00100,0b00110,0b01001,0b11001,0b00000},
cam4[]={0b01110,0b01110,0b00100,0b00100,0b00111,0b01001,0b11000,0b00000},
cam5[]={0b01110,0b01110,0b00100,0b00100,0b01100,0b00110,0b01100,0b00000};
//mios monopic
///PROGRAMA
void main(void)
{
lcd_init(); //inicializa lcd
for(; { //bucle...
lcd_gotoxy(2,1); //donde se va a mostrar la animacion de la bateria
lcd_send_byte(1,0); //muestra animacion
recarga(); //crea animacion
delay_ms(70);
caminante();
lcd_gotoxy(3,1);
lcd_send_byte(1,1); // muestra animacion por monopic
cara();
lcd_gotoxy(4,1);
lcd_send_byte(1,2);
caminante();
delay_ms(70);
cont++; //apunta a siguiente animacion
} //...infinito
}
void cara(void){
char i;
lcd_send_byte(0,0x40);
void caminante(void){
char i; //indice para for
En línea
RE: Ejemplitos en C para 16F648A
« Respuesta #155 : 19 de Octubre de 2005, 06:31:00 »
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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void){
char i;
int8 grado[]={0b00000110,0b00001001,0b00000110};
lcd_putc(" Termometro
VsZeNeR"05" ); //presentacion...
delay_ms(800);
lcd_putc("f" ); //...inicial
lcd_putc(" VsZeNeR"05
Temperatura:" ); //pantalla temp
for(; ; ){ //bucle...
lcd_gotoxy(14,2);
printf(lcd_putc,"%d",read_ds1620(0xAA)); //muestra temperatura por pantalla
delay_ms(500);
lcd_putc("" );
} //...infinito
}
LIBRERIA OBSOLETA
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
char opcion=0; //variable encargada de mostrar menu de 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
}
Muchas gracias, la q verdad es q sí que sirve. Y la verdad es que lo había hecho yo ya, pero
te lo agradezco igualmente. Mi problema es cuando quiero usar una variable definida en
main como variable global en una función del archivo .h. Dirás que lo pase como
parámetro, pero mi problema es q esa variable cambia en una rutina de interrupción que
está en el archivo principal (.c) y la función q está en el .h debe ser capaz de usarla. Si
pongo la rutina de interrupción en el .h funcionará? Y si quiero tener varios archivos .h (es
un programa bastante largo y debo tenrlo ordenado para presentarlo) basta con que lo ponga
la rutina de interrupción en uno, o tiene q estar en el .c? Espero haberme explicado más o
menos. Te pongo el código (q es más largo todavía de lo q aparece aqui), aunq lo único q
sirve para mi pregunta del main.c es la rutina de interrupción de Timer.
/* ARCHIVO MAIN.C*/
#include <18F452.h>
#include <string.h>
#include <stdlib.h>
#include <on_off.h>
#fuses
HS,NOCPD,NOCPB,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOSTVREN
,NOEBTR,NOEBTRB,NOWRTB,NOWRTC,NOWRTD
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
//int
seno[64][9]={{1,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1},{1,0,0,1,1,0,0,1,0},{1,0,1,0,0,1,0,1,1},
{1,0,1,1,0,0,0,1,1},{1,0,1,1,1,1,0,1,0},{1,1,0,0,1,0,0,0,0},{1,1,0,1,0,0,1,0,0},{1,1,0,1,1,0,1,
1,1},{1,1,1,0,0,1,0,0,0},{1,1,1,0,1,0,1,1,1},{1,1,1,1,0,0,1,0,0},{1,1,1,1,0,1,1,1,0},{1,1,1,1,1
,0,1,1,0},{1,1,1,1,1,1,1,0,0},{1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,0,1},{1,1,
1,1,1,1,0,0,1},{1,1,1,1,1,0,0,1,0},{1,1,1,1,0,1,0,0,0},{1,1,1,0,1,1,1,0,0},{1,1,1,0,0,1,1,1,0},
{1,1,0,1,1,1,1,1,0},{1,1,0,1,0,1,1,0,0},{1,1,0,0,1,1,0,0,1},{1,1,0,0,0,0,0,1,1},{1,0,1,1,0,1,1,
0,1},{1,0,1,0,1,0,1,0,1},{1,0,0,1,1,1,1,0,1},{1,0,0,1,0,0,1,0,0},{1,0,0,0,0,1,0,1,0},{0,1,1,1,1
,0,0,0,1},{0,1,1,0,1,0,1,1,1},{0,1,0,1,1,1,1,1,0},{0,1,0,1,0,0,1,1,0},{0,1,0,0,0,1,1,1,0},{0,0,
1,1,1,1,0,0,0},{0,0,1,1,0,0,0,1,1},{0,0,1,0,0,1,1,1,1},{0,0,0,1,1,1,1,1,0},{0,0,0,1,0,1,1,1,0},
{0,0,0,1,0,0,0,0,0},{0,0,0,0,1,0,1,0,1},{0,0,0,0,0,1,1,0,0},{0,0,0,0,0,0,1,0,1},{0,0,0,0,0,0,0,
0,1},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,1,0,0},{0,0,0,0,0,1,0,1,0},{0,0,0,0,1
,0,0,1,0},{0,0,0,0,1,1,1,0,1},{0,0,0,1,0,1,0,1,0},{0,0,0,1,1,1,0,1,0},{0,0,1,0,0,1,0,1,1},{0,0,
1,0,1,1,1,1,0},{0,0,1,1,1,0,0,1,1},{0,1,0,0,0,1,0,0,1},{0,1,0,1,0,0,0,0,0},{0,1,0,1,1,1,0,0,0},
{0,1,1,0,1,0,0,0,1},{0,1,1,1,0,1,0,1,0},{1,0,0,0,0,0,1,0,0}};
long int
sin[64]={256,281,305,330,353,376,397,418,436,453,468,481,492,500,506,510,511,510,50
6,500,492,481,468,453,436,418,397,376,353,330,305,28,255,230,206,181,158,135,114,93,
75,58,43,30,19,11,5,1,0,1,5,11,19,30,43,58,75,93,114,135,158,181,206,230};
long int
tri[64]={0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,271,287,303,319,
335,351,367,383,399,415,431,447,463,479,495,511,495,479,463,447,431,415,399,383,367,
351,335,319,303,287,271,256,240,224,208,192,176,160,144,128,112,96,80,64,48,32,16};
int tipo_s=0,opcion=1,canal=1, tiempo=0x80,n=1;
int trojo=0;
int tverde=0;
int y;
int reloj=0,cont12=0,cont64=0;
#INT_RDA
void rsis(void)
{
char string[20];
gets(string);
opcion=atol(string); //Leemos la opcion introducida
switch(opcion)
{
case 1:
printf("
1 -> Seno
2 -> Triangular
3 -> Cuadrada
0 -> Salida nula" ;
printf("
case 2:
printf("
Frecuencia: " ;
gets(string);
tiempo=atol(string);
if(tiempo<128||tiempo>255){
printf("
case 3:
printf("
default:
printf("
Opción incorrecta. Introduzca 1 o 2" ;
}
printf("
if(cont12<12)
cont12++;
else{
output_high(PIN_A2); //Pulso de LOADIN
output_low(PIN_A2);
cont12=0;
if(cont64==64)
cont64=0;
else
cont64+=n;
}
}
}
void seno()
{
enciende(tiempo,canal);
while (input(PIN_E2)==1)
{
if(cont12<9)
{
if(bit_test(sin[cont64],8-cont12))
output_high(PIN_A4); //Debe coger el dato
else
output_low(PIN_A4);
}
else
output_low(PIN_A4); //Debe coger 4 ceros. Canal 1 y para indicar que son
datos
}
}
void triang()
{
enciende(tiempo,canal);
while (input(PIN_E2)==1)
{
if(cont12<9)
{
if(bit_test(tri[cont64],8-cont12))
output_high(PIN_A4); //Debe coger el dato
else
output_low(PIN_A4);
}
else{
output_low(PIN_A4); //Debe coger 4 ceros. Canal 1 y para indicar que
son datos
}
}
}
void cuad()
{
int cuad=0;
int cambio=0;
enciende(tiempo,canal);
cuad=cont12;
while (input(PIN_E2)==1)
{
if(reloj==1&&cuad!=cont12)
{
if(cambio==0){
output_high(PIN_A4);
cambio=1;
}
else{
output_low(PIN_A4);
cambio=0;
}
cuad=cont12;
}
}
}
void main()
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
set_tris_a(0x00);
set_tris_b(0xFF);
set_tris_c(0b10111111);
set_tris_d(0x00);
set_tris_e(0b101);
output_a(0x20);
output_low(PIN_E1);
while(1)
{
y=0,cont12=0,cont64=0;
while (input(PIN_E2)==1)
{
output_low(PIN_A1);
output_high(PIN_A0);
switch(tipo_s)
{
case 1:
output_high(PIN_A0);
output_d(1);
seno(); break;
case 2:
output_high(PIN_A1);
output_d(2);
triang(); break;
case 3:
output_d(3);
cuad(); break;
case 0:
output_d(0);
output_low(PIN_A4); break;
}
}
while (input(PIN_C0)==1)
{
apaga();
output_low(PIN_A0);
output_high(PIN_A1);
if (input(PIN_C2)==0)
tipo_s=1;
if (input(PIN_C4)==0)
tipo_s=2;
if(input(PIN_C3)==0)
tipo_s=3;
if(input(PIN_C5)==0){
tipo_s=0;
}
output_d(tipo_s);
}
while(input(PIN_C1)==1)
{
apaga();
output_low(PIN_A0);
output_high(PIN_A1);
if(input(PIN_C3)==0){
if(tiempo<254)
tiempo++;
n=1;
}
if(input(PIN_C5)==0){
if(tiempo>0x40)
tiempo--;
else
n++;
}
if (input(PIN_C2)==0)
if(tiempo<245)
tiempo+=10;
if (input(PIN_C4)==0)
if(tiempo>0x80)
tiempo-=10;
output_d(tipo_s|0b10110000);
if(y==0){
printf("
Que desea cambiar?" ;
printf("
}
}
}
/*ARCHIVO ON_OFF.H*/
void enciende(tiempo,canal)
{
int fin=0;
enable_interrupts(INT_TIMER2);
setup_timer_2(T2_DIV_BY_1,tiempo,1);
set_timer2(0);
cont12=0;
ouput_low(PIN_A4);
switch(canal)
{
case 1:
while(fin==0)
{
if(cont12<2) //Se deja el primer paso del contador por seguridad
output_high(PIN_A4); //1º bit a 1
else
if(cont12>1&&cont12<5)
ouput_low(PIN_A4); //3 bits a 0
else
if(cont12<7)
output_high(PIN_A4); //2 bits a 1
else
{
output_high(PIN_A2); //Pulso de LOADIN
output_low(PIN_A2);
fin=1;
cont12=0;
}
}
break;
case 2:
while(fin==0)
{
if(cont12<2) //Se deja el primer paso del contador por seguridad
output_low(PIN_A4); //1º bit a 0
else
if(cont12==2)
ouput_high(PIN_A4); //2º bit a 1
else
if(cont12>2&&cont12<5)
output_low(PIN_A4); //2 bits a 0
else
if(cont12<7)
ouput_high(PIN_A4); //2 bits a 1
else
{
output_high(PIN_A2); //Pulso de LOADIN
output_low(PIN_A2);
fin=1;
cont12=0;
}
}
break;
case 3:
while(fin==0)
{
if(cont12<3) //Se deja el primer paso del contador por seguridad
output_low(PIN_A4); //2 bits a 0
else
if(cont12=3)
ouput_high(PIN_A4); //3º bit a 1
else
if(cont12==4)
output_low(PIN_A4); //1 bit a 0
else
if(cont12<7)
ouput_high(PIN_A4); //2 bits a 1
else
{
output_high(PIN_A2); //Pulso de LOADIN
output_low(PIN_A2);
fin=1;
cont12=0;
}
}
break;
case 4:
while(fin==0)
{
if(cont12<4) //Se deja el primer paso del contador por seguridad
output_low(PIN_A4); //3 bits a 0
else
if(cont12==4)
ouput_low(PIN_A4); //4º bit a 0
else
if(cont12<7)
output_high(PIN_A4); //2 bits a 1
else
{
output_high(PIN_A2); //Pulso de LOADIN
output_low(PIN_A2);
fin=1;
cont12=0;
}
}
break;
}
}
void apaga()
{
disable_interrupts(INT_TIMER2);
cont12=0,cont64=0;
}
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
setup_ccp1(CCP_PWM); //ccp1 modo PWM
lcd_init(); //inicializa lcd
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( ); //cambia frecuencia
}
Suerte!!!
///PROGRAMA
void main(void)
{
char cont=0; //definicion de...
signed char bcd=-1; //...variables
delay_ms(450);
////////////////////////////////////////////////////////////////////////////////////
// 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
///PROGRAMA
void main(void)
{
char led_on=0b0001; //led a iluminar
do{ //bucle...
Decir, que en este ejemplo se ha programado de tal manera que podamos saber que pin
genero la interrupcion, segun sea el pin la secuencia de luces de interrupcion se repetira
mas o menos veces hasta terminar y volver al programa principal. La parte del codigo para
averiguar el pin que genero la interrupcion esta en la ayuda del compilador(CCS) asi no se
pierde tiempo en crear otro....bueno hasta la proxima!!!
Buenas!!!!bien, viendo el trabajo que estan haciendo mis compañeros de enseñar 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 pequeña 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 enseñamos 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
//////////////////////////////////////////////////////////////////////////////////
void main(void)
{
int i; //variable contador
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
}
Bien, pues decir antes que nada, que las letras no estan realizadas en formato standard
ehh!!!!jeje
PD: Felices fiestas a todos los integrantes del foro que aunque en la lejania, este medio
parece algo magico ya que nos une un poquito mas.....FELIZ NAVIDAD!!!
Buenasss jeje!!!bien, aqui otro ejmeplito mas con el periferico 7seg...ya sabemos contar
desde 0 a 9, desde 9 a 0 e incluso de 0 a 9 y viceversa!!!!!vamos a seguir contando jeje esta
vez aqui un ejemplito de un contador desde 00 a 99 y vuelta a empezar...aqui el programita:
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; //7seg hex
0-9
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
}
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
///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}; //bcd
parte alta 0-9
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);
Bien decir, que este no fue el programa final que grabe en el pic....pero bueno, creo que este
es mas ilustrativo a la programacion, el que finalmente grabe en el pic manejaba la hora en
una variable y mediante una funcion obtenia los valores a representar.....
Ya sabemos que hora es tanto con una RTC como con este ejemplo!!!!
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 pequeña 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 FUNCIONES
BYTE gethex1( ); //verifica que esta dentro del rango y muestra por pantalla
BYTE gethex( ); //devuelve el numero en hex
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); //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_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); //reloj interno de 4MHz
enable_interrupts(int_rda); //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;
////////////////////////////////////////////////////////////////////////////////////
// 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 pequeña 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 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
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); //reloj interno de 4MHz
enable_interrupts(int_rda); //activo interrupcion serial rs-232
enable_interrupts(global); //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;
Suerte!!!
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz
}while(TRUE); //...infinito
}
Este programa simplemente es para mostrar como manejar la libreria vs_saa1064.c para el
manejo del dispositivo! si teneis alguna duda del programa o la libreria, ya sabeis!
Suerte!!!
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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz
do{ //bucle...
///MANIPULAMOS SAA1064 CON DIVERSAS CONFIGURACIONES
saa1064_conf(0b00010000); //3mA & NO parpadeo & Estatico
saa1064_putc(0x66,0x3F); //40
delay_ms(1500);
}while(TRUE); //...infinito
}
Pues ya esta explicada la libreria del dispositivo SAA1064 con los dos programitas, tanto
para modo dinamico como pa modo estatico...
Hasta otra!!!
////////////////////////////////////////////////////////////////////////////////////
// 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 pequeña 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 (a esta instrucción es a la que me refiero, es como si el
compilador no me las reconociera)
Y también he tenido inconvenientes con esta otra instrucción en este otro programa
que vos has desarrollado
////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////
Una sugerencia más, vos subís los programas al servidor, y de ahí hay que
descargarlos, pero resulta que si por algún motivo alguien tiene alguna otra versión,
no se pueden abrir, evidentemente me refiero al Proteus,, lo que te sugeriría si tu
puedes y no es molestia a parte de subirlo colocada una imagen de cómo
implementaste el circuito, que se yo quizá la captura la puedas hacer con la tecla
print scr de tu máquina y la pegues en algún programa de dibujo., a si quizá podría
facilitar algunas cosas (repito sólo es una sugerencia sin ánimos de ofender).
Buenass!!!!hacia tiempo que no posteaba ningun ejemplito asi que ya es hora!jeje bien,
como bien sabemos, el 16F648A no tiene conversor A/D asi que para trabajar con medidas
y tal necesitamos un chip conversor, en este caso vamos a usar uno que tiene bastante
aceptacion y hay informacion en algun que otro libro, es el fabricado por Philips el
PCF8591, sirve tanto como A/D y D/A, he realizado una "mini libreria" para su manejo,
aqui esta:
///////////////////////////////////////////////////////////////////////////////////////////////////
/// VsZeNeR"06 ///
/// 13/Marzo/06 ///
/// vszener@gmail.com ///
/// ///
/// Libreria: vs_pcf8591.c Compilador: CCS ///
/// Version: 0.0 ///
/// ///
/// Notas: Controlador para manejo del dispositivo pcf8591 ///
/// de Philips. ///
/// Este dispositivo se encarga, mediante I2C, del tratamiento de ///
/// conversor A/D como D/A. ///
/// Modo: ///
/// ¨¨¨¨¨¨ ·D/A: 8 bits ///
/// ·A/D: 8 bits con 4 entradas analogicas ///
/// ///
/// Funciones: ///
/// MODO D/A ///
/// -------- ///
/// pcf8591_dac_init( ); -> Inicializa el dispositivo ///
/// write_dac_value(int data); -> Escribe el volatje a mostrar ///
/// por AOUT(8 bits) ///
/// stop_dac( ); -> Para el dispositivo. Una vez ///
/// realizada esta opcion, para ///
/// a utilizar AOUT debemos ///
/// inicializarlo de nuevo! ///
/// MODO A/D ///
/// -------- ///
/// pcf8591_adc_init(control); -> Inicializa el dispositivo. ///
/// Debemos enviar el byte de ///
/// control: ///
/// Byte de control: 0 X XX 0 X XX ///
/// 0 A EA 0 I NC ///
/// ///
/// A: Permiso Salida analogica 0 -> AOUT alta impedancia ///
/// 1 -> AOUT habilitada ///
/// EA: Programacion entradas analogicas: 00 -> 4 entradas simples ///
/// 01 -> 3 entradas dif. ///
/// 10 -> Simples y dif ///
/// 11 -> 2 entradas dif. ///
/// I: Incremento 0 -> No hay autoincremento ///
/// 1 -> Autoincremento de la entrada del A/D ///
/// NC: Numero del canal de la entrada 00 -> Canal 0 ///
/// 01 -> Canal 1 ///
/// 10 -> Canal 2 ///
/// 11 -> Canal 3 ///
/// read_adc_value(int data); -> Lee el volatje a mostrar ///
/// ///
/// La direccion del dispositivo se configura con los pines A2A1A0, donde en este ///
/// caso se ha elegido GND(000). Se he habilitado siempre la salida AOUT en D/A ///
/// y deshabilitado siempre en A/D. ///
///////////////////////////////////////////////////////////////////////////////////////////////////
Hasta otra!!!
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz
Suerte!!!
Aqui el mismo programa del Maestro VS_ZeNeR, pero para 16f84 . Se que no es mucho ,
pero si a alguien le interesa.....
El circuito no tiene ninguna modificacion mas que la del cambio de pic , los pines se
conectan igual(en los mismos puertos)
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"06
// 13/Marzo/06
//
// Programa: Manejo del dispositivo PCF8591 en modo D/A
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.245
// 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 señal analogica del
// pcf8591.
// Agregado (): Calculo de la resolucion de escalones de conversion 2 exp 8 = 256,
entonces
// V de Referencia / 256 = incremento de cada escalon, en este caso
// 2.56V/256 = 10mv(resolucion del conversor)
// Aqui se modifica el programa para usar el 16f84 (que solo lo he probado en
// simulacion) como pueden ver he realizado
// minimas modificaciones algunas
// sentencias han sido puestas tipo comentario agregándole dos barras en la
// parte delantera. Fijense que estoy usando otra version de ccs (eso por si les
// da algun error)
// Conexiones: B7 -> SDA pcf8591
// B6 -> SCL pcf8591
// B0 -> Boton
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
//setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz
Hola de nuevo: este es otra variante del programa con pfc8591 pero en este caso.
hemos hecho una modificación a tu ejemplo DAC y lo hemos hecho para un ADC , la
particularidad que tiene para este(ejercicio ( ADC ) según veo es que vos lo inicializar con
una palabra de configuración y luego lo que haces es leerlo, sacando su valor por pantalla,
en un ciclo While dentro del cual hay un retardo para que si vos quisieras pudieras ver las
transiciones de un estado a otro, para lo cual se ha agregado un contador de muestra (que se
ve en el display al ejecutar el programa)
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"06
// 13/Marzo/06
//
// Programa: Manejo del dispositivo PCF8591 en modo A/D
// Version: 0.0
//
// Dispositivo: PIC 16F84A Compilador: CCS vs3.245
// Entorno IDE: MPLAB IDE v7.31 Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra como usar el conversor pfc8591 como adc.
// La Vref es de 2,56v por lo tanto la resolucion del conversor es 10mV.
// Básicamente lo que aquí hacemos es inicializar el conversor con la palabra
// de configuración y luego sólo resta leer (obviamente estamos modificando la
// tención analógica de entrada) sólo nos resta corregir un ligero error que es
// el que apenas pasa el valor de 128 en que se muestra valor negativo.
// Se muestra por pantalla de lcd(LM016L)
//
//
// Conexiones: RA1 -> SDA pcf8591
// RA0 -> SCL pcf8591
//
// lcd(LM016L)
// B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// VSS y VEE -> gnd
// VDD ->VCC
//
// pcf8591
// A0,A1,A2.EXT , AGND ->gnd
// AN0 divisor resistivo con potenciometro (2.5v Variables)
// VREF=2.56 (en est6e caso)(pin14) divisor resistivo con potenciometro
//
//
//////////////////////////////////////////////////////////////////////////////////
//Programa prueba del conversor como adc.
#include <16f84a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define PCF8591_SCL PIN_A0 //definicion de pines...
#define PCF8591_SDA PIN_A1 //...de manejo del pcf8591
#include <vs_pcf8591.c> //libreria pcf8591
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd
///DEFINICION VARIABLES GLOBALES
int x=1; //variable de salida por AOUT
unsigned char dato=0;
///LLAMADA FUNCION INTERRUPCION
//#INT_EXT
///PROGRAMA
void main(void)
{
lcd_init();
lcd_gotoxy(1,1);
lcd_putc("f Voltimetro" ) ;
lcd_gotoxy(3,2);
lcd_putc(" Digital!!!" ) ;
lcd_gotoxy(1,1);
printf(lcd_putc,"X= %d",x ) ;
lcd_gotoxy(9,1);
printf(lcd_putc,"%d mV",dato) ;
x++;
}
}
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 señal 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
//////////////////////////////////////////////////////////////////////////////////
///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz
Buenas pelusac!, la resolucion del DAC, transforma el dato digital de entrada al DAC en su
tension analogica de salida, segun sea el dispositivo a usar tendra una ecuacion u otra en
este caso la del PCF8591 es la siguiente:
Codigo:
Vref - Vagnd
Vaout = Vagnd + ------------------ [ D0 · 2^0 + D1·2^1 +...+D7 ·
2^7]
256
Del D0-D7 son los registros de datos del DAC y es el dato digital que nosotros enviaremos
al dispositivo pcf8591 mediante la siguiente funcion:
Codigo:
2.56- 0
Vaout = 0 + ------------------ [ 75] = 750mV = 0.75V
256
Bueno y que mejor que despues de la actualizacion un ejemplito mas!!!jeje, este ejemplito
se basa en la conexion de 4 saa1064 los cuales trabajan mediante el bus i2c, por lo tanto,
este ejemplo ilustra como trabajar con el bus i2c con varios dispositivos, aparte este
programa es interesante ya que simplemente con dos pines del pic conseguimos gobernar
16 display's de 7 segmentos!!!....aqui el codigo:
Código
GeSHi (c):
1. ///////////////////////////////////////////////////////////////////
/////////////////
2. // VsZeNeR'06
3. // 22/Mayo/06
4. // vszener@gmail.com
5. //
6. // Programa: Manejo de 4 SAA1064 en modo DINAMICO -> 16
Display's 7seg
7. // Version: 1.0
8. //
9. // Dispositivo: PIC 16F648A Compilador: CCS vs3.249
10. // Entorno IDE: MPLAB IDE v7.31 Simulador:
Proteus 6.7sp3
11. //
12. // Notas: Este programa muestra por 16 display's de 7seg
mensajes de texto, para
13. // ello usamos 4 dispositivos SAA1064 de bus I2C.
14. //
15. // Conexiones: A0 -> SDA saa1064
16. // A1 -> SCL
saa1064
17. //////////////////////////////////////////////////////////////////
////////////////
18.
19. #include <16f648a.h> //pic a
utilizar
20. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el
programador
21. #fuses INTRC
//oscilador interno
22. #use delay (clock=4000000) //Fosc=4Mhz
23. #define SAA1064_DINAMICO //trabajar
en modo dinamico el saa1064
24. #define SAA1064_SCL PIN_A1 //definicion
de pines...
25. #define SAA1064_SDA PIN_A0 //...de
manejo del saa1064
26. #include <vs_saa1064M.c> //libreria
saa1064M
27.
28. ///PROGRAMA
29. void main(void)
30. {
31. setup_oscillator(OSC_4MHZ);
//configuracion del oscilador interno a 4MHz
32.
33. saa1064_init(0x76);
//inicializo saa1064 conectado a Vcc
34. saa1064_conf(0b01110001); //21mA & NO
parpadeo & Dinamico
35. saa1064_putc(0x76,0x3F,0x38,0x77); //HOLA
36. delay_ms(1000);
37.
38. saa1064_stop();
//paro el saa1064 conectado a Vcc
39.
40. saa1064_init(0x72);
//inicializo saa1064 conectado a 3/8 Vcc
41. saa1064_conf(0b00100011); //6mA &
parpadeo 1&3 & Dinamico
42. saa1064_putc(0x71,0x5C,0x50,0x5C); //Foro
43. delay_ms(1000);
44.
45. saa1064_stop();
//paro el saa1064 conectado a 3/8 Vcc
46.
47. saa1064_init(0x74);
//inicializo saa1064 conectado a 5/8 Vcc
48. saa1064_conf(0b01000101); //12mA &
parpadeo 2&4 & Dinamico
49. saa1064_putc(0x78,0x5C,0x5E,0x5C); //todo
50. delay_ms(1000);
51.
52. saa1064_stop();
//paro el saa1064 conectado a 5/8 Vcc
53.
54. saa1064_init(0x70);
//inicializo saa1064 conectado a GND
55. saa1064_conf(0b00110111); //9mA &
parpadeo TODO & Dinamico
56. saa1064_putc(0x73,0x30,0x39,0x86); //PIC!
57. delay_ms(1000);
58.
59. saa1064_stop();
//paro el saa1064 conectado a GND
60. }
61.
62.
Para este ejemplo he modificado la libreria del dispositivo, asi mediante la direccion de
cada dispositivo manejaremos el que queramos(hasta un maximo de 4 saa1064), la libreria
modificada es la siguiente: vs_saa1064m.c
Suerte!!!
Pues un ejemplito mas, aunque ya fue realizado uno similar, esta vez usamos la libreria
correcta!!!el programa consta de un termometro digital usando el dispositivo ds1620, el
cual se comunica con el pic mediante 3 pines(3-wire), aqui el programa:
Código
GeSHi (c):
1. ///////////////////////////////////////////////////////////////////
/////////////////
2. // VsZeNeR'06
3. // 23/Mayo/06
4. // vszener@gmail.com
5. //
6. // Programa: Termometro digital mediante el ds1620
7. // Version: 1.0
8. //
9. // Dispositivo: PIC 16F648A Compilador: CCS vs3.249
10. // Entorno IDE: MPLAB IDE v7.31 Simulador:
Proteus 6.7sp3
11. //
12. // Notas: Este programa muestra por el hyperterminal la
temperatura leida
13. // del dispositivo ds1620.
14. //
15. // Conexiones: A0 -> DQ ds1620
16. // A1 ->
CLK/CONV# ds1620
17. // A2 -> RST#
ds1620
18. //////////////////////////////////////////////////////////////////
////////////////
19.
20. #include <16f648a.h> //pic a
utilizar
21. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el
programador
22. #fuses INTRC
//oscilador interno
23. #use delay (clock=4000000) //Fosc=4Mhz
24. #use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1) //manejo del RS232
25. #define DS1620_DQ PIN_A0
//declaracion...
26. #define DS1620_CLK PIN_A1
27. #define DS1620_RST PIN_A2 //...de
pines para el ds1620
28. #include <vs_ds1620.c> //libreria
ds1620
29.
30. ///LLAMADA FUNCION INTERRUPCION
31. #INT_TIMER1
32. void interrupcion() //leemos la temp y la enviamos via serial
rs232 al hyperterminal
33. {
34. printf("\fVsZeNeR'06 -> Termometro
Digital\n\r\n\rTemperatura: %3.1f ºC",read_ds1620());
35. }
36.
37. ///PROGRAMA
38. void main(void)
39. {
40. setup_oscillator(OSC_4MHZ); //configurac
41. enable_interrupts(INT_TIMER1);
//interrupcion TIMER1 activada
42. SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_8);
//configuracion interrupcion TMR1
43. set_timer1(10); //ca
44. enable_interrupts(GLOBAL); //activadas
45. setup_uart(TRUE); //ac
46.
47. for(;;){} //bucle infinito -> espera
interrupcion del TMR1
48. }
49.
Para la libreria del ds1620 visitad este link [LIBRERIA CCS] DS1620
Decir que el dispositivo ds1620 que trae PROTEUS no asume numero decimal, aunque la
libreria si lo asume!!!
Suerte!!!
Hola:
Este programita está basado en las enseñanzas de él maestro VSzener.
Acá hay un programa con el cual nuestra intención es testear sensores, al principio lo
habíamos realizado con El pic 16F84a, pero evidentemente como este micro controlador no
tiene la suficiente cantidad de memoria nos pasamos al 16F28, sin embargo no sé por qué
razón, supongo que por la cantidad de memoria no me permite colocar variables globales.
También me gustaría saber la forma, en realidad se cómo mandar por el puerto serial pero
quiso o lo mande o imprima los datos cuando estos cambien y no estarlos enviando
constantemente.
En cuanto a las representación que usamos esto fue, debido a que usando la representación
de un número flotante nos consumía una gran cantidad de memoria. Si les es de ayuda esto
se interpreta en la siguiente manera.
Supongamos
dato = 211 (en realidad serían 2,11 volts), la primera parte imprime sólo la parte entera,
dato /100 = 211/100 = imprime la parte entera o sea = 2.
////////////////////////////////////////////////////////////////////////////////////
//
// 28/Mayo/06
//
// Programa: Manejo del dispositivo PCF8591 en modo A/D
// Version: 0.0
//
// Dispositivo: PIC 16F84A Compilador: CCS vs3.245
// Entorno IDE: MPLAB IDE v7.31 Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra como usar el conversor pfc8591 como adc.
// La Vref es de 2,56v por lo tanto la resolucion del conversor es 10mV.
// Básicamente lo que aquí hacemos es inicializar el conversor con la palabra
// de configuración y luego sólo resta leer (obviamente estamos modificando la
// tención analógica de entrada) sólo nos resta corregir un ligero error que es
// el que apenas pasa el valor de 128 en que se muestra valor negativo.
// Se muestra por pantalla de lcd(LM016L)
//
//
// Conexiones: RA1 -> SDA pcf8591
// RA0 -> SCL pcf8591
//
// lcd(LM016L)
// B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// VSS y VEE -> gnd
// VDD ->VCC
//
// pcf8591
// A0,A1,A2.EXT , AGND ->gnd
// AN0,AN1,AN2,AN3 divisor resistivo con potenciometro (2.5v Variables)
// VREF=2.56 (en est6e caso)(pin14) divisor resistivo con potenciometro
//
//
//////////////////////////////////////////////////////////////////////////////////
/******************************************************/
/********** Programa Medidor de Presion con 16f628 ***/
/******************************************************/
#INT_TIMER0
void interrupcion( )
{
int8 dato; //almacena lectura del pcf8591
///PROGRAMA
void main(void)
{
while(TRUE);//bucle infinito
Este programa consiste en cuatro pulsadores conectados a la parte alta del puerto b, si son
presionados cambiaran el estado del bit correspondiente del puerto b generando una
interrupcion, en dicha interrupcion, incrementaremos una variable global la cual nos servira
en el programa principal para encender led's, aqui el programa:
Código
GeSHi (c):
1. ///////////////////////////////////////////////////////////////////
/////////////////
2. // VsZeNeR'06
3. // 01/Julio/06
4. //
5. // Programa: Prueba Interrupcion debido a cambio de
estado del portb <4:7>
6. // Version: 0.0
7. //
8. // Dispositivo: PIC 16F648A Compilador: CCS vs3.249
9. // Entorno IDE: MPLAB IDE v7.40 Simulador:
Proteus 6.9sp4
10. //
11. // Notas: Este programa se encarga de ver si el compilador de
la casa CCS no desactiva
12. // correctamente la interrupcion del puerto b,
para ello debe:
13. // 1. Leer el puerto del puerto B
14. // 2. Borrar el bit de la
interrupcion(bit RBIF)
15. // Cada vez que hay un cambio de estado en los
pines del puerto B <4:7>
16. // se producira una interrupcion, la cual
incrementa una variable que se utilizara
17. // en el programa principal para mostrar la
iluminacion de led's. Aparte,
18. // cada vez que se produzca una interrupcion se
iluminara un led conectado al pin
19. // A4 que se apagara cuando salgamos de dicha
interrupcion.
20. //
21. // Conexiones: A0 -> A dec 4028
22. // A1 -> B dec
4028
23. // A2 -> C dec
4028
24. // A3 -> D dec
4028
25. // A4 -> led
indicador de interrupcion
26. // B4 -> boton
27. // B5 -> boton
28. // B6 ->
boton
29. // B7 -> boton
30. //
31. // Conclusion: El CCS no realiza bien el
tratamiento de la interrupcion
32. // del portB, por lo
que tendremos que leer/escribir algun pin
33. // del portB o el
puerto entero.
34. //////////////////////////////////////////////////////////////////
////////////////
35.
36. #include <16f648a.h> //pic a
utilizar
37. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el
programador
38. #fuses INTRC
//oscilador interno
39. #use delay (clock=4000000) //Fosc=4Mhz
40. #use fast_io(b)
41. #use fast_io(a)
42.
43.
44. ///DECLARACION DE VARIABLES GLOBALES
45. int variable=0;
46.
47. ///LLAMADA FUNCION INTERRUPCION
48. #INT_RB
49. void IntPortB4_7()
50. {
51. output_high(pin_a4); //indicador de interrupcion
on
52.
53. //Activar la linea de abajo para ver los cambios!!!
54. // while(!input(PIN_B4) || !input(PIN_B5) || !input(PIN_B6)
|| !input(PIN_B7)); //elimina rebotes
55. //en caso que funcione el ccs no deberia abordar de nuevo la
interrupcion hasta un cambio de estado
56. //de cualquiera de los pines <4:7> del portb. El CCS falla, por lo
que si tenemos la linea de lectura/escritura
57. //del puerto b(o alguno de sus pines) desactivada siempre nos
entrara en la interrupcion!
58.
59. variable++;
//incrementamos variable
60.
61. if(variable>0b00001001) //¿se ha iluminado
el ultimo led?
62. variable=0; //SI ->
reset variable
63.
64. output_low(pin_a4); //indicador
interrupcion off
65. }
66.
67. ///PROGRAMA
68. void main(void)
69. {
70. setup_oscillator(OSC_4MHZ); //configuramos el
oscilador a 4MHz
71.
72. set_tris_a (0x00); //porta
salida
73. set_tris_b (0xFF); //portb
entrada
74.
75. enable_interrupts(int_rb); //activar
interrupcion rb4:7
76. enable_interrupts(GLOBAL); //activar
interrupciones
77.
78. output_low(pin_a4); //indicador
de la interrupcion off
79.
80. do{ //bucle...
81. output_a(variable); //mostramos
por el porta el valor de variable
82. }while(TRUE);
//...infinito
83. }
84.
85.
Bien, ahora vamos con las explicaciones, el programa tal como esta, si lo simulamos o lo
montamos, nos enerara interrupciones siempre, ya que el CCS no realiza correctamente el
fin de la interrupcion como es debido, para que funcione correctamente, debemos
leer/escribir en el puerto b, vereis que en el programa hay una linea de codigo comentada,
es esta:
Código
GeSHi (c):
Descomentadla y volver a simular o a cargar el archivo e el pic y ponerlo andar vereis que
ya funciona correctamente, esto es debido a que dicha linea, aparte de eliminar los rebotes,
lee el estado de alguno de los pines del puerto b, por lo que segun nos dicta el manual,
cumplimos correcamente los pasos a seguir para desactivar la interrupcion del puerto b.
Asi que recordar que para un buen tratamiento de la interrupcion del puerto b, tendremos
que leer/escribir en dicho puerto para no tener problemas, ya que nuestro compilador no
nos hace el trabajo que deberia hacer.
Y con respecto al programa que el amigo Simulpic puso, decir y volver a repetir que la
funcion output_log/high no tenia nada que ver en el funcionamiento del porgrama en si para
el tratamiento correcto de la funcion de interrupcion, simplemente era de indicador de que
la habiamos abordado, lo que pasa que al escribir sobre un pin del puerto b pues ya
corregimos el error del CCS...
PD: Supongo que no es un error en si del CCS, quizas no puso la sentencia de lectura del
puerto b porque es de esperar que en el abordaje de la interrupcion el programador vea que
pin a realizado dicha llamada de interrupcion, por lo que ya estamos leyendo en el puerto b,
aunque deberian indicarlo por algun lado...
Suerte!!!
#include <16F84.h>
#fuses NOWDT,RC, NOPUT, NOPROTECT
#use delay(clock=4000000)
int nInd;
BOOLEAN lInterrupt;
#int_RB
RB_isr()
{
nInd++;
lInterrupt = TRUE;
#asm movf PORTB,0 #endasm
}
void main() {
nInd = 0;
lInterrupt = FALSE;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
while(true)
{
if (lInterrupt==TRUE)
{
output_a(nInd);
lInterrupt = FALSE;
}
}
}
Podras ver todo lo comentado, si comentas y descomentas la línea: #asm movf PORTB,0
#endasm
y realizas una simulación en Proteus.
Un saludo.
En línea
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.'
Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada"
Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin
aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..
Este programa consiste en cuatro pulsadores conectados a la parte alta del puerto b, si son
presionados cambiaran el estado del bit correspondiente del puerto b generando una
interrupcion, en dicha interrupcion, incrementaremos una variable global la cual nos servira
en el programa principal para encender led's, aqui el programa:
Código
GeSHi (c):
86. //////////////////////////////////////////////////////////////////
//////////////////
87. // VsZeNeR'06
88. // 01/Julio/06
89. //
90. // Programa: Prueba Interrupcion debido a cambio de
estado del portb <4:7>
91. // Version: 0.0
92. //
93. // Dispositivo: PIC 16F648A Compilador: CCS vs3.249
94. // Entorno IDE: MPLAB IDE v7.40 Simulador:
Proteus 6.9sp4
95. //
96. // Notas: Este programa se encarga de ver si el compilador de
la casa CCS no desactiva
97. // correctamente la interrupcion del puerto b,
para ello debe:
98. // 1. Leer el puerto del puerto B
99. // 2. Borrar el bit de la
interrupcion(bit RBIF)
100. // Cada vez que hay un cambio de estado en los
pines del puerto B <4:7>
101. // se producira una interrupcion, la cual
incrementa una variable que se utilizara
102. // en el programa principal para mostrar la
iluminacion de led's. Aparte,
103. // cada vez que se produzca una interrupcion se
iluminara un led conectado al pin
104. // A4 que se apagara cuando salgamos de dicha
interrupcion.
105. //
106. // Conexiones: A0 -> A dec 4028
107. // A1 -> B dec
4028
108. // A2 -> C dec
4028
109. // A3 -> D dec
4028
110. // A4 -> led
indicador de interrupcion
111. // B4 -> boton
112. // B5 -> boton
113. // B6 ->
boton
114. // B7 -> boton
115. //
116. // Conclusion: El CCS no realiza bien el
tratamiento de la interrupcion
117. // del portB, por lo
que tendremos que leer/escribir algun pin
118. // del portB o el
puerto entero.
119. //////////////////////////////////////////////////////////////////
////////////////
120.
121. #include <16f648a.h> //pic a
utilizar
122. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el
programador
123. #fuses INTRC
//oscilador interno
124. #use delay (clock=4000000) //Fosc=4Mhz
125. #use fast_io(b)
126. #use fast_io(a)
127.
128.
129. ///DECLARACION DE VARIABLES GLOBALES
130. int variable=0;
131.
132. ///LLAMADA FUNCION INTERRUPCION
133. #INT_RB
134. void IntPortB4_7()
135. {
136. output_high(pin_a4); //indicador de interrupcion
on
137.
138. //Activar la linea de abajo para ver los cambios!!!
139. // while(!input(PIN_B4) || !input(PIN_B5) || !input(PIN_B6)
|| !input(PIN_B7)); //elimina rebotes
140. //en caso que funcione el ccs no deberia abordar de nuevo la
interrupcion hasta un cambio de estado
141. //de cualquiera de los pines <4:7> del portb. El CCS falla, por lo
que si tenemos la linea de lectura/escritura
142. //del puerto b(o alguno de sus pines) desactivada siempre nos
entrara en la interrupcion!
143.
144. variable++;
//incrementamos variable
145.
146. if(variable>0b00001001) //¿se ha iluminado
el ultimo led?
147. variable=0; //SI ->
reset variable
148.
149. output_low(pin_a4); //indicador
interrupcion off
150. }
151.
152. ///PROGRAMA
153. void main(void)
154. {
155. setup_oscillator(OSC_4MHZ); //configuramos el
oscilador a 4MHz
156.
157. set_tris_a (0x00); //porta
salida
158. set_tris_b (0xFF); //portb
entrada
159.
160. enable_interrupts(int_rb); //activar
interrupcion rb4:7
161. enable_interrupts(GLOBAL); //activar
interrupciones
162.
163. output_low(pin_a4); //indicador
de la interrupcion off
164.
165. do{ //bucle...
166. output_a(variable); //mostramos
por el porta el valor de variable
167. }while(TRUE);
//...infinito
168. }
169.
170.
Bien, ahora vamos con las explicaciones, el programa tal como esta, si lo simulamos o lo
montamos, nos enerara interrupciones siempre, ya que el CCS no realiza correctamente el
fin de la interrupcion como es debido, para que funcione correctamente, debemos
leer/escribir en el puerto b, vereis que en el programa hay una linea de codigo comentada,
es esta:
Código
GeSHi (c):
Descomentadla y volver a simular o a cargar el archivo e el pic y ponerlo andar vereis que
ya funciona correctamente, esto es debido a que dicha linea, aparte de eliminar los rebotes,
lee el estado de alguno de los pines del puerto b, por lo que segun nos dicta el manual,
cumplimos correcamente los pasos a seguir para desactivar la interrupcion del puerto b.
En CCS, existe otra funcion la cual limpia las interrupciones: clear_interrupt(level); , la he
probado y simplemente borra el bir RBIF, por lo que no nos vale....
Asi que recordar que para un buen tratamiento de la interrupcion del puerto b, tendremos
que leer/escribir en dicho puerto para no tener problemas, ya que nuestro compilador no
nos hace el trabajo que deberia hacer.
Y con respecto al programa que el amigo Simulpic puso, decir y volver a repetir que la
funcion output_log/high no tenia nada que ver en el funcionamiento del porgrama en si para
el tratamiento correcto de la funcion de interrupcion, simplemente era de indicador de que
la habiamos abordado, lo que pasa que al escribir sobre un pin del puerto b pues ya
corregimos el error del CCS...
PD: Supongo que no es un error en si del CCS, quizas no puso la sentencia de lectura del
puerto b porque es de esperar que en el abordaje de la interrupcion el programador vea que
pin a realizado dicha llamada de interrupcion, por lo que ya estamos leyendo en el puerto b,
aunque deberian indicarlo por algun lado...
Suerte!!!
Citar
// Luces del auto fantastico por Ralf2, Foro todopic!
#include <16F876a.h>
#device adc = 10
#use delay (CLOCK = 4000000)
#fuses XT,NOWDT,NOLVP
#byte port_b=6
#byte port_c=7
#use fast_io(all)
void main()
{
int x;
port_b=0;
port_c=0;
set_tris_b(0);
set_tris_c(0);
port_b=1;
while(1)
{
for (x=0;x<=14;x++)
{
shift_left(&port_b,2,0);
delay_ms(100);
}