Sunteți pe pagina 1din 200

Re: Empezando con CCS

Desconectado « Respuesta #4 en: 27 Julio 2007, 23:06 »

Mensajes: 75 ////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// Practica 1 : Parpadeo de LED´S con PIC16F84A ///
/// para el foro.elhacker.net by Marco ///
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

///////////////////////////// DIRECTIVAS DE PREPROCESADO


Mas recargado que
//////////////////////
nunca
/// libreria para el manejo del pic16f84a
#include <16F84A.h>

/// declara la frecuencia del cristal


#use delay(clock=8000000)

///configura los fusibles


/// HS es la configuraricion del oscilador la cual indica High speed es
decir
/// frecuencias altas esto es a partir de 8 Mhz.
/// NOWDT deshabilita el Watch Dog Timer
/// NOPUT deshabilita le reseteo de power up timer
/// NOPROTECT deshabilita la proteccion del codigo del pic.
#fuses HS,NOWDT,NOPUT,NOPROTECT

/// asignamos a variable port_b el espacio memoria 0x06 que es la dir


de port_b
#byte port_b=0x06

//////////////////////////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;

////////////////////////// Principal //////////////////////////////////////////

void main()
{

/// declaramos el puerto B como salidas


set_tris_b(0);

/// lo igualamos con cero para que tengamos un valor inicial de lo


contrario
/// no sabriamos con que valor iniciaria al comienzo de nuestro
programa
port_b=0;

/// bucle infinito para que las instrucciones que tiene siempre se
ejecuten
while (true)

/// activa todos los pins del puerto B


/// otra instruccion que podemos poner es contador=255 las dos son lo
mismo
contador=0xff;
port_b=contador;

/// Retardo de 1000 milisegundos es decir 1 segundo


delay_ms(1000);

//// apaga todos los pins del puerto B}


contador=0x00;
port_b=contador;

/// Retardo de 1000 milisegundos es decir 1 segundo


delay_ms(1000);

} /// fin de bucle while


} /// fin de funcion principal main

aqui los archivos para PICC y Proteus

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// Practica 2 /////////////////////////////////
// Esta practica pasa la informacion que hay en el puerto B y la pasa //
// al puerto A //
///////////////////////// 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

#use fast_io(B) /// con esta instruccion evitamos que


/// se este configurando cada vez que usamos
#use fast_io(C) /// alguna instruccion de entrada o salida

#byte portb = 6 // se definen las direcciones de memoria


#byte portc = 7

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++;

if((conteo&0x0f)>9) // aqui observamos si el primer display llego a 10


// para solo comparar los primeros 4 bit hacemos una
// operacion and con 0x0f
{
conteo=conteo+10; // hacemos que los 4 bits mas significativos incrementen
conteo=conteo&0xf0;
}
if(conteo>99) {conteo=0;} // verificamos que la cuenta se haga de 0 a 99

else{ portb=conteo; delay_ms(400);}


} //fin de ciclo while
} //fin de programa

////////////////////////////////////////////////////////////////////////////////
////////////// Practica 2 //////////////////////
////////////// practica que escribe en una LCD //////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////// 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
#include <lcd.c> // Librería para el manejo del lcd para ver las conexiones
// abran el archivo C:\Archivos de programa\PICC\Drivers\lcd.c
// y ahi les muestra.

////////////////////////////////////////////////////////////////////////////////
// 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

MARCO_RECARGADO Re: Introduccion a la programacion de PICS en lenguaje C (CCS)


« Respuesta #22 en: 18 Septiembre 2007, 15:52 »
Desconectado
Hola pues en esta ocasion la practica consiste en leer un reloj de tiempo
Mensajes: 75 real.
con ayuda de una libreria

////////////////////////////////////////////////////////////////////////////////
////////////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//////////////////////////////////////

#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
#use i2c(Master, SDA=PIN_C4, SCL=PIN_C3)
#include <ds1307.c>

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 portc = 7 /// se definen direcciones de memoria


#byte portd = 8

#bit portd0 = 0x08.0


#bit portd1 = 0x08.1
#bit portd2 = 0x08.2
#bit portd3 = 0x08.3
#bit portd4 = 0x08.4
#bit portd5 = 0x08.5
#bit portd6 = 0x08.6
#bit portd7 = 0x08.7

#bit portc0 = 0x07.0


#bit portc1 = 0x07.1
#bit portc2 = 0x07.2
#bit portc3 = 0x07.3
#bit portc4 = 0x07.4
#bit portc5 = 0x07.5
#bit portc6 = 0x07.6
#bit portc7 = 0x07.7

#bit dato_6a = dato_6.0


#bit dato_6b = dato_6.1
#bit dato_6c = dato_6.2
#bit dato_6d = dato_6.3

#bit dato_5a = dato_5.0


#bit dato_5b = dato_5.1
#bit dato_5c = dato_5.2
#bit dato_5d = dato_5.3

#bit dato_4a = dato_4.0


#bit dato_4b = dato_4.1
#bit dato_4c = dato_4.2
#bit dato_4d = dato_4.3

#bit dato_3a = dato_3.0


#bit dato_3b = dato_3.1
#bit dato_3c = dato_3.2
#bit dato_3d = dato_3.3

#bit dato_2a = dato_2.0


#bit dato_2b = dato_2.1
#bit dato_2c = dato_2.2
#bit dato_2d = dato_2.3

#bit dato_1a = dato_1.0


#bit dato_1b = dato_1.1
#bit dato_1c = dato_1.2
#bit dato_1d = dato_1.3

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()
{

ds1307_init(); ///se inicializa el ds1307

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();

// Set date for -> 15 June 2005 Tuesday


// Set time for -> 15:20:55 (9:49:00 am)
ds1307_set_date_time(24,4,7,2,9,49,00); /// se escribe ne le displositivo

while(1)
{
delay_ms(1000);

ds1307_get_date(day,month,yr,dow); /// se obtiene la fecha


ds1307_get_time(hrs,min,sec); /// se obtiene la hora

////////////////////bin2bcd(sec) funcion para pasar de binario(hasta 99) a bcd

////////////////////bcd2bin(sec) funcion para pasar de bcd(hasta 99) a binario

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 /////////////////////////////////////////////

RE: Ejemplitos en C para 16F648A


« Respuesta #1 : 13 de Agosto de 2005, 16:38:00 »

El primer ejemplo como no!!! la iluminacion de un led!!!jeje alguien alguna vez a visto
programa similar???jeje bueno fuera de bromas por alguno hay que empezar y este es el
nivel inferior jeje. El programa consiste en el encendido y apagado d eun led cada 0.5s por
el pin RB0 del pueto B:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 6/Agosto/05
//
//Programa: Parpadeo de un led cada 0.5s
//Version: 0.0
//
//Dispositivo: PIC 16F648A Compilador: CCS vs3.227
//Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
//Notas: Parpadeo de un led cada 0.5s por el pin RB0 del puerto B
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fast_io(b)

///PROGRAMA
void main(void)
{
set_tris_b(0xFE); //portb como salida(RB0,las demas desactivadas)
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

do{
output_low(PIN_B0); //led off
delay_ms(500);
output_high(PIN_B0); //led on
delay_ms(500);
}while(TRUE); //bucle infinito
}

RE: Ejemplitos en C para 16F648A


« Respuesta #5 : 14 de Agosto de 2005, 05:49:00 »

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

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 6/Agosto/05
//
//Programa: Parpadeo de tres leds cada 0.5s
//Version: 0.1
//
//Dispositivo: PIC 16F648A Compilador: CCS vs3.227
//Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
//Notas: Parpadeo de tres leds cada 0.5s de tres formas diferentes:
// RB0 -> con la funcion output_high()/output_low()
// RB1 -> definiendo el pin RB1
// RB2 -> con la funcion output_bit()
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOCPD,NOWDT,NOPUT,NOLVP,NOBROWNOUT //ordenes programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fast_io(b)
#bit RB1=0x106.1 //definicion pin potrb B1

///PROGRAMA
void main(void)
{
set_tris_b(0xF8); //puerto b como salida
disable_interrupts(GLOBAL); //todas interrupciones desactivadas

RB1=0; //valor inicial B1 para que los led"s se iluminen igual


do{
output_high(PIN_B0); //led"s on
RB1=!RB1;
output_bit(PIN_B2,1);
delay_ms(500);

output_low(PIN_B0); //led"s off


RB1=!RB1;
output_bit(PIN_B2,0);
delay_ms(500);
}while(TRUE); //bucle infinito
}

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 14/Agosto/05
//
// Programa: Parpadeo de cuatro leds cada 0.5s
// Version: 0.2
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Parpadeo de cuatro leds cada 0.5s de cuatro formas diferentes:
// RB0 -> con la funcion output_high()/output_low()
// RB1 -> definiendo el pin RB1
// RB2 -> con la funcion output_bit()
// RB3 -> con la funcion bit_set()/bit_clear()
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOCPD,NOWDT,NOPUT,NOLVP,NOBROWNOUT //ordenes para el
programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3) //pin de salida portb
#bit RB1=0x106.1 //definicion pin potrb B1
#byte portb=06

///PROGRAMA
void main(void)
{
set_tris_b(0x00); //puerto b como salida
disable_interrupts(GLOBAL); //todas interrupciones desactivadas

RB1=0; //valor inicial B1 para que los led"s se iluminen igual


do{
output_high(PIN_B0); //led"s on
RB1=!RB1;
output_bit(PIN_B2,1);
bit_set(portb,3);
delay_ms(500);

output_low(PIN_B0); //led"s off


RB1=!RB1;
output_bit(PIN_B2,0);
bit_clear(portb,3);
delay_ms(500);
}while(TRUE); //bucle infinito
}
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"04
// 7/Agosto/05
//
// Programa: Coche Fantastico
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Barrido de led"s simulando la iluminacion del coche fantastico por el
// puerto A
//
// RA0 -> 1º Led
// RA1 -> 2º Led
// RA2 -> 3º Led
// RA3 -> 4º Led
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(A) //puerto A como salida

///DECLARACIONES DE FUNCIONES
void derecha(void); //ilumina led"s derecha a izquierda
void izquierda(void); //ilumina led"s izquierda a derecha

///PROGRAMA
void main(void)
{
set_tris_a(0xF0); //porta como salida menos RA4(desactivado)
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

do{ //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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B) //puerto B como salida
#byte portb= 0x6 //direccion port b

///PROGRAMA
void main(void)
{
int led_on=0b0001; //led a iluminar
set_tris_b(0xf0); //portb como salida (algunas desactivadas)
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

do{ //bucle...

do{ //iluminacion hacia izquierda


portb=led_on;
rotate_left(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,3)==0);

do{ //iluminacion hacia derecha


portb=led_on;
rotate_right(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,0)==0);

}while(TRUE); //...infinito
}

// VsZeNeR"05
// 15/Agosto/05
//
// Programa: Juego de luces
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Iluminacion de juego de luces fuera-dentro y viceversa por el puerto B.
// Adaptacion a c por vszener del codigo en basic de lordlafebre.
//
// RB0 -> 1º Led
// RB1 -> 2º Led
// RB2 -> 3º Led
// RB3 -> 4º Led
// RB4 -> 5º Led
// RB5 -> 6º Led
// RB6 -> 7º Led
// RB7 -> 8º Led
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B) //puerto B

///PROGRAMA
void main(void)
{
signed char i; //variable indice
int leds[4]={0b10000001,0b01000010,0b00100100,0b00011000}; //led"s

set_tris_b(0x00); //portb como salida


disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

do{ //bucle...

for(i=0;i<4;i++){ //led"s on fuera-dentro


output_b(leds[ i ]); //ilumino led"s correspondientes
delay_ms(100);
}
for(i=3;i>-1;i--){ //led"s on dentro-fuera
output_b(leds[ i ]); //ilumino led"s correspondientes
delay_ms(100);
}

}while(TRUE); //...infinito
}

RE: Ejemplitos en C para 16F648A


« Respuesta #23 : 15 de Agosto de 2005, 06:11:00 »

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

for(i=0;i<4;i++){ //led"s on fuera-dentro


output_b(leds[ i ]); //ilumino led"s correspondientes
delay_ms(100);
}
for(i=3;i>-1;i--){ //led"s on dentro-fuera
output_b(leds[ i ]); //ilumino led"s correspondientes
delay_ms(100);
}
}
la guardamos con el nombre de vs_lib_luces.h
Y aqui el programa principal:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 15/Agosto/05
//
// Programa: Luces
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Programa que consiste en que si por el pin A0 del porta lee un "0" logico
// es decir, esta en low, se ejecuta la iluminacion del coche fantastico
// por el portb, en cambio si por el pin A0 del porta se recibe un estado alto
// un "1" logico(high), se ejecuta por el portb la iluminacion de encender les"s
// de fuera-dentro y viceversa. Tener en cuenta que hay que poner la
// directiva NOLVP para que el pin B4 sea de salida
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#include <vs_lib_luces.h> //nuestra libreria para las funciones
kit(),juego_luces()
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use standard_io(B)
#use standard_io(A)

///PROGRAMA
void main(void)
{
set_tris_a(0xFF); //porta como entrada
set_tris_b(0x00); //portb como salida
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

do{ //bucle...
if(!input(PIN_A0)) //¿switch cerrado?
kit(); //SI ->ejecuta coche fantastico(kit)
else
juego_luces(); //NO ->ejecuta juego luces
}while(TRUE); //...infinito
}

RE: Ejemplitos en C para 16F648A


« Respuesta #25 : 16 de Agosto de 2005, 07:30:00 »

El ejemplito de hoy se basa en hacer un contador ascendente del 0 al 9 y volver a empezar,


para ello trabajaremos con el periferico 7segmentos de catodo comun, aqui el codigo:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"04
// 14/Agosto/05
//
// Programa: Contador ascendente 0-9
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Contador del 0 al 9 cada 0,5s y vuelta a empezar. Tener en cuenta
// que hay que poner la directiva NOLVP para que el pin B4 sea de salida
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)

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

set_tris_b(0x00); //portb como salida


disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

do{ //bucle...
output_b(tab7seg[ i ]); //muestra por portb digito 7 segmentos
delay_ms(500);
i++; //incremento contador para visualizar siguiente digito
if(i>9) //¿ya se ha mostrado el digito 9?
{
i=0; //SI -> vuelve a empezar(digito 0)
}
}while(TRUE); //...infinito
}

RE: Ejemplitos en C para 16F648A


« Respuesta #29 : 17 de Agosto de 2005, 03:38:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)

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

set_tris_b(0x00); //portb como salida


disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

do{ //bucle...
output_b(tab7seg[ i ]); //muestra por portb digito 7 segmentos
delay_ms(500);
i--; //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
}

RE: Ejemplitos en C para 16F648A


« Respuesta #31 : 18 de Agosto de 2005, 05:12:00 »

Ya que sabemos contar del 0 al 9 y del 9 al 0 mediante el periferico 7 segmentos.....esta vez


el ejemplito propuesto es incorporarle un switch por el porta(pin A0) y si dicho switch esta
abierto el contador sera ascendente(del 0 al 9) y si esta cerrado el switch el contador sera
descendente(del 9 al 0)....aqui el codigo:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"04
// 14/Agosto/05
//
// Programa: Contador reversible 0-9
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Contador reversible 0 al 9 viceversa cada 0,5s y vuelta a empezar. Tener
// en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
// salida. Cuando el switch esta cerrado se lee por el pin A0 del porta un
// "0" logico(pin A0 low)y el contador se configura como descendente encambio
// si el switch esta abierto se lee por el pin A0 del porta un "1"
// logico(pin A0 high) por lo tanto el contador se configura como ascendente
//
// Conexiones: A0 -> switch a
// B0 -> a 7seg ____
// B1 -> b 7seg f | |b
// B2 -> c 7seg |g |
// B3 -> d 7seg ----
// B4 -> e 7seg e | |c
// B5 -> f 7seg |____|
// B6 -> g 7seg d
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3,PIN_B4,PIN_B5,PIN_B6)
#use standard_io(A)

///DECLARACION DE FUNCIONES
void up(void); //funcion cuenta ascendente
void down(void); //funcion cuenta descendente

///DECLARACION VARIABLES GLOBALES


signed char i; //contador para tabla 7 seg (se tiene en cuenta el signo)
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; //7seg hex 0-
9
///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
///inicializamos el contador
if(!input(PIN_A0)) //para ello leemos el estado del pin A0 del porta
i=10; //contador descendente
else
i=-1; //contador ascendente

do{ //bucle...
if(input(PIN_A0)) //¿switch abierto?
up(); //SI -> contador ascendente
else
down(); //NO -> contador descendente

output_b(tab7seg[ i ]); //muestra por portb digito 7 segmentos


delay_ms(500);
}while(TRUE); //...infinito
}

