Lista de contenido:
- Ejemplo Nº1: Gestión de puertos en C: encendido de un led.
- Ejemplo Nº2: Multiplexación de Displays de 7 segmentos.
- Ejemplo Nº3: Menú de control con LCD 16x2 e I2C con PCF8574.
- Ejemplo Nº4: Visualizar el estado de las entradas del Puerto A en la Pantalla GLCD 128x64.
- Ejemplo Nº5: Introducir datos por el teclado y visualizarlos en el LCD.
- Ejemplo Nº6: Diseño básico de control de acceso de una puerta, a través de un teclado 3x4, guardando la clave de 3 dígitos en la memoria EEPROM.
- Ejemplo Nº7: Generar una señal modulada en ancho de pulso proporcional al dato introducido por techado 3x4.
- Ejemplo Nº8: Modulo de temperatura con el sensor lm35, con salida de 4 a 20m[A], con los datos visualizados en una pantalla oled de 0.96".
- Ejemplo Nº9: Modulo de temperatura - Humedad con el sensor HDT11, con los datos visualizados en una pantalla LCD de 16x2.
- Ejemplo Nº10: Modulo de temperatura con el sensor LM35 y el PIC16F1824, con salida de 4 a 20m[A], con los datos visualizados en una pantalla LCD, con modelo 3D del diseño PCB.
________________________________________
Ejemplo Nº1: Gestión de Puertos en C:Encendido de un led.
________________________________________
> PIC16F877A
> Gestión de puertos en c a través de la RAM.
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ
//NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#BYTE TRISB =0x86 // TRISB en 86h
#BYTE PORTB =0x06 // PORTB en 06h
#BYTE OPTION_REG =0x81 // OPTION_REG EN 81h
void main()
{
bit_clear(OPTION_REG,7); // Habilitación Pull-up
bit_set(TRISB,0); // B0 como entrada
bit_clear(TRISB,1); // B1 como salida
bit_clear(PORTB,1); // B1 en low (apaga el led)
while(1){
if(bit_test(portb,0)==1) // Si RB0 es 1
bit_clear(portb,1); // RB1 en low (apaga el led)
else
bit_set(portb,1); // Si RB0 es 0 ,enciende el led
}
}
> Gestión de puertos en c a través de las Directivas .
# USE FAST_IO
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ
//NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#use fast_io(B) // <-------
void main()
{
port_b_pullups (TRUE); // Habilitación Pull-up
set_tris_B(0x01);
output_low(PIN_B1); // B1 en low (apaga el led)
while(1){
if(input(PIN_B0)==1) // Si B0 es 1
output_low(PIN_B1); // B1 en low (apaga el led)
else
output_high(PIN_B1); // Si B0 es 0 ,enciende el led
}
}
# USE STANDARD_IO
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ
//NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#use standard_io(B) // <-------
void main()
{
port_b_pullups (TRUE); // Habilitación Pull-up
output_low(PIN_B1); // B1 en low (apaga el led)
while(1){
if(input(PIN_B0)==1) // Si B0 es 1
output_low(PIN_B1); // B1 en low (apaga el led)
else
output_high(PIN_B1); // Si B0 es 0 ,enciende el led
}
}
# USE FIXED_IO
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ
//NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#use fixed_io(b_outputs=pin_b1) // <------- se especifica la salida
void main()
{
port_b_pullups (TRUE); // Habilitación Pull-up
output_low(PIN_B1); // B1 en low (apaga el led)
while(1){
if(input(PIN_B0)==1) // Si B0 es 1
output_low(PIN_B1); // B1 en low (apaga el led)
else
output_high(PIN_B1); // Si B0 es 0 ,enciende el led
}
}
__________________________________________
Ejemplo Nº2: Multiplexación de Displays de 7 segmentos.
__________________________________________
# CONTADOR DE 0 A 99
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ
//NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#use fast_io(B)
#use fast_io(A)
byte CONST DISPLAY[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//números del 0 al 9 para el display de catodo comun.
void main()
{
byte ud=0,dec=0;
int g=2; // tiempo de multiplexado
SET_TRIS_B(0x00); // salida el puerto B
SET_TRIS_A(0x00); // salida el puerto A
OUTPUT_B(0x00); //poner a todas las salidas en low
while(1){
for(dec=0;dec<10;dec++){ // para las decenas
for(ud=0;ud<10;ud++){ //para las unidades
for(int i=0;i<10;i++){ // tiempo de conteo
OUTPUT_A(0x02); // RA1=1,RA0=0, enciende el display de la unidades
OUTPUT_B(DISPLAY[ud]); //muestra el digito de las unidades
delay_ms(g); // tiempo de multiplexado
OUTPUT_A(0x01); // RA1=0,RA0=1, enciende el display de la decena
OUTPUT_B(DISPLAY[dec]);//muestra el digito de las decenas
delay_ms(g); // tiempo de multiplexado
}
}
}
}
}
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ
//NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#use fast_io(B)
byte CONST DISPLAY[10]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9};
//números del 0 al 9 para el display de catodo comun.
void main()
{
byte ud=0,dec=0;
int g=10; // tiempo de multiplexado
SET_TRIS_B(0x00); // salida el puerto B
OUTPUT_B(0x00); //poner a todas las salidas en low
while(1){
for(dec=0;dec<10;dec++){ // para las decenas
for(ud=0;ud<10;ud++){ //para las unidades
for(int i=0;i<20;i++){ // tiempo de conteo
OUTPUT_B(0X10); // RB(7-4)=0001,RB(3-0)=0000, enciende el display de la unidades
OUTPUT_B(DISPLAY[ud]); //muestra el digito de las unidades
delay_ms(g); // tiempo de multiplexado
OUTPUT_B(0X20); // RB(7-4)=0010,RB(3-0)=0000, enciende el display de la DECENAS
OUTPUT_B(DISPLAY[dec]);//muestra el digito de las decenas
delay_ms(g); // tiempo de multiplexado
}
}
}
}
}
__________________________________
Ejemplo Nº3: Menú de control con LCD 16x2.
__________________________________
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ //NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#DEFINE USE_PORTB_LCD TRUE
#include <lcd.c>
#use standard_io(C)
#use standard_io(A)
enum funciones {med,cal,ini}; //Asigna un valor a cada elemento
//med = 0, cal = 1 e ini = 2
void medir(void){ // Función de medir
output_toggle(pin_C0); //cambia el estado logico del pin C0
}
void calibrar(void){ // Función de calibrar
output_toggle(pin_C1); //cambia el estado logico del pin C1
}
void inicializar(void){ // Función de medir
output_toggle(pin_C2); //cambia el estado logico del pin C2
}
void run_func(int numfunc){
switch(numfunc){
case med:
medir();
break;
case cal:
calibrar();
break;
case ini:
inicializar();
break;
}
}
void main(){
char item=0 ; //variable de funciones
char n_menus=3; //numero de funciones
lcd_init();
while(TRUE){
int1 x=input_state(pin_C0);//lee la entrada del pin C0-C2 sin cambiar el sentido del terminal
int1 y=input_state(pin_C1);//(no modifica el registro tris)
int1 z=input_state(pin_C2);//y almacena en la variable x , y , z
lcd_gotoxy(1,2);
printf(lcd_putc,"%u",item); //improme el valor de la variable item
lcd_gotoxy(1,1); // Columna 1,Fila 1
if(input(PIN_A0) ==1){ //detecta el botón de selección
item++; // Si pulsa ,aumenta la variable
delay_ms(300); // para evitar rebotes
lcd_putc('\f'); } // Borra todo lo que halla en el display
if(item>(n_menus-1)){ //si la variabe supera el numero de funciones
item=0;} // la inicializa
switch(item){
case(0):
printf(lcd_putc,"MEDIR");
if(x==1){lcd_gotoxy(10,2);printf(lcd_putc,"on");} //imprime en estado de la salida
if(x==0){lcd_gotoxy(10,2);printf(lcd_putc,"off");} //imprime en estado de la salida
break;
case(1):
printf(lcd_putc,"CALIBRAR");
if(y==1){lcd_gotoxy(10,2);printf(lcd_putc,"on");} //imprime en estado de la salida
if(y==0){lcd_gotoxy(10,2);printf(lcd_putc,"off");} //imprime en estado de la salida
break;
case(2):
printf(lcd_putc,"INICIALIZAR");
if(z==1){lcd_gotoxy(10,2);printf(lcd_putc,"on");} //imprime en estado de la salida
if(z==0){lcd_gotoxy(10,2);printf(lcd_putc,"off");} //imprime en estado de la salida
break;
}
if(input(PIN_A1) == 1){ //sí se pulsa el botóon de selección....
delay_ms(200);
lcd_putc('\f'); // Borra todo lo que halla en el display
run_func(item); } //se llama a la función correspondiente
}
}
Descarga la simulación en proteus 8.13 del circuito aquí
# Menú de control con LCD 16x2 y C.I PCf8574->I2c-.
#C.I PCf8574
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ //NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#use i2c(Master,Fast=10000, sda=PIN_C4, scl=PIN_C3)
#include "i2c_Flex_LCD.c"
#use standard_io(C)
enum funciones {med,cal,ini}; //Asigna un valor a cada elemento
//med = 0, cal = 1 e ini = 2
void medir(void){ // Función de medir
output_toggle(pin_C0); //cambia el estado logico del pin C0
}
void calibrar(void){ // Función de calibrar
output_toggle(pin_C1); //cambia el estado logico del pin C1
}
void inicializar(void){ // Función de medir
output_toggle(pin_C2); //cambia el estado logico del pin C2
}
void run_func(int numfunc){
switch(numfunc){
case med:
medir();
break;
case cal:
calibrar();
break;
case ini:
inicializar();
break;
}
}
void main(){
char item=0 ; //variable de funciones
char n_menus=3; //numero de funciones
lcd_init(0x4A,16,2);
lcd_backlight_led(ON); //Enciende la luz de Fondo
while(TRUE){
int1 x=input_state(pin_C0);//lee la entrada del pin C0-C2 sin cambiar el sentido del terminal
int1 y=input_state(pin_C1);//(no modifica el registro tris)
int1 z=input_state(pin_C2);//y almacena en la variable x , y , z
lcd_gotoxy(1,2);
printf(lcd_putc,"%u",item); //improme el valor de la variable item
lcd_gotoxy(1,1); // Columna 1,Fila 1
if(input(PIN_C5) ==1){ //detecta el botón de selección
item++; // Si pulsa ,aumenta la variable
delay_ms(300); // para evitar rebotes
lcd_putc('\f'); } // Borra todo lo que halla en el display
if(item>(n_menus-1)){ //si la variabe supera el numero de funciones
item=0;} // la inicializa
switch(item){
case(0):
printf(lcd_putc,"MEDIR");
if(x==1){lcd_gotoxy(10,2);printf(lcd_putc,"on");} //imprime en estado de la salida
if(x==0){lcd_gotoxy(10,2);printf(lcd_putc,"off");} //imprime en estado de la salida
break;
case(1):
printf(lcd_putc,"CALIBRAR");
if(y==1){lcd_gotoxy(10,2);printf(lcd_putc,"on");} //imprime en estado de la salida
if(y==0){lcd_gotoxy(10,2);printf(lcd_putc,"off");} //imprime en estado de la salida
break;
case(2):
printf(lcd_putc,"INICIALIZAR");
if(z==1){lcd_gotoxy(10,2);printf(lcd_putc,"on");} //imprime en estado de la salida
if(z==0){lcd_gotoxy(10,2);printf(lcd_putc,"off");} //imprime en estado de la salida
break;
}
if(input(PIN_C6) == 1){ //sí se pulsa el botóon de selección....
delay_ms(200);
lcd_putc('\f'); // Borra todo lo que halla en el display
run_func(item); } //se llama a la función correspondiente
}
}
Descarga la simulación en proteus 8.13 del circuito aquí
________________________________________
Ejemplo Nº4: Visualizar el estado de las entradas del Puerto A en la Pantalla GLCD 128x64 .
________________________________________
Funciones para controlar el GLCD:
glcd_line(x1, y1, x2, y2, color)
Dibuja una linea desde la coordenada (x1,y1) hasta (x2,y2), la variable color puede ser ON o OFF, esta es la que habilita la linea o no (para mostrarla o no).
glcd_rect(x1, y1, x2, y2, fill, color)
Dibuja un rectángulo desde la coordenada (x1,y1) hasta (x2,y2), la variable fill es para rellenar el rectángulo si esta en YES, o solo dibuja el contorno con NO. la variable color al igual que en el resto de las funciones es la que habilita o no el rectángulo.
glcd_bar(x1, y1, x2, y2, width, color)
Dibuja una barra desde la coordenada (x1,y1) hasta (x2,y2), la variable width es el número de pixel de ancho de la barra, la variable color al igual que en el resto de las funciones es la que habilita o no la barra.
glcd_circle(x, y, radius, fill, color)
Dibuja un circulo en la coordenada (x,y), la variable radius es el numero de pixeles de radio de del circulo, a variable fill es para rellenar el circulo si esta en YES, o solo dibuja el contorno con NO. la variable color al igual que en el resto de las funciones es la que habilita o no el circulo.
glcd_text57(x, y, textptr, size, color)
Escribe texto en la coordenada (x,y), la variable textptr es la variable puntero donde esta alojado el carácter o string, a variable size es el tamaño del carácter, la variable color al igual que en el resto de las funciones es la que habilita o no el texto.
glcd_pixel(x, y, color)
Dibuja un punto o pixel en la dirección de la coordenada (x,y), la variable color al igual que en el resto de las funciones es la que habilita o no el punto o pixel.
#include <16f877a.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT //HS POR QUE SE ESTA USANDO UN CRISTAL DE 20 MZ //NOWDT , NO SE UTILIZARA EL PERRO GUARDIAN
#use delay(clock=20M) //Relojde 20M[HZ]
#include <HDM64GS12.c>
#include <graphics.c>
#use standard_io(A)
void main(){
CHAR A5[]="A5";
CHAR A4[]="A4";
CHAR A3[]="A3";
CHAR A2[]="A2";
CHAR A1[]="A1";
CHAR A0[]="A0";
CHAR IN[]="PUERTO A";
glcd_init(ON);
glcd_text57(33,30,A5,1,1);
glcd_text57(49,30,A4,1,1);
glcd_text57(65,30,A3,1,1);
glcd_text57(81,30,A2,1,1);
glcd_text57(97,30,A1,1,1);
glcd_text57(113,30,A0,1,1);
glcd_text57(30,5,IN,2,1);
while(TRUE){
if(input_state(PIN_A5)==0){glcd_rect(32,40,46,60,1,1);}
if(input_state(PIN_A5)==1){glcd_rect(32,40,46,60,1,0);glcd_rect(32,40,46,60,0,1);}
if(input_state(PIN_A4)==0){glcd_rect(48,40,62,60,1,1);}
if(input_state(PIN_A4)==1){glcd_rect(48,40,62,60,1,0);glcd_rect(48,40,62,60,0,1);}
if(input_state(PIN_A3)==0){glcd_rect(64,40,78,60,1,1);}
if(input_state(PIN_A3)==1){glcd_rect(64,40,78,60,1,0);glcd_rect(64,40,78,60,0,1);}
if(input_state(PIN_A2)==0){glcd_rect(80,40,94,60,1,1);}
if(input_state(PIN_A2)==1){glcd_rect(80,40,94,60,1,0);glcd_rect(80,40,94,60,0,1);}
if(input_state(PIN_A1)==0){glcd_rect(96,40,110,60,1,1);}
if(input_state(PIN_A1)==1){glcd_rect(96,40,110,60,1,0);glcd_rect(96,40,110,60,0,1);}
if(input_state(PIN_A0)==0){glcd_rect(112,40,126,60,1,1);}
if(input_state(PIN_A0)==1){glcd_rect(112,40,126,60,1,0);glcd_rect(112,40,126,60,0,1);}
delay_ms(500);
}
}
Descarga la simulación en proteus 8.13 del circuito aquí
________________________________________
Ejemplo Nº5: Introducir datos por el teclado y visualizarlos en el LCD.
________________________________________
#include <16f877A.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT
#use delay(clock=20M)
//#DEFINE USE_PORTB_LCD FALSE
//#DEFINE USE_PORTB_KBD FALSE
#DEFINE USE_PORTB_KBD
#include <lcd.c>
#include <kbd.c>
void main(){
char k;
int x;
lcd_init();
kbd_init();
port_b_pullups(true); //puerto B el hig-(1)-(true)
lcd_putc("\fListo...\n"); // \f Borra todo lo que halla en el display
while(TRUE){
k=kbd_getc(); //se guarda el valor de la tecla en la variable K
x=k-48;
if (k != 0){
if (k == '*' ){ lcd_putc('\f');}
else{
lcd_putc(k);
delay_ms(500);
printf(lcd_putc,"\f Car=%c",k); //imprime caracter
delay_ms(500);
printf( lcd_putc,"\f Car=%u",k); //Imprime valor ASCII
delay_ms(500);
printf(lcd_putc,"\f Num=%u",x); //Imprime valor numerico
delay_ms(500);
lcd_putc("\fListo...\n");
}
}
}
}
Descarga la simulación en proteus 8.13 del circuito aquí
________________________________________
Ejemplo Nº6: Diseño básico de Control de acceso de una puerta, a través de un teclado 3x4,guardando la clave de 3 dígitos en la memoria EEPRON.
________________________________________
Descarga la simulación en proteus 8.13 del circuito aquí
#include <16f877A.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT
#use delay(clock=20M)
//#DEFINE USE_PORTB_LCD FALSE
//#DEFINE USE_PORTB_KBD FALSE
#DEFINE USE_PORTB_KBD
#include <lcd.c>
#include <kbd.c>
#include <stdlib.h>
#use standard_io(c)
#rom 0x2100 = {'7','2','5'} //posicion 0,1,2 de la Eeprom con los datos
// 7, 2 y 3 respectivamente
void main(){
char k=0;
int i=0;
char data[3],clave[3]; //Matrices para guardar clave y datos
lcd_init();
kbd_init();
port_b_pullups(TRUE);
while (TRUE) {
i=0; //posicion de la Matriz
printf(lcd_putc,"\fpulsar tecla 1\n");// para primer dato
while(i<=2){ //para tres datos i=0,1,2
k=kbd_getc(); //lee el teclado
if(k!=0){
data[i]=k; //se guarda en la posicion correspondiente
i++;// i +1
k=0;
printf(lcd_putc,"\fpulsar tecla %u\n",i+1);//siguiente dato
}
}
for(i=0;i<=2;i++){ //pasa datos de Eepron a la matriz clave
clave[i]=read_eeprom(i);
}
if((data[0]==clave[0])&&(data[1]==clave[1])&&(data[2]==clave[2])){
printf(lcd_putc,"\fPuerta Abierta"); //Compara los datos y la clave
output_high(PIN_C0); // si es igual da pulso al rele
delay_ms(500);
output_low(PIN_C0);
}
else{
printf(lcd_putc,"\fPuerta Cerrada"); // Clave erronea
delay_ms(1000);
}
}
}
________________________________________
Ejemplo Nº7: Generar una señal modulada en ancho de pulso proporcional al dato introducido por un teclado 3x4.
________________________________________
#include <16f877A.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT
#use delay(clock=20M)
//#DEFINE USE_PORTB_LCD FALSE
//#DEFINE USE_PORTB_KBD FALSE
#DEFINE USE_PORTB_KBD
//#include <lcd.c>
#include <kbd.c>
#use standard_io(C)
void main(){
char k=0, k_ant='0';
char PWMH=0,PWML=0;
kbd_init();
port_b_pullups(TRUE);
while (TRUE) {
k=kbd_getc();
if(k=='\0'){ // si no se presiona la tecla (\0) se usa
k=k_ant; // el valor anterior
}
if((k=='*') || (k=='#')){
k='0';
}
k_ant=k;
k=k-48;
PWMH=K*(255/9);
PWML=255-PWMH;
for(PWMH;PWMH>0;PWMH--){ OUTPUT_HIGH(PIN_C0);}
for(PWML;PWML>0;PWML--){ OUTPUT_LOW(PIN_C0);}
}
}
Descarga la simulación en proteus 8.13 del circuito aquí
-Mejora Con CCP1 y lcd para visualizar los datos
#include <16f877A.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOPROTECT,BROWNOUT
#use delay(clock=20M)
#DEFINE USE_PORTB_KBD
#include <lcd.c>
#include <kbd.c>
#include <stdlib.h>
#include <map_function.c> // Libreria para hacer conversiones
#use standard_io(c)
void main(){
char k=0;
int8 valor_pwm=0,valor_tecla=0,porcentaje=0;
lcd_init();
kbd_init();
port_b_pullups(TRUE);
setup_timer_2(t2_div_by_16, 255, 1);
setup_ccp1(ccp_pwm);
set_pwm1_duty(0); // Motor PIN_C2
while (TRUE) {
k=kbd_getc();
if(k!=0){
valor_tecla=k-48;
valor_pwm = map(valor_tecla, 0, 9, 0, 255);
porcentaje = map(valor_tecla, 0, 9, 0, 100);
set_pwm1_duty(valor_pwm);
lcd_gotoxy(1,1);
printf(lcd_putc,"PWM:%u ",valor_pwm);
lcd_gotoxy(9,1);
printf(lcd_putc,"tecla: %u ",valor_tecla);
lcd_gotoxy(1,2);
printf(lcd_putc,"Porcentaje: %u%% ",porcentaje);
k=0;
}
}
}
Descarga la simulación en proteus 8.13 del circuito aquí
________________________________________
Ejemplo Nº8: Modulo de temperatura con el sensor Lm35,Con salida de 4 a 20m[A],con los datos visualizados en una pantalla oled de 0.96".
________________________________________
Data sheet del LM35
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Descarga la simulación en proteus 8.13 del circuito aquí
#include <18f2550.h>
#device adc=10
#device PASS_STRINGS = IN_RAM
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,CPUDIV1,NODEBUG,VREGEN,NOPBADEN
#use I2C(MASTER, SDA=PIN_B0, SCL=PIN_B1, FAST=400000, STREAM=SSD1306_STREAM)
#use delay(clock=20M)
#include <map_function.c>
#define SSD1306_I2C_ADDRESS 0x7a // Direccion 0x78 o 0x7A
#include <SSD1306_OLED.c> // Libreria para manejo de pantalla OLED por I2C
int8 temperatura;
int16 valor_adc,valor_adc1;
int8 nivel;
char buffer[10],corrie[10],H[10];
void main(){
setup_adc_ports(AN0);
setup_adc(adc_clock_internal);
setup_ccp1(ccp_pwm);
set_pwm1_duty(0);
setup_timer_2(t2_div_by_16, 255, 1);
SSD1306_Begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS); // Inicializa la pantalla OLED
SSD1306_ClearDisplay(); // Inicialmente se limpia la pantalla OLED
SSD1306_Display();
while(true) {
set_adc_channel(0);
delay_us(2);
valor_adc = read_adc();
set_adc_channel(1);// Lectura del ADC
delay_us(2);
valor_adc1 = read_adc();
if (0<=valor_adc && valor_adc<=123){
SSD1306_ClearDisplay();
float adc_tem=map(valor_adc,0,123,0,122.76);
temperatura=map(adc_tem,0,122.76,0,60);
nivel=map(temperatura,0,60,32,0);
int valor_pwm = map(valor_adc, 0, 123, 52, 255);
float corriente = map(valor_adc,0,123,4,20);
float voltage_linea=map(valor_adc1,0,1023,0,5);
float corriente_linea=(voltage_linea/248)*1000;
set_pwm1_duty(valor_pwm);
sprintf(buffer, "%u C", temperatura);
SSD1306_DrawText(55, 6, buffer, 2);
// sprintf(volt, "%f V", voltage);
SSD1306_DrawCircle(104,5,2);
// SSD1306_DrawText(45, 45, volt, 2);
sprintf(corrie, "%3.1fmA", corriente);
SSD1306_DrawText(53, 28, corrie, 2);
SSD1306_DrawRoundRect(50, 1, 65,21,5);
SSD1306_DrawRoundRect(48, 25, 80,20,5);
//////
// SSD1306_DrawLine(23, 39,28, 39,TRUE);
SSD1306_DrawCircle(14,50,10);
//SSD1306_DrawCircle(14,50,10);
SSD1306_FillCircle(14,50,7,TRUE);
SSD1306_DrawCircleHelper(14, 7, 7, 3);
SSD1306_DrawLine(7, 42, 7, 7,TRUE);
SSD1306_DrawLine(21, 42,21, 7,TRUE);
SSD1306_DrawPixel(9, 41,0);
SSD1306_DrawPixel(8, 42,0);
SSD1306_DrawPixel(19, 41,0);
SSD1306_DrawPixel(20, 42,0);
SSD1306_FillRect(10, 40, 9, 4,TRUE);
//
SSD1306_FillRect(10, 8, 9, 32,TRUE);
SSD1306_FillRect(10, 8, 9, nivel,0);
///niveles
// lineas de nivel de temperatura
SSD1306_DrawLine(23, 40,28, 40,TRUE);
SSD1306_DrawText(30, 39,"0", 1);
SSD1306_DrawLine(23, 29,28, 29,TRUE);
SSD1306_DrawText(30, 29,"20", 1);
SSD1306_DrawLine(23, 18,28, 18,TRUE);
SSD1306_DrawText(30, 19,"40", 1);
SSD1306_DrawLine(23, 9,28, 9,TRUE);
SSD1306_DrawText(30, 9,"60", 1);
//temperatura cº
SSD1306_DrawText(0, 5,"C", 1);
SSD1306_DrawCircle(4,2,1);
sprintf(H,"%3.2f mA",corriente_linea);
SSD1306_DrawText(55, 50, H, 1);
SSD1306_Display();
}
}
}
________________________________________
Ejemplo Nº9: Modulo de temperatura - Humedad con el sensor HDT11,con los datos visualizados en una pantalla Lcd de 16x2.
________________________________________
Descarga la simulación en proteus 8.13 del circuito aquí
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOLVP,NOBROWNOUT
#use delay(clock=20M)
#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
#use standard_io(D)
#define DHT11_PIN PIN_D0
#define LCD_DB4 PIN_D4 // Pines de la pantalla LCD
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7
#define LCD_RS PIN_D2
#define LCD_E PIN_D3
#include <LCD_16X2.c> // Libreria para el manejo de la pantalla LCD
#include <DHT11.c>
#include <stdio.h>
int data_ok = 0;
float humedad, temperatura;
void main()
{
lcd_init();
while(true)
{
data_ok = DHT11_read_data(&humedad, &temperatura);
if(data_ok == 1)
{
lcd_clear();
lcd_gotoxy(1,1);
printf(lcd_putc,"Hum = %0.1f%%", humedad);
lcd_gotoxy(1,2);
printf(lcd_putc,"Tem = %0.1fC", temperatura);
printf("Hum = %0.1f%%\r\n",humedad);
printf("Tem = %0.1fC\r\n\r\n",temperatura);
}
else
{
lcd_clear();
lcd_gotoxy(2,1);
lcd_putc("No Conectado");
}
delay_ms(1400);
}
}
________________________________________
Ejemplo Nº10: Modulo de temperatura con el sensor Lm35 y el pic16F1824,Con salida de 4 a 20m[A],con los datos visualizados en una pantalla lcd ,con modelo 3D del diseño PCB.
________________________________________
Descarga la simulación en proteus 8.13 del circuito aquí
#include <16F1824.h>
#device adc=10
#use delay(clock=4M)
#use standard_io(C)
#define LCD_DB4 PIN_C2
#define LCD_DB5 PIN_C3
#define LCD_DB6 PIN_C4
#define LCD_DB7 PIN_C5
#define LCD_RS PIN_C0
#define LCD_E PIN_C1
#include <LCD_16X2.c>
#include <map_function.c>
#use standard_io(A)
#include <MATH.h>
void main(){
lcd_init();
output_low(PIN_A1);
setup_timer_2(t2_div_by_16, 255, 1);
setup_adc_ports(ALL_ANALOG);
setup_adc(adc_clock_internal);
float tensionAnt=0,tension,corriente,temperatura;
int1 activado=1;
int16 i=0;
lcd_clear();
while(TRUE){
set_adc_channel(0);
delay_us(5);
tension=read_adc()*5.0/1023.0; //Lee el ADC y convierte en valor de tensión
if(i>=0 && i<500){ //Lazo de 500 iteraciones para sacar promedio
tensionAnt=tension+tensionAnt; //Suma del acumulado para sacar promedio
i++;
continue;
}
tension=tensionAnt/500;
corriente=tension*(1000/62.5);
temperatura=map(corriente,4,20,0,100);
temperatura=abs(temperatura);
lcd_gotoxy(1,1);
lcd_putc("TEMPERATURA");
lcd_gotoxy(1,2);
printf(lcd_putc,"%0.2f ",temperatura);
lcd_gotoxy(7,2);
lcd_putc("C");
lcd_gotoxy(10,2);
printf(lcd_putc,"%0.2f",corriente);
lcd_gotoxy(15,2);
lcd_putc("mA");
tensionAnt=0;
i=0;
if(corriente>20.1){output_high(PIN_A1);activado=1;}
if(corriente<20.1){output_low(PIN_A1);activado=0;}
if(activado){
output_high(PIN_A2);
delay_ms(500);
output_low(PIN_A2);
delay_ms(500);
}
}
}
0 Comentarios