void up(void) //funcion cuenta ascendente


{
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)
}

void down(void) //funcion cuenta descendente


{
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)
}

RE: Ejemplitos en C para 16F648A


« Respuesta #33 : 20 de Agosto de 2005, 18:21:00 »
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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use fixed_io(a_outputs=PIN_A0,PIN_A1) //A0,A1 como salidas en porta

char i=0,j=0,flag=0,var=20; //variables globales

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 1 segundo?
var--; //SI -> decremento var...
if(var<18)
var=20; //...ajuste fino de 1s
flag=0; //reset flag para contar 1s
if(i> { //¿se ha mostrado por 1º 7seg digito 9?
i=0; //SI -> i=0 (muestra digito 0) (*)
j++; //incremento indice j
if(j>9){ //¿se ha mostrado por 2º 7seg digito 9?
j=0;} //SI -> j=0 (muestra digito 0)
}
else{ //(*) NO -> incrementa i
i++;}
}
set_timer0(61); //reset TMR0
flag++; //incremento variable flag
}

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

set_tris_b(0x00); //portb como salida


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

RE: Ejemplitos en C para 16F648A


« Respuesta #36 : 22 de Agosto de 2005, 10:24:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use fixed_io(a_outputs=PIN_A0,PIN_A1) //A0,A1 como salidas en porta

//VARIABLES GLOBALES
signed char i=0,j=0; //indices(se tiene en cuenta signo para comprobaciones de fin
tab7seg)
char flag=0,var=20;
short cuenta=0; //cuenta=0 -> Contador ascendente ; cuenta=1 -> Contador
descendente

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 1 segundo?rutina:actualizar indices y contador
ascendente/descendente
var--; //SI -> decremento var...
if(var<18)
var=20; //...ajuste fino de 1s
flag=0; //reset flag para contar 1s
if(cuenta==0){ //¿Contador ascendente?
if(i> { //SI -> ¿se ha mostrado por 1º 7seg digito 9?
i=0; //SI -> i=0 (muestra digito 0) (*)
j++; //incremento indice j
if(j>9){ //¿se ha mostrado digito 99?
cuenta=1; //SI -> contador descendente...
j=9; //restauro...
i=8; //...indices
}
}
else{ //(*) NO -> incrementa i
i++;}
}
else{ //Contador descendente
i--; //decremento indice i
if(i<0){ //¿fin tab7seg en indice i?
i=9; //SI -> restauro i
j--; //decremento indice j
if(j<0){ //¿fin tab7seg en indice j 00?
cuenta=0; //SI -> Contador descendente
i=1; //restauro...
j=0; //...indices
}
}
}
} //fin actualizar indices y contador ascendente/descendente
set_timer0(61); //reset TMR0
flag++; //incremento variable flag
}

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

set_tris_b(0x00); //portb como salida


enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion
TMR0
set_timer0(61); //carga TMR0
enable_interrupts(GLOBAL); //activadas interrupciones

do{ //bucle...
output_high(PIN_A1); //2º 7seg off
output_low(PIN_A0); //1º 7seg on
delay_ms(15);
output_b(tab7seg[ i ]); //muestra por portb digito 7 segmentos
output_low(PIN_A1); //2º 7seg on
output_high(PIN_A0); //1º 7seg off
delay_ms(15);
output_b(tab7seg[ j ]); //muestra por portb digito 7 segmentos
}while(TRUE); //...infinito
}

RE: Ejemplitos en C para 16F648A


« Respuesta #38 : 22 de Agosto de 2005, 16:32:00 »

Misteriosamente este programa no estaba....asi que lo pongo de nuevo(simplemente estaba


su descarga...), es un contador ascendente bcd que cuenta pulsando el boton:

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.

RE: Ejemplitos en C para 16F648A


68. « Respuesta #39 : 22 de Agosto de 2005, 18:20:00 »

Y aqui va la version de contador de 0a9 en display de 7 segmento formato BCD y


boton...peo esta vez dos botones, uno por el pin A0 que sis e pulsa se incrementa un digito
y s emuestra por el 7seg BCD y otro boton por el pin A1 que si se pulsa se decrementa en
una unidad y s emuestra por display de 7seg BCD:

////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3)
#use standard_io(A)

///PROGRAMA
void main(void)
{
signed char i=0; //contador para tabla BCD
int
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1
001}; //BCD 0-9

set_tris_a(0xFF); //porta como entrada


disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

output_b(tabBCD[ i ]); //inicializa displayBCD digito 0

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
}

RE: Ejemplitos en C para 16F648A


« Respuesta #41 : 24 de Agosto de 2005, 07:40:00 »

Bueno celebrando mi mensaje numero 100!!!(parece que fue ayer...)aqui un ejemplito


massss de contador en display"s de 7seg...ya se que estais cansados de ver numeritos y mas
numeritossss jeje pero weno asi ya sabemos programar display"s de 7seg multiplexados,
interrupciones y demas cositas...esta vez es un SUPER CONTADOR!!!!!jeje ascendente(de
momento) que cuenta de 0000 a 9999 y vuelta a empezar....bueno compañeros, ya no hay
excusa que no sabemos contar!!!!:

////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3) //A0,A1,A2,A3 como
salidas en porta

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

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 1 segundo?
var--; //SI -> decremento var...
if(var<18)
var=20; //...ajuste fino de 1s
flag=0; //reset flag para contar 1s
if(i> { //¿se ha mostrado por 1º 7seg digito 9?
i=0; //SI -> i=0 (muestra digito 0) (*)
j++; //incremento indice j
if(j>9){ //¿se ha mostrado por 2º 7seg digito 9?
j=0; //SI -> j=0 (muestra digito 0)
w++; //incremento indice w
if(w>9){ //¿se ha mostrado por 3º 7seg digito 9?
w=0; //SI -> w=0 (muestra digito 0)
z++; //incremento indice z
if(z>9) //¿se ha mostrado por 4º 7seg digito 9?
z=0; //SI -> z=0 (muestra digito 0)
}
}
}
else{ //(*) NO -> incrementa i
i++;}
}
set_timer0(61); //reset TMR0
flag++; //incremento variable flag
}

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

set_tris_b(0x00); //portb como salida


enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion
TMR0
set_timer0(61); //carga TMR0
enable_interrupts(GLOBAL); //activadas interrupciones

do{ //bucle...
output_high(PIN_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
}

RE: Ejemplitos en C para 16F648A


« Respuesta #43 : 25 de Agosto de 2005, 06:04:00 »

Este ejemplito de hoy es para animar al BETI!!!aunque perdiera la supercopa


españa....ainsss, el programa consiste en 7 display"s de 7seg multiplexados parpadeando la
palabra "beti":

////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use standard_io(A)

///PROGRAMA
void main(void)
{
char i; //contador de visualizacion BETI

set_tris_b(0x00); //portb como salida


set_tris_a(0x00); //porta como salida
disable_interrupts(GLOBAL); //activadas interrupciones

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
}

RE: Ejemplitos en C para 16F648A


« Respuesta #50 : 25 de Agosto de 2005, 08:43:00 »

jejeje la virgen!!!!jeje la verdad que el chiko no se compliko la cabeza mucho....y yo ke


kreia ke radon estaba hablando en broma de eso de tumbar los 7seg.....jeje ke
descaro!..ainsss por cierto xootraoox interesante el data sheet que pusiste haber si lo leo
detenidamente me interesan los "chismes" esos....bueno se que al Depor le hace mas falta
los animos ya que no estamos en europa ni nada asi que haciendole caso a nocturno66 aqui
va el programita que anima al depor diciendo: AUPA DEPO y suena un pitidito....como
mejor he podido poner las letras en display"s de 7seg jeje:

////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use standard_io(A)

///PROGRAMA
void main(void)
{
char rep,cont=0,i=0,j=1,w=2,z=0; //variables
int tab7seg[6]={0x77,0x3E,0x73,0x5E,0x79,0x3F}; //A U P D E O

set_tris_b(0x00); //portb como salida


set_tris_a(0x00); //porta como salida
disable_interrupts(GLOBAL); //desactivadas interrupciones
do{ //bucle...
for(rep=0;rep<15;rep++){ //bucle visualizacion aupa/depo
output_a(0b1110);
output_b(tab7seg[ i ]); //1º 7seg on
delay_ms(10);
output_a(0b1101);
output_b(tab7seg[ j ]); //2º 7seg on
delay_ms(10);
output_a(0b1011);
output_b(tab7seg[ w ]); //3º 7seg on
delay_ms(10);
output_a(0b0111);
output_b(tab7seg[ z ]); //4º 7seg on
delay_ms(10);
}

cont=!cont; //cont=~cont
if(cont==1){ //muestra:
i=3; //D
j=4; //E P
z=5;} //O
else{ //muestra:
i=0; //A
j=1; //U P
z=0;} //A

output_b(0b10000000); //Buzzer on...todo...


output_a(0b0000);
delay_ms(500); //...apagado durante 0,5s
}while(TRUE); //...infinito
}

RE: Ejemplitos en C para 16F648A


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

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


comun...esta vez el ejemplo consiste en 4 display"s de 7seg mostrar la palabra "hola" e ir
rotandola hacia la izquierda:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 21/Agosto/05
//
// Programa: HOLA
// 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 HOLA por cuatro display"s de 7 segmentos
// multiplexados. El mensaje se va rotando por los display"s hacia la
// izquierda. Tener en cuenta que hay que poner la directiva NOLVP
// para que el pin B4 sea de salida.
// Se utiliza variables locales:
// * i -> indice tabla 7seg para mostrar 1º 7seg
// * j -> indice tabla 7seg para mostrar 2º 7seg
// * z -> indice tabla 7seg para mostrar 3º 7seg
// * w -> indice tabla 7seg para mostrar 4º 7seg
// * flag -> variable que cuenta 0.5s
// * var -> ajuste fino para que desborde cada medio segundo.
// Utilizamos la funcion de interrupcion para actualizar indices de la
// tabla de 7seg para mostrar la palabra correspondiente en el respectivo
// 7seg, para ello el TMR0 se desborda cada 0.5s, para ello debe ser cargado
// con 61(equivale a un desbordamiento cada 50ms mas o menos), para obtener
// un desbordamiento de 0.5s utilizamos una variable(flag) que no entra en
// la actualizacion de indices hasta transcurrido 0.5s.
// Conexiones:
// · RA0 -> Display 1º 7seg
// · RA1 -> Display 2º 7seg
// · RA2 -> Display 3º 7seg
// · RA3 -> Display 4º 7seg
// · RB0 -> a 7seg
// · RB1 -> b 7seg
// · RB2 -> c 7seg
// · RB3 -> d 7seg
// · RB4 -> e 7seg
// · RB5 -> f 7seg
// · RB6 -> g 7seg
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use standard_io(A)

char i=0,j=1,z=2,w=3,var=10,flag=0; //indices para tabla 7 seg

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 1 segundo?
var--; //SI -> decremento var...
if(var<18)
var=10; //...ajuste fino de 1s
flag=0; //reset flag para contar 1s
i++; //incrementos...
j++;
z++;
w++; //...indices para mostrar en 7seg
if(i>3) //¿Ha llegado fin tab7seg?
i=0; //SI -> restaura indice i
if(j>3) //¿Ha llegado fin tab7seg?
j=0; //SI -> restaura indice j
if(z>3) //¿Ha llegado fin tab7seg?
z=0; //SI -> restaura indice z
if(w>3) //¿Ha llegado fin tab7seg?
w=0; //SI -> restaura indice w
}

set_timer0(61); //reset TMR0


flag++; //incremento variable flag
}

///PROGRAMA
void main(void)
{
int tab7seg[4]={0x76,0x3F,0x38,0x77}; //7seg H O L A
set_tris_b(0x00); //portb como salida
set_tris_a(0x00); //porta como salida
enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion
TMR0
set_timer0(61); //carga TMR0
enable_interrupts(GLOBAL); //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
}

RE: Ejemplitos en C para 16F648A


« Respuesta #56 : 26 de Agosto de 2005, 17:15:00 »
Aqui va otro ejemplito mas!!!!y mas con 7seg!!!!jeje ke jartura de estos
dispositivos......ainsss jeje, bueno esta vez consiste en mostrar por pantaya un cuadradito ke
se desplaza de izquierda a derechas y viceversa:

////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use standard_io(A)
///PROGRAMA
void main(void)
{
char i=0; //contador de display on
int display_on[4]={0b1110,0b1101,0b1011,0b0111}; //tabla display on

set_tris_b(0x00); //portb como salida


set_tris_a(0x00); //porta como salida
disable_interrupts(GLOBAL); //desactivadas interrupciones

output_b(0x63); //muestra por pantalla simbolo


output_a(display_on[ i ]); //inicializo display

do{ //bucle...
for(i=0;i<3;i++){ //hacia la izquierda
delay_ms(100);
output_a(display_on[ i ]);
}

for(i=3;i>0;i--){ //hacia la derecha


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

RE: Ejemplitos en C para 16F648A


« Respuesta #57 : 27 de Agosto de 2005, 14:58:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#include <STDLIB.H> //libreria donde esta la funcion rand();
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3)
#use standard_io(A)

///PROGRAMA
void main(void)
{
char num=0; //variable almacena numero aleatorio

set_tris_a(0xFF); //porta como entrada


disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

srand(10); //maximo hasta 9


for( ; ; ){ //bucle...
if(!input(PIN_A0)) //¿se ha pulsado el boton?
{
do{ //elimina...
num=rand(); //genera numero pseudo-aleatorio
}while(!input(PIN_A0)); //...rebotes
}
output_b(num); //muestra por portb digito 7 segmentos
} //...infinito
}

RE: Ejemplitos en C para 16F648A


« Respuesta #60 : 29 de Agosto de 2005, 05:04:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

///PROGRAMA
void main(void)
{
lcd_init(); //inicializa lcd
printf(lcd_putc,"hola mundo ; )
VsZeNeR"05" ); //muestra por pantalla el mensaje
}

RE: Ejemplitos en C para 16F648A


« Respuesta #62 : 29 de Agosto de 2005, 18:30:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

///PROGRAMA
void main(void)
{
lcd_init(); //inicializa lcd
delay_ms(2); //retardo para apreciarse todos los caracteres
printf(lcd_putc,"hola mundo ; )
VsZeNeR"05" ) ; //muestra por pantalla el mensaje
}

RE: Ejemplitos en C para 16F648A


« Respuesta #65 : 30 de Agosto de 2005, 07:33:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

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

lcd_init(); //inicializa lcd

do{ //bucle...
for(x=1;x<27;x++){ //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);

if(x>15) //¿ya esta completa la 1º fila del lcd?


y=2; //SI -> escribe en 2º fila

printf(lcd_putc,"%c",abecedario[ x ]); //muestra por pantalla el caracter


delay_ms(300);
}
printf(lcd_putc,"f " ) ; //borra pantalla del lcd
y=1; //restablece indice
}while(TRUE); //...infinito
}

RE: Ejemplitos en C para 16F648A


« Respuesta #69 : 31 de Agosto de 2005, 06:25:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

///PROGRAMA
void main(void)
{
char y=1; //indice columnas
signed char x=1; //indice filas
lcd_init(); //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
}

RE: Ejemplitos en C para 16F648A


« Respuesta #75 : 01 de Septiembre de 2005, 09:46:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

///DEFINICION VARIABLES GLOBALES


char y=1; //indice columnas
signed char x=1; //indice filas

///DECLARACION DE FUNCIONES
void derecha(void); //mensaje hacia la derecha
void izquierda(void); //mensaje hacia la izquierda

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

while(TRUE){ //bucle...
derecha() ;
izquierda() ;
} //...infinito
}

///FUNCION MUESTRA MENSAJE DE IZQUIERDA -> DERECHA


void derecha(void)
{
do{
lcd_gotoxy(x,y); //cursor para escribir mensaje
lcd_putc("VsZeNeR"05" ); //muestra por pantalla el mensaje
delay_ms(150);
x++; //incremento indice de filas
if(x>17){ //¿ya se ha mostrado mensaje entero por 1ºfila?
x=-8; //SI -> indice fila x=-8
y++; //incremento indice columnas
if(y>2){ //¿ya se ha mostrado mensaje entero por 2ºfila?
x=16; //SI -> actualiza indice filas
y=2; //actualiza indice columnas
return;} //sal de la funcion derecha()
}
lcd_putc("f" ); //borra pantalla
}while(TRUE);
}
///FUNCION MUESTRA MENSAJE DE DERECHA -> IZQUIERDA
void izquierda(void)
{
do{
x--; //decremento indice de filas
if(x<-9){ //¿ya se ha mostrado mensaje entero por 2ºfila?
x=16; //SI -> indice fila x=16
y--; //decremento indice columnas
if(y<1){ //¿ya se ha mostrado mensaje por 1º fila?
x=-8; //SI -> restauro indice filas
y=1; //restauro indice columnas
return;} //sal de la funcion izquierda()
}
lcd_gotoxy(x,y) ; //cursor para escribir mensaje
lcd_putc("VsZeNeR"05" ) ; //muestra por pantalla el mensaje
delay_ms(150) ;
lcd_putc("f" ) ; //borra pantalla
}while(TRUE) ;
}
RE: Ejemplitos en C para 16F648A
« Respuesta #76 : 03 de Septiembre de 2005, 06:11:00 »

Buenass!!!el programita de hoy consiste en sacar por pantalla(lcd) 4 mensajes que


grabaremos previamente mediante software, en la eeprom interna del pic:

////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd
///PROGRAMA
void main(void)
{
char LAST_VOLUME=0,volume; //variables de direccion escritura eeprom y mensaje
char mensaje1[]="VsZeNeR"05"; //mensajes...
char mensaje2[]="HOLA";
char mensaje3[]="FORO";
char mensaje4[]="TODOPIC!"; //a escribir en eeprom interna y mostrar en lcd

lcd_init(); //inicializa lcd

write_eeprom(LAST_VOLUME,mensaje1); //escritura de los mensajes...


LAST_VOLUME++;
write_eeprom(LAST_VOLUME,mensaje2);
LAST_VOLUME++;
write_eeprom(LAST_VOLUME,mensaje3);
LAST_VOLUME++;
write_eeprom(LAST_VOLUME,mensaje4); //...en la eeprom interna(0 hasta la 3)

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 »

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


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

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"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)
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

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

lcd_init(); //inicializa lcd


printf(lcd_putc,"Presione boton
para contador0a9" ); //muestra mensaje inicio

do{ //espera hasta que se pulse boton...


}while(input(PIN_A0)==1);
printf(lcd_putc,"f" ); //...para borrar pantalla e iniciar contador

printf(lcd_putc,"
VsZeNeR"05" ); //auto publicidad en la 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 »

Holaaaa!!!!el programita de hoy consiste en grabar 4 mensajes en la memoria externa


24LC256(32KB I2C EEPROM) y despues leerlos para mostrarlos por la lcd:

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

#include <16f648a.h> //pic a utilizar


#use delay(CLOCK=4000000) //Fosc=4Mhz
#fuses HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT //comandos para
el programador
#define use_portb_lcd TRUE //utilizar el port b para lcd
#define EEPROM_SDA PIN_A1 //definimos los pines donde...
#define EEPROM_SCL PIN_A0 //la eeprom ira conectada
#include <24256.c> //libreria de eeprom externa 24LC256
#include <lcd.c> //libreria de lcd

///PROGRAMA
void main(void){
int dir=0; //direccion de eeprom a escribir y leer mensajes
char men1[]="VsZeNeR"05"; //declaracion de...
char men2[]="Hola";
char men3[]="Foro";
char men4[]="TODOPIC!"; //...mensajes a escribir y leer por 25LC256

lcd_init(); //inicializa lcd


init_ext_eeprom(); //inicializa eeprom

lcd_putc("~ Escribiendo en...


24LC256
");
delay_ms(500);
write_ext_eeprom(dir,men1 ) ; //proceso de escribir...
dir++;
write_ext_eeprom(dir,men2 ) ;
dir++;
write_ext_eeprom(dir,men3 ) ;
dir++;
write_ext_eeprom(dir,men4) ; //...los mensajes en la eeprom externa
lcd_putc("fFin de escritura en
24LC25" ) ;
delay_ms(1500) ;

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
}

RE: Ejemplitos en C para 16F648A


« Respuesta #84 : 08 de Septiembre de 2005, 07:28:00 »

Buenas!!!!hoy vamos a trasladar un programa anterirmente realizado en display de 7seg a


la lcd....esta vez vamos hacer un dado y su resultado se mostrara por la lcd:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 08/Septiembre/05
//
// Programa: Dado digital con lcd y buzzer
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
// Notas: Dado digital, que al presionar el boton conectado al pin A0 del porta
// genera un numero pseudo-aleatorio mediante la funcion rand() que se
// encuentra en la libreria STDLIB.H. El numero pseudo-aleatorio es elegido
// mediante la funcion rand() y segun los "rebotes" producidos por el boton.Tener
// en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
// salida. Cuando agregamos un boton a nuestro circuito hay que tener en cuenta
// que este dispositivo genera "rebotes" que hay que ser eliminados para
// una correcta visualizacion en la lcd del digito seleccionado. Esta vez
// la eliminacion de "los rebotes" se ha realizado mediante software.
//
// Conexiones: A0 -> boton
// B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// B3 -> Buzzer(beep)
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#define RAND_MAX 7 //dado solamente 6 numeros
#include <STDLIB.H> //libreria donde esta la funcion rand();
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use fast_io(A)
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

///PROGRAMA
void main(void)
{
char num=0; //variable almacena numero aleatorio

set_tris_a(0xFF); //porta como entrada


disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

lcd_init(); //inicializa lcd


srand(10); //maximo hasta 9
lcd_putc("Dado Electronico
Pulse boton..." );

while(input(PIN_A0)){} //Se mantiene cabecera hasta que se pulse el boton

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

printf(lcd_putc,"%d",num); //muestra por lcd numero


lcd_putc("" ); //retrocede un espacio
output_high(PIN_B3); //activa buzzer(beep)
delay_ms(50); //tiempo de escucha del beep
output_low(PIN_B3); //desactiva buzzer(beep)
}
} //...infinito
}

vszener RE: Ejemplitos en C para 16F648A


Moderador « Respuesta #95 : 11 de Septiembre de 2005, 05:30:00 »
Local
PIC24H Bueno el siguiente ejemplito vamos a utilizar un RTC(real time clock), es
decir un reloj de tiempo real, el dispositivo rtc a tratar es el DS1302 de
Desconectado Dallas Semiconductor, este dispositivo aparte de dar la hora en tiempo
real, tambien da la fecha, es decir es un dispositivo que se comporta como
Sexo: reloj-calendario, la pagina que dedica Dallas al dispositivo:
España http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2685
Y vamos a trabajar con la libreria que trae CCS para este dispositivo la
Mensajes: cual es DS1302.C donde estan todas las funciones definidas para el
2380 manejo del dispositivo en cuestion, la pagina web donde esta la libreria
mencionada:
http://www.ccsinfo.com/data.shtml
Bien, mirarse los enlaces anteriores(los data sheet) para saber con que nos
enfrentamos!!!!jeje
Al lio!!!!

VsZeNeR En línea

Nos vemos en los bares!!!!!

vszener RE: Ejemplitos en C para 16F648A


Moderador « Respuesta #96 : 11 de Septiembre de 2005, 05:39:00 »
Local
PIC24H Y bien he aqui el programita!!!jeje bien decir que he intentado utilizar las
funciones basicas del DS1302, es decir, su configuracion(escribir la hora y
la fecha) y despues su posterior lectura para mostrarla por la lcd, la
Desconecta programacion es algo extensa pero creo que asi es mas clara, se puede
do eliminar ciertas lineas de codigo e incluso hacerse de otra forma(la cual ya
pondre), pero entonces resulta mas lioso de entender el funcionamiento del
Sexo: programa....jeje, bueno aqui el programita:
España
////////////////////////////////////////////////////////////////////////////////////
Mensajes: // VsZeNeR"05
2380 // 09/Septiembre/05
//
// Programa: Reloj-Calendario DS1302
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
VsZeNeR
// Notas: Se muestra por pantalla de lcd(LM016L) la fecha y hora obtenida
mediante la
// lectura del DS1302. Pudiendose modificar mediante los botones
Conf/Ok y up.
// Se utiliza variables globales:
// ·day-> dia ds1302
// ·mth -> mes ds1302
// ·year -> 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.
// ·var -> ajuste fino para que desborde cada 130ms aprox.
// Se carga el TMR0 con 0 por lo tanto se desborda en 65ms aprox,
queremos
// visualizar y restaurar valores cogidos del ds1302 cada 130ms aprox
por lo tanto
// utilizamos una variable llamada flag que sera la encargada de dicha
tarea.
// Al inicio del programa debe ser configurado el reloj, siendo el boton
"up" el
// encargado de ir moviendose mediante las opciones del
menu:hora,minutos,....
// y el boton "Conf/Ok" el encargado de configurar el reloj(cuando
estemos en modo ver
// hora y fecha) o el encargado de salir de la configuracion de las
opciones(cuando
// estemos en formato de configurar fecha y hora).
// Tener en cuenta que hay que poner la directiva NOLVP para que el
pin B4 sea de
// salida.
// Conexiones: A0 -> RST DS1302
// A1 -> SCLK DS1302
// A2 -> I/O DS1302
// A3 -> Boton "up"
// A5 -> Boton "Conf/Ok"
// B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// B3 -> Zumbador(beep)
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#use delay(CLOCK=4000000) //Fosc=4Mhz
#fuses
HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT,NOMCLR
//comandos para el programador
#use standard_io(a)
#use standard_io(b)
#define use_portb_lcd TRUE //utilizar el port b para lcd
#define RTC_SCLK PIN_A1 //definimos pin"s...
#define RTC_IO PIN_A2
#define RTC_RST PIN_A0 //...de conexion de la rtc ds1302
#include <ds1302.c> //libreria de rtc ds1302
#include <lcd.c> //libreria de lcd
///VARIABLES GLOBALES
byte day,mth,year,dow,hour,min,sec; //variabes para ds1302
byte menu=0,flag=0,var=2; //variables para menu configurar

///DEFINICION DE FUNCIONES
void configurar(void);
void horas(void);
void minutos(void);
void dia(void);
void mes(void);
void anio(void);
void beep(void);

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 130ms aprox?
var--; //SI -> decremento var...
if(var==0)
var=2; //...ajuste fino de 130ms aprox
flag=0; //reset flag para contar 130ms aprox
rtc_get_date(day,mth,year,dow); //coge dia,mes,año
rtc_get_time(hour,min,sec ); //coge hora,minuto,segundo
printf(lcd_putc,"fFecha: %2X/%2X/%2X
Hora: %2X:%2X:%2X",day,mth,year,hour,min,sec);

//lcd
}

set_timer0(0); //reset TMR0


flag++; //incremento variable flag
}

///PROGRAMA
void main(void){

enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada


setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion
interrupcion TMR0
set_timer0(0); //carga TMR0

lcd_init(); //inicializa lcd


rtc_init(); //inicializa rtc

lcd_putc("Reloj Calendario
VsZeNeR"05" ); //presentacion...
delay_ms(800); //...inicial

configurar(); //ve a menu configurar


enable_interrupts(GLOBAL); //activadas interrupciones

for( ; ; ){ //bucle...
if(input(PIN_A5)==0){ //Si se pulsa Conf....
while(!input(PIN_A5)){} //elimina rebotes
beep();
configurar();
} //ve a menu

configurar
} //...infinito
}

///FUNCION CONFIGURAR
void configurar(void){
disable_interrupts(GLOBAL); //desactivadas interrupciones

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

//apunta siguiente opcion


}
break;
case 1: lcd_putc("fConfigurar
minutos?" ); //minutos
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
minutos();
menu=2;

//apunta siguiente opcion


}
break;
case 2: lcd_putc("fConfigurar
dia?" ); //dias
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
dia();
menu=3;

//apunta siguiente opcion


}
break;
case 3: lcd_putc("fConfigurar
mes?" ); //mes
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
mes();
menu=4;

//apunta siguiente opcion


}
break;
case 4: lcd_putc("fConfigurar
anio?" ); //años
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
anio();
menu=5;

//apunta siguiente opcion


}
break;
case 5: lcd_putc("fSalir
configurar?" ); //salir configuracion
if(!input(PIN_A5)){
menu=6;
beep();
}
}

if(!input(PIN_A3)){ //controla el boton up...


while(!input(PIN_A3)){}
menu++;
if(menu>5)
menu=0;
} //...para mostrar menu
por lcd

delay_ms(130); //retardo para ver lcd


}while(menu<6);

menu=0;

//actualiza indices menu


rtc_set_datetime(day,mth,year,dow,hour,min); //nueva hora,minuto,...
enable_interrupts(GLOBAL); //activadas

interrupciones
set_timer0(0);

//carga TMR0
}
///FUNCION CONFIGURA HORAS
void horas(void){
printf(lcd_putc,"fConf.Horas:
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
hour++; //SI ->

incremento hour
switch(hour){ //limites...
case 0x0A: hour=0x10;break;
case 0x1A: hour=0x20;break;
case 0x24: hour=0x00;
}

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

//muestra por lcd day


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

lcd
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA 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

Nos vemos en los bares!!!!!

vszener RE: Ejemplitos en C para 16F648A


Moderador « Respuesta #98 : 13 de Septiembre de 2005, 10:14:00 »
Local
PIC24H Buenas!!!!jeje hoy hace un mes que inicie este post!!!!y ya van 33
ejemplitos creo!!!!!jeje ya sabemos encender y apagar led"s de casi todas
Desconectado las formas habidas por haber, sabemos utilizar display"s de 7seg(solos,
multiplexados,de anodo comun, de catodo comun,bcd.....), sabemos
Sexo: utilizar lcd 2x16, sabemos leer y escribir en eeprom externa e interna,
España sabemos manejar un rtc.....jeje no veas en un mes lo que ha dado de si!jeje
bien pues ahora el proposito es interaccionar con el PC, es decir
Mensajes: "enchufar" el PIC al PC, debemos saber que tenemos tener en cuenta la
2380 compatibilidad de tensiones de los pines del pic con las del puerto RS232
a tratar!para ello usaremos un dispositivo llamado MAX232 que adapta
las tensiones adecuandolas al PC y al PIC, aqui el enlace al MAX232 de
dallas semiconductor:
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/1798
Desde esta dire os explican el funcionamiento del MAX232:
http://www.x-robotics.com/
VsZeNeR
!!!

En línea

Nos vemos en los bares!!!!!

vszener RE: Ejemplitos en C para 16F648A


Moderador « Respuesta #99 : 13 de Septiembre de 2005, 10:18:00 »
Local
PIC24H Holaa!!!!!aqui esta el ejemplito de interaccionar el pic con el pc, bien
consiste en mostrar por lcd un mensaje y por el pc otro:
Desconectado ////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
Sexo: // 11/Septiembre/05
España //
// Programa: Comunicacion PC via RS232
Mensajes: // Version: 0.0
2380 //
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) en la primera linea la
// frase "hola mundo " y en la segunda linea "VsZeNeR"05". Se
muestra el
VsZeNeR // mismo mensaje por el PC. Tener en cuenta que hay que poner la
directiva
// NOLVP para que el pin B4 sea de salida.
//
// Conexiones: B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// A0 -> T1IN MAX232
// A1 -> R1OUT MAX232
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h> //pic a utilizar
#fuses
XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //ordenes
para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) //manejo del
RS232
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd

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

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

Decir que en la simulacion con PROTEUS, se utilizado el MAX232, esto


no hace falta para la simulacon ya que directamente podriamos haber
conectado las patitas Tx y Rx al correspondiente del virtual terminal de
PROTEUS, se ha añadido para se vea su conexion del pic al pc......ya hace
un mes que inicie el post!!!!!oleeeee!!!!

En línea

RE: Ejemplitos en C para 16F648A


« Respuesta #101 : 16 de Septiembre de 2005, 07:58:00 »

Buenas!!!!Bien, el siguiente ejemplito es basado el un programa anteriormente realizado, es


un reloj-calendario(ds1302) peor esta vez por el PC, es decir anteriormente hicimos un
reloj-calendario pero en una lcd y esta vez es usando el RS232, la programacion se ha
modificado muy poco, solamente se ha mejorado el modo configurar horas-fecha para que
no diera tantos saltos y poquito mas(intentare con mas tiempo revisarlo entero para hacer
un codigo optimo), aqui el programa:

////////////////////////////////////////////////////////////////////////////////////
// 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)
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#use delay(CLOCK=4000000) //Fosc=4Mhz
#fuses
HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT,NOMCLR //comandos
para el programador
#use standard_io(a)
#use standard_io(b)
#use rs232(baud=9600, xmit=PIN_B1, rcv=PIN_B2, FORCE_SW) //manejo del RS232
#define RTC_SCLK PIN_A1 //definimos pin"s...
#define RTC_IO PIN_A2
#define RTC_RST PIN_A0 //...de conexion de la rtc ds1302
#include <ds1302.c> //libreria de rtc ds1302

///VARIABLES GLOBALES
byte day,mth,year,dow,hour,min,sec; //variabes para ds1302
byte menu=0,flag=0,var=2; //variables para menu configurar

///DEFINICION DE FUNCIONES
void configurar(void);
void horas(void);
void minutos(void);
void dia(void);
void mes(void);
void anio(void);
void beep(void);

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 130ms aprox?
var--; //SI -> decremento var...
if(var==0)
var=2; //...ajuste fino de 130ms aprox
flag=0; //reset flag para contar 130ms aprox
rtc_get_date(day,mth,year,dow); //coge dia,mes,año
rtc_get_time(hour,min,sec ); //coge hora,minuto,segundo
printf("fFecha: %2X/%2X/%2X
Hora: %2X:%2X:%2X",day,mth,year,hour,min,sec); //lcd
}

set_timer0(0); //reset TMR0


flag++; //incremento variable flag
}

///PROGRAMA
void main(void){

enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada


setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion
TMR0
set_timer0(0); //carga TMR0

rtc_init(); //inicializa rtc

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();
}
}

do{ //controla pulsador...


if(!input(PIN_A3)){
while(!input(PIN_A3)){}
menu++;
flag++;
if(menu>5)
menu=0;
}
if(!input(PIN_A5)) //controla pulsador...
flag++; //..."Conf/Ok"
}while(!flag); //.."Up"

flag=0;
}while(menu<6);

menu=0; //actualiza indices menu


rtc_set_datetime(day,mth,year,dow,hour,min); //nueva hora,minuto,...
enable_interrupts(GLOBAL); //activadas interrupciones
set_timer0(0); //carga TMR0
}
///FUNCION CONFIGURA HORAS
void horas(void){
printf("fConf.Horas:
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por v.terminal
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("
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por v.terminal
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA MINUTOS
void minutos(void){
printf("fConf.Minutos:
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por v.terminal
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("
Hora: %2X:%2X:%2X",hour,min,sec); //muestra por v.terminal
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA DIAS
void dia(void){
printf("fConf.Dias:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por v.terminal
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("fConf.Dias:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por v.terminal
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA MES
void mes(void){
printf("fConf.Mes:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por v.terminal
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
mth++; //SI -> incremento mth
switch(mth){ //limites...
case 0x0A: mth=0x10;break;
case 0x13: mth=0x01;
} //...mth
printf("fConf.Mes:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por v.terminal
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA AÑOS
void anio(void){
printf("fConf.Año:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por v.terminal
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("fConf.Año:
Fecha: %2X/%2X/%2X",day,mth,year); //muestra por v.terminal
}
}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
}

RE: Ejemplitos en C para 16F648A


« Respuesta #104 : 18 de Septiembre de 2005, 04:56:00 »

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

kbd_init(); //inicializa teclado

port_b_pullups(TRUE); //necesario para teclado

puts("Manejo del teclado 3x4 VsZeNeR"05" ); //inicio...


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

for( ; ; ) { //bucle...
do{ //hacer hasta...
c=kbd_getc(); //recogemos tecla pulsada
}while(c==""); //...que no se pulse tecla

printf("" ); //retrocede una posicion(borra ultima tecla)


printf("%c",c); //mensaje por v.terminal
} //...infinito
}

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:

RE: Ejemplitos en C para 16F648A


« Respuesta #107 : 20 de Septiembre de 2005, 11:02:00 »

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_init(); //inicializa lcd

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

lcd_putc(c); //muestra tecla pulsada en lcd


lcd_putc("" ); //retrocede una posicion(escribe encima de la ultima tecla mostrada)
} //...infinito

RE: Ejemplitos en C para 16F648A


« Respuesta #111 : 22 de Septiembre de 2005, 08:08:00 »

Buenas!!!el programa de hoy consiste en manejar un pokitin mas el lcd y el keypad de


forma dinamica...esta vez vamos a usar un keypad de 4x4 pero nos va hacer falta modificar
en algo la libreria que os puse en algun mensaje anterior ya que necesitamos adaptarla al
teclado que aparece en PROTEUS, decir que vamos a usar un teclado el cual no viene
instalado en PROTEUS sino que os lo debeis bajar de los enlaces que os puse en un
anterior post...ahi si vienen ya que yo lo he sacado de esos enlaces(es necesario ya que sino
lo haceis PROTEUS dara un error de librerias....), bien el programita consiste en hacer una
llave electronica, es decir nosotros introducimos un password/clave la cual se almacenara
en una variable y despues tendremos un menu donde podremos cambiar la clave o
comprobarla con una introducida por teclado....decir que la programacion se ha realizado
caracter por caracter al introducir y comprobar la clave por lo que el codigo es mas extenso,
peor creo que asi es mas ilustrativo.....ya en la revision de este ejemplito intentaremos
modificarlo para hacerlo mas optimo!aqui el programita ke me enrollo jeje!!!:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 21/Septiembre/05
//
// Programa: Clave
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
// Notas: Se pide por lcd una clave a introducir, despues hay un menu de opciones:
// 0->Introducir password
// 1->Cambiar clave
// Los caracteres * o # son fin de instruccion/accion, si estamos en cambiar clave
// o en comprobar clave, cada vez que se pulsen dichos caracteres se terminara
// la accion. Para introducir clave, tecleamos caracteres hasta pulsar * o # y la clave
// ya estara almacenada. Para comprobar clave, tecleamos caracteres hasta pulsar * o #
// y se comprobara la clave introducida con la nuestra almacenada.
// Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
salida.
// Se utiliza variables globales:
// ·c-> almacena letra pulsada del keypad
// ·limit -> longitud de clave
// ·i -> contador
// ·var -> 1->Clave incorrecta
// ·clave[16] -> almacena clave(maximo 16 caracteres)
//
// Conexiones: B0 -> D0 LCD/Columna 1 keypad
// B1 -> D1 LCD/Columna 2 keypad
// B2 -> D2 LCD/Columna 3 keypad
// B3 -> D3 LCD/Columna 4 keypad
// B4 -> D4 LCD/Fila A keypad
// B5 -> D5 LCD/Fila B keypad
// B6 -> D6 LCD/Fila C keypad
// B7 -> D7 LCD/Fila D keypad
// A0 -> RS LCD
// A1 -> RW LCD
// A2 -> E LCD
// A3 -> Led red
// A5 -> Led green
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h> //pic a utilizar
#fuses
XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT,NOMCLR //ordenes para
el programador
#use delay (clock=4000000) //Fosc=4Mhz
#include<kbd4x4ABCD_PROTEUS.c> //libreria manejo keypad
#include<lcd2.c> //libreria manejo lcd 8bits
#use fixed_io(a_outputs=PIN_A3,PIN_A5)
#use fast_io(B)

///DEFINICION DE FUNCIONES
void nueva_clave(void); //funcion que cambia clave
void comprueba_clave(void); //funcion que comprueba clave

///VARIABLES GLOBALES
char clave[16],c,limit;
signed char i;
boolean var=0;

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

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

nueva_clave(); //introducimos clave

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

if(c=="1") //ve a introducir nueva clave


nueva_clave();
if(c=="0") //ve a comprobar clave
comprueba_clave();
} //...infinito
}
///FUNCION CAMBIAR CLAVE
void nueva_clave(void){
lcd_putc("fNueva clave:
" ); //presentacion
for(i=0;i<16;i++){
do{ //espera hasta...
c=kbd_getc();
}while(c==0); //...pulsar una tecla

if(c=="*" || c=="#"){ //si se pulsa * o # se sale de la funcion


if(i==0){ //no se sale...
lcd_putc("
Escribe una!!!" );
delay_ms(500);
lcd_putc("
" );
lcd_gotoxy(1,2);
i=-1;
continue; //...hasta poner una clave valida
}
break; //salir de funcion nueva_clave
}
lcd_putc("*" );
limit=i+1; //longitud de la clave
clave[ i ]=c; //almacena clave(maximo 16 caracteres)
}
}
///FUNCION COMPROBAR CLAVE
void comprueba_clave(void){
lcd_putc("fIntroduce clave:
" ); //presentacion

for(i=0; ;i++){ //bucle no sale...


do{ //espera hasta...
c=kbd_getc();
}while(c==0); //...pulsar una tecla

lcd_putc("*" );

if(c=="#" || c=="*"){ //si se pulsa * o # se sale de la funcion


if(i==0){ //no se sale...
lcd_putc("
Escribe una!!!" );
delay_ms(500);
lcd_putc("
" );
lcd_gotoxy(1,2);
i=-1;
continue;
} //...poner una clave valida
if(i!=limit) //para ser correcto debe tener tb longitud correcta
var=1;
break; //salimos si se pulsa tecla * o #
}

if(c!=clave[ i ]) //comprobacion de caracteres correctos


var=1; //No es correcto->clave incorrecta
} //...hasta pulsar * o #

if(var>0){ //Clave incorrecta


lcd_putc("fClave
Incorrecta!" );
output_high(PIN_A3);
delay_ms(500);
output_low(PIN_A3);
}
else{ //Clave correcta
lcd_putc("fClave
Correcta!" );
output_high(PIN_A5);
delay_ms(500);
output_low(PIN_A5);
}
var=0; //reset var
}

RE: Ejemplitos en C para 16F648A


« Respuesta #113 : 24 de Septiembre de 2005, 06:58:00 »

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.

RE: Ejemplitos en C para 16F648A


« Respuesta #114 : 27 de Septiembre de 2005, 10:26:00 »

Buenas!!!jeje despues de las minis-vacaciones que me he dado(isla magica....por cierto


muy bonito las actuaciones en la calle y los teatros, hacer un examen pufff jeje aunque
aprovado seguro!jeje...)he vuelto con mas programas!jeje, bien el siguiente programa
vamos a trabajar con un periferico interno del PIC, en este caso con la interrupcion externa
de la patita RB0, por dicha patita se recibira una señal cuadrada de 1Hz,eso significa que
cada 1s habra un nivel logico alto(se puede programar para que atendamos a la interrupcion
en nivel logico bajo) el cual producira una interrupcion, en dicha llamada de la interrupcion
se mostrara por el porta en codigo BCD numeros del 0 al 9 y su correspondiente conversion
a binario. Aqui el codigo:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 27/Septiembre/05
//
// Programa: Contador BCD y binario del 0 al 9
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Contador 0 al 9 usando interrupcion externa por el pin B0. Tener
// en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
// salida.
//
// Conexiones: A0 -> A 74247/Led D1
// A1 -> B 74247/Led D2
// A2 -> C 74247/Led D3
// A3 -> D 74247/Led D4
// B0 -> Interrupcion externa
// BCD:
// d c b a NUM
// 0000 0
// 0001 1
// 0010 2
// 0011 3
// 0100 4
// 0101 5
// 0110 6
// 0111 7
// 1000 8
// 1001 9
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(b)
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)

///VARIABLES GLOBALES
char i=0; //contador para tabla BCD
char
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,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

for( ; ; ){} //bucle infinito esperando interrupcion


}

RE: Ejemplitos en C para 16F648A


« Respuesta #133 : 29 de Septiembre de 2005, 13:02:00 »

Buenas!!!!el ejemplo de hoy se trata de manejar el periferico interno ccp(modulos de


captura: comparacion y modulacion de anchuras de pulsos), el cual puede actuar de las
siguientes maneras: Como captura, como comparacion o como modulacion de anchura de
pulsos(PWM). En este ejemplo lo vamos a configurar como comparacion. Es decir por la
patita RB3/ccp1 conectaremos una señal de pulsos la cual generara una interrupcion cada
flanco de subida(un 1 logico por dicho pin) pero si pulsamos el boton conectado a la patita
RB0/int generara una interrupcion externa(ya programada e el ejemplo anterior...)la cual
cambiara el modo de comparacion, pasando este a capturar y generar una interrupcion por
el pin RB3/ccp1 cada flanco descendente es decir de bajada(un 0 logico por dicho
pin)...bueno y la interrupcion lo que hace es simplemente aumentar indice de contador para
mostrar numeros del 0 al 9 en bcd....lo importante es saber programar los perifericos! aqui
el programa:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 29/Septiembre/05
//
// Programa: Uso del CCP1 como comparador ascendente/descendente
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.20 Simulador: Proteus 6.7sp3
//
// Notas: Contador 0 al 9 usando interrupcion ccp1 por el pin B3/ccp1. Si no pulsamos
// el boton, la cuenta del contador sera cada flanco ascendente que entre por
// la patita RB3/ccp1, en cambio si pulsamos el boton, la cuenta del contador sera
// cada flanco descendente que reciba el pin RB3/ccp1. Tener en cuenta que hay que
// poner la directiva NOLVP para que el pin B4 sea de salida. Aparte se a programado
// mediante la instruccion INTRC el oscilador interno de 4MHz asi tendremos las
// patitas RA7 Y RA6 libres.
//
// Conexiones: A0 -> A
// A1 -> B
// A2 -> C
// A3 -> D
// B0 -> Interrupcion externa
// B3 -> Interrupcion ccp1
// BCD:
// d c b a NUM
// 0000 0
// 0001 1
// 0010 2
// 0011 3
// 0100 4
// 0101 5
// 0110 6
// 0111 7
// 1000 8
// 1001 9
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(b)
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)

///VARIABLES GLOBALES
char i=0; //contador para tabla BCD
char
tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1
001};//BCD 0-9
boolean var=0; //variable para captura en alto(var=0) o en bajo(var=1)

///LLAMADA FUNCION INTERRUPCION


#INT_CCP1
void ccp1()
{
if(i>9) //¿se ha mostrado digito 9?
i=0; //SI -> restaura valor indice(para mostrar digito 0)
output_a(tabBCD[ i ]); //muestra por porta digito 7 segmentos
i++; //incremento contador indice tabBCD
}

#INT_EXT
void IntRB0()
{
var=!var; //complementa valor de modo
if(!var) //¿var!=0?
setup_ccp1(CCP_CAPTURE_RE); //SI -> ccp1 modo captura configurado flanco
ascendente
else
setup_ccp1(CCP_CAPTURE_FE); //NO -> ccp1 modo captura configurado flanco
descendente

}
///PROGRAMA
void main(void)
{
setup_ccp1(CCP_CAPTURE_RE); //ccp1 modo captura configurado flanco ascendent
enable_interrupts(int_ext); //activar interrupcion externa
ext_int_edge(H_TO_L); //configuracion:interrupcion cuando señal esta en baja
enable_interrupts(INT_CCP1); //activar interrupcion en ccp1
enable_interrupts(GLOBAL); //todas las interrupciones desactivadas

for( ; ; ){} //bucle infinito esperando interrupcion


}

Fijarse bien en la simulacion en PROTEUS en la patita RB3/ccp1 cuando hay un cuadrado


rojo o azul, el rojo indica entrada en alta y el azul en baja asi pulsando el boton sabreis
como esta configurado el ccp1 en comparacion en flanco ascendente o descendente.

RE: Ejemplitos en C para 16F648A


« Respuesta #137 : 30 de Septiembre de 2005, 12:22:00 »

Buenas!!! al final me he puesto manos a la obra y he realizado la animacion de carga de una


bateria....jeje, para ello se diseña los caracteres de la bateria(al 0%, al 20%, al 40%, al 60%,
al 80% y al 100%), decir que solamente he utilizado una posicion de memoria de la
GCRAM(aunque cada animacion ocupa 8 posiciones), he ido machacando valores.......aqui
el codigo:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 30/Septiembre/05
//
// Programa: Bateria
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) la animacion de carga de
// una bateria, para ello se han 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

///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};
///PROGRAMA
void main(void)
{
lcd_init(); //inicializa lcd

recarga(); //crea 1 animacion

lcd_gotoxy(5,1); //presentacion...
lcd_putc("Cargando
VsZeNeR"05" ); //...inicial

for( ; ; ){ //bucle...
lcd_gotoxy(2,1); //donde se va a mostrar la animacion de la bateria
lcd_send_byte(1,0); //muestra animacion
delay_ms(250);
cont++; //apunta a siguiente animacion
recarga(); //crea animacion
} //...infinito
}

///FUNCION ENCARGADA DE CREAR ANIMACION


void recarga(void){
char i; //indice para for

lcd_send_byte(0,0x40); // se escribe en la GCRAM posicion 0x40

switch(cont){ //selecciona animacion


case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,bat0[ i ]);
break;
case 1: for(i=0;i<8;i++) //bateria al 20%
lcd_send_byte(1,bat20[ i ]);
break;
case 2: for(i=0;i<8;i++) //bateria al 40%
lcd_send_byte(1,bat40[ i ]);
break;
case 3: for(i=0;i<8;i++) //bateria al 60%
lcd_send_byte(1,bat60[ i ]);
break;
case 4: for(i=0;i<8;i++) //bateria al 80%
lcd_send_byte(1,bat80[ i ]);
break;
case 5: for(i=0;i<8;i++) //bateria al 100%
lcd_send_byte(1,bat100[ i ]);
cont=0; //restaura indice de crear animacion
}
}

RE: Ejemplitos en C para 16F648A


« Respuesta #139 : 01 de Octubre de 2005, 11:02:00 »

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

///DECLARACION DE VARIABLES GLOBALES


char cont=0,lim=1; //contador que apunta al nuevo caracter diseñado
int8 cocod1[]={0b00001111,0b00011110,0b00011100,0b00011000},
cocod2[]={0b00000000,0b01111111,0b11111111,0b11111100},
cocoi1[]={0b00011110,0b00001111,0b00000111,0b00000011},
cocoi2[]={0b00000000,0b01111111,0b11111111,0b00000011};

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

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


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

for( ; ; ){ //bucle...
recarga(); //funcion para el movimiento del comecocos
if(lim>16) //limites...
lim=16;
if(lim<1)
lim=1; //...de lcd
lcd_putc("f
VsZeNeR"05" );
lcd_gotoxy(lim,1); //movimiento de la animacion
lcd_send_byte(1,0); //muestra animacion
} //...infinito
}

///FUNCION ENCARGADA DE CREAR ANIMACION


void recarga(void){
signed char i; //indice para for

lcd_send_byte(0,0x40); // se escribe en la GCRAM posicion 0x40

switch(getc() ){ //selecciona animacion


case "4": if(!cont){ //movimiento hacia izquierda
for(i=0;i<4;i++) //boca abierta
lcd_send_byte(1,cocoi1[ i ]);
for(i=3;i>-1;i--)
lcd_send_byte(1,cocoi1[ i ]);
cont++;
}
else{ //boca cerrada
for(i=0;i<4;i++)
lcd_send_byte(1,cocoi2[ i ]);
for(i=3;i>-1;i--)
lcd_send_byte(1,cocoi2[ i ]);
cont=0;
}
lim--; //apunta siguiente posicion a mostrar animacion en lcd
break;
case "6": if(!cont){ //movimiento hacia derecha
for(i=0;i<4;i++) //boca abierta
lcd_send_byte(1,cocod1[ i ]);
for(i=3;i>-1;i--)
lcd_send_byte(1,cocod1[ i ]);
cont++;
}
else{ //boca cerrada
for(i=0;i<4;i++)
lcd_send_byte(1,cocod2[ i ]);
for(i=3;i>-1;i--)
lcd_send_byte(1,cocod2[ i ]);
cont=0;
}
lim++; //apunta siguiente posicion a mostrar animacion en lcd
}
}

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
//////////////////////////////////////////////////////////////////////////////////

#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
void cara(void);//carita creada por monopic

///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};
int8 triste[]={0b11011,0b00000,0b11011,0b11011,0b00000,0b01110,0b10001};
//mios monopic

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

recarga(); //crea 1 animacion


lcd_gotoxy(5,1); //presentacion...
lcd_putc("Cargando
VsZeNeR"05" ; //...inicial

for(; { //bucle...
lcd_gotoxy(2,1); //donde se va a mostrar la animacion de la bateria
lcd_send_byte(1,0); //muestra animacion
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
}

///FUNCION ENCARGADA DE CREAR ANIMACION


void recarga(void){
char i; //indice para for

lcd_send_byte(0,0x40); // se escribe en la GCRAM posicion 0x40

switch(cont){ //selecciona animacion


case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,bat0);
break;
case 1: for(i=0;i<8;i++) //bateria al 20%
lcd_send_byte(1,bat20);
break;
case 2: for(i=0;i<8;i++) //bateria al 40%
lcd_send_byte(1,bat40);
break;
case 3: for(i=0;i<8;i++) //bateria al 60%
lcd_send_byte(1,bat60);
break;
case 4: for(i=0;i<8;i++) //bateria al 80%
lcd_send_byte(1,bat80);
break;
case 5: for(i=0;i<8;i++) //bateria al 100%
lcd_send_byte(1,bat100);
cont=0; //restaura indice de crear animacion
}
}

void cara(void){
char i;
lcd_send_byte(0,0x48);

switch(cont){ //selecciona animacion


case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,triste);
break;
case 3: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,feliz);
break;
cont=cont; }
}

RE: Ejemplitos en C para 16F648A


« Respuesta #144 : 03 de Octubre de 2005, 07:50:00 »

Escrito originalmente por monopic

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
//////////////////////////////////////////////////////////////////////////////////

#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
void cara(void);//carita creada por monopic

///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};
int8 triste[]={0b11011,0b00000,0b11011,0b11011,0b00000,0b01110,0b10001};
//mios monopic

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

recarga(); //crea 1 animacion


lcd_gotoxy(5,1); //presentacion...
lcd_putc("Cargando
VsZeNeR"05" ; //...inicial

for(; { //bucle...
lcd_gotoxy(2,1); //donde se va a mostrar la animacion de la bateria
lcd_send_byte(1,0); //muestra animacion
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
}

///FUNCION ENCARGADA DE CREAR ANIMACION


void recarga(void){
char i; //indice para for

lcd_send_byte(0,0x40); // se escribe en la GCRAM posicion 0x40

switch(cont){ //selecciona animacion


case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,bat0);
break;
case 1: for(i=0;i<8;i++) //bateria al 20%
lcd_send_byte(1,bat20);
break;
case 2: for(i=0;i<8;i++) //bateria al 40%
lcd_send_byte(1,bat40);
break;
case 3: for(i=0;i<8;i++) //bateria al 60%
lcd_send_byte(1,bat60);
break;
case 4: for(i=0;i<8;i++) //bateria al 80%
lcd_send_byte(1,bat80);
break;
case 5: for(i=0;i<8;i++) //bateria al 100%
lcd_send_byte(1,bat100);
cont=0; //restaura indice de crear animacion
}
}

void cara(void){
char i;
lcd_send_byte(0,0x48);

switch(cont){ //selecciona animacion


case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,triste);
break;
case 3: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,feliz);
break;
cont=cont; }
}

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

RE: Ejemplitos en C para 16F648A


« Respuesta #150 : 05 de Octubre de 2005, 22:06:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f877a.h> //pic a utilizar


#fuses XT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE
#include <lcd420.c> //libreria manejo de la lcd

///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

recarga(); //crea 1 animacion


lcd_gotoxy(6,1); //presentacion...
lcd_putc("Monopic " ; //...inicial

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
}

///FUNCION ENCARGADA DE CREAR ANIMACION


void recarga(void){
char i; //indice para for

lcd_send_byte(0,0x48); // se escribe en la GCRAM posicion 0x40

switch(cont){ //selecciona animacion


case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,bat0);
break;
case 1: for(i=0;i<8;i++) //bateria al 20%
lcd_send_byte(1,bat20);
break;
case 2: for(i=0;i<8;i++) //bateria al 40%
lcd_send_byte(1,bat40);
break;
case 3: for(i=0;i<8;i++) //bateria al 60%
lcd_send_byte(1,bat60);
break;
case 4: for(i=0;i<8;i++) //bateria al 80%
lcd_send_byte(1,bat80);
break;
case 5: for(i=0;i<8;i++) //bateria al 100%
lcd_send_byte(1,bat100);
cont=0; //restaura indice de crear animacion
}
}

void cara(void){
char i;
lcd_send_byte(0,0x40);

switch(cont){ //selecciona animacion


case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,triste);
break;
case 3: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,feliz);
break;
cont=cont; }
}

void caminante(void){
char i; //indice para for

lcd_send_byte(0,0x50); // se escribe en la GCRAM posicion 0x56

switch(cont){ //selecciona animacion


case 0: for(i=0;i<8;i++) //bateria al 0%
lcd_send_byte(1,cam0);
break;
case 1: for(i=0;i<8;i++) //bateria al 20%
lcd_send_byte(1,cam1);
break;
case 2: for(i=0;i<8;i++) //bateria al 40%
lcd_send_byte(1,cam2);
break;
case 3: for(i=0;i<8;i++) //bateria al 60%
lcd_send_byte(1,cam3);
break;
case 4: for(i=0;i<8;i++) //bateria al 80%
lcd_send_byte(1,cam4);
break;
case 5: for(i=0;i<8;i++) //bateria al 100%
lcd_send_byte(1,cam5);
cont=0; //restaura indice de crear animacion
}
}

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#use delay(CLOCK=4000000) //Fosc=4Mhz
#fuses HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT //comandos para
el programador
#fuses INTRC //oscilador interno
#use standard_io(a)
#use standard_io(b)
#define use_portb_lcd TRUE //utilizar el port b para lcd
#define DS1620_DQ PIN_A0 //declaracion de pins...
#define DS1620_CLK PIN_A1
#define DS1620_RST PIN_A2 //...para el ds1620
#include <ds1620.c> //libreria del termometro ds1620
#include <lcd.c> //libreria de lcd

///PROGRAMA
void main(void){
char i;
int8 grado[]={0b00000110,0b00001001,0b00000110};

lcd_init(); //inicializa lcd

lcd_putc(" Termometro
VsZeNeR"05" ); //presentacion...
delay_ms(800);
lcd_putc("f" ); //...inicial

lcd_putc(" VsZeNeR"05
Temperatura:" ); //pantalla temp

lcd_send_byte(0,0x40); // se escribe en la GCRAM posicion 0x40


for(i=0;i<3;i++) //dibujo del simbolo grado º
lcd_send_byte(1,grado[ i ]);
lcd_gotoxy(16,2); //donde se va a mostrar º
lcd_send_byte(1,0); //muestra animacion

ds1620_init(); //inicializa ds1620

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

Aqui la primera prueba con la libreria ds1620.c!

LIBRERIA OBSOLETA

RE: Ejemplitos en C para 16F648A


« Respuesta #159 : 03 de Noviembre de 2005, 03:12:00 »

Holaaaaa!!!!jeje bien, el programa de hoy consiste en manejar el periferico CCP1


configurado como PWM, decir que el PWM consiste en obtener a frecuencias
constantes(por lo tanto periodo constante) una anchura de pulso variable(la cual nosotros
programamos), en este caso, la anchura de pulsos para las frecuencias constantes es siempre
la misma, la mitad del periodo, y las frecuencias las obtenemos mediante el preescaler del
TMR2....aqui el ejemplito:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 2/Noviembre/05
//
// Programa: Uso del CCP1 como PWM
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.235
// Entorno IDE: MPLAB IDE v7.22 Simulador: Proteus 6.7sp3
//
// Notas: Usamos el modulo CCP1 como PWM, para ello configuramos el TMR2 de sus
tres
// formas distintas mediante el preescales(1,4,16) que nos dara distintas frecuencias.
// El ciclo viene determinado por (1/clock)*4*t2div*(periodo+1), donde en este caso
// clock=4MHz y periodo=127.
// Frecuencias:
// ·T2_DIV_BY_1 -> 128us -> 7,81KHz
// ·T2_DIV_BY_4 -> 512us -> 1,95KHz
// ·T2_DIV_BY_16 -> 2,05ms -> 487,8Hz
// En este programa tendremos un nivel alto a la mitad de la frecuencia obtenida
mediante
// la relacion valor*(1/clock)*t2div donde valor=%nivel alto del pulso
// Anchura del pulso(Duty):
// ·128us -> 64us -> 64us/(1*(1/4000000)) = 256
// ·512us -> 256us -> 256us/(4*(1/4000000)) = 256
// ·2,05ms -> 1,02ms -> 1,02ms/(16*(1/4000000)) = 256
//
// Conexiones: B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// B3 -> Canal 1 osciloscopio
// A0 -> Boton
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


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

///PROGRAMA
void main(void)
{
char opcion=0; //variable encargada de mostrar menu de frec

setup_ccp1(CCP_PWM); //ccp1 modo PWM

lcd_init(); //inicializa lcd

cambia_frec(opcion); //muestra primera frec

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

///FUNCION ENCARGADA DE CAMBIAR LA FRECUENCIA POR CCP1


void cambia_frec(char menu)
{
lcd_putc("f" );
switch(menu){ //menu para eleccion de frecuencias
case 0: setup_timer_2(T2_DIV_BY_1, 127, 1); //128us -> 7,81kHz
set_pwm1_duty(256); //64us/(1*(1/4000000)) = 256
lcd_putc(" VsZeNeR"05
Frec=7,81KHz" );
break;
case 1: setup_timer_2(T2_DIV_BY_4, 127, 1); //512us -> 1,95kHz
set_pwm1_duty(256); //256us/(4*(1/4000000)) = 256
lcd_putc(" VsZeNeR"05
Frec=1,95KHz" );
break;
case 2: setup_timer_2(T2_DIV_BY_16, 127, 1); //2,05ms -> 487,8Hz
set_pwm1_duty(256); //1,02ms/(16*(1/4000000)) = 256
lcd_putc(" VsZeNeR"05
Frec=487,8Hz" );
}
}

Decir que la frecuencia que obtenemos son de 7,81kHz,1,95kHz y 487,8Hz y se cambia


pulsando en boton que esta en el pin A0. Observar en la simulacion PROTEUS en el
osciloscopio las divisiones del Timerbase para ver y comprobar que la anchura de pulso es
la calculada y por o tanto la deseada. Aqui dejo un enlace a un post donde se habla del tema
del PWM y se explica en que consiste

RE: Ejemplitos en C para 16F648A


« Respuesta #163 : 04 de Noviembre de 2005, 08:53:00 »

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("

Tipo senal numero: " ;


gets(string);
tipo_s=atol(string);
output_d(tipo_s|0b10110000);
if(tipo_s>3){
printf("

Opcion incorrecta. Tipo de señal fijada: Salida nula." ;


tipo_s=0;
}
break;

case 2:
printf("

Introduzca número entre 128 y 255

Frecuencia: " ;
gets(string);
tiempo=atol(string);
if(tiempo<128||tiempo>255){
printf("

Opcion incorrecta. Tiempo fijado a 128." ;


tiempo=128;
}
break;

case 3:
printf("

Elija Canal (1, 2, 3 o 4): " ;


gets(string);
canal=atol(string);
output_d(canal|0b10100000);
if(canal>4){
printf("

Opcion incorrecta. Canal fijado a 1." ;


canal=1;
}
break;

default:
printf("
Opción incorrecta. Introduzca 1 o 2" ;
}

printf("

Que desea cambiar?" ;


printf("

1 -> Tipo de senal


2 -> Frecuencia
3 -> Canal de salida" ;
printf("

Opcion numero: " ;


}

#int_timer2 //Funcion a la que se llama periodicamente


clock_isr() { // the RTCC (timer0) overflows (255->0).
if (reloj == 0){
reloj = 1;
output_high(PIN_A3);}
else{
reloj = 0;
output_low(PIN_A3);

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 retardo(int n) { // retardo de n x 100ms ; 0 <= n => 255


for (; n!=0; n--)
delay_ms(100);
}

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(canal|0b10100000); //Indicamos el canal en el display


retardo(4);

output_d(tipo_s|0b10110000);

retardo(6); //Indicamos el tipo de señal en el display

if(y==0){
printf("
Que desea cambiar?" ;
printf("

1 -> Tipo de senal


2 -> Frecuencia
3 -> Canal de salida" ;
printf("

Opcion numero: " ;


}
y=1;

}
}
}

/*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;
}

RE: Ejemplitos en C para 16F648A


« Respuesta #169 : 07 de Noviembre de 2005, 01:34:00 »

Buenas!!!bien el ejemplito de hoy consiste en manejar igualmente que el programa anterior


el modulo CCP1 en modo PWM, pero en vez de ser constante como el anterior a 50% la
anchura de pulso, se ha programado para que sea variable a 50% y al 75%, tambien este
programa pretende aparte de manejar dicho modulo, la utilizacion y creacion de archivos .h,
los cuales haran que el programa principal main este mas estructurado en tema codigo:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 6/Noviembre/05
//
// Programa: Uso del CCP1 como PWM al 50% y 75%
// Version: 1.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22 Simulador: Proteus 6.7sp3
//
// Notas: Usamos el modulo CCP1 como PWM, para ello configuramos el TMR2 de sus
tres
// formas distintas mediante el preescales(1,4,16) que nos dara distintas frecuencias.
// El ciclo viene determinado por (1/clock)*4*t2div*(periodo+1), donde en este caso
// clock=4MHz y periodo=127.
// Frecuencias:
// ·T2_DIV_BY_1 -> 128us -> 7,81KHz
// ·T2_DIV_BY_4 -> 512us -> 1,95KHz
// ·T2_DIV_BY_16 -> 2,05ms -> 487,8Hz
// La anchura de pulso en nivel alto depende de la relacion valor*(1/clock)*t2div
donde
// valor=%nivel alto del pulso.
// Anchura del pulso(Duty):
// *Para 50%:
// ·128us -> 64us -> 64us/(1*(1/4000000)) = 256
// ·512us -> 256us -> 256us/(4*(1/4000000)) = 256
// ·2,05ms -> 1,02ms -> 1,02ms/(16*(1/4000000)) = 256
// *Para 75%:
// ·128us -> 96us -> 96us/(1*(1/4000000)) = 384
// ·512us -> 384us -> 384us/(4*(1/4000000)) = 384
// ·2,05ms -> 1,54ms -> 1,54ms/(16*(1/4000000)) = 384
// Este programa tambien ha pretendido abarcar como crear archivos .h para
// que dicho codigo sea mas estructurado.
// Conexiones: B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// B3 -> Canal 1 osciloscopio
// A0 -> Boton
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#include<vs_fuses&demas.h> //libreria manejo fuses
#define use_portb_lcd TRUE //definir portb lcd
#include<lcd.c> //libreria manejo lcd
#include<vs_variables_globales.h> //libreria manejo de funciones
#include<vs_funciones.h> //libreria manejo de variables

///PROGRAMA
void main(void)
{
setup_ccp1(CCP_PWM); //ccp1 modo PWM
lcd_init(); //inicializa lcd

cambia_frec( ); //muestra primera frec


cambia_duty( ); //muestra primer ancho de pulso

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

if(!input(PIN_A1)){ //¿se ha pulsado el boton?


do{ //SI -> eliminar...
}while(!input(PIN_A1)); //...rebotes del boton
duty++; //apunta a siguiente frec
if(duty>1) //¿ya se han mostrado todas las anchuras de pulso?
duty=0; //SI -> resetea duty
cambia_duty(); //cambia anchura pulso
}
} //...infinito
}

Suerte!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #175 : 08 de Noviembre de 2005, 09:00:00 »

Buneasss!!!Bien el ejemplito de hoy trata de como insertar codigo ASM en nuestro


programa en C. Normalmente dicho codigo en ASM se hace para temporizaciones muy
finas, en este caso lo usaremos para gobernar el programa. Dicho programa realiza la
iluminacion sucesiva de 4 led"s mediante un decodificador, en ASM se ha programado
como manejar la variable cont para dar la instruccion a que led encender, el programa
tambien realiza a la vez, la cuenta ascendente de un numero bcd 0a9 mediante un bcd-7seg,
esta vez el codigo ASM se encarga de todo tanto de la variable como de mostrarlo por
pantalla....bueno no me enrrollo mas!!!jeje aqui el programa:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 8/Noviembre/05
//
// Programa: Led"s & display 7seg andodo comun
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22 Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra como incorporar codigo ASM en nuestro programa en C.
// Los modulos en asm manejan lso perifericos(uno es una barra de led"s, se
// iluminan hasta 4 led"s de forma consecutiva y vuelta a empezar, y el otro
// maneja un contador ascendente bcd de 0a9 y vuelta a empezar). Se usa los
// perifericos decodificador 4555 y bcd-7seg 74247.
// Conexiones: A0 -> A 4555 DEC
// A1 -> B 4555 DEC
// B4 -> A 74247
// B5 -> B 74247
// B6 -> C 74247
// B7 -> D 74247
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#use fast_io(a)
#use fast_io(b)
#byte PORTB=0x06 //definicion del PORTB
#byte STATUS=0x03 //definicion del STATUS

///PROGRAMA
void main(void)
{
char cont=0; //definicion de...
signed char bcd=-1; //...variables

set_tris_a (0x00); //porta salida


set_tris_b (0x00); //portb salida
for( ; ; ){ //bucle...
output_a(cont); //enciende led correspondiente

#asm //modulo asm para manejar bcd->7seg


movlw 1 ;w <- 1
addwf bcd,1 ;bcd <- w + bcd
movf bcd,0 ;w <- bcd
sublw 10 ;10- w
btfsc STATUS,2 ;¿se ha llegado a 9?
goto igual ;SI->ve a igual
swapf bcd,0 ;NO: w <- parte alta bcd
goto muestra ;ve a muestra
igual:
movlw 0 ;w <- 0
movwf bcd ;bcd <- w
muestra:
movwf PORTB ;PORTB <- w
#endasm //fin modulo asm para manejar bcd->7seg

delay_ms(450);

#asm //modulo asm para manejar led"s


movlw 1 ;w <- 1
addwf cont,1 ;cont <- w + cont
#endasm //fin modulo asm para manejar led"s

if(cont>3) //¿se ha mostrado el ultimo led?


cont=0; //SI-> reset cont
} //...infinito
}

Los perifericos que utilizamos, sus data sheet son:


Para el decodificador 4555:
http://pdf.alldatasheet.com/datasheet-pdf/view/26919/TI/CD4555BE.html
RE: Ejemplitos en C para 16F648A
« Respuesta #177 : 15 de Noviembre de 2005, 08:05:00 »

Buenas!!!!bien, el programa de hoy se basa en las interrupciones producidas al cambio de


estado por uno de los pines del portb dedicados a dicha tarea, los pines que generan
interrupcion son <4:7>. El programa en si realiza la secuencia de luces del coche fantastico
con 4 led"s hasta que uno de los pines <4:7> cambia de estado del port b, entonces genera
una interrupcion y realiza una secuencia de iluminacion de los led"s distinta, aparte cada
vez que estemos en una interrupcion se iluminara el led conectado al pin b0....bueno aqui el
codigo!:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 15/Noviembre/05
//
// Programa: Interrupcion debido a cambio de estado del portb <4:7>
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22 Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra como funciona la interrupcion de cambio de estado de
// algunos de los pines <4:7> del portb. Mientras no se pulse ningun boton,
// ilumina 4 led"s de forma consecutiva y viceversa, cuando se produce un
// cambio de estado en algunos de los pines del port b <4:7> genera interrupcion.
// Se ha programado de tal forma que sepa diferenciar que pin genera la interrupcion.
// Interrupcion:
// B4 -> Se produce la secuencia de iluminacion 1 vez
// B5 -> Se produce la secuencia de iluminacion 2 veces
// B6 -> Se produce la secuencia de iluminacion 3 veces
// B7 -> Se produce la secuencia de iluminacion 4 veces
// Conexiones: A0 -> led
// A1 -> led
// A2 -> led
// A3 -> led
// B0 -> led
// B4 -> boton
// B5 -> boton
// B6 -> boton
// B7 -> boton
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(a)
#use fast_io(b)
#byte port_b=0x06 //declaracion del puerto b

///DECLARACION DE FUNCIONES GLOBALES


void led(void); //funcion que ejecuta la iluminacion del porta dada la interrupcion

///DECLARACION DE VARIABLES GLOBALES


int last_b; //variable de almacenar el estado del portb

///LLAMADA FUNCION INTERRUPCION


#INT_RB
void IntPortB4_7( )
{
char cont=0; //contador para la iluminacion de la interrupcion
byte changes; //variable que almacena que pin a realizado la interrupcion

output_high(PIN_B0); //indicador interrupcion on

changes = last_b ^ port_b; //changes<-pin que genera la interrupcion

last_b = port_b; //last_b=como estaba el portb antes de interrupcion

if (bit_test(changes,4 )&& !bit_test(last_b,4)) //¿PIN_B4 genera interrupcion?


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

cont=0; //reset variable cont


output_low(PIN_B0); //indicador interrupcion off
}

///PROGRAMA
void main(void)
{
char led_on=0b0001; //led a iluminar

set_tris_b (0b11111110); //portb entrada menos pin B0 es salida

enable_interrupts(int_rb); //activar interrupcion rb4:7


enable_interrupts(GLOBAL); //activar interrupciones

do{ //bucle...

do{ //iluminacion hacia izquierda


output_a(led_on);
rotate_left(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,3)==0);

do{ //iluminacion hacia derecha


output_a(led_on);
rotate_right(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,0)==0);
last_b = input_b( );
}while(TRUE); //...infinito
}
///FUNCION QUE EJECUTA LA SECUENCIA DE ILUMINACION DEBIDO A
INTERRUPCION POR EL PORTB4:7
void led(void)
{
signed char i; //variable indice
int leds[2]={0b1001,0b0110}; //led"s

for(i=0;i<2;i++){ //led"s on fuera-dentro


output_a(leds[ i ]); //ilumino led"s correspondientes
delay_ms(150);
}
for(i=1;i>-1;i--){ //led"s on dentro-fuera
output_a(leds[ i ]); //ilumino led"s correspondientes
delay_ms(150);
}
}

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!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #193 : 23 de Diciembre de 2005, 06:17:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#use fast_io(a)
#use fast_io(b)

///DEFINICION VARIABLES GLOBALES


int letra[5],opcion=0;

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER1
void interrupcion()
{
switch(opcion){ //selecciona letra
case 0: letra[0]=0b00000001; //A
letra[1]=0b01110110;
letra[2]=0b01110110;
letra[3]=0b01110110;
letra[4]=0b00000001;
opcion++;
break;
case 1: letra[0]=0b01001001; //B
letra[1]=0b00110110;
letra[2]=0b00110110;
letra[3]=0b00110110;
letra[4]=0b00000000;
opcion++;
break;
case 2: letra[0]=0b00111110; //C
letra[1]=0b00111110;
letra[2]=0b00111110;
letra[3]=0b00111110;
letra[4]=0b01000001;
opcion++;
break;
case 3: letra[0]=0b01000001; //D
letra[1]=0b00111110;
letra[2]=0b00111110;
letra[3]=0b00111110;
letra[4]=0b00000000;
opcion++;
break;
case 4: letra[0]=0b00111110; //E
letra[1]=0b00110110;
letra[2]=0b00110110;
letra[3]=0b00110110;
letra[4]=0b00000000;
opcion++;
break;
case 5: letra[0]=0b01111110; //F
letra[1]=0b01110110;
letra[2]=0b01110110;
letra[3]=0b01110110;
letra[4]=0b00000000;
opcion++;
break;
case 6: letra[0]=0b01001110; //G
letra[1]=0b00110110;
letra[2]=0b00110110;
letra[3]=0b00111110;
letra[4]=0b01000001;
opcion++;
break;
case 7: letra[0]=0b00000000; //H
letra[1]=0b01110111;
letra[2]=0b01110111;
letra[3]=0b01110111;
letra[4]=0b00000000;
opcion++;
break;
case 8: letra[0]=0b00111110; //I
letra[1]=0b00111110;
letra[2]=0b00000000;
letra[3]=0b00111110;
letra[4]=0b00111110;
opcion++;
break;
case 9: letra[0]=0b01111111; //J
letra[1]=0b00000000;
letra[2]=0b00111110;
letra[3]=0b00101110;
letra[4]=0b01001111;
opcion++;
break;
case 10: letra[0]=0b00111110; //K
letra[1]=0b01011101;
letra[2]=0b01101011;
letra[3]=0b01110111;
letra[4]=0b00000000;
opcion++;
break;
case 11: letra[0]=0b00111111; //L
letra[1]=0b00111111;
letra[2]=0b00111111;
letra[3]=0b00111111;
letra[4]=0b00000000;
opcion++;
break;
case 12: letra[0]=0b00000000; //M
letra[1]=0b01111101;
letra[2]=0b01111011;
letra[3]=0b01111101;
letra[4]=0b00000000;
opcion++;
break;
case 13: letra[0]=0b00000011; //N
letra[1]=0b01011111;
letra[2]=0b01101111;
letra[3]=0b01110111;
letra[4]=0b00000011;
opcion++;
break;
case 14: letra[0]=0b00000011; //Ñ
letra[1]=0b01011101;
letra[2]=0b01101101;
letra[3]=0b01110101;
letra[4]=0b00000011;
opcion++;
break;
case 15: letra[0]=0b01000001; //O
letra[1]=0b00111110;
letra[2]=0b00111110;
letra[3]=0b00111110;
letra[4]=0b01000001;
opcion++;
break;
case 16: letra[0]=0b01111001; //P
letra[1]=0b01110110;
letra[2]=0b01110110;
letra[3]=0b01110110;
letra[4]=0b00000000;
opcion++;
break;
case 17: letra[0]=0b00000001; //Q
letra[1]=0b00011110;
letra[2]=0b00101110;
letra[3]=0b00111110;
letra[4]=0b01000001;
opcion++;
break;
case 18: letra[0]=0b01111001; //R
letra[1]=0b00110110;
letra[2]=0b01010110;
letra[3]=0b01100110;
letra[4]=0b00000000;
opcion++;
break;
case 19: letra[0]=0b01001110; //S
letra[1]=0b00110110;
letra[2]=0b00110110;
letra[3]=0b00110110;
letra[4]=0b00111001;
opcion++;
break;
case 20: letra[0]=0b01111110; //T
letra[1]=0b01111110;
letra[2]=0b00000000;
letra[3]=0b01111110;
letra[4]=0b01111110;
opcion++;
break;
case 21: letra[0]=0b01000000; //U
letra[1]=0b00111111;
letra[2]=0b00111111;
letra[3]=0b00111111;
letra[4]=0b01000000;
opcion++;
break;
case 22: letra[0]=0b01100000; //V
letra[1]=0b01011111;
letra[2]=0b00111111;
letra[3]=0b01011111;
letra[4]=0b01100000;
opcion++;
break;
case 23: letra[0]=0b01000000; //W
letra[1]=0b00111111;
letra[2]=0b01000111;
letra[3]=0b00111111;
letra[4]=0b01000000;
opcion++;
break;
case 24: letra[0]=0b00111011; //X
letra[1]=0b01010111;
letra[2]=0b01101111;
letra[3]=0b01010111;
letra[4]=0b00111011;
opcion++;
break;
case 25: letra[0]=0b01111110; //Y
letra[1]=0b01111101;
letra[2]=0b00000011;
letra[3]=0b01111101;
letra[4]=0b01111110;
opcion++;
break;
case 26: letra[0]=0b00111100; //Z
letra[1]=0b00111010;
letra[2]=0b00110110;
letra[3]=0b00101110;
letra[4]=0b00011110;
opcion=0;
}
set_timer1(3036); //TMR1 se desborda cada 0,5s
}

void main(void)
{
int i; //variable contador

enable_interrupts(INT_TIMER1); //interrupcion TIMER1 activada


setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //configuracion TMR1
set_timer1(65535); //carga TMR1 para un desbordamiento inmediato
enable_interrupts(GLOBAL); //activadas interrupciones

set_tris_b (0x00); //portb salida


set_tris_a (0x00); //porta salida

do{ //bucle...
for(i=0;i<5;i++){
output_a( i ); //columnas
output_b(letra[ i ]); //filas
delay_ms(10); //pausa para poder verse
}
}while(TRUE); //...infinito
}
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!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #198 : 11 de Enero de 2006, 20:10:00 »

Escrito originalmente por vszener

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B)
#use fixed_io(a_outputs=PIN_A0,PIN_A1) //A0,A1 como salidas en porta

char i=0,j=0,flag=0,var=20; //variables globales

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 1 segundo?
var--; //SI -> decremento var...
if(var<18)
var=20; //...ajuste fino de 1s
flag=0; //reset flag para contar 1s
if(i> { //¿se ha mostrado por 1º 7seg digito 9?
i=0; //SI -> i=0 (muestra digito 0) (*)
j++; //incremento indice j
if(j>9){ //¿se ha mostrado por 2º 7seg digito 9?
j=0;} //SI -> j=0 (muestra digito 0)
}
else{ //(*) NO -> incrementa i
i++;}
}
set_timer0(61); //reset TMR0
flag++; //incremento variable flag
}

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

set_tris_b(0x00); //portb como salida


enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion
TMR0
set_timer0(61); //carga TMR0
enable_interrupts(GLOBAL); //activadas interrupciones

do{ //bucle...
output_high(PIN_A1); //2º 7seg off
output_low(PIN_A0); //1º 7seg on
delay_ms(15);
output_b(tab7seg[ i ]); //muestra por portb digito 7 segmentos
output_low(PIN_A1); //2º 7seg on
output_high(PIN_A0); //1º 7seg off
delay_ms(15);
output_b(tab7seg[ j ]); //muestra por portb digito 7 segmentos
}while(TRUE); //...infinito
}

RE: Ejemplitos en C para 16F648A


« Respuesta #206 : 20 de Enero de 2006, 11:14:00 »

Holaaa!!!bueno, aqui dejo un programa que se sale de la tematica de aprendizaje a


programar perifericos internos del pic, pero vamos creo que es ilustrativo a la programacion
del mismo y hardware, hace tiempo que pense en regalarle un reloj digital a mi niña, y
bueno pue sme puse manos a la obra, el conteo y la realizacion del reloj lo realiza todo el
pic, aqui el programa:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 29/Noviembre/05
//
// Programa: Reloj digital 7seg
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22 Simulador: Proteus 6.7sp3
//
// Notas: Reloj digital en 7seg. Se utiliza un DEC 4555 para realizar el barrido
// de los 7seg, se usa tambien, un BCD-7Seg 4543 para la visualizacion
// de los numeros en el 7seg. El reloj esta compuesto de 4 botones.
// Botones: Hora/Minutos->RB1: Cuando estemos en modo Configuracion,
// pasar de hora a minutos para incrementar.
// + ->RB2: Para incrementar en una unidad el digito actual.
// Configuracion/Ok->RB3: Si se pulsa pasamos al modo
// configuracion para poder actualizar
// la hora actual, una vez actualizada,
// si se pulsa pasamos al modo de reloj
// Conexiones: A0 -> A 4555 DEC
// A1 -> B 4555 DEC
// A2 -> 2 led"s en serie(secundero)
// A5 -> Boton reset(externo)
// B1 -> Boton Hora/Minuto
// B2 -> Boton +
// B3 -> Boton Configuracion/Ok
// B4 -> A 4543
// B5 -> B 4543
// B6 -> C 4543
// B7 -> D 4543
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOCPD,NOWDT,NOPUT,NOLVP,NOBROWNOUT //ordenes para el
programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2)
#use fixed_io(b_outputs=PIN_B4,PIN_B5,PIN_B6,PIN_B7)
#bit RA2=05.2 //secundero

///DEFINICION DE FUNCIONES
void configurar(void);
///VARIABLES GLOBALES
char min1=0,min2=0,hor1=0,hor2=0;
char flag=0,var=119; //variables de ajuste de 1 minuto
char tab[10]={0x00,0b00010000,0b00100000,0b00110000,
0b01000000,0b01010000,0b01100000,0b01110000,0b10000000,0b10010000}; //bcd
parte alta 0-9

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER1
void interrupcion()
{
if(flag>var){ //¿Ya es 1 minuto?
var--; //SI -> decremento var...
if(var<118)
var=120; //...ajuste fino de 1min
flag=0; //reset flag para contar 1min
min1++;
if(min1>9){ //¿Se ha mostrado xx:x9?
min1=0; //SI -> reset min1 xx:x0
min2++;
if(min2>5){ //¿Se ha mostrado xx:59?
min2=0; //SI -> reset min2 xx:00
hor1++;
if(hor2==2){ //¿Estamos en modo noche 2x:xx?
if(hor1>3) //SI -> ¿Se ha mostrado 23:59?
goto noche;}//SI -> ve a noche
if(hor1>9){ //No estamos en modo noche-> ¿se ha mostrado 19:59?
noche: hor1=0; //SI -> reset hor1 x0:00 || noche: reset hor1 x0:00
hor2++;
if(hor2>2) //¿Se ha mostrado 23:59?
hor2=0; //SI -> reset hor2 00:00
}
}
}
}
RA2=!RA2; //parpadeo secundero cada 0,5s
set_timer1(3036); //reset TMR1
flag++;
}
///PROGRAMA
void main(void)
{
enable_interrupts(INT_TIMER1); //interrupcion TIMER1 activada
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //configuracion TMR1
set_timer1(3036); //carga TMR1 para desvordar cada 0.5s
enable_interrupts(GLOBAL); //activadas interrupciones

do{ //bucle...
output_low(PIN_A0); //Primer 7seg...
output_low(PIN_A1); //...on
output_b(tab[min1]);
delay_ms(10);
output_low(PIN_A1); //Segundo 7seg...
output_high(PIN_A0); //...on
output_b(tab[min2]);
delay_ms(10);
output_high(PIN_A1); //Tercer 7seg...
output_low(PIN_A0); //...on
output_b(tab[hor1]);
delay_ms(10);
output_high(PIN_A0); //Cuarto 7seg...
output_high(PIN_A1); //...on
output_b(tab[hor2]);
delay_ms(10);
if(!input(PIN_B3)){ //¿Se ha pulsado boton Configuracion?
while(!input(PIN_B3)){} //SI -> elimina rebotes pulsador...
configurar(); //...ve a configurar
}
}while(TRUE); //...infinito
}
///FUNCION QUE CONFIGURA LA HORA ACTUAL
void configurar(void){
boolean sal=0;
char menu=0; //menu=0: incremento minutos || menu=1: incremento horas
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas
do{
do{
output_a(0b00);
output_b(tab[min1]);
delay_ms(10);
output_a(0b01);
output_b(tab[min2]);
delay_ms(10);
output_a(0b10);
output_b(tab[hor1]);
delay_ms(10);
output_a(0b11);
output_b(tab[hor2]);
delay_ms(10);
if(!input(PIN_B1)){ //¿Se ha pulsado boton Horas/Minutos?
while(!input(PIN_B1)){}
menu=!menu; //SI -> Cambia minutos/horas y viceversa
}
if(!input(PIN_B2)){ //¿Se ha pulsado boton +?
while(!input(PIN_B2)){}
sal=1; //SI -> incrementa una unidad el digito(segun variable menu)
}
if(!input(PIN_B3)){ //¿Se ha pulsado boton Ok?
while(!input(PIN_B3)){}
sal=1; //SI -> salir...
menu=2; //...modo Configurar y mostrar hora actualizada
}
}while(sal==0);

sal=0; //reset variable sal


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

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!!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #209 : 27 de Enero de 2006, 06:31:00 »

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 VARIABLES GLOBALES


boolean menu=1,opcion=1; //si menu=0 se muestra el menu de inicio...
//...si opcion=1 estamos en modo direccion
// opcion=0 estamos en modo dato

///DECLARACION DE FUNCIONES
BYTE gethex1( ); //verifica que esta dentro del rango y muestra por pantalla
BYTE gethex( ); //devuelve el numero en hex

///LLAMADA FUNCION INTERRUPCION


#int_rda
void rs232()
{
BYTE i=0,j=0,address,value; //definicion...
char digito; //...variables

disable_interrupts(global); //apago interrupcion

digito=getc(); //almaceno dato serial(rs232) en digito

puts("
****************************************************" );

switch(digito){
case "0": menu=!menu; //muestra menu
break;
case "1": printf("LLenando buffer..." ) ; //llena memoria 0xff
for(i=0; i<16;i++){
for(j=0; j<16;j++)
write_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;

do{ //espera hasta tener un dato correcto


digit = getc( );
if(opcion==0) //si estamos introduciendo un dato no hace falta las restricciones
break;
}while((digit<"0" || digit>"9") && (digit<"A" || digit>"F") && (digit<"a" || digit>"f") );

putc(digit); //muestra por pantalla el dato introducido

if(digit<="9") //se ha introducido un numero


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

hi = gethex1( ); //parte alta


lo = gethex1( ); //parte baja
if(lo==0xdd)
return(hi);
else
return( hi*16+lo );
}
Bueno, recordar que si quereis implementarlo en la vida real debereis retocar el formato de
presentacion del menu, ya que en proteus no reconoce algunos como en y tal....asi que se ha
programado para una "aceptable" vision en proteus!

RE: Ejemplitos en C para 16F648A


« Respuesta #211 : 31 de Enero de 2006, 04:59:00 »

Buenass!!!lo prometido es deuda! aqui esta el programa que gestiona la lectura/escritura de


una eeprom externa, concretamente la 24LC256:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"06
// 23/Enero/06
//
// Programa: RS232 Y PIC
// Version: 1.0 REVISION del programa 48
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.30 Simulador: Proteus 6.7sp3
//
// Notas: Se interacciona el PC con el PIC mediante RS232 para el tratamiento de la
memoria
// eeprom externa 24LC256,se muestra por v.terminal un menu:
// · 0 -> Muestra nuevamente el menu
// · 1 -> LLena la eeprom a 0xFF
// · 2 -> Lee la eeprom en modo hex
// · 3 -> Escribe en la eeprom
// · 4 -> Lee la eeprom en modo texto(ASCII)
// Todas las acciones se realizan mediante la interrupcion del puerto serial.
// Al comienzo del programa, realizar el paso 1. en caso de empezar a escribir
// en la eeprom!. Decir que las funciones gethex1() y gethex() estan sacadas
// de la libreria incluida en CCS, input.c, estan puestas en el programa
// por la 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 VARIABLES GLOBALES


boolean menu=1,opcion=1; //si menu=0 se muestra el menu de inicio...
//...si opcion=1 estamos en modo direccion
// opcion=0 estamos en modo dato

///DECLARACION DE FUNCIONES
BYTE gethex1( ); //verifica que esta dentro del rango y muestra por pantalla
BYTE gethex( ); //devuelve el numero en hex
///LLAMADA FUNCION INTERRUPCION
#int_rda
void rs232( )
{
BYTE i=0,j=0,value; //definicion...
EEPROM_ADDRESS address;
char digito; //...variables

disable_interrupts(global); //apago interrupcion

digito=getc( ); //almaceno dato serial(rs232) en digito

puts("
****************************************************" );

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

void main(void)
{
setup_oscillator(OSC_4MHZ); //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;

do{ //espera hasta tener un dato correcto


digit = getc();
if(opcion==0) //si estamos introduciendo un dato no hace falta las restricciones
break;
}while((digit<"0" || digit>"9") && (digit<"A" || digit>"F") && (digit<"a" || digit>"f" ));

putc(digit); //muestra por pantalla el dato introducido

if(digit<="9" ) //se ha introducido un numero


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

hi = gethex1(); //parte alta


lo = gethex1( ); //parte baja
if(lo==0xdd)
return(hi);
else
return( hi*16+lo );
}

Bueno, pues aqui esta!

Suerte!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #215 : 05 de Febrero de 2006, 11:05:00 »

Buenasss!!!bien, el sigiente programa es simplemente manejar el dispositivo SAA1064 de


Philips, el cual sirve para manejar display"s de 7segmentos mediante bus I2C, tanto para la
libreria del dispositivo para CCS como para PROTEUS lo podeis encontrar en el siguiente
post:
Libreria: SAA1064 (CCS)
El SAA1064 es util para ahorrar pines del pic(ya que solamente usa 2 para manejo del I2C),
dicho dispositivo puede actuar tanto en modo dinamico(manejando un total de 4 display"s
multiplexados), como en modo estatico(solamente 2 display"s), puede controlar la
iluminosidad, parpadeo,...mirar el enlace anterior donde esta el data sheet!, bueno el
ejemplo es manejar el SAA1064 en modo dinamico:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"06
// 29/Enero/06
//
// Programa: Manejo del dispositivo SAA1064 en modo DINAMICO
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.30 Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra pos cuatro display"s de 7seg mensajes de texto, para
// ello usamos el dispositivo SAA1064 de bus I2C.
//
// Conexiones: A0 -> SDA saa1064
// A1 -> SCL saa1064
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#define SAA1064_DINAMICO //trabajar en modo dinamico el saa1064
#define SAA1064_SCL PIN_A1 //definicion de pines...
#define SAA1064_SDA PIN_A0 //...de manejo del saa1064
#include <vs_saa1064.c> //libreria saa1064

///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz

saa1064_init(); //inicializo saa1064


do{ //bucle...
///MANIPULAMOS SAA1064 CON DIVERSAS CONFIGURACIONES
saa1064_conf(0b00010001); //3mA & NO parpadeo & Dinamico
saa1064_putc(0x76,0x3F,0x38,0x77); //HOLA
delay_ms(1500);

saa1064_conf(0b00100011); //6mA & parpadeo 1&3 & Dinamico


saa1064_putc(0x71,0x5C,0x50,0x5C); //Foro
delay_ms(1500);

saa1064_conf(0b01000101); //12mA & parpadeo 2&4 & Dinamico


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

saa1064_conf(0b00110111); //9mA & parpadeo TODO & Dinamico


saa1064_putc(0x73,0x30,0x39,0x86); //PIC!
delay_ms(1500);

saa1064_conf(0b01110001); //21mA & NO parpadeo & Dinamico


saa1064_putc(0x5B,0x3F,0x3F,0x7D); //2006
delay_ms(1500);

///MANIPULAMOS SAA1064 A CONFIGURACION FIJA -> CAMBIAMOS


SOLAMENTE DIGITO DESEADO
saa1064_conf(0b01110001); //21mA & NO parpadeo & Dinamico -
>Configuracion fija!
saa1064_putc(0x76,0x3F,0x38,0x77); //HOLA -> texto donde trabajar!
delay_ms(1500);

saa1064_subaddress(1,0xFF); //Pongo en el 1º digito el caracter 8.


delay_ms(1500);
saa1064_putc(0x76,0x3F,0x38,0x77); //reset -> HOLA

saa1064_subaddress(2,0xFF); //Pongo en el 2º digito el caracter 8.


delay_ms(1500);
saa1064_putc(0x76,0x3F,0x38,0x77); //reset -> HOLA

saa1064_subaddress(3,0xFF); //Pongo en el 3º digito el caracter 8.


delay_ms(1500);
saa1064_putc(0x76,0x3F,0x38,0x77); //reset -> HOLA
saa1064_subaddress(4,0xFF); //Pongo en el 4º digito el caracter 8.
delay_ms(1500);
saa1064_putc(0x76,0x3F,0x38,0x77); //reset -> HOLA

}while(TRUE); //...infinito
}

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!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #219 : 09 de Febrero de 2006, 03:59:00 »

Holaaa!!!Bueno, trabajando un poco mas con la libreria del SAA1064, el siguiente ejemplo
quiere mostrar como trabajar con las funciones de dicha libreria para modo ESTATICO, es
decir, simplemente manejaremos dos display"s de 7 segmentos, aqui el programa:

////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"06
// 29/Enero/06
//
// Programa: Manejo del dispositivo SAA1064 en modo ESTATICO
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.30 Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra por dos display"s de 7seg numeros, para
// ello usamos el dispositivo SAA1064 de bus I2C.
//
// Conexiones: A0 -> SDA saa1064
// A1 -> SCL saa1064
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#define SAA1064_SCL PIN_A1 //definicion de pines...
#define SAA1064_SDA PIN_A0 //...de manejo del saa1064
#include <vs_saa1064.c> //libreria saa1064

///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz

saa1064_init( ); //inicializo saa1064

do{ //bucle...
///MANIPULAMOS SAA1064 CON DIVERSAS CONFIGURACIONES
saa1064_conf(0b00010000); //3mA & NO parpadeo & Estatico
saa1064_putc(0x66,0x3F); //40
delay_ms(1500);

saa1064_conf(0b00100010); //6mA & parpadeo & Estatico


saa1064_putc(0x4F,0x06); //31
delay_ms(1500);

saa1064_conf(0b01000100); //12mA & parpadeo & Estatico


saa1064_putc(0x5B,0x5B); //22
delay_ms(1500);

saa1064_conf(0b00110110); //9mA & parpadeo & Estatico


saa1064_putc(0x06,0x4F); //13
delay_ms(1500);

saa1064_conf(0b01110000); //21mA & NO parpadeo & Estatico


saa1064_putc(0x3F,0x66); //04
delay_ms(1500);

///MANIPULAMOS SAA1064 CON CONFIGURACION FIJA -> CAMBIAMOS


SOLO UN DIGITO
saa1064_conf(0b00010000); //3mA & NO parpadeo & Estatico -> configuracion fija!
saa1064_putc(0x3F,0x3F); //00 -> texto donde trabajar!
delay_ms(1500);
saa1064_subaddress(1,0xff); //cambio el 1º digito por 8 ->08
delay_ms(1500);
saa1064_putc(0x3F,0x3F); //restauro -> 00

saa1064_subaddress(2,0xff); //cambio el 2º digito por 8 ->80


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!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #225 : 04 de Marzo de 2006, 07:21:00 »

1) mi primera consulta es respecto a: como hago para obtener una temporización de un


segundo exacto, ya que en el programa que has dado como ejemplo no es un
segundo exacto.
2) tenes ejemplos o has hecho ejemplos de programas que controlen, motores paso a
paso, motores de continua, y motores de alterna.
3) tenés ejemplos que hayas hecho conectando conversores al microcontrolador, ya
sé que viene con un conversor analógico digital pero en caso de que tuvieras que
conectar un conversador externo.

Sugerencia, no se si te sirva o no, dado que tenés tantos conocimientos y tenés


tantos ejemplos, tranquilamente y casi muy similar a lo que has hecho en la página
web, que podrías poner en campaña de acuerdo a tu tiempo para organizar un libro
de programación en lenguaje C para microcontroladores, dado que en castellano no
he visto ningún libro de ése tipo y tus ejemplos son bastante didácticos y
entendibles, agregando mucho ejemplos más como ligeras variantes sobre lo que ya
tenés hecho más algunas que inventes (no creo que te cueste mucho) podrías lanzar
un buen libro y harías una muy buena cantidad de dinero. (Sólo es una sugerencia
sin ánimos de ofender)

4) He tenido inconvenientes con una instrucción en alguna de tus últimos


programas, es como si no me reconociera el programa esa instrucción.
Por ejemplo:

////////////////////////////////////////////////////////////////////////////////////
// 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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno (a esta instrucción es a la que me refiero, es como
si el compilador no me las reconociera)
#use delay (clock=4000000) //Fosc=4Mhz
#define SAA1064_DINAMICO //trabajar en modo dinamico el saa1064
#define SAA1064_SCL PIN_A1 //definicion de pines...
#define SAA1064_SDA PIN_A0 //...de manejo del saa1064
#include <vs_saa1064.c> //libreria saa1064

Acaso será por la versión de compilador? PICC IDE 3.43


PCB3.203

Será por eso?

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).

Verdaderamente te felicito por el trabajo estás haciendo, es admirable de los


conocimientos que por seres de programación y ánimos para seguir adelante.

Mi nombre es Pedro y sobre de la república Argentina

RE: Ejemplitos en C para 16F648A


« Respuesta #232 : 23 de Marzo de 2006, 07:04:00 »

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. ///
///////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef PCF8591_SCL //para definir los pines de manejo del pcf8591...


#define PCF8591_SCL PIN_B0
#define PCF8591_SDA PIN_B1
#endif //...en caso de no ser definidos en el programa principal
#use i2c(master,sda=PCF8591_SDA, scl=PCF8591_SCL) //i2c

/////////////MODO: D/A ///////////////////////////////////////////////////////////////////////////

void stop_dac(void){ //funcion para parar el dac


i2c_stop( );
}

void write_dac_value(int data){ //funcion que escribe en AOUT


i2c_write(data);
}

void pcf8591_dac_init(){ //funcion para inicializar pcf8591


output_high(PCF8591_SDA);
output_high(PCF8591_SCL);
i2c_start( );
i2c_write(0b10010000); //direccion en modo escritura
i2c_write(0b01000000); //palabra de control habilitando AOUT
}

/////////////MODO: A/D ////////////////////////////////////////////////////////////////////////////

int read_adc_value(void){ //funcion para la lectura del pcf8591


byte data;
data=i2c_read(1); //lee y se almacena en la variable data
return data; //devuelve la informacion leida
}

void pcf8591_adc_init(int control){ //funcion para inicializar pcf8591


output_high(PCF8591_SDA);
output_high(PCF8591_SCL);
control=(0b00110111 & control); //palabra de control correcta -> deshabilita AOUT
i2c_start( );
i2c_write(0b10010000); //direccion en modo escritura
i2c_write(control); //palabra de control
i2c_stop( );

i2c_start( ); //iniciamos comandos...


i2c_write(0b10010001); //...de lectura
}
Bien, pues con esta "mini libreria" trabajaremos en un par de ejemplitos!

Hasta otra!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #234 : 23 de Marzo de 2006, 07:10:00 »

Holaaa!!!he aqui un programita que maneja la libreria y el dispositivo pcf8591!, en este


caso como D/A, es decir, mediante un pulsador vamos sumando un valor que sera mostrado
por el pcf8591 en el pin AOUT, dicho valor es de 8 bits y se vera el encendido paulatino de
un led y su tension correspondiente por dicho pin:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"06
// 13/Marzo/06
//
// Programa: Manejo del dispositivo PCF8591 en modo D/A
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.242
// Entorno IDE: MPLAB IDE v7.31 Simulador: Proteus 6.7sp3
//
// Notas: Este programa muestra el encendido paulatino de un diodo led
// conectado al pcf8591 configurado para actuar como D/A.
// La Vref es de 2,5v por lo tanto la resolucion del conversor es 10mV.
// Al pulsar el boton se produce una interrupcion, en dicha interrupcion
// se incrementa la variable "dato" en una unidad y se muestra por el pcf8591
// por el pin AOUT, al ser de tipo entero dicha variable puede llegar hasta
// 255 siendo este el valor maximo que puede alcanzar la señal analogica del
// pcf8591.
//
// Conexiones: B7 -> SDA pcf8591
// B6 -> SCL pcf8591
// B0 -> Boton
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#define PCF8591_SCL PIN_B6 //definicion de pines...
#define PCF8591_SDA PIN_B7 //...de manejo del pcf8591
#include <vs_pcf8591.c> //libreria pcf8591

///DEFINICION VARIABLES GLOBALES


int dato; //variable de salida por AOUT

///LLAMADA FUNCION INTERRUPCION


#INT_EXT
void IntRB0()
{
dato++; //incremento variable dato
write_dac_value(dato); //salida analogica AOUT
}

///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz

enable_interrupts(int_ext); //activar interrupcion externa


ext_int_edge(H_TO_L); //configuracion:interrupcion cuando señal esta en baja
enable_interrupts(GLOBAL); //activar interrupciones

pcf8591_dac_init( ); //inicializamos pcf8591 en modo D/A

write_dac_value(dato); //voltaje inicial de salida 0v

sleep( ); //modo reposo hasta la interrupcion


}

Suerte!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #239 : 26 de Marzo de 2006, 06:24:00 »

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
//////////////////////////////////////////////////////////////////////////////////

//#include <16f648a.h> //pic a utilizar


#include <16f84a.h> //pic a utilizar

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


//#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#define PCF8591_SCL PIN_B6 //definicion de pines...
#define PCF8591_SDA PIN_B7 //...de manejo del pcf8591
#include <vs_pcf8591.c> //libreria pcf8591

///DEFINICION VARIABLES GLOBALES


int dato; //variable de salida por AOUT

///LLAMADA FUNCION INTERRUPCION


#INT_EXT
void IntRB0()
{
dato=dato+5; //incremento variable dato
write_dac_value(dato); //salida analogica AOUT
}

///PROGRAMA
void main(void)
{
//setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz

enable_interrupts(int_ext); //activar interrupcion externa


ext_int_edge(H_TO_L); //configuracion:interrupcion cuando señal esta en baja
enable_interrupts(GLOBAL); //activar interrupciones

pcf8591_dac_init(); //inicializamos pcf8591 en modo D/A

write_dac_value(dato); //voltaje inicial de salida 0v

sleep(); //modo reposo hasta la interrupcion


}

RE: Ejemplitos en C para 16F648A


« Respuesta #240 : 26 de Marzo de 2006, 06:31:00 »

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();

delay_ms(3000); //retraso para que se vea en pantalla los mensajes

lcd_gotoxy(1,1);

lcd_putc("f Voltimetro" ) ;

lcd_gotoxy(3,2);

lcd_putc(" Digital!!!" ) ;

delay_ms(3000); //retraso para que se vea en pantalla los mensajes

lcd_putc("f" ); //borra pantalla

pcf8591_adc_init(0b00000000); //inicializamos pcf8591 en modo A/D habilitando canal


0 solamente
//ver la palabra de configuracion en la hoja de datos o en la libreria
//perfectamente explicada por VS_ZeNeR
while (x<100){

lcd_gotoxy(1,1);

printf(lcd_putc,"X= %d",x ) ;

dato=read_adc_value(); //se guarda valor en variable dato

lcd_gotoxy(9,1);

printf(lcd_putc,"%d mV",dato) ;

delay_ms(1000); //retraso para que se vea en pantalla los mensajes

x++;

lcd_putc("f" ); //borra pantalla

}
}

RE: Ejemplitos en C para 16F648A


« Respuesta #245 : 30 de Marzo de 2006, 13:09:00 »

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
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE
#include <lcd.c> //libreria para lcd
#define PCF8591_SCL PIN_A0 //definicion de pines...
#define PCF8591_SDA PIN_A1 //...de manejo del pcf8591
#include <vs_pcf8591.c> //libreria pcf8591

///LLAMADA FUNCION INTERRUPCION


#INT_TIMER0
void interrupcion( )
{
int dato; //almacena lectura del pcf8591
float variable; //tratamiento de la informacion a representar

dato=read_adc_value( ); //lee del pcf8591


variable=(float)dato*0.009803; //se procesa la señal para su representacion
printf(lcd_putc,"fTension: %1.2f V",variable); //muestra por lcd
lcd_putc("
VsZeNeR"06" );

set_timer0(0 ); //carga TMR0


}

///PROGRAMA
void main(void)
{
setup_oscillator(OSC_4MHZ); //configuracion del oscilador interno a 4MHz

enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada


setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion
TMR0

lcd_init( ); //inicializamos lcd

set_timer0(0 ); //carga TMR0 -> temporizacion maxima aprox 65.5ms


enable_interrupts(GLOBAL); //activadas interrupciones

pcf8591_adc_init(0b00000000); //inicializamos pcf8591 en modo D/A con


entradas
//entradas analog. simples
while(TRUE){ } //bucle infinito
}

Bueno ya podemos con nuestro pic usar los convertidores!!!hasta otra!!!

RE: Ejemplitos en C para 16F648A


« Respuesta #247 : 31 de Marzo de 2006, 08:29:00 »

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:

write_dac_value(dato); //salida analogica AOUT

Previamente definiremos la variable dato como un byte.


En el data sheet del dispositivo pcf8591 , concretamente en la pagina 8, la primera figura
esta la formula de la resolucion, pero te voy a poner un ejemplo, ¿que tension de salida
analogica por AOUT del dispositivo pcf8591 en modo DAC tendra, si Vref es de 2,56v y el
pin AGND esta conectado a masa(0v), siendo el dato de entrada(D0-D7) 0b01001011?
El dato de enbtrada en decimal es 75(dato que queremos pasar a analogico)
Pues nos vamos a la formula que te puse antes de la resolucion:
Codigo:

2.56- 0
Vaout = 0 + ------------------ [ 75] = 750mV = 0.75V
256

Si tienes alguna duda preguntamela!

Re: Ejemplitos en C para 16F648A


« Respuesta #256 : 25 de Mayo de 2006, 11:41:21 »

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!!!

Re: Ejemplitos en C para 16F648A


« Respuesta #257 : 26 de Mayo de 2006, 06:59:26 »

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!!!

Re: Ejemplitos en C para 16F648A


« Respuesta #259 : 28 de Mayo de 2006, 10:12:16 »

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.

printf(lcd_putc,"V4:%d.%d",dato /100,(dato-(dato/100)*100)); //muestra por

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.

Luego imprime la coma . El siguiente paso es la parte de decimal = dato-


(dato/100)*100) que al solo imprimir la parte entera imprimirá el 11.

////////////////////////////////////////////////////////////////////////////////////
//
// 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 ***/
/******************************************************/

#include <16f628.h> //pic a utilizar


#fuses XT,NOWDT,NOPROTECT,noPUT,nolvp//ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portb_lcd TRUE
#include <lcd.c> //libreria para lcd
#define PCF8591_SCL PIN_A0 //definicion de pines...
#define PCF8591_SDA PIN_A1 //...de manejo del pcf8591
#include <vs_pcf8591.c> //libreria pcf8591
#use rs232(baud=9600, xmit=PIN_A2, rcv=PIN_A3) //manejo del RS232
///LLAMADA FUNCION INTERRUPCION

#INT_TIMER0

void interrupcion( )
{
int8 dato; //almacena lectura del pcf8591

dato=read_adc_value( ); //lee del pcf8591


lcd_gotoxy(9,2);
printf(lcd_putc,"V4:%d.%d",dato/100,(dato-(dato/100)*100)); //muestra por lcd, la ultima
parte obedece solo
//a una forma de representar con enteros
printf("V4=%3u \t ",dato);//con esta parte se imprime en El puerto serial (RS232)

dato=read_adc_value( ); //lee del pcf8591


lcd_gotoxy(1,1);
printf(lcd_putc,"V1:%d.%d",dato/100,(dato-(dato/100)*100)); //muestra por lcd
//a una forma de representar con enteros
printf("V1=%3u \t ",dato);//con esta parte se imprime en El puerto serial (RS232)

dato=read_adc_value( ); //lee del pcf8591


lcd_gotoxy(9,1);
printf(lcd_putc,"V2:%d.%d",dato/100,(dato-(dato/100)*100)); //muestra por lcd
printf("V2=%3u \t ",dato);//con esta parte se imprime en El puerto serial (RS232)

dato=read_adc_value( ); //lee del pcf8591


lcd_gotoxy(1,2);
printf(lcd_putc,"V3:%d.%d",dato/100,(dato-(dato/100)*100)); //muestra por lcd
printf("V3=%3u \t ",dato);//con esta parte se imprime en El puerto serial (RS232)

set_timer0(0 ); //carga TMR0


}

///PROGRAMA
void main(void)
{

lcd_init( ); //inicializamos lcd

lcd_putc(" Medidor de \n Presion...");


delay_ms(2000);
lcd_putc("\f");

enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada


setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0

set_timer0(0 ); //carga TMR0 -> temporizacion maxima aprox 65.5ms


enable_interrupts(GLOBAL); //activadas interrupciones

pcf8591_adc_init(0b00000100); //inicializamos pcf8591

while(TRUE);//bucle infinito

Re: Ejemplitos en C para 16F648A


« Respuesta #280 : 01 de Julio de 2006, 09:59:00 »

Buenas!!! lo prometido es deuda!!! como bien dice el amigo jfh900, el compilador de la


casa CCS no hace un tratamiento de la interrupcion del cambio d elos pines del puerto b
<4:7> correctamente, concretamente no realiza bien la tarea al abandonar la interrupcion,
ya que ellos simplementen borran el flag de la interrupcion(el RBIF) y como bien indica el
manual, debemos borrar ese flag pero aparte leer/escribir en el puerto b, asi que nuestro
compilador se le 'ha olvidado' esa parte de leer en el puerto b, provocando asi una llamada
continua de la funcion de interrupcion, para poner pruebas tenemos el programa del amigo
jfh900, y aqui otro:

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):

1. while(!input(PIN_B4) || !input(PIN_B5) || !input(PIN_B6) ||


!input(PIN_B7)); //elimina rebotes
2.

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!!!

Re: Ejemplitos en C para 16F648A


« Respuesta #279 : 24 de Junio de 2006, 14:12:30 »

Efectivamente ya se va centrando el tema, pero debo de aclarar que yo en ningun caso he


dicho que para refrescar los lantch haya que poner output_low(pin_b0); eso estaba en un
programa que Simulpic posteo y que no entendia para que servia. Yo lo que puse fue
utilizar: #asm movf PORTB,0 #endasm que lo que hace es leer el puerto B y como hemos
visto refrescar los lantch. Por que he hecho de esta forma?: en primer lugar como es una
instrucción que hay que poner dentro del tratamiento de la interrupción, debe de ser lo mas
corta ya rapida posible, por eso la pongo en ASM para que el compilador no ponga su
tratamiento de entradas y salidas. Como ves lo que hago es leer el puerto b mediante la
lectura del pin B0, ¿por qué el B0? pues por que es el primero numéricamente y como da
igual leer uno que otro he seleccionado este. Un programa de prueba podria ser:

#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;

set_tris_a(0x0); // Todo salidas


set_tris_b(0xFF); // Todo entradas
output_a(0xFF);

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..!!..

Desde España Jesús


Re: Ejemplitos en C para 16F648A
« Respuesta #280 : 01 de Julio de 2006, 09:59:00 »

Buenas!!! lo prometido es deuda!!! como bien dice el amigo jfh900, el compilador de la


casa CCS no hace un tratamiento de la interrupcion del cambio d elos pines del puerto b
<4:7> correctamente, concretamente no realiza bien la tarea al abandonar la interrupcion,
ya que ellos simplementen borran el flag de la interrupcion(el RBIF) y como bien indica el
manual, debemos borrar ese flag pero aparte leer/escribir en el puerto b, asi que nuestro
compilador se le 'ha olvidado' esa parte de leer en el puerto b, provocando asi una llamada
continua de la funcion de interrupcion, para poner pruebas tenemos el programa del amigo
jfh900, y aqui otro:

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):

3. while(!input(PIN_B4) || !input(PIN_B5) || !input(PIN_B6) ||


!input(PIN_B7)); //elimina rebotes
4.

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!!!

Re: Ejemplitos en C para 16F648A


« Respuesta #442 : 25 de Octubre de 2009, 20:03:45 »

Que tal amigos!


Aqui les coloco un nuevo ejemplito
Esta vez se trata del juego de luces del auto fantastico.

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);
}

for (x=0; x<=14;x++)


{
shift_right(&port_b,2,0);
delay_ms(100);
}
}

